You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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. 版本1问题:生成的DOCX可在MS Word中打开,但LibreOffice转换时报错Error: source file could not be loaded,无法生成PDF。
  2. 版本2问题:DOCX可正常打开,Shell执行转换能生成PDF,但PDF中无表格内容。

解决方案

针对版本1的问题解决

  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}";
    
  2. 补全命名空间:确保Table对象为\PhpOffice\PhpWord\Element\Table,避免生成的XML结构不完整。
  3. 检查文件权限:确保运行PHP的用户(如www-data)对文件和输出目录有读写权限:
    chown www-data:www-data document.docx doc_print/
    chmod 644 document.docx
    chmod 755 doc_print/
    
  4. 清理残留进程:无头模式下可能有残留LibreOffice进程锁定文件,先清理:
    pkill -f libreoffice
    

针对版本2的问题解决

问题根源是setValue默认转义XML特殊字符,导致表格XML被当成普通文本。需关闭转义:

// 修改setValue代码,第三个参数设为false关闭转义
$word_template->setValue('table', $doc_table_xml, false);

内容的提问来源于stack exchange,提问作者Garry

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 01:14:57