PHPWord api使用方法整理,加载模板文件,替换模板内容,动态表格生成,表格行数不定处理方式,复制表格,循环表格


使用PHPWord生成合同什么的很方便,也很简单,就是在doc模板文件中提前设置好变量名称,如${name},然后替换成真实内容就行,包括word中动态表格(行数不定)的处理也非常简单。

加载模板文件

1
2
$path = "tpl.doc" ;   //指明你的word模板地址
$phpWordProcessor  new  TemplateProcessor( $path );  //加载模板文件

 

替换模板中内容

word中动态内容使用${varName}标记,然后替换成实际内容即可

WX20190718-111533@2x.png

1
2
3
4
$phpWordProcessor ->setValue( 'company' , "北京3W测试公司" );
$phpWordProcessor ->setValue( 'company_address' , "北京市海淀区中关村创业大街" );
$phpWordProcessor ->setValue( 'company_mobile' , "15600059668" );
$phpWordProcessor ->setValue( 'company_name' , "李德龙" );

替换动态表格内容

实际开发中遇到一个问题就是,合同中有个表格,但是表格有多少行数据是动态的,有几行数据就显示几行,不能多。最初想的办法是建立多个模板文件,比如20个doc文件,第一个文件中只设置2行,第二个文件只设置2行,实际数据有几行,我就调用第几个文件....这是一个笨办法,好在临时解决了问题,但是非常的2,PHPWord中处理这种问题非常方便。

首先我们创建表格模板,只需要创建一行就行,然后我们在代码中根据实际情况进行复制,有多少行就复制多少行

WX20190718-111911@2x.png

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$phpWordProcessor ->cloneRow( 'index' ,3);    //找到要复制的地方,随便复制其中的1个变量名即可
 
//依次替换其中的内容,第一行就是 原变量名#1,第二行就是  原变量名#2 ,以此类推
$phpWordProcessor ->setValue( 'index#1' '1' );
$phpWordProcessor ->setValue( 'type#1' '资金补贴' );
$phpWordProcessor ->setValue( 'service_title#1' '中关村小微补贴' );
$phpWordProcessor ->setValue( 'service_scale#1' '20%' );
$phpWordProcessor ->setValue( 'service_cash#1' '成功后付款' );
 
$phpWordProcessor ->setValue( 'index#2' '2' );
$phpWordProcessor ->setValue( 'type#2' '资金补贴' );
$phpWordProcessor ->setValue( 'service_title#2' '研发补贴' );
$phpWordProcessor ->setValue( 'service_scale#2' '20%' );
$phpWordProcessor ->setValue( 'service_cash#2' '成功后付款' );
 
$phpWordProcessor ->setValue( 'index#3' '3' );
$phpWordProcessor ->setValue( 'type#3' '资金补贴' );
$phpWordProcessor ->setValue( 'service_title#3' '海淀补贴' );
$phpWordProcessor ->setValue( 'service_scale#3' '20%' );
$phpWordProcessor ->setValue( 'service_cash#3' '成功后付款' );

复制之后的表格模板,实际自动变成了如下样子

WX20190718-112324@2x.png

替换复杂表格内容

如表格形式是这样的,我们要动态添加多行

WX20190718-112504@2x.png

也很简单

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
$values  array (    
     array (    
         'userId'         => 1,    
         'userFirstName'  =>  'James' ,    
         'userName'       =>  'Taylor' ,    
         'userPhone'      =>  '+1 428 889 773' ,    
     ),    
     array (    
         'userId'         => 2,    
         'userFirstName'  =>  'Robert' ,    
         'userName'       =>  'Bell' ,    
         'userPhone'      =>  '+1 428 889 774' ,    
     ),    
     array (    
         'userId'         => 3,    
         'userFirstName'  =>  'Michael' ,    
         'userName'       =>  'Ray' ,    
         'userPhone'      =>  '+1 428 889 775' ,    
     ),    
);    
$phpWordProcessor ->cloneRowAndSetValues( 'userId' $values );

也可以一行一行的设置值

1
2
3
4
5
6
7
8
9
10
11
12
13
$phpWordProcessor ->cloneRow( 'userId' , 3);
$phpWordProcessor ->setValue( 'userId#1' '1' );
$phpWordProcessor ->setValue( 'userFirstName#1' 'James' );
$phpWordProcessor ->setValue( 'userName#1' 'Taylor' );
$phpWordProcessor ->setValue( 'userPhone#1' '+1 428 889 773' );
$phpWordProcessor ->setValue( 'userId#2' '2' );
$phpWordProcessor ->setValue( 'userFirstName#2' 'Robert' );
$phpWordProcessor ->setValue( 'userName#2' 'Bell' );
$phpWordProcessor ->setValue( 'userPhone#2' '+1 428 889 774' );
$phpWordProcessor ->setValue( 'userId#3' '3' );
$phpWordProcessor ->setValue( 'userFirstName#3' 'Michael' );
$phpWordProcessor ->setValue( 'userName#3' 'Ray' );
$phpWordProcessor ->setValue( 'userPhone#3' '+1 428 889 775' );

不得不赞叹一声,真是强大

复制块内容或删除块内容

如果我们在模板中有一块内容,可能展示也可能不展示,则可通过复制或删除块进行处理。

现在word模板中添加一个块,块格式形如 ${block_name}块内容${/block_name}

1
2
3
4
5
word模板中添加这么一个块,块的名字自定义
 
${block}
此处内容是否展示,可以控制
${/block}

在代码中可通过cloneBlock来复制块,复制1份,就相当于显示此块内容了, 当然也可以复制多份;也可以通过deleteBlock来删除块

1
2
3
4
5
$phpWordProcessor ->cloneBlock( 'block' , 1);   //显示模板中的块
 
$phpWordProcessor ->cloneBlock( 'block' , 3);   //复制多份
 
$phpWordProcessor ->deleteBlock( 'block' );   //删除块

 

复制块或删除块无效

如果已经按照上述方法进行复制块操作,但是死活就是不成功的时候,可能是因为文档内容太多,导致cloneBlock内部的preg_match方法中的字符串过长。

原因是php在进行正则匹配的时候,有个递归次数限制pcre.recursion_limit,无限次的递归容易消耗所有进程的可用堆栈,最后导致PHP崩溃。所以默认“pcre.backtrack_limit ”的值默认只设了100000。当我们word中内容过大时候,就导致超出这个递归次数限制,导致匹配出无结果,也就没有办法实现复制块的操作。

解决办法:修改“pcre.backtrack_limit ”的值默认,在代码前面加一句,搞定! 

1
ini_set ( 'pcre.backtrack_limit' , 999999999);

 

下载word文件

1
2
3
4
5
6
$filename  = iconv( "utf-8" , "gb2312" , "测试" );    //防止有的浏览器下载之后中文乱码
 
header( "Content-type: application/vnd.ms-word" );
header( "Content-Disposition:attachment;filename=" . $filename . ".docx" );
header( 'Cache-Control: max-age=0' );
$phpWordProcessor ->saveAs( "php://output" );

原文转载自:http://shanhuxueyuan.com/news/detail/124.html


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM