我们手动处理word 全部替换时,只需要ctrl+H 就可以调出,执行过程中,我们并没有看到word对那些区域处理,只知道结果是全部替换了。
而在C#通过Microsoft.Office.Interop 来处理时,理所当然地认为只要对doc.range进行替换就可以了,实际上效果并不是跟我们想的一样,比如文本框的内容就没有替换。
原因是,word里面将不同的区域分成了不同类型的story类型,每个story类型有多个story,例如文本框就是一种story类型,不同文本框又是该类型下的各个子story。
因此,我们需要对所有的story类型的所有的story的range进行替换就可以达到全局替换的效果。
示例代码如下:
/// <summary>
/// 替换所有符合的text
/// </summary>
/// <param name="doc"></param>
/// <param name="text"></param>
/// <param name="replaceText"></param>
public static void ReplaceAll(Word.Document doc, string text, string replaceText, Logger log)
{
//story ranges 里面保存了不同类型的story range, 每个story range可以通过NextStoryRange来获取同一类型下所有的story range。
foreach (Word.Range storyRange in doc.StoryRanges)
{
Word.Range range = storyRange;
while (range != null)
{
ReplaceAllText(range, text, replaceText, log);
range = range.NextStoryRange;
}
}
}
private static void ReplaceAllText(Word.Range range, string text, string replaceText, Logger log)
{
Word.Find find = range.Find;
find.ClearFormatting();
find.Replacement.ClearFormatting();
find.Text = text;
find.Replacement.Text = replaceText;
find.Forward = true;
find.Wrap = Word.WdFindWrap.wdFindContinue;
find.Format = false;
find.MatchCase = true;
find.MatchWholeWord = false;
find.MatchWildcards = false;
find.MatchSoundsLike = false;
find.MatchAllWordForms = false;
try
{
log.WriteLine($"替换所有【{text}】->【{replaceText}】!");
find.Execute(find.Text, find.MatchCase, find.MatchWholeWord, find.MatchWildcards, find.MatchSoundsLike, find.MatchAllWordForms,
find.Forward, find.Wrap, find.Format, find.Replacement.Text, Word.WdReplace.wdReplaceAll, false, false, false, false);
}
catch (Exception ex)
{
log.WriteException(ex, "ReplaceAll");
}
}