phpword使用TemplateProcessor对模板进行替换

最近有个需求,对一个docx模板文件进行内容替换,这里记录一下遇到的一些难点和解决办法

1.单个表格替换,其中第一列需要纵向合并动态数量的单元格
模板名称:${table}
代码:

$tableStyle = array(
    'borderColor' => '000000', // 边框颜色(黑色)
    'borderSize' => 6, // 边框大小(6/8 磅)
    'cellMargin' => 50, // 单元格内边距
    'alignment' => \PhpOffice\PhpWord\SimpleType\JcTable::CENTER, // 表格居中
);
$resultTable = new \PhpOffice\PhpWord\Element\Table($tableStyle);
                $modelName = $model["name"];
                $row = $resultTable->addRow();
                //设置表头
                $row->addCell(2500,['bgColor' => '#B6DDE8'])->addText("content1", array('name' => 'Arial', 'size' => 14, 'color' => '000000', 'bold' => true));
                $row->addCell(3000,['bgColor' => '#B6DDE8'])->addText("content2", array('name' => 'Arial', 'size' => 14, 'color' => '000000', 'bold' => true));
                $row->addCell(2000,['bgColor' => '#B6DDE8'])->addText("content3", array('name' => 'Arial', 'size' => 14, 'color' => '000000', 'bold' => true));
                $row->addCell(2000,['bgColor' => '#B6DDE8'])->addText("content4", array('name' => 'Arial', 'size' => 14, 'color' => '000000', 'bold' => true));
                foreach ($model["children"] as  $key=>$child){
                    $resultTable->addRow();
//重点,需要合并的纵向单元格第一个的style设置["vMerge" => "restart"],后面的单元格设置["vMerge" => "continue"]
                    if ($key == 0){
                        $resultTable->addCell(2500,["vMerge" => "restart"])->addText($modelName, array('name' => 'Arial', 'size' => 14, 'color' => '000000', 'bold' => true));
                    }else{
                        $resultTable->addCell(null,["vMerge" => "continue"]);
                    }
                    $resultTable->addCell(2500)->addText("text1", array('name' => 'Arial', 'size' => 14, 'color' => '000000', 'bold' => true));
                    $resultTable->addCell(2000)->addText("text2", array('name' => 'Arial', 'size' => 14, 'color' => '000000', 'bold' => true));
                    $resultTable->addCell(2000)->addText("text3", array('name' => 'Arial', 'size' => 14, 'color' => '000000', 'bold' => true));
                }
                //最后将字符串替换为整个表格
                $tmpTemplateProcessor->setComplexBlock("table", $resultTable);

2.将一个字符串替换为复杂的多段文字,多个表格模块
逻辑:先将单个字符串的占位符替换成多个占位符,然后将docx保存为临时文件,重新读取,再将对应的段落和表格替换。注意这里有个坑,setComplexBlock会将段落所有的内容都替换掉,如果你只有一个段落但是里面有很多占位符,多次使用setComplexBlock后,只会有一个替换后的内容显示。
占位符:
${safe_table_block}
${safe_table}
${/safe_table_block}

$modelListStringArr =["parahraph_1","table_1","parahraph_2","table_2"]
//生成多个段落占位符
$templateProcessor->cloneBlock('safe_table_block', count($modelListStringArr), true, true);
        // 替换每个块中的占位符
        foreach ($modelListStringArr as $index => $paragraph) {
            $templateProcessor->setValue('safe_table#' . ($index + 1), htmlspecialchars($paragraph));
        }
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用NPOI替换Word模板中的字段并导出可以分为以下几个步骤: 1. 引入NPOI库 首先,在项目中引入NPOI库。可以通过NuGet包管理器或手动下载DLL文件的方式引入。 2. 创建Word模板 创建一个Word模板,其中需要用到的字段用“占位符”表示,如“{{Name}}”、“{{Age}}”等等。 3. 加载Word模板 使用NPOI库打开Word模板。 ```csharp FileStream fs = new FileStream("模板.docx", FileMode.Open, FileAccess.ReadWrite); XWPFDocument doc = new XWPFDocument(fs); ``` 4. 替换模板中的字段 使用NPOI库中的`XWPFParagraph`类和`XWPFRun`类,遍历Word模板中的所有段落和文本,查找需要替换的字段,并进行替换。 ```csharp foreach (var para in doc.Paragraphs) { var text = para.Text; if (text.Contains("{{Name}}")) { text = text.Replace("{{Name}}", "张三"); para.ReplaceText("{{Name}}", "张三"); } if (text.Contains("{{Age}}")) { text = text.Replace("{{Age}}", "18"); para.ReplaceText("{{Age}}", "18"); } } ``` 5. 导出Word文档 使用NPOI库中的`XWPFDocument`类中的`Write`方法导出Word文档。 ```csharp using (FileStream fs = new FileStream("导出.docx", FileMode.Create, FileAccess.Write)) { doc.Write(fs); } ``` 完整示例代码如下: ```csharp using System.IO; using NPOI.XWPF.UserModel; namespace ConsoleApp { class Program { static void Main(string[] args) { //加载Word模板 FileStream fs = new FileStream("模板.docx", FileMode.Open, FileAccess.ReadWrite); XWPFDocument doc = new XWPFDocument(fs); //替换模板中的字段 foreach (var para in doc.Paragraphs) { var text = para.Text; if (text.Contains("{{Name}}")) { text = text.Replace("{{Name}}", "张三"); para.ReplaceText("{{Name}}", "张三"); } if (text.Contains("{{Age}}")) { text = text.Replace("{{Age}}", "18"); para.ReplaceText("{{Age}}", "18"); } } //导出Word文档 using (FileStream fs = new FileStream("导出.docx", FileMode.Create, FileAccess.Write)) { doc.Write(fs); } } } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值