将 MergeField 更改为纯文本
Change MergeField to text only
我需要将文本替换为 MergeField
,并且只是简单的文本。我发现 on the topic. It works for me. This code changes the text, but leaves the field as MergeField
. And other question 将 MergeField
更改为文本。但如果一行中有多个这样的字段,则第二个将被删除。
此时,我对第一个 link 中的代码进行了一些调整。我需要添加什么才能将 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();
}
更新
我错了。第二个代码link。该行中的第二个字段未删除。它留下来。但不落入循环,被忽略。我不明白为什么。
问题
topic 中的代码仅在 MergeField
位于不同段落中时有效。如果有多个段落,则只处理第一个MergeField
。其余忽略不计。
这是因为删除了父元素。
Run rFldCode = (Run)field.Parent;
...
rFldCode.Remove();
foreach
的下一个元素将来自下一段。我的意思是我的问题代码的第一个循环。
解决方案
收集 List
中 MergeField
的所有部分。
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]);
}
我需要将文本替换为 MergeField
,并且只是简单的文本。我发现 MergeField
. And other question 将 MergeField
更改为文本。但如果一行中有多个这样的字段,则第二个将被删除。
此时,我对第一个 link 中的代码进行了一些调整。我需要添加什么才能将 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();
}
更新
我错了。第二个代码link。该行中的第二个字段未删除。它留下来。但不落入循环,被忽略。我不明白为什么。
问题
topic 中的代码仅在 MergeField
位于不同段落中时有效。如果有多个段落,则只处理第一个MergeField
。其余忽略不计。
这是因为删除了父元素。
Run rFldCode = (Run)field.Parent;
...
rFldCode.Remove();
foreach
的下一个元素将来自下一段。我的意思是我的问题代码的第一个循环。
解决方案
收集 List
中 MergeField
的所有部分。
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]);
}