使用phpWord生成DOCX模板文档后,Ubuntu下LibreOffice转PDF遇问题
PHPWord填充模板表格后LibreOffice转PDF问题解决
场景概述
我有一个包含${table}标记的template.docx模板,需要用PHPWord生成document.docx,再在Ubuntu系统上通过LibreOffice将其转换为PDF。以下是我的代码及遇到的问题:
填充表格的两种实现
版本1:使用PHPWord Table对象
$doc_table = new \PhpOffice\PhpWord\Element\Table(); if(count($table_data)>0) { foreach ($table_data as $k1 => $row) { $doc_table->addRow(); foreach ($row as $k2 => $col) { $doc_table->addCell()->addText($col); }; }; }; $word_template = new \PhpOffice\PhpWord\TemplateProcessor('template.docx'); $word_template->setComplexBlock('table', $doc_table); $word_template->saveAs('document.docx');
版本2:手动拼接XML
$doc_table_xml = '<w:tbl>'. '<w:tblPr>'. '<w:tblStyle w:val="TableGrid"/>'. '<w:tblW w:w="0" w:type="auto"/>'. '<w:tblBorders>'. '<w:top w:val="single" w:sz="6" w:space="0" w:color="auto"/>'. '<w:left w:val="single" w:sz="6" w:space="0" w:color="auto"/>'. '<w:bottom w:val="single" w:sz="6" w:space="0" w:color="auto"/>'. '<w:right w:val="single" w:sz="6" w:space="0" w:color="auto"/>'. '<w:insideH w:val="single" w:sz="6" w:space="0" w:color="auto"/>'. '<w:insideV w:val="single" w:sz="6" w:space="0" w:color="auto"/>'. '</w:tblBorders>'. '<w:tblLook w:val="04A0"/>'. '</w:tblPr>'. '<w:tblGrid>'. str_repeat('<w:gridCol/>',count($table_data['0'])). '</w:tblGrid>'; if(count($table_data)>0) { foreach ($table_data as $k1 => $row) { $trow_xml = '<w:tr>'; foreach ($row as $k2 => $col) { $trow_xml.= '<w:tc><w:tcPr/>'.'<w:p><w:t>'.$col.'</w:t></w:p></w:tc>'; } $doc_table_xml.= $trow_xml.'</w:tr>'; } } $doc_table_xml.= '</w:tbl>' ; $word_template = new \PhpOffice\PhpWord\TemplateProcessor('template.docx'); $word_template->setValue('table', $doc_table_xml); $word_template->saveAs('document.docx');
PDF转换代码
$command = 'libreoffice --headless --convert-to pdf:writer_pdf_Export document.docx --outdir doc_print'; $output = shell_exec($command);
遇到的问题
- 版本1问题:生成的DOCX可在MS Word中打开,但LibreOffice转换时报错
Error: source file could not be loaded,无法生成PDF。 - 版本2问题:DOCX可正常打开,Shell执行转换能生成PDF,但PDF中无表格内容。
解决方案
针对版本1的问题解决
- 使用绝对路径:LibreOffice无头模式对相对路径支持不佳,需指定完整绝对路径:
$docx_path = realpath('document.docx'); $output_dir = realpath('doc_print'); $command = "/usr/bin/libreoffice --headless --convert-to pdf:writer_pdf_Export {$docx_path} --outdir {$output_dir}"; - 补全命名空间:确保Table对象为
\PhpOffice\PhpWord\Element\Table,避免生成的XML结构不完整。 - 检查文件权限:确保运行PHP的用户(如
www-data)对文件和输出目录有读写权限:chown www-data:www-data document.docx doc_print/ chmod 644 document.docx chmod 755 doc_print/ - 清理残留进程:无头模式下可能有残留LibreOffice进程锁定文件,先清理:
pkill -f libreoffice
针对版本2的问题解决
问题根源是setValue默认转义XML特殊字符,导致表格XML被当成普通文本。需关闭转义:
// 修改setValue代码,第三个参数设为false关闭转义 $word_template->setValue('table', $doc_table_xml, false);
内容的提问来源于stack exchange,提问作者Garry
相关产品推荐
相关产品推荐

