使用phpword操作word
官方文档:https://phpword.readthedocs.io/en/latest/ (opens new window)
安装phpword
库
composer require phpoffice/phpword
1
# 创建word文档
$phpWord = new \PhpOffice\PhpWord\PhpWord();
// 设置文档默认字体为-仿宋
$phpWord->setDefaultFontName('仿宋');
// 设置文档默认字体大小为9号字体
$phpWord->setDefaultFontSize(9);
$section = $phpWord->addSection();
// 这里是一个字体样式,为文字居中
$center = ['alignment' => \PhpOffice\PhpWord\SimpleType\Jc::CENTER];
$para = $section->addTextRun($center);
$para->addText("上面这段操作可以创建一个居中的文字");
$section->addText('直接添加一行文字');
// 这里是一个表格样式
$styleTable = array('borderSize' => 6, 'borderColor' => 'black', 'cellMargin' => 60);
// 为文档添加一个名为`table`的表格样式
$phpWord->addTableStyle('table', $styleTable);
// 添加一个表格,设置样式为上方设置的`table`
$table = $section->addTable('table');
// 设置表格宽度
$table->setWidth(5000);
// 这里配置了个单元格样式,文字水平居中,单元格垂直居中
$cellStyle = ["textDirectionHorizontal" => "center", "valign" => "center"];
$table->addRow();
$table->addCell(null, array('gridSpan' => 5))->addText("这里合并了横向5个单元格");
$table->addRow();
$table->addCell(400, $cellStyle)->addTextRun($center)->addText('序号');
$table->addCell(500, $cellStyle)->addTextRun($center)->addText('标题1');
$table->addCell(700, $cellStyle)->addTextRun($center)->addText('标题2');
$table->addCell(500, $cellStyle)->addTextRun($center)->addText('标题3');
$table->addCell(2900)->addText('标题4');
$table->addRow();
$table->addCell(400, $cellStyle)->addTextRun($center)->addText(1);
$table->addCell(500, $cellStyle)->addTextRun($center)->addText(内容);
$table->addCell(700, $cellStyle)->addTextRun($center)->addText(内容);
$table->addCell(500, $cellStyle)->addTextRun($center)->addText(内容);
$table->addCell(2900)->addText('内容');
# 忽略-S
// 保存Word文档到临时文件
$tempFile = tempnam(sys_get_temp_dir(), 'word');
$writer = IOFactory::createWriter($phpWord, 'Word2007');
$writer->save($tempFile);
// 读取临时文件并输出
header('Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document');
header('Content-Disposition: attachment;filename="example.docx"');
readfile($tempFile);
// 删除临时文件
unlink($tempFile);
// 忽略-E,使用下面的导出代码
// 清除输出缓冲区
if (ob_get_length()) ob_end_clean();
// 设置响应头
header('Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document');
header('Content-Disposition: attachment; filename="Report.docx"; filename*=UTF-8\'\'' . rawurlencode('文件.docx'));
header('Cache-Control: max-age=0');
header('Expires: 0');
header('Pragma: public');
// 创建 Writer 并输出到 php://output
$writer = IOFactory::createWriter($phpWord, 'Word2007');
$writer->save('php://output');
exit; // 确保脚本终止,不再输出其他内容
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# 读取并操作word
在使用phpword
读取word操作保存的时候,不知道为什么内容样式会被改变,没有深入研究,暂时使用python-docx
完成读取并操作word任务
$objReader = IOFactory::createReader('Word2007');
/** @var PhpWord $phpWord */
$phpWord = $objReader->load('example.docx');
foreach ($phpWord->getSections() as $k => $section) {
foreach ($section->getElements() as $k1=> $element) {
/** @var TextRun $a */
$a = $element;
dump(get_class($element));
echo '========';
if($element instanceof Table){
dump($element);die;
}
if ($element instanceof TextRun/* && strpos($element->getText(), '指定的文本') !== FALSE*/) {
foreach ($element->getElements() as $k2=> $c){
echo '----------';
dump(get_class($c));
if($c instanceof Text){
dump($c->getText().'===='.$k.'==='.$k1.'==='.$k2);
}
}
}
}
}
$demo = $phpWord->getSections()[0]->getElements()[13]->getElements()[1];
$demo->setText("张三\r\n");
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 使用word模板处理
文档地址:https://phpword.readthedocs.io/en/latest/templates-processing.html?highlight=TemplateProcessor
$tmp = new TemplateProcessor('Template.docx');
$tmp->setValue('firstname', 'John'); // ${firstname}
$tmp->setValue('lastname', 'Doe'); // ${lastname}
$data = ['A' => 10, 'B' => 20, 'C' => 30, 'D' => 40, 'E' => 50];
// --- 柱形图 ---
$chart_sight_all = new Chart('column', array_keys($data), array_values($data), [], '图表标题');
$chart_sight_all->getStyle()
->setShowAxisLabels()
->setShowGridY()
->setWidth(Converter::inchToEmu(6))
->setHeight(Converter::inchToEmu(5))
->setDataLabelOptions(['showCatName' => false]);
// --- 柱形图结束 ---
// --- 饼图 ---
$chart_sight_all = new Chart('pie', array_keys($data), array_values($data), [], '图表标题');
$chart_sight_all->getStyle()
->setTitle($title)
->setShowAxisLabels()
->setShowLegend(true)
->setWidth(Converter::inchToEmu(6))
->setHeight(Converter::inchToEmu(3))
->setShowGridY()
->setDataLabelOptions(['showCatName' => false]);
// --- 饼图结束 ---
// 处理图表 ${chart}
$tmp->setChart('chart', $chart_sight_all);
// 设置带格式的文本 ${textrun}
$tmp->setComplexValue('textrun', $this->getTextRun('带格式的文本', false));
// --- 表格 ---
$table = new Table($tableStyle);
$table->addRow();
//标题
$tableStyle= ['borderColor' => '000000', 'borderSize' => 6, 'width' => 9000];
$tableTextAlign = ['align' => 'center'];
$tableTextFont = ['name' => '宋体', 'size' => 8, 'bold' => false];
$table->addCell(9000, ['gridSpan' => 11])->addText("标题", ['name' => '宋体', 'size' => 14], $tableTextAlign);
$table->addRow();
$cell = $table->addCell(null, ['vMerge' => 'restart', 'valign' => 'center']);
$cell->addText('序号', $tableTextFont, $tableTextAlign);
$cell = $table->addCell(null, ['vMerge' => 'restart', 'valign' => 'center']);
$cell->addText('姓名', $tableTextFont, $tableTextAlign);
$cell = $table->addCell(null, ['vMerge' => 'restart', 'valign' => 'center']);
$table->addCell(null, ['gridSpan' => 2])->addText('合并两格', $tableTextFont, $tableTextAlign);
$table->addCell(null, ['gridSpan' => 2])->addText('合并两格', $tableTextFont, $tableTextAlign);
$table->addRow();
$table->addCell(null, ['vMerge' => 'continue']);
$table->addCell(null, ['vMerge' => 'continue']);
$table->addCell(null, ['vMerge' => 'continue']);
$table->addCell(null, ['vMerge' => 'continue']);
$table->addCell()->addText('标题1', $tableTextFont, $tableTextAlign);
$table->addCell()->addText('标题1', $tableTextFont, $tableTextAlign);
$table->addCell(null, ['vMerge' => 'continue']);
$tmp->setComplexBlock('table#' . $i, $table);
// --- 表格结束 ---
// 克隆块
// ${block}
// ${name}去${location}玩
// ${/block}
$num = 5; // clone数量
$tmp->cloneBlock('block', 5, true, true);
$tmp->setValue('name#1', 'John'); // 索引从1开始
$tmp->setValue('location#1', 'John');
$tmp->setValue('name#2', 'John');
$tmp->setValue('location#2', 'John');
// 输出文件
$tmp->saveAs($url);
// 带格式的文本
protected function getTextRun($text, $bold = true, $size = 8): TextRun
{
$textRun = new TextRun();
$textRun->addText($text, array('bold' => $bold, 'size' => $size));
return $textRun;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
上次更新: 2025/06/24, 16:02:42