资讯专栏INFORMATION COLUMN

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

468122151 / 2543人阅读

摘要:注文件需要使用编码在文件中按照参考文件方式插入复制符号到文件正常的输出替换。

因工作需要,使用了版本比较旧的PHPWord项目
官方已不见维护更新,上次版本更新是在Fri Jul 8, 2011 at 8:00 AM
如果PHP版本>=5.3.3,强烈推荐使用PHPOffice/PHPWord这个开源项目
本篇针对的为旧版本的PHPWord

基本安装

见官网

问题总结 Autoloader自动加载部分情况下失败

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

/**
 * 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时字符分离了,导致匹配不上模板标签;

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

phpword: setValue() not working

stackoverflow: PhpWord doesn"t replace text

解决办法

参考http://stackoverflow.com/a/21750677/5270710

改进Template类:
可参考Github: Arisse/PHPWord_CloneRow对Template类进行改造。
因为下面仍需要修改Template类,这儿暂时就不贴代码了,下面一并贴出改造后的代码。

中文乱码

参考CSDN: PHPWord利用模板替换字符串生成精确的word文档

编辑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);
}
空格输出

参考CSDN: PhpWord 如何输出换行符到 word?

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

标记符号输出

参考百度经验: 如何在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("
","",$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();//输出全部内容到浏览器
}
参考文档汇总

CodePlex: PHPWord;

Github: PHPOffice/PHPWord;

phpword: setValue() not working;

stackoverflow: PhpWord doesn"t replace text;

Github: Arisse/PHPWord_CloneRow;

CSDN: PHPWord利用模板替换字符串生成精确的word文档;

CSDN: PhpWord 如何输出换行符到 word?

关于我

文章转载自我的博客:
Heier Blog: 使用PHPWord对Word文件做模板替换

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/22183.html

相关文章

  • PHPWord中文手册整理

    摘要:修正中文支持的问题,使用前如果发现乱码,需要进行一些修正解决编码问题,会对输入的文字进行编码转化,如果你使用或者编码的话就会出现乱码,如果你用编码,就查找类库中所有方法中的转码将其删除,如果你采用或者编码,使用进行编码转换。 修正 中文支持的问题,使用前如果发现乱码,需要进行一些修正: 解决编码问题,PHPword 会对输入的文字进行utf8_encode编码转化,如果你使用GBK、...

    wangdai 评论0 收藏0
  • PHP制作word简历

    摘要:模板替换的方式制作简历在许多招聘网站都有一个简历下载的功能,如何用实现呢在里面就有一个非常简单的生成一个文档,向文档中插入一些文字。安装创建控制器及方法用于测试,并建立路由。 PHP操作word有一个非常好用的轮子,就是phpword,该轮子可以在github上查找到(PHPOffice/PHPWord)。上面有较为详细的例子和代码,其中里面的源码包含有一些常用的操作例子,包括设置页眉...

    Donne 评论0 收藏0
  • 使用PHPWord合并Word文档,在文档指定页插入另一个文档的内容

    摘要:提示不支持文件的读取有一个客户有这样的需求,需要在里使用组件,把一个文档的内容,插入另一个文档的指定页内。由于两个文档的内容都不是固定的,所以不能使用的功能。当读取到指定的分页符之后,再读取的内容,跟着前面的内容插入,最后保存新的文档。 提示:不支持.doc文件的读取有一个客户有这样的需求,需要在ThinkPHP里使用PHPWord组件,把一个文档(DOC1)的内容,插入另一个文档(D...

    RobinTang 评论0 收藏0
  • PHP 实现Office word 关键词添加背景色

    摘要:需求最近做一个新闻规范扫描的工具,需要将中的内容读取出来扫描可疑错误词文本,并将错误可疑文本添加背景颜色。内容扫描规范识别不在本文中描述,重点说怎样通过编程语言操作实现文字添加背景色。 需求:最近做一个word新闻规范扫描的工具,需要将wold中的内容读取出来扫描可疑、错误词文本,并将错误可疑文本添加背景颜色。内容扫描规范识别不在本文中描述,重点说怎样通过编程语言操作word实现文字添...

    harriszh 评论0 收藏0
  • eyoucms v1.4.9授权破解版 易优cms企业建站系统去版权版 v1.4.9

    摘要:授权破解版易优企业建站系统易优企业建站系统是一款十分优秀专业的为企业创建网站服务的软件。去版权破解版强大好用,为企业创建网站提供很多帮助和便利。直接去易优官网,购买商业授权即可去除版权。eyoucms v1.4.9授权破解版(易优企业建站系统)是一款十分优秀专业的为企业创建网站服务的软件。eyoucms v1.4.9去版权破解版 强大好用,为企业创建网站提供很多帮助和便利。易优cms破解授权...

    番茄西红柿 评论0 收藏2637

发表评论

0条评论

468122151

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<