php实现将HTML页面转换成word并且保存的方法


Posted in PHP onOctober 14, 2016

本文实例讲述了php实现将HTML页面转换成word并且保存的方法。分享给大家供大家参考,具体如下:

这里用使用到一个PHP的工具叫:PHPWord。

生成Word的原理是,将堆规定好了的xml压缩成一个zip包,并且把后缀名改成doc或者docx即可。

所以使用PHPWord,需要你的PHP环境安装zip.dll压缩扩展,我写了一个demo.

功能说明:

20150507 — HTML中的<p>标签和<ol>列表标签的获取
20150508 — 新增获取文章中的图片功能
20150509 — 新增行间距,并且过滤一下错误图片
20150514 — 新增表格处理,并且将代码改成面向对象
20150519 — 新增GD库处理网络图片

require_once 'PHPWord.php';
require_once 'SimpleHtmlDom.class.php';
class Word{
 private $url;
 private $LinetextArr = array();
 public $CurrentDir;
 public $error = array(); //错误数组
 public $filename = null;
 public $Allowtag = "p,ol,ul,table";
 /**数据统计**/
 public $DownImg = 0;
 public $expendTime = 0;
 public $HttpRequestTime = 0;
 public $ContentLen = 0;
 public $HttpRequestArr = array();
 public $expendmemory = 0;
 public function __construct($url)
 {
 $startTime = $this->_Time();
 $startMemory = $this->_memory();
 $this->url = $url;
 $UrlArr = parse_url($this->url);
 $this->host = $UrlArr["scheme"]."://".$UrlArr['host'];
 $this->CurrentDir = getcwd();
 $this->LinetextArr["table"] = array();
 $html = new simple_html_dom($this->url);
 $this->HttpRequestArr[] = $this->url;
 $this->HttpRequestTime++;
 foreach($html->find($this->Allowtag) as $key=>$value)
 {
 if($value->tag == "table")
 {
 $this->ParseTable($value,0,$this->LinetextArr["table"]);
 }
 else
 {
 $this->AnalysisHtmlDom($value);
 }
 $this->error[] = error_get_last();
 }
 $endTime = $this->_Time();
 $endMemory = $this->_memory();
 $this->expendTime = round(($endTime-$startTime),2); //微秒
 $this->expendmemory = round(($endMemory-$startMemory)/1000,2); //bytes
 $this->CreateWordDom();
 }
 private function _Time()
 {
 return array_sum(explode(" ", microtime()));
 }
 private function _memory()
 {
 return memory_get_usage();
 }
 /**
 * 解析HTML中的Table,这里考虑到多层table嵌套的情况
 * @param $value HTMLDOM
 * @param $i 遍历层级
 * **/
 private function ParseTable($value,$i,$Arr)
 {
 if($value->firstChild() && in_array($value->firstChild()->tag,array("table","tbody","thead","tfoot","tr")))
 {
 foreach($value->children as $k=>$v)
 {
 $this->ParseTable($v,$i++,$Arr);
 }
 }
 else
 {
 foreach($value->children as $k=>$v)
 {
 if($v->firstChild() && $v->firstChild()->tag != "table")
 {
 $Arr[$i][] = array("tag"=>$v->tag,"text"=>trim($v->plaintext));
 }
 if(!$v->firstChild())
 {
 $Arr[$i][] = array("tag"=>$v->tag,"text"=>trim($v->plaintext));
 }
 }
 }
 }
 /**
 * 解析HTML里面的表情
 * @param $value HTMLDOM
 * **/
 private function AnalysisHtmlDom($value)
 {
 $tmp = array();
 if($value->has_child())
 {
 foreach($value->children as $k=>$v)
 {
 $this->AnalysisHtmlDom($v);
 }
 }
 else
 {
 if($value->tag == "a")
 {
 $tmp = array("tag"=>$value->tag,"href"=>$value->href,"text"=>$value->innertext);
 }
 else if($value->tag == "img")
 {
 $src = $this->unescape($value->src);
 $UrlArr = parse_url($src);
 if(!isset($UrlArr['host']))
 {
 $src = $this->host.$value->src;
 $UrlArr = parse_url($src);
 }
 $src = $this->getImageFromNet($src,$UrlArr); //表示有网络图片,需要下载
 if($src)
 {
  $imgsArr = $this->GD($src);
  $tmp = array("tag"=>$value->tag,"src"=>$src,"text"=>$value->alt,"width"=>$imgsArr['width'],"height"=>$imgsArr['height']); }
 }
 else
 {
 $tmp = array("tag"=>$value->tag,"text"=>strip_tags($value->innertext));
 }
 $this->LinetextArr[] = $tmp;
 }
 }
 /**
 * 根据GD库来获取图片的如果太多,进行比例压缩
 * **/
 private function GD($src)
 {
 list($width, $height, $type, $attr) = getimagesize($src);
 if($width > 800 || $height > 800 )
 {
 $width = $width/2;
 $height = $height/2;
 }
 return array("width"=>$width,"height"=>$height);
 }
 /**
 * 将Uincode编码转移回原来的字符
 * **/
 public function unescape($str) {
 $str = rawurldecode($str);
 preg_match_all("/(?:%u.{4})|&#x.{4};|&#\d+;|.+/U",$str,$r);
 $ar = $r[0];
 foreach($ar as $k=>$v) {
 if(substr($v,0,2) == "%u"){
 $ar[$k] = iconv("UCS-2BE","UTF-8",pack("H4",substr($v,-4)));
 }
 elseif(substr($v,0,3) == "&#x"){
 $ar[$k] = iconv("UCS-2BE","UTF-8",pack("H4",substr($v,3,-1)));
 }
 elseif(substr($v,0,2) == "&#"){
 $ar[$k] = iconv("UCS-2BE","UTF-8",pack("n",substr($v,2,-1)));
 }
 }
 return join("",$ar);
}
 /**
 * 图片下载
 * @param $Src 目标资源
 * @param $UrlArr 目标URL对应的数组
 * **/
 private function getImageFromNet($Src,$UrlArr)
 {
 $file = basename($UrlArr['path']);
 $ext = explode('.',$file);
 $this->ImgDir = $this->CurrentDir."/".$UrlArr['host'];
 $_supportedImageTypes = array('jpg', 'jpeg', 'gif', 'png', 'bmp', 'tif', 'tiff');
 if(isset($ext['1']) && in_array($ext['1'],$_supportedImageTypes))
 {
 $file = file_get_contents($Src);
 $this->HttpRequestArr[] = $Src;
 $this->HttpRequestTime++;
 $this->_mkdir(); //创建目录,或者收集错误
 $imgName = md5($UrlArr['path']).".".$ext['1'];
 file_put_contents($this->ImgDir."/".$imgName,$file);
 $this->DownImg++;
 return $UrlArr['host']."/".$imgName;
 }
 return false;
 }
 /**
 * 创建目录
 * **/
 private function _mkdir()
 {
 if(!is_dir($this->ImgDir))
 {
 if(!mkdir($this->ImgDir,"7777"))
 {
 $this->error[] = error_get_last();
 }
 }
 }
 /**
 * 构造WordDom
 * **/
 private function CreateWordDom()
 {
 $PHPWord = new PHPWord();
 $PHPWord->setDefaultFontName('宋体');
 $PHPWord->setDefaultFontSize("11");
 $styleTable = array('borderSize'=>6, 'borderColor'=>'006699', 'cellMargin'=>120);
 // New portrait section
 $section = $PHPWord->createSection();
 $section->addText($this->Details(),array(),array('spacing'=>120));
 //数据进行处理
 foreach($this->LinetextArr as $key=>$lineArr)
 {
 if(isset($lineArr['tag']))
 {
 if($lineArr['tag'] == "li")
 {
 $section->addListItem($lineArr['text'],0,"","",array('spacing'=>120));
 }
 else if($lineArr['tag'] == "img")
 {
 $section->addImage($lineArr['src'],array('width'=>$lineArr['width'], 'height'=>$lineArr['height'], 'align'=>'center'));
 }
 else if($lineArr['tag'] == "p")
 {
 $section->addText($lineArr['text'],array(),array('spacing'=>120));
 }
 }
 else if($key == "table")
 {
 $PHPWord->addTableStyle('myOwnTableStyle', $styleTable);
 $table = $section->addTable("myOwnTableStyle");
 foreach($lineArr as $key=>$tr)
 {
 $table->addRow();
 foreach($tr as $ky=>$td)
 {
 $table->addCell(2000)->addText($td['text']);
 }
 }
 }
 }
 $this->downFile($PHPWord);
 }
 public function Details()
 {
 $msg = "一共请求:{$this->HttpRequestTime}次,共下载的图片有{$this->DownImg}张,并且下载完成大约使用时间:{$this->expendTime}秒,整个程序执行大约消耗内存是:{$this->expendmemory}KB,";
 return $msg;
 }
 public function downFile($PHPWord)
 {
 if(empty($this->filename))
 {
 $UrlArr = parse_url($this->url);
 $this->filename = $UrlArr['host'].".docx";
 }
 // Save File
 $objWriter = PHPWord_IOFactory::createWriter($PHPWord, 'Word2007');
 $objWriter->save($this->filename);
 header("Pragma: public");
 header("Expires: 0");
 header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
 header("Cache-Control: public");
 header("Content-Description: File Transfer");
 //Use the switch-generated Content-Type
 header('Content-type: application/msword');//输出的类型
 //Force the download
 $header="Content-Disposition: attachment; filename=".$this->filename.";";
 header($header);
 @readfile($this->filename);
 }
}

