C#中的Openxml只更新段落中的第一个合并字段
我在一个文档中有大约10个C#中的Openxml只更新段落中的第一个合并字段,c#,merge,openxml,C#,Merge,Openxml,我在一个文档中有大约10个MERGEFIELD,我试图用一些值替换文本。这是密码 using (WordprocessingDocument document = WordprocessingDocument.Open(destinationFileName, true)) { document.ChangeDocumentType(DocumentFormat.OpenXml.WordprocessingDocumentType.Docu
MERGEFIELD
,我试图用一些值替换文本。这是密码
using (WordprocessingDocument document = WordprocessingDocument.Open(destinationFileName, true))
{
document.ChangeDocumentType(DocumentFormat.OpenXml.WordprocessingDocumentType.Document);
MainDocumentPart docPart = document.MainDocumentPart;
docPart.AddExternalRelationship("http://schemas.openxmlformats.org/officeDocument/2006/relationships/attachedTemplate", new Uri(destinationFileName, UriKind.RelativeOrAbsolute));
docPart.Document.Save();
IEnumerable<FieldChar> fldChars = document.MainDocumentPart.RootElement.Descendants<FieldChar>();
if (fldChars == null) { return; }
string fieldList = string.Empty;
FieldChar fldCharStart = null;
FieldChar fldCharEnd = null;
FieldChar fldCharSep = null;
FieldCode fldCode = null;
string fldContent = String.Empty;
int i = 1;
foreach(var fldChar in fldChars)
{
System.Diagnostics.Debug.WriteLine(i + ": " + fldChar);
i++;
string fldCharPart = fldChar.FieldCharType.ToString();
System.Diagnostics.Debug.WriteLine("Field Char Length: " + fldChar.Count());
System.Diagnostics.Debug.WriteLine("Field Char part: " + fldCharPart);
switch(fldCharPart)
{
case "begin": // start of the field
fldCharStart = fldChar;
System.Diagnostics.Debug.WriteLine("Field Char Start: " + fldCharStart);
// get the field code, which will be an instrText element
// either as sibling or as a child of the parent sibling
fldCode = fldCharStart.Parent.Descendants<FieldCode>().FirstOrDefault();
System.Diagnostics.Debug.WriteLine("Field Code: " + fldCode);
if (fldCode == null)
{
fldCode = fldCharStart.Parent.NextSibling<Run>().Descendants<FieldCode>().FirstOrDefault();
System.Diagnostics.Debug.WriteLine("New Field Code: " + fldCode);
}
if (fldCode != null && fldCode.InnerText.Contains("MERGEFIELD"))
{
fldContent = getFieldValue(query, prescriber, fldCode.InnerText);
fieldList += fldContent + "\n";
System.Diagnostics.Debug.WriteLine("Field content: " + fldContent);
}
break;
case "end": // end of the field
fldCharEnd = fldChar;
System.Diagnostics.Debug.WriteLine("Field char end: " + fldCharEnd);
break;
case "separate": // complex field with text result
fldCharSep = fldChar;
break;
default:
break;
}
if((fldCharStart != null) && (fldCharEnd != null))
{
if(fldCharSep != null)
{
Text elemText = (Text)fldCharSep.Parent.NextSibling().Descendants<Text>().FirstOrDefault();
elemText.Text = fldContent;
System.Diagnostics.Debug.WriteLine("Element text: " + elemText);
// Delete all field chas with their runs
DeleteFieldChar(fldCharStart);
DeleteFieldChar(fldCharEnd);
DeleteFieldChar(fldCharSep);
fldCode.Remove();
}
else
{
Text elemText = new Text(fldContent);
fldCode.Parent.Append(elemText);
fldCode.Remove();
System.Diagnostics.Debug.WriteLine("Element Text !sep: " + elemText);
DeleteFieldChar(fldCharStart);
DeleteFieldChar(fldCharEnd);
DeleteFieldChar(fldCharSep);
}
fldCharStart = null;
fldCharEnd = null;
fldCharSep = null;
fldCode = null;
fldContent = string.Empty;
}
}
System.Diagnostics.Debug.WriteLine("Field list: " + fieldList);
}
使用(WordprocessingDocument=WordprocessingDocument.Open(destinationFileName,true))
{
document.ChangeDocumentType(DocumentFormat.OpenXml.WordprocessingDocumentType.document);
MainDocumentPart docPart=document.MainDocumentPart;
docPart.AdderExternalRelationship(“http://schemas.openxmlformats.org/officeDocument/2006/relationships/attachedTemplate,新Uri(destinationFileName,UriKind.RelativeOrAbsolute));
docPart.Document.Save();
IEnumerable fldChars=document.MainDocumentPart.RootElement.subjects();
如果(fldChars==null){return;}
string fieldList=string.Empty;
FieldChar fldCharStart=null;
FieldChar fldCharEnd=null;
FieldChar fldCharSep=null;
字段代码fldCode=null;
string fldContent=string.Empty;
int i=1;
foreach(fldChars中的var fldChar)
{
系统.诊断.调试.写线(i+“:”+fldChar);
i++;
字符串fldCharPart=fldChar.FieldCharType.ToString();
System.Diagnostics.Debug.WriteLine(“字段字符长度:+fldChar.Count());
System.Diagnostics.Debug.WriteLine(“字段字符部分:+fldCharPart”);
开关(fldCharPart)
{
案例“开始”://字段的开始
fldCharStart=fldChar;
System.Diagnostics.Debug.WriteLine(“字段字符开始:+fldCharStart”);
//获取字段代码,它将是instrText元素
//作为兄弟姐妹或作为父兄弟姐妹的子代
fldCode=fldCharStart.Parent.subjections().FirstOrDefault();
System.Diagnostics.Debug.WriteLine(“字段代码:“+fldCode”);
如果(fldCode==null)
{
fldCode=fldCharStart.Parent.NextSibling().subjections().FirstOrDefault();
System.Diagnostics.Debug.WriteLine(“新字段代码:“+fldCode”);
}
if(fldCode!=null&&fldCode.InnerText.Contains(“合并字段”))
{
fldContent=getFieldValue(查询、处方、fldCode.InnerText);
fieldList+=fldContent+“\n”;
System.Diagnostics.Debug.WriteLine(“字段内容:+fldContent”);
}
打破
案例“结束”://字段结束
fldCharEnd=fldChar;
System.Diagnostics.Debug.WriteLine(“字段字符结束:+fldCharEnd”);
打破
case“separate”://带文本结果的复杂字段
fldCharSep=fldChar;
打破
违约:
打破
}
if((fldCharStart!=null)&(fldCharEnd!=null))
{
如果(fldCharSep!=null)
{
Text elemText=(Text)fldCharSep.Parent.NextSibling().subjects().FirstOrDefault();
elemText.Text=fldContent;
System.Diagnostics.Debug.WriteLine(“元素文本:“+elemText”);
//删除所有字段CHA及其运行
DeleteFieldChar(fldCharStart);
DeleteFieldChar(fldCharEnd);
DeleteFieldChar(fldCharSep);
fldCode.Remove();
}
其他的
{
Text elemText=新文本(fldContent);
fldCode.Parent.Append(elemText);
fldCode.Remove();
System.Diagnostics.Debug.WriteLine(“元素文本!sep:+elemText”);
DeleteFieldChar(fldCharStart);
DeleteFieldChar(fldCharEnd);
DeleteFieldChar(fldCharSep);
}
fldCharStart=null;
fldCharEnd=null;
fldCharSep=null;
fldCode=null;
fldContent=string.Empty;
}
}
System.Diagnostics.Debug.WriteLine(“字段列表:“+fieldList”);
}
它在某种程度上起作用。问题是当一个段落中有多个字段时。在本文档的一个段落中,我有大约4个合并字段,之后每个段落中都有一个字段。仅更新段落中的第一个合并字段,而未触及段落中的其余字段。然后,它移动到下一段并查找字段。我怎样才能解决这个问题 看起来您将简单的邮件合并替换复杂化了。与其循环浏览段落,不如获取文档中的所有mailmerge字段并替换它们
private const string FieldDelimeter = " MERGEFIELD ";
foreach (FieldCode field in doc.MainDocumentPart.RootElement.Descendants<FieldCode>())
{
var fieldNameStart = field.Text.LastIndexOf(FieldDelimeter, System.StringComparison.Ordinal);
var fieldName = field.Text.Substring(fieldNameStart + FieldDelimeter.Length).Trim();
foreach (Run run in doc.MainDocumentPart.Document.Descendants<Run>())
{
foreach (Text txtFromRun in run.Descendants<Text>().Where(a => a.Text == "«" + fieldName + "»"))
{
txtFromRun.Text = "Replace what the merge field here";
}
}
}
doc.MainDocumentPart.Document.Save();
private const string FieldDelimeter=“MERGEFIELD”;
foreach(doc.MainDocumentPart.RootElement.Subjections()中的FieldCode字段)
{
var fieldNameStart=field.Text.LastIndexOf(FieldDelimeter,System.StringComparison.Ordinal);
变量fieldName=fie