用PhpWord中的格式替换文本中的html标记

enxuqcxy  于 2023-08-02  发布在  PHP
关注(0)|答案(2)|浏览(345)

我拥有的:

  • 模板文档template.docx,内部带有标记-${position_to_insert_text}
  • 变量$text_to_insert_in_template中的字符串,其中包含<strong> html标记-My <strong>example string</strong> with html tag.
    我想要的:
  • 打开模板template.docx
  • ${position_to_insert_text}替换为$text_to_insert_in_template
  • <strong></strong>标签之间插入的文本必须是强格式的-我的示例字符串带有html标签。
    我做什么:
$text_to_insert_in_template = 'My <strong>example string</strong> with html tag.';
$template_path = 'templates/template.docx';

$templateProcessor = new \PhpOffice\PhpWord\TemplateProcessor($template_path);
$templateProcessor->setValue('position_to_insert_text', $text_to_insert_in_template);
$templateProcessor->saveAs('result.docx');

字符串

结果

损坏的result.docx文档无法打开。原因-未处理html标记。如果htmlspecialchars($text_to_insert_in_template)作为结果,我可以打开result.docx,但html标记显示为纯文本。
我尝试将html标签替换为原生单词标签

$text_to_insert_in_template = 'My <strong>example string</strong> with html tag.';
$template_path = 'templates/template.docx';

$text_to_insert_in_template = str_replace('<strong>', "<w:b val='true'/>", $text_to_insert_in_template);
$text_to_insert_in_template = str_replace('</strong>', "<w:b val='false'/>", $text_to_insert_in_template);

$templateProcessor = new \PhpOffice\PhpWord\TemplateProcessor($template_path);
$templateProcessor->setValue('position_to_insert_text', $text_to_insert_in_template);
$templateProcessor->saveAs('result.docx');


因此,我可以打开result.docx,但里面的文本也没有格式和html标签:
x1c 0d1x的数据
我怎样才能得到我想要的结果?- 我的示例字符串带html标签。

5hcedyr0

5hcedyr01#

我们手头有一个类似的任务。在寻找解决方案时,我发现了这个问题,并希望留下我们的解决方案作为示例。
一般的问题是,使用HTML标记作为宏的值还不被模板处理器支持。根据您的PhpWord设置,甚至可以使用setValue方法对值进行转义。错误的WordProcessingML可能会破坏您的文档。
但是模板处理器允许用PhpWord元素替换包含宏的<w:p>段落(setComplexBlock)或<w:r>文本串(setComplexValue)。
PhpWord支持将HTML基本解析为容器元素,如表格单元格或文本框。您可以使用它将HTML标记添加到模板中。不幸的是,这也将添加容器元素。
我们不想有这个额外的 Package 器,而是实现了两者的混合,使用 Package 器容器,但只打印其内容。
步骤如下:

  • 创建一个自定义的TemplateProcessor类,它扩展了PhpWord的通用TemplateProcessor(在我们的示例中没有命名空间,但您可以根据自己的喜好添加合适的命名空间),
  • 添加一个setHtmlBlockValue方法,该方法
  • 示例化一个容器元素(在我们的例子中是TextBox),
  • 利用Html助手类将HTML标记解析到其中,
  • 然后使用Container写入器将容器内容呈现为符合Word2007的WordProcessingML,
  • 最后但并非最不重要的是用所呈现的内容替换包含宏的整个段落。
<?php

use PhpOffice\PhpWord\Element\TextBox;
use PhpOffice\PhpWord\Shared\Html;
use PhpOffice\PhpWord\Shared\XMLWriter;
use PhpOffice\PhpWord\TemplateProcessor as PhpWordTemplateProcessor;
use PhpOffice\PhpWord\Writer\Word2007\Element\Container;

/**
 * Custom PhpWord template processor.
 *
 * Extends the generic template processor of PhpWord by means to
 * replace a macro with HTML markup content.
 */
class TemplateProcessor extends PhpWordTemplateProcessor {

    /**
     * Replaces a macro block with the given HTML markup.
     *
     * PhpWord's variables replacing doesn't allow to use HTML markup as
     * macro replacement content.
     *
     * This method is a workaround that uses the PhpWord Html service to
     * parse Html into PhpWord elements, adds them as children to a
     * container element (TextBox), then uses the Container writer to
     * write its children elements only.
     *
     * @param string $search
     *   The macro (variable) name.
     * @param string $markup
     *   The HTML markup as a string.
     */
    public function setHtmlBlockValue($search, $markup)
    {
      // Create a dummy container element for the content.
      $wrapper = new TextBox();

      // Parse the given HTML markup and add it as child elements
      // to the container.
      Html::addHtml($wrapper, $markup);

      // Render the child elements of the container.
      $xmlWriter = new XMLWriter();
      $containerWriter = new Container($xmlWriter, $wrapper, false);
      $containerWriter->write();

      // Replace the macro parent block with the rendered contents.
      $this->replaceXmlBlock($search, $xmlWriter->getData(), 'w:p');
    }

}

字符串
它可以在没有手动操作HTML的情况下使用,并且支持与PhpWords Html helper支持的相同的标记和属性:

$text_to_insert_in_template = 'My <strong>example string</strong> with html tag.';
$template_path = 'templates/template.docx';

$templateProcessor = new TemplateProcessor($template_path);
$templateProcessor->setHtmlBlockValue('position_to_insert_text', $text_to_insert_in_template);
$templateProcessor->saveAs('result.docx');


上面的代码旨在作为灵感,并与使用CKEditor创建的经过消毒的HTML标记一起使用。您可以根据需要对其进行更改(例如,使用表格单元格,替换文本串而不是段落,...)。

vatpfxk5

vatpfxk52#

$toOpenXML  = new HTMLtoOpenXML\Parser();
 $this->template->replaceXmlBlock('placeholder', $toOpenXML->fromHTML($html));

字符串

相关问题