我需要将文本替换为MergeField,只需使用文本。我在这个话题上找到了question。对我来说很管用。此代码更改文本,但将字段保留为MergeField。和other question,将MergeField更改为文本。但是,如果一行中有几个这样的字段,则第二个字段将被删除。
此时,我对第一个链接中的代码做了一些调整。要将MergeField更改为文本,需要添加什么?
string sourceFile = @"C:\Users\Owl\Desktop\Template.docm";
string targetFile = @"C:\Users\Owl\Desktop\Result.docx";
File.Copy(sourceFile, targetFile, true);
using (WordprocessingDocument document = WordprocessingDocument.Open(targetFile, true))
{
document.ChangeDocumentType(WordprocessingDocumentType.Document);
foreach (FieldCode field in document.MainDocumentPart
.RootElement.Descendants<FieldCode>())
{
int indexEndName = field.Text.IndexOf("\\");
string fieldName = string.Format("«{0}»",
field.Text.Substring(11, indexEndName - 11).Trim());
foreach (Run run in document.MainDocumentPart.Document.Descendants<Run>())
{
foreach (Text txtFromRun in run.Descendants<Text>()
.Where(a => a.Text == fieldName))
{
txtFromRun.Text = "some text";
}
}
}
document.MainDocumentPart.Document.Save();
}更新
我犯了一个错。第二个链接上的代码。行中的第二个字段未删除。它会留下的。但没有陷入循环,被忽视了。我不明白为什么。
发布于 2019-07-24 10:13:36
问题
topic的代码只有在MergeField在不同的段落中时才能工作。如果有多个段落,将只处理第一个MergeField。其余的被忽略了。
这是因为父元素被移除。
Run rFldCode = (Run)field.Parent;
...
rFldCode.Remove();foreach的下一个元素将来自下一段。我是说我的问题代码的第一个循环。
解决方案
在MergeField中收集List的所有部分。
Run rFldParent = (Run)field.Parent;
List<Run> runs = new List<Run>();
runs.Add(rFldParent.PreviousSibling<Run>()); // begin
runs.Add(rFldParent.NextSibling<Run>()); // separate
runs.Add(runs.Last().NextSibling<Run>()); // text
runs.Add(runs.Last().NextSibling<Run>()); // end清晰的图片。这对我有很大的帮助。

现在移除这些项目
foreach(Run run in runs)
{
run.Remove();
}以及文本字段<w:instrText xml:space="preserve"> MERGEFIELD...
field.Remove(); // instrText并添加新文本
rFldParent.Append(new Text(replacementText));现在,不仅仅是MergeField,而是文本。

全码
string sourceFile = @"C:\Users\Owl\Desktop\Template.docm";
string targetFile = @"C:\Users\Owl\Desktop\Result.docx";
File.Copy(sourceFile, targetFile, true);
using (WordprocessingDocument document = WordprocessingDocument.Open(targetFile, true))
{
document.ChangeDocumentType(WordprocessingDocumentType.Document);
foreach (FieldCode field in document.MainDocumentPart.RootElement.Descendants<FieldCode>())
{
ReplaceMergeFieldWithText(field, "some text");
}
document.MainDocumentPart.Document.Save();
}
private void ReplaceMergeFieldWithText(FieldCode field, string replacementText)
{
if (field == null || replacementText == string.Empty)
{
return;
}
Run rFldParent = (Run)field.Parent;
List<Run> runs = new List<Run>();
runs.Add(rFldParent.PreviousSibling<Run>()); // begin
runs.Add(rFldParent.NextSibling<Run>()); // separate
runs.Add(runs.Last().NextSibling<Run>()); // text
runs.Add(runs.Last().NextSibling<Run>()); // end
foreach(Run run in runs)
{
run.Remove();
}
field.Remove(); // instrText
rFldParent.Append(new Text(replacementText));
}奖金
要插入不同的值,必须创建一个Dictionary。其中键是MergeField名称,值是要插入的文本。
缩短字段名
int indexEndName = field.Text.IndexOf("\\");
string fieldName = field.Text.Substring(11, indexEndName - 11).Trim();例如
Dictionary<string, string> dict = new Dictionary<string, string>();
dict.Add("key 1", "value 1");
dict.Add("key 2", "value 2");
dict.Add("key 3", "value 3");
...
foreach (FieldCode field in document.MainDocumentPart.RootElement.Descendants<FieldCode>())
{
int indexEndName = field.Text.IndexOf("\\");
string fieldName = field.Text.Substring(11, indexEndName - 11).Trim();
ReplaceMergeFieldWithText(field, dict[fieldName]);
}https://stackoverflow.com/questions/57172301
复制相似问题