为啥“deleteBlocks”在 phpWord 中不起作用?

Posted

技术标签:

【中文标题】为啥“deleteBlocks”在 phpWord 中不起作用?【英文标题】:Why is "deleteBlocks" not working in phpWord?为什么“deleteBlocks”在 phpWord 中不起作用? 【发布时间】:2020-04-24 20:34:10 【问题描述】:

我正在尝试在 Word 文档中使用块,但遇到了一些问题。首先,当我在文档中声明一个块时,如果我不使用“cloneBlock”函数,结果如下所示:

$sec
example
$/sec

也许我必须使用该功能才能正常显示。但我的主要问题是“deleteBlock”不起作用。如果我不克隆该块,则生成的 docx 已损坏。但是,如果我克隆该块,“deleteBlock”函数不会删除该块,它会在我的最终 docx 文件中显示该块内的信息。

这是我的代码:

//Word
// Creating the new document...
$templateProcessor = new \phpOffice\PhpWord\TemplateProcessor('../example.docx');
//set value
//$templateProcessor->setValue('title', 'Example');

//Triplicate block
$templateProcessor->cloneBlock('firstblock', 3, true, true);
$templateProcessor->setValue('firstname#1', 'John');
$templateProcessor->setValue('lastname#1', 'Doe');
$templateProcessor->setValue('firstname#2', 'John');
$templateProcessor->setValue('lastname#2', 'Doe');
$templateProcessor->setValue('firstname#3', 'John');
$templateProcessor->setValue('lastname#3', 'Doe');

//Delete Block
$templateProcessor->cloneBlock('sec', 1, true, true);
$templateProcessor->deleteBlock('sec');
$templateProcessor->saveAs('example.docx');

Docx 模板:

$firstblock
Hello $firstname $lastname!
$/firstblock
$sec
example
$/sec

更新: 我没有使用函数“deleteBlock”,而是使用了这样的函数“cloneBlock”,它删除了块:

//Delete Block
$templateProcessor->cloneBlock('sec', 0, true, true);

所以,我写了 0 次克隆块,所以它消失了 但我还有另一个问题。我不知道为什么,但这只是有时有效

【问题讨论】:

您找到解决方案了吗?目前我最终创建了多个模板文件,因为我无法删除块或行 【参考方案1】:

试试这个。我稍微更改了replaceBlock中的正则表达式,我还添加了一个删除未使用模式的功能,它可能会派上用场)我会马上警告你 - 不是真正测试所以小心使用它

class PatchedTemplateProcessor extends TemplateProcessor

    /**
     *  Remove $* and $/* from temporary document
     */
    public function removeSearchPatterns()
    
        preg_match_all(
            '/(\$\[^\]*\)/',
            $this->tempDocumentMainPart,
            $matches,
            PREG_SET_ORDER
        );


        foreach ($matches as $match)
            $this->tempDocumentMainPart = str_replace(
                $match,
                '',
                $this->tempDocumentMainPart
            );
        
    

    /**
     * @param string $blockname
     * @param string $replacement
     */
    public function replaceBlock($blockname, $replacement)
    
        $matches = array();
        preg_match(
            '/(<w:t.*>\$' . $blockname . '<\/w:.*?t>)(.*)(<w:t.*\$\/' . $blockname . '<\/w:.*?t>)/is',
            $this->tempDocumentMainPart,
            $matches
        );

        if (isset($matches[3])) 
            $this->tempDocumentMainPart = str_replace(
                $matches[2] . $matches[3],
                $replacement,
                $this->tempDocumentMainPart
            );
        
    

    /**
     * Delete a block of text.
     *
     * @param string $blockname
     */
    public function deleteBlock($blockname)
    
        $this->replaceBlock($blockname, '');
    

【讨论】:

【参考方案2】:

我不确定为什么用户 @d1845412 删除了他们之前的答案,但它实际上解决了我的问题。我用下面的代码覆盖了 deleteBlock 方法,它似乎工作。与对 replaceBlock 方法的较大更改相比,我更喜欢这种小的更改。

/**
 * Override this method since deleteBlock doesn't seem to work.
 * @param string $blockname
 */
public function deleteBlock($blockname)

    $this->cloneBlock($blockname, 0, true, true);

【讨论】:

以上是关于为啥“deleteBlocks”在 phpWord 中不起作用?的主要内容,如果未能解决你的问题,请参考以下文章

PHPWord使用PHPWord替换模板变量大段文字并换行设置字体字号

PHPWord使用PHPWord替换模板变量大段文字并换行设置字体字号

PHPWord使用PHPWord自动生成TOC根据内容的目录完整示例 | table of contents (TOC)

PHPWord使用PHPWord自动生成TOC根据内容的目录完整示例 | table of contents (TOC)

PHPWord使用PHPWord自动生成TOC根据内容的目录完整示例 | table of contents (TOC)

Laravel生成Word文档 - phpword