php 模板替换,使用PHPWord对Word文件做模板替换

因工作需要,使用了版本比较旧的PHPWord项目

官方已不见维护更新,上次版本更新是在Fri Jul 8, 2011 at 8:00 AM

如果PHP版本>=5.3.3,强烈推荐使用PHPOffice/PHPWord这个开源项目

本篇针对的为旧版本的PHPWord

基本安装

问题总结

Autoloader自动加载部分情况下失败

在使用Yii 1配置自动加载时无法正常加载类库,需对其PHPWord/Autoloader.php做部分调整,这儿借鉴了PHPExcel的Autoloader:

/**

* PHPWord_Autoloader

*/

class PHPWord_Autoloader

{

/**

* Register the Autoloader with SPL

*

*/

public static function Register() {

$functions = spl_autoload_functions();

foreach ( $functions as $function)

spl_autoload_unregister($function);

$functions = array_merge(array(array('PHPWord_Autoloader','Load')),$functions);

foreach ( $functions as $function)

$x = spl_autoload_register($function);

return $x;

} // function Register()

/**

* Autoload a class identified by name

*

* @param string $pClassName Name of the object to load

*/

public static function Load($pClassName){

if ((class_exists($pClassName,FALSE)) || (strpos($pClassName, 'PHPWord') !== 0)) {

// Either already loaded, or not a PHPWord class request

return FALSE;

}

$pClassFilePath = PHPWORD_BASE_PATH .

str_replace('_',DIRECTORY_SEPARATOR,$pClassName) .

'.php';

if ((file_exists($pClassFilePath) === FALSE) || (is_readable($pClassFilePath) === FALSE)) {

// Can't load

return FALSE;

}

require($pClassFilePath);

} // function Load()

}

模板替换时无法识别模板标签

表现

使用/复制官方样例的模板文件替换正常

自己手动敲出模板标签替换异常

原因

PHPWord的替换规则是将Word文件解析成XML进行替换处理,当Word解析成XML时字符分离了,导致匹配不上模板标签;

具体分析可参考一下资料:

解决办法

改进Template类:

可参考Github: Arisse/PHPWord_CloneRow对Template类进行改造。

因为下面仍需要修改Template类,这儿暂时就不贴代码了,下面一并贴出改造后的代码。

中文乱码

编辑PHPWord/Template.php,找到代码$replace = utf8_encode($replace);,删除或者注释掉这行代码,添加$replace = iconv( 'gbk','utf-8', $replace);,比如代码改为如下:

/**

* Set a Template value

*

* @param mixed $search

* @param mixed $replace

*/

public function setValue($search, $replace) {

if(substr($search, 0, 2) !== '${' && substr($search, -1) !== '}') {

$search = '${'.$search.'}';

}

if(!is_array($replace)) {

//$replace = utf8_encode($replace);

$replace =iconv('gbk', 'utf-8', $replace); // 注释掉上面行后添加这行

}

$this->_documentXML = str_replace($search, $replace, $this->_documentXML);

}

空格输出

在想要输出换行的地方用
代替即可.

标记符号输出

参考百度经验: 如何在word中选择打钩的方框

仅以输出□和☑为例,其它符号与之类似。

注:PHP文件需要使用UTF-8编码

在Word文件中按照参考文件方式插入☑;

复制符号到PHP文件;

正常的输出替换。

具体代码见如下的项目代码。

Template类代码

// code

/**

* Set a Template value

*

* @param mixed $search

* @param mixed $replace

*/

public function setValue($search, $replace, $limit=-1) {

if(substr($search, 0, 1) !== '{' && substr($search, -1) !== '}') {

$search = '{'.$search.'}';

}

if(!is_array($replace)) {

// $replace = utf8_encode($replace);

// $replace = iconv( 'gbk','utf-8', $replace);

$replace = str_replace("\n","
",$replace);

}

preg_match_all('/\{[^}]+\}/', $this->_documentXML, $matches);

foreach ($matches[0] as $k => $match) {

$no_tag = strip_tags($match);

if ($no_tag == $search) {

$match = '{'.$match.'}';

$this->_documentXML = preg_replace($match, $replace, $this->_documentXML, $limit);

if ($limit == 1) {

break;

}

}

}

}

// code

项目代码

// @author Heier xheier@outlook.com

public function actionExportPersonTable() {

// 获取数据部分代码

// ...

$PHPWord = new PHPWord();

// Word模板目录

$personBasePath = Yii::app()->basePath.'/person/';

// 删除目录下临时文件-十分钟以前

$this->delfile( $personBasePath, 10 );

// 模板文件名

$tempName = $personBasePath . '/moban.docx';

$word = $PHPWord->loadTemplate( $tempName );

// 项目使用的是GBK编码,需要做转换

$username = iconv('gbk', 'utf-8', getUserNameById($personData[0]['user_id']) );

$personal_type = $personData[0]['personal_type'];

// 模板替换开始

// 可以输出打勾的方框

$deptA=$deptBP=$deptB=$deptC=$deptD = '□';

if( $DirectorLevel == 'A' ) {

$deptA = '☑';

} elseif( $DirectorLevel == 'B+' ) {

$deptBP = '☑';

} elseif( $DirectorLevel == 'B' ) {

$deptB = '☑';

} elseif( $DirectorLevel == 'C' ) {

$deptC = '☑';

} elseif( $DirectorLevel == 'D' ) {

$deptD = '☑';

}

$word->setValue('deptA', $deptA);

$word->setValue('deptBP', $deptBP);

$word->setValue('deptB', $deptB);

$word->setValue('deptC', $deptC);

$word->setValue('deptD', $deptD);

// 设置其它替换

// ...

// 生成临时文件以供下载

$tmpFileName = md5( time().'Heier' );

$word->save($personBasePath . '/' . $tmpFileName .'.docx');

$file = $personBasePath . '/' . $tmpFileName .'.docx';

// 下载Word文件

ob_start(); //打开缓冲区

$fp = fopen($file,"r");

$file_size = filesize($file);

$downFileName = 'XXX.docx';

header("Cache-Control: public");

header("Content-type: application/octet-stream");

header("Accept-Ranges: bytes");

header("Content-Disposition: attachment; filename={$downFileName}");

header("Pragma:no-cache");

header("Expires:0");

$buffer = 1024;

$file_count = 0;

//向浏览输出回数据

while(!feof($fp) && $file_count < $file_size){

$file_con = fread($fp,$buffer);

$file_count += $buffer;

echo $file_con;

}

ob_end_flush();//输出全部内容到浏览器

}

参考文档汇总

关于我

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/302243.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

服务端和客户端证书各种组合下对访问者(浏览器/中间人)的影响

今天本来想研究下nginx下如果获取SSL指纹&#xff0c;但是环境没有装成功就尝试了下如果不用nginx直接在服务端拿到SSL指纹&#xff0c;没想到从创建自签名证书到如何开启证书&#xff0c;以及服务端证书和客户端证书各种组合校验的测试就花了我很长时间。(注意自签名证书用Rsa…

Android之应用APN、WIFI、GPS定位小例子

转自一个网上项目&#xff0c;由于是例子打包下载&#xff0c;出处不详。例子中自我写入注释。Activity类&#xff1a;package com.maxtech.common;import com.maxtech.common.gps.GpsTask;import com.maxtech.common.gps.GpsTaskCallBack;import com.maxtech.common.gps.GpsTa…

如果科学家封神,会有什么称号?

全世界只有3.14 % 的人关注了数据与算法之美你听说过“天雷真君”吗&#xff1f;你知道“虐猫狂人"吗&#xff1f;其实这两个称号是网友分别送给大科学家富兰克林和薛定谔的。今天让我们看看伟大的科学家们还有一些什么有趣的称号。尺规小王子高斯如来神展傅立叶勾股圣手—…

mac php mcrypt,MacOSX 10.10安装mcrypt详细教程分享

mcrypt 是使用安全技术来交换数据文件加密方法. 这是必需的&#xff0c;例如一些 Magento 的 Web 应用程序,购物车软件或一个 PHP 框架&#xff0c;比如 Laravel. 本教程在 OS X 10.10 Yosemite 经过测试。本指南是真正为用户提供了PHP运行于OSX Yosemite 的5.5.14 版本。其他下…

WPF加载高德地图

WPF开发者QQ群&#xff1a; 340500857 前言 有小伙伴问如何加载高德地图。欢迎转发、分享、点赞&#xff0c;谢谢大家~。 接着上一篇源码中放了我的 BingMap Key 请大家不要滥用&#xff0c;谢谢。也可以自行申请 BingMap Key https://www.bingmapsportal.com/效果预览&#x…

深度学习与机器学习到底什么关系?

最近广州的天气老是变幻无常&#xff0c;前脚还冻得瑟瑟发抖&#xff0c;后脚又开始夏天模式&#xff08;如下图&#xff09;&#xff0c;让小天甚是怀念每天艳阳高照的夏天&#xff0c;虽然热了点但好歹不用担心猝不及防地收到寒风暴雨黄色预警。说到夏天&#xff0c;不得不提…

全选按钮的使用。winfrom程序中,对全选按钮的理解,欢迎拍砖!

最近在做公司项目时&#xff0c;用到了一些单选多选的处理情况。特编辑此文&#xff0c;欢迎批评指正。&#xff08;有图有真相&#xff09; winfrom程序。 首先&#xff0c;需要绑定某些用户&#xff0c;该用于由当前登陆用户获取。 private void BindUser() { …

php 新浪面试题,php程序员面试题(新浪篇)

新浪PHP工程笔试题1. 写一个函数&#xff0c;尽可能高效的&#xff0c;从一个标准 url 里取出文件的扩展名例如: http://www.sina.com.cn/abc/de/fg.php?id1 需要取出 php 或 .php2. 在 HTML 语言中&#xff0c;页面头部的 meta 标记可以用来输出文件的编码格式&#xff0c;以…

理工男一般不浪漫,一浪漫便值很多年

今晚是平安夜接下来就是圣诞元旦小木先祝大家幸福、快乐、健康一年一度“最佳”圣诞元旦礼物奖就要发表了中了直男毒的礼物你们挚爱的女朋友可是不要的哦今天小木就大家扒一扒满满直男的礼物是怎样的&#xff01;Part 1“男票送了我一箱木瓜&#xff0c;说是丰胸疗程&#xff0…

C#序列化与反序列化详解

什么是序列化以及如何实现序列化&#xff1f;序列化是通过将对象转换为字节流&#xff0c;从而存储对象或将对象传输到内存&#xff0c;数据库或文件的过程。主要用途是保存对象的状态&#xff0c;包括对象的数据&#xff0c;以便能够在需要是重建对象。反向过程称为 反序列化。…

云计算涉足网游

随着云计算的发展&#xff0c;网游完全无端化指日可待。 互联网从C/S结构慢慢的过渡到B/S结构&#xff0c;网络游戏也从端游慢慢过渡到页游。比起市场上动辄7G、14G大型端游来说&#xff0c;页游实在是一个太过方便的东西。比如不用频繁的更新客户端&#xff0c;如果是安装在了…

php父子遍历,php无限分类父子追溯方法

php 无限分类之父级分类和子分类的追溯方法&#xff0c;代码片段如下&#xff1a;//返回所有的叶子节点public function scanNodeOfTree($result,$fid){$checkexist false;for ($i0; $iif($fid $result[$i][ParentId]){$checkexist true;$arr . $this->scanNodeOfTree($r…

TLS是如何保障数据传输安全(中间人攻击)

前言前段时间和同事讨论HTTPS的工作原理&#xff0c;当时对这块知识原理掌握还是靠以前看了一些博客介绍&#xff0c;深度不够&#xff0c;正好我这位同事是密码学专业毕业的&#xff0c;结合他密码学角度对tls加解密(DH这块)的阐述&#xff0c;让我对这块原理有了更进一步的理…

除了 Python ,这些语言写的机器学习项目也很牛

全世界只有3.14 % 的人关注了数据与算法之美Python 由于本身的易用优势和强大的工具库储备&#xff0c;成为了在人工智能及其它相关科学领域中最常用的语言之一。尤其是在机器学习&#xff0c;已然是各大项目最偏爱的语言。其实除了 Python &#xff0c;也不乏有开发者用其他语…

php 输入值,php-HTML输入值更改

我有一个PHP更新页面,其中显示一个包含数据库值的文本字段.就像这样,它正在工作,现在,我需要将此更新后的值放回数据库中&#xff01;我已经使用过这样的代码,但是它没有更新&#xff1a;$title$_POST[title];$v_id $_GET[v_id];$sql mysql_query("update vehicles set …

马斯克又要搞事情,不锈钢材质的Space X“星际飞船”正式亮相

全世界只有3.14 % 的人关注了数据与算法之美近日&#xff0c;据美国科技媒体 Teslarati 报道&#xff0c;今年 Space X &#xff08;太空探索技术公司&#xff09;已经开始研发“星际飞船”&#xff08;Starship&#xff09;和 “Super Heavy”&#xff0c;而“星际飞船”则是火…

记一次 .NET 某外贸Web站 内存泄漏分析

一&#xff1a;背景 1. 讲故事上周四有位朋友加wx咨询他的程序内存存在一定程度的泄漏&#xff0c;并且无法被GC回收&#xff0c;最终机器内存耗尽&#xff0c;很尴尬。沟通下来&#xff0c;这位朋友能力还是很不错的&#xff0c;也已经做了初步的dump分析&#xff0c;发现了托…

归档日志 delete input 和delete all input 区别

关于archivelog delete input 和delete all input区别 1 rman的归档位置定义两个 log_archive_dest_1 string LOCATION/oracle/archive log_archive_dest_2 string LOCATION/oracle/archive2/ 2 执行alter system switch lo…

java取整公式,Java取整函数 四舍五入函数-Go语言中文社区

简介Math类中提供了5个与取整相关的函数&#xff0c;如下所示&#xff1a;static double ceil(double a)&#xff1a;天花板函数&#xff0c;返回大于等于a的最小整数(但是以浮点数形式存储)。static double floor(double a)&#xff1a;地板函数&#xff0c;返回小于等于a的最…