上面的代码重点感觉不是word生成,而是Simplehtmldom的使用,这是一个开源的HTML解析器,之前有提到,这几天在看他的代码,

引出了两个学习方向

① 正在表达式

② 这个扩展的函数整理

看源代码的收获:

PHP的异常是可以捕获的,而且PHP的错误也是可以捕获的。

error_get_last() //用这个函数可以捕获页面中的PHP错误,不谢。

希望本文所述对大家PHP程序设计有所帮助。

PHP 相关文章推荐
分页显示Oracle数据库记录的类之一
Oct 09 PHP
使用PHP数组实现无限分类,不使用数据库,不使用递归.
Dec 09 PHP
php中文验证码实现方法
Jun 18 PHP
PHP伪造来源HTTP_REFERER的方法实例详解
Jul 06 PHP
PHP实现通过get方式识别用户发送邮件的方法
Jul 16 PHP
百万级别知乎用户数据抓取与分析之PHP开发
Sep 28 PHP
如何在旧的PHP系统中使用PHP 5.3之后的库
Dec 02 PHP
浅谈PHP值mysql操作类
Jun 29 PHP
thinkphp框架实现删除和批量删除
Jun 29 PHP
thinkPHP5.1框架使用SemanticUI实现分页功能示例
Aug 03 PHP
Laravel框架Eloquent ORM修改数据操作示例
Dec 03 PHP
php7 图形用户界面GUI 开发示例
Feb 22 PHP
PHP中多线程的两个实现方法
Oct 14 #PHP
PHP在innodb引擎下快速代建全文搜索功能简明教程【基于xunsearch】
Oct 14 #PHP
PHP面向对象自动加载机制原理与用法分析
Oct 14 #PHP
ThinkPHP打水印及设置水印位置的方法
Oct 14 #PHP
PHP 将dataurl转成图片image方法总结
Oct 14 #PHP
php版微信公众号接口实现发红包的方法
Oct 14 #PHP
PHP版微信第三方实现一键登录及获取用户信息的方法
Oct 14 #PHP
You might like
PHP zlib扩展实现页面GZIP压缩输出
2010/06/17 PHP
解析PHP跨站刷票的实现代码
2013/06/18 PHP
thinkphp3查询mssql数据库乱码解决方法分享
2014/02/11 PHP
typecho插件编写教程(一):Hello World
2015/05/28 PHP
Yii多表联合查询操作详解
2016/06/02 PHP
PHP+AJAX 投票器功能
2017/11/11 PHP
PHP使用XMLWriter读写xml文件操作详解
2018/07/31 PHP
php实现单笔转账到支付宝功能
2018/10/09 PHP
PHP精确到毫秒秒杀倒计时实例详解
2019/03/14 PHP
cnblogs TagCloud基于jquery的实现代码
2010/06/11 Javascript
BOM与DOM的区别分析
2010/10/26 Javascript
增强用户体验友好性之jquery easyui window 窗口关闭时的提示
2012/06/22 Javascript
JS实现单行文字不间断向上滚动的方法
2015/01/29 Javascript
一道常被人轻视的web前端常见面试题(JS)
2016/02/15 Javascript
jquery设置表单元素为不可用的简单代码
2016/07/04 Javascript
JQuery和HTML5 Canvas实现弹幕效果
2017/01/04 Javascript
nodejs接入阿里大鱼短信验证码的方法
2017/07/10 NodeJs
webpack css加载和图片加载的方法示例
2018/09/11 Javascript
JS中自定义事件的使用与触发操作实例分析
2019/11/01 Javascript
echarts.js 动态生成多个图表 使用vue封装组件操作
2020/07/19 Javascript
基于vue与element实现创建试卷相关功能(实例代码)
2020/12/07 Vue.js
Python程序设计入门(5)类的使用简介
2014/06/16 Python
Python实现程序的单一实例用法分析
2015/06/03 Python
python之文件的读写和文件目录以及文件夹的操作实现代码
2016/08/28 Python
浅谈python字典多键值及重复键值的使用
2016/11/04 Python
Python绘制正余弦函数图像的方法
2018/08/28 Python
详解python项目实战:模拟登陆CSDN
2019/04/04 Python
pycharm设置python文件模板信息过程图解
2020/03/10 Python
Python Request类源码实现方法及原理解析
2020/08/17 Python
Python中Yield的基本用法
2020/10/18 Python
python 通过pip freeze、dowload打离线包及自动安装的过程详解(适用于保密的离线环境
2020/12/14 Python
PurCotton全棉时代官网:100%天然棉花生产的生活护理用品
2016/11/18 全球购物
实习护理工作自我评价
2013/09/25 职场文书
后勤采购员岗位职责
2013/12/19 职场文书
《一本男孩子必读的书》教学反思
2014/02/19 职场文书
保健品市场营销方案
2014/03/31 职场文书