phpword使用心得

开发初期应该先估计下自己需要用到哪些功能,在phpword的github中samples文件夹内作者提供了不少使用示例了,不仔细看的话,倒是有可能走弯路.

以下记录下自己使用到的功能和调用,避坑

葵花宝典

phpword手册

https://phpword.readthedocs.io/en/latest/

phpword github

https://github.com/PHPOffice/PHPWord

phpword初级使用

初始化phpword对象

1
$phpword = new \PhpOffice\PhpWord\PhpWord();

纸张格式/大小/版面/分栏

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 提供了Paper纸张类
$paper = new \PhpOffice\PhpWord\Style\Paper();
$paper->setSize('A4');
$section_style['pageSizeH'] = $paper->getHeight();
$section_style['pageSizeW'] = $paper->getWidth();

# 可选设置,纸张方向,默认portrait=竖,landscape横
# 这个设置其实就是宽高对调
$section_style['orientation'] = 'portrait';

# 可选设置,分栏,默认2栏,colsSpace和breakType的相关,可以参看手册
$section_style['colsNum'] = '2';
$section_style['colsSpace'] = '1440';
$section_style['breakType'] = 'continuous';

$section = $phpword->addSection($section_style);

phpword paper类没有提供的纸张类型,可以自定义纸张

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# paper文件路径
# src/PhpWord/Style/Paper.php
# 此处可以对应自定义添加任何你想要的纸张类型
private $sizes = array(
'A3' => array(297, 420, 'mm'),
'A4' => array(210, 297, 'mm'),
'A5' => array(148, 210, 'mm'),
'B4' => array(250, 352, 'mm'),
'B5' => array(176, 250, 'mm'),
'8K' => array(259, 367, 'mm'),
'16K' => array(183, 259, 'mm'),
'Folio' => array(8.5, 13, 'in'),
'Legal' => array(8.5, 14, 'in'),
'Letter' => array(8.5, 11, 'in'),
);

单位转换

1
2
3
4
use PhpOffice\PhpWord\Shared\Converter;
# 厘米转像素
$width_px = Converter::cmToPixel($width_cm);
# 具体可以参看Converter类中,提供了很多单位转换

表格添加

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 设置一个默认的表格样式
$phpword->addTableStyle(
'default',
array(
'borderColor' => '000000',
'borderSize' => 10,
'cellMargin' => 50
),
array('bgColor' => 'ffffff')
);

# 添加一个表格,样式用default
$table1 = $section->addTable('default');
$table1->addRow(500);
$table1->addCell(100,['valign'=>'center'])
->addText('单元格1',['size' => '14','bold' => true],['align' => 'center']);
$table1->addCell(100,['valign'=>'center'])
->addText('单元格2',['size' => '14','bold' => true],['align' => 'center']);
$table1->addCell(100,['valign'=>'center'])
->addText('单元格3',['size' => '14','bold' => true],['align' => 'center']);
$table1->addCell(100,['valign'=>'center'])
->addText('单元格4',['size' => '14','bold' => true],['align' => 'center']);

添加图片

1
$section->addImage('http://xxx.com/1.jpg', ['width'=>'100','height'=>'100']);

添加换行

1
2
$breaks = 2;
$section->addTextBreak(v);

添加多个连续不换行的元素

1
2
3
$textrun_section = $section->addTextRun();
$textrun_section->addText('文字文字');
$textrun_section->addImage('http://xxx.com/1.jpg', ['width'=>'100','height'=>'100']);

添加一段html内容

1
2
3
4
# 但是一定要注意html的标签一定要是成对闭合的,否则空白
# 闭合可以看附录的php处理html标签的闭合方法
$html = '<div><p>html内容</p><p><img src="http://xxx.com/1.jpg" /></p></div>';
\PhpOffice\PhpWord\Shared\Html::addHtml($section, $html, false, false);

附录

php处理html标签闭合

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
* 用于处理未闭合的html内容闭合
* @param $html
* @return mixed|string
*/
function closetags($html) {
preg_match_all('#<(?!meta|img|br|hr|input\b)\b([a-z]+)(?: .*)?(?<![/|/ ])>#iU', $html, $result);
$openedtags = $result[1];
preg_match_all('#</([a-z]+)>#iU', $html, $result);
$closedtags = $result[1];
$len_opened = count($openedtags);
if (count($closedtags) == $len_opened) {
return $html;
}
$openedtags = array_reverse($openedtags);
for ($i=0; $i < $len_opened; $i++) {
if (!in_array($openedtags[$i], $closedtags)) {
$html .= '</'.$openedtags[$i].'>';
}else {
unset($closedtags[array_search($openedtags[$i], $closedtags)]);
}
}
return $html;
}