我正在使用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文件,看到的结果如下:
所以,我的问题是,如何替换包含另一个字段的段落内的合并字段。 对不起,我的英语不好