Openxmlsdk:用HTML文本替换MergeField

时间:2018-07-16 04:49:45

标签: c# openxml-sdk mergefield

我正在使用DocumentFormat.OpenXml替换模板docx文件中的合并字段。

步骤1,我编写了查找合并字段的方法

            var instructionRegEx = new Regex(@"[\w]*\sMERGEFIELD\s+(?<name>[\w]+)", RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace | RegexOptions.Singleline);

            string GetFieldName(OpenXmlElement field)
            {
                string outerXml = field.OuterXml;
                if (!string.IsNullOrEmpty(outerXml))
                {
                    Match m = instructionRegEx.Match(outerXml);
                    if (m.Success)
                    {
                        return m.Groups["name"].ToString().Trim();
                    }
                }
                return string.Empty;
            }

            using (var docx = WordprocessingDocument.Open(filePath, true))
            {
                var fields = docx.MainDocumentPart.RootElement.Descendants<SimpleField>().Select(item => (OpenXmlElement)item)
                    .Concat(docx.MainDocumentPart.RootElement.Descendants<FieldCode>().Select(item => (OpenXmlElement)item))
                    .ToList();
                foreach (var field in fields)
                {
                    var name = GetFieldName(field);
                    if (string.IsNullOrEmpty(name)) continue;
                    switch (name)
                    {
                     ///
                    }
                }
            }

第2步,我编写了替换html文本的方法

 public static void ReplaceHtml(this WordprocessingDocument document, OpenXmlElement el, string html, bool disableHtmlHeader = false, string color = "", string alignment = "", string lineHeight = "", bool removeStyle = true)
        {
            var formatImportPart = document.MainDocumentPart.AddAlternativeFormatImportPart(AlternativeFormatImportPartType.Html);
            var idOfPart = document.MainDocumentPart.GetIdOfPart(formatImportPart);
            var convertedHtml = html.ConvertHtmlContent(disableHtmlHeader: disableHtmlHeader, aligment: alignment, color: color, lineHeight: lineHeight, removeStyle: removeStyle);
            using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(convertedHtml)))
            {
                formatImportPart.FeedData(ms);
            }
            var altChunk = new AltChunk
            {
                Id = idOfPart
            };
            var r = new Run();
            foreach (RunProperties placeholderrpr in el.Parent.Descendants<RunProperties>())
            {
                r.Append(new RunProperties(placeholderrpr.OuterXml));
            }
            r.Append(altChunk);
            ReplaceElement(el, r);
        }
private static void ReplaceElement(OpenXmlElement el, OpenXmlElement newEl)
        {
            if (el == null) return;
            if (el is SimpleField)
            {
                el.Parent.ReplaceChild(newEl, el);
            }
            else if (el is FieldCode)
            {
                var parent = el.Parent;
                var begin = parent.PreviousSibling();
                var separate = parent.NextSibling();
                var runText = separate.NextSibling();
                var end = runText.NextSibling();
                var another = end.NextSibling();
                var container = parent.Parent;                    
                container.InsertAfter(newEl, parent);
                container.RemoveChild(parent);
                container.RemoveChild(begin);
                container.RemoveChild(separate);
                container.RemoveChild(runText);
                container.RemoveChild(end);
            }
        }

在RemoveChild之后,包含合并字段的段落为空时,代码运行良好。但是,如果它仍然包含某些元素,则替换合并字段后的docx文件将损坏。 我已经用xml工具打开docx文件,看到的结果如下: enter image description here

enter image description here

所以,我的问题是,如何替换包含另一个字段的段落内的合并字段。 对不起,我的英语不好

0 个答案:

没有答案