首页 > 解决方案 > WordprocessingDocument:如何替换包含在一组特殊字符中的特定文本?

问题描述

我需要基于一个模板生成几个word文档。在每个文档中都需要替换某些字符串(所有字符串都包含在一对花括号中,以便轻松区分它们)。

我试过了 :

** 阅读整个模板并使用 Regex.Replace 替换所有出现的单词

using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(document, true))
    {
        string docText = null;
        using (StreamReader sr = new StreamReader(wordDoc.MainDocumentPart.GetStream()))
            docText = sr.ReadToEnd();

        foreach (var key in keysToSearch)
            docText = new Regex(key, RegexOptions.IgnoreCase).Replace(docText, replaceText);

        using (StreamWriter sw = new StreamWriter(wordDoc.MainDocumentPart.GetStream(FileMode.Create)))
            sw.Write(docText);
    }

** 并且还可以访问每个 Text 元素

using ( WordprocessingDocument doc =
                    WordprocessingDocument.Open(@"yourpath\testdocument.docx", true))
            {
                var body = doc.MainDocumentPart.Document.Body;
                var paras = body.Elements<Paragraph>();

                foreach (var para in paras)
                {
                    foreach (var run in para.Elements<Run>())
                    {
                        foreach (var text in run.Elements<Text>())
                        {
                            if (text.Text.Contains("{{FullName}}"))
                            {
                                text.Text = text.Text.Replace("{{FullName}}", "replaced-text");
                            }
                        }
                     }
                }
          }

但上述解决方案均无效,因为在 .docx 文件中,所有这些大括号都存储在不同的文本元素 ( <w:t>) 中:

            <w:r w:rsidR="00786C31" w:rsidRPr="00475C3D">
                <w:rPr>
                    <w:b/>
                    <w:sz w:val="36"/>
                    <w:highlight w:val="yellow"/>
                    <w:lang w:val="es-PE"/>
                </w:rPr>
                <w:t>{{</w:t>
            </w:r>
            <w:proofErr w:type="spellStart"/>
            <w:r w:rsidR="001B7FC4" w:rsidRPr="00475C3D">
                <w:rPr>
                    <w:b/>
                    <w:sz w:val="36"/>
                    <w:highlight w:val="yellow"/>
                    <w:lang w:val="es-PE"/>
                </w:rPr>
                <w:t>FullName</w:t>
            </w:r>
            <w:proofErr w:type="spellEnd"/>
            <w:r w:rsidR="00786C31" w:rsidRPr="00475C3D">
                <w:rPr>
                    <w:b/>
                    <w:sz w:val="36"/>
                    <w:highlight w:val="yellow"/>
                    <w:lang w:val="es-PE"/>
                </w:rPr>
                <w:t>}}</w:t>
            </w:r>

有什么方法可以使用特殊字符在模板中标记变量,以便我可以轻松找到并替换它们?

标签: c#regexms-wordopenxmlwordprocessingml

解决方案


我们使用类似的方法将变量存储到文档中并在之后替换它。关于此的一些经验:如果您更改文档并简单地保存它,那么这些字符通常会按上述方式进行转换。如果您选择另存为,则文档通常会被完全重写,并且特殊字符将保留。我们对双字符有很好的经验,例如 ||lastname|| 在使用另存为方法时正确保存它们。管道符号看起来不是由 MS 字编码的


推荐阅读