【问题标题】:manipulating template in PHPWord在 PHPWord 中操作模板
【发布时间】:2025-12-10 18:30:01
【问题描述】:

我正在为我正在开发的网络应用程序的报告模块使用 PHP 的 Word 文档生成器。我选择 PHPWord 是因为 PHPDocX 的免费版本功能非常有限,而且它的页脚说明它只是一个免费版本。我有客户提供的模板。我想要的是加载模板并向其添加动态元素,例如附加文本或表格。我的代码在这里:

<?php
require_once '../PHPWord.php';

$PHPWord = new PHPWord();

$document = $PHPWord->loadTemplate('Template.docx');
$document->setValue('Value1', 'Great');

$section = $PHPWord->createSection();
$section->addText('Hello World!');
$section->addTextBreak(2);

$document->setValue('Value2', $section);

$document->save('test.docx');
?>

我尝试创建一个新部分并尝试将其分配给模板中的一个变量(Value2),但出现此错误:

[28-Jan-2013 10:36:37 UTC] PHP Warning:  utf8_encode() expects parameter 1 to be string, object given in /Users/admin/localhost/PHPWord_0.6.2_Beta/PHPWord/Template.php on line 99

【问题讨论】:

    标签: php ms-word phpword


    【解决方案1】:

    根据文档,当您使用模板时,您不能将内容添加到文件中。

    无法将新的 PHPWord 元素添加到加载的模板文件中。

    Documentation

    【讨论】:

      【解决方案2】:

      全新版本的 CloneRow 和 setValue

      现在您可以克隆合并的单元格。 修复了许多带有 OOXML 标记的错误。

      还有新方法 setValue - 现在忽略模式中的垃圾标签。喜欢

      {My<trash ooxml tags>Pattern}
      

      您可以在此处找到代码、文档和示例: https://github.com/Arisse/PHPWord_CloneRow

      【讨论】:

        【解决方案3】:

        setValue 期望第二个参数是纯字符串。无法提供 section 对象。

        我已经深入研究了代码,但没有一种简单的方法可以让 section 对象返回 setValue 函数可以使用的值。

        因为我遇到了同样的问题,所以我为 Template.php 文件编写了一个补丁,允许您在用 s​​etValue 替换它们的标签之前克隆表行。每行都有一个唯一的 id,让您可以识别每个不同行的模板标签。

        这就是它的工作原理:

        将此函数添加到您的 Template.php 文件(位于 PHPWord 目录中)

        public function cloneRow($search, $numberOfClones) {
            if(substr($search, 0, 2) !== '${' && substr($search, -1) !== '}') {
                $search = '${'.$search.'}';
            }
            $tagPos      = strpos($this->_documentXML, $search);
            $rowStartPos = strrpos($this->_documentXML, "<w:tr", ((strlen($this->_documentXML) - $tagPos) * -1));
            $rowEndPos   = strpos($this->_documentXML, "</w:tr>", $tagPos) + 7;
        
            $result = substr($this->_documentXML, 0, $rowStartPos);
            $xmlRow = substr($this->_documentXML, $rowStartPos, ($rowEndPos - $rowStartPos));
            for ($i = 1; $i <= $numberOfClones; $i++) {
                $result .= preg_replace('/\$\{(.*?)\}/','\${\\1#'.$i.'}', $xmlRow);
            }
            $result .= substr($this->_documentXML, $rowEndPos);
            $this->_documentXML = $result;
        }
        

        在您的模板文件中,为每个表格添加一行,您将用作模板行。假设您在该行中添加了标签 ${first_name}。

        要获得一个有 3 行的表格,请调用: $document->cloneRow('first_name', 3);

        模板的工作副本现在更新为包含 3 行的表格。行内的每个标签都附加了 # 和行号。

        要设置您的值,请使用 setValue $document->setValue('first_name#1', '第一行的名字'); $document->setValue('first_name#2', '第二行的名字'); $document->setValue('first_name#3', '第三行的名字');

        我希望这是有用的!我将在此处保留代码和文档的更新版本:http://jeroen.is/phpword-templates-with-repeating-rows/

        【讨论】: