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 相关文章推荐
PHP 高手之路(一)
Oct 09 PHP
dedecms模版制作使用方法
Apr 03 PHP
用PHP伪造referer突破网盘禁止外连的代码
Jun 15 PHP
php 在文件指定行插入数据的代码
May 08 PHP
PHP的switch判断语句的“高级”用法详解
Oct 01 PHP
用PHP代码在网页上生成图片
Jul 01 PHP
php图像处理类实例
Jul 28 PHP
PHP中strcmp()和strcasecmp()函数字符串比较用法分析
Jan 07 PHP
php 生成Tab键或逗号分隔的CSV
Sep 24 PHP
php实现的表单验证类完整示例
Aug 13 PHP
Yii框架安装简明教程
May 15 PHP
Laravel6.18.19如何优雅的切换发件账户
Jun 14 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教程孙仲岳主讲
2008/01/07 PHP
基于PHP文件操作的详解
2013/06/05 PHP
php读取文件内容的三种可行方法示例介绍
2014/02/08 PHP
php5.3以后的版本连接sqlserver2000的方法
2014/07/28 PHP
php的curl封装类用法实例
2014/11/07 PHP
PHP+Ajax实现的无刷新分页功能详解【附demo源码下载】
2017/07/03 PHP
asp 的 分词实现代码
2007/05/24 Javascript
bgsound 背景音乐 的一些常用方法及特殊用法小结
2010/05/11 Javascript
JQuery 文本框使用小结
2010/05/22 Javascript
Javascript中匿名函数的多种调用方式总结
2013/12/06 Javascript
轻松创建nodejs服务器(9):实现非阻塞操作
2014/12/18 NodeJs
js实现带缓冲效果的仿QQ面板折叠菜单代码
2015/09/06 Javascript
jQuery中的AjaxSubmit使用讲解
2016/09/25 Javascript
ES6新特性之解构、参数、模块和记号用法示例
2017/04/01 Javascript
jquery请求servlet实现ajax异步请求的示例
2017/06/03 jQuery
详解React Native开源时间日期选择器组件(react-native-datetime)
2017/09/13 Javascript
koa上传excel文件并解析的实现方法
2018/08/09 Javascript
layui表格分页 记录勾选的实例
2019/09/02 Javascript
10分钟学会js处理json的常用方法
2020/12/06 Javascript
[49:54]Ti4 循环赛第三日 LGD vs Titan
2014/07/12 DOTA
[09:47]2018DOTA2亚洲邀请赛4.5SOLO赛 No[o]ne vs Sumail
2018/04/06 DOTA
Python标准库defaultdict模块使用示例
2015/04/28 Python
Python备份目录及目录下的全部内容的实现方法
2016/06/12 Python
Python生成随机数组的方法小结
2017/04/15 Python
python定时利用QQ邮件发送天气预报的实例
2017/11/17 Python
python引用(import)某个模块提示没找到对应模块的解决方法
2019/01/19 Python
对Python中TKinter模块中的Label组件实例详解
2019/06/14 Python
html5拍照功能实现代码(htm5上传文件)
2013/12/11 HTML / CSS
【HTML5】3D模型--百行代码实现旋转立体魔方实例
2016/12/16 HTML / CSS
亚马逊印度站:Amazon.in
2017/10/15 全球购物
煤矿安全演讲稿
2014/05/09 职场文书
2014年光棍节活动策划方案(创意集锦)
2014/09/29 职场文书
2015年安康杯竞赛活动总结
2015/03/26 职场文书
大学生暑假实习总结
2015/07/13 职场文书
python实现会员管理系统
2022/03/18 Python
MySQL表锁、行锁、排它锁及共享锁的使用详解
2022/04/02 MySQL