12

如何替换页眉/页脚中的“FIELD”?

例如:带有文件名和日期的 Word doc 文件。代替文件路径 - [FilePath] 代替 C://Documents/Location/Filename.doc ,[Date] 代替 18/07/2013。

我可以用范围替换任何文本。

foreach (Microsoft.Office.Interop.Word.Section section in wordDocument.Sections)
{
   section.Headers[WdHeaderFooterIndex.wdHeaderFooterPrimary].Range.Text.Replace(sourceDocPath, "[File Path]");

   section.Footers[WdHeaderFooterIndex.wdHeaderFooterPrimary].Range.Text.Replace(sourceDocPath, "[File Path]"); 
}

这适用于文件名,但对于日期,无法猜测要替换的格式。这都是因为我无法获取要替换的确切字段信息。

下面的代码我也不能使用

wordApp.Selection.Find.Execute(ref textToReplace, ref typeMissing, 
        ref typeMissing, ref typeMissing, ref typeMissing, ref typeMissing, 
        ref typeMissing, ref typeMissing, ref typeMissing, ref typeMissing, 
        ref replaceTextWith, ref replaceAll, ref typeMissing, ref typeMissing, 
        ref typeMissing, ref typeMissing);

到目前为止,我看到的唯一方法是处理所有可能的日期格式并替换,但这对我来说似乎不是一个好方法。

根据使用 Storyrange 给出的评论进行更新。

没有给我确切的字段信息说 [DATE]。当我遍历故事范围时,我得到的类型信息是关于部分信息的 wdstorytype,而不是关于字段信息的信息。

foreach (Microsoft.Office.Interop.Word.Range tmpRange in wordDocument.StoryRanges)
                    {
                        string strtype = tmpRange.StoryType.ToString();
                        tmpRange.Find.Text = "18/07/2013";
                        tmpRange.Find.Replacement.Text = "";
                        tmpRange.Find.Replacement.ParagraphFormat.Alignment =
                            Microsoft.Office.Interop.Word.WdParagraphAlignment.wdAlignParagraphJustify;

                        tmpRange.Find.Wrap = Microsoft.Office.Interop.Word.WdFindWrap.wdFindContinue;
                        object replaceAll = Microsoft.Office.Interop.Word.WdReplace.wdReplaceAll;

                        tmpRange.Find.Execute(ref missing, ref missing, ref missing,
                            ref missing, ref missing, ref missing, ref missing,
                            ref missing, ref missing, ref missing, ref replaceAll,
                            ref missing, ref missing, ref missing, ref missing);
                    }

更新: 在这里看起来对我有帮助,但似乎不起作用。知道如何在导出之前强制文档对象使用以下内容。

field.ShowCodes = true;
4

3 回答 3

15

最后在浏览了关于 introp.word 的糟糕文档之后,得到了解决方案

// Loop through all sections
foreach (Microsoft.Office.Interop.Word.Section section in wordDocument.Sections) {

    wordDocument.TrackRevisions = false; //Disable Tracking for the Field replacement operation

    //Get all Headers
    Microsoft.Office.Interop.Word.HeadersFooters headers = section.Headers;

    //Section headerfooter loop for all types enum WdHeaderFooterIndex. wdHeaderFooterEvenPages/wdHeaderFooterFirstPage/wdHeaderFooterPrimary;                          
    foreach (Microsoft.Office.Interop.Word.HeaderFooter header in headers)
    {
        Fields fields = header.Range.Fields;

        foreach (Field field in fields)
        {
            if (field.Type == WdFieldType.wdFieldDate)
            {
                field.Select ();
                field.Delete ();
                wordApplication.Selection.TypeText ("[DATE]");
            }
            else if (field.Type == WdFieldType.wdFieldFileName)
            {
                field.Select ();
                field.Delete ();
                wordApplication.Selection.TypeText ("[FILE NAME]");

            }
        }
    }

    //Get all Footers
    Microsoft.Office.Interop.Word.HeadersFooters footers = section.Footers;

    //Section headerfooter loop for all types enum WdHeaderFooterIndex. wdHeaderFooterEvenPages/wdHeaderFooterFirstPage/wdHeaderFooterPrimary; 
    foreach (Microsoft.Office.Interop.Word.HeaderFooter footer in footers)
    {
        Fields fields = footer.Range.Fields;

        foreach (Field field in fields)
        {
            if (field.Type == WdFieldType.wdFieldDate)
            {
                field.Select ();
                field.Delete ();
                wordApplication.Selection.TypeText ("[DATE]");
            }
            else if (field.Type == WdFieldType.wdFieldFileName)
            {
                field.Select ();
                field.Delete ();
                wordApplication.Selection.TypeText ("[FILE NAME]");

            }
        }
    }
}
于 2013-07-19T04:53:57.530 回答
3

杰伊,

也许有点晚了,但无论如何......

无法评论,所以我回答。

就当前接受的答案而言,我认为有一天可能对您(或其他人)有用的东西很少。

  1. 要回答上次更新中的问题,您可以使用类似这样的方法来打开字段代码,然后使用 Find 来搜索字段内容:

    wordDocument.ActiveWindow.View.ShowFieldCodes = true;
    

    因此,您可以在搜索之前将其打开(除非已经打开),并在完成后将其恢复。

  2. 您提供给自己的解决方案适用于大多数情况,我使用过一段时间。但是,我遇到了一个包含 2000 个部分的文档。循环遍历这些部分将依次循环遍历相同的标题。在我的情况下,处理文档超时(考虑到可接受的处理时间)

  3. StoryRanges 的解决方案可能是更好的方法(结合切换域代码)
    使用它的一些示例(通用搜索和替换):
    http
    ://word.mvps.org/faqs/customization/ReplaceAnywhere.htm https://wls .wwco.com/blog/2010/07/03/find-and-replace-in-word-using-c-net/

  4. 要记住的一件事:不要忘记在 Shapes of Range 中搜索东西

  5. 我猜你想出了如何替换字段。无论如何,我实际上是将简单文本转换为字段。

    一旦 Find.Execute 击中某些东西,范围将被选中,我会这样做

    theDoc.Fields.Add(range, WdFieldType.wdFieldDocVariable, "myDocVar");
    

TL;DR:如果您的文档在格式上是可预测的,并且只有少量部分并且文本不在形状内,那么不要担心所有这些。

于 2016-12-06T00:40:34.413 回答
1
object replaceAll = MSWord.WdReplace.wdReplaceAll;
foreach (Microsoft.Office.Interop.Word.Section section in oDoc.Sections)
{
    Microsoft.Office.Interop.Word.Range footerRange =  section.Footers[Microsoft.Office.Interop.Word.WdHeaderFooterIndex.wdHeaderFooterPrimary].Range;
    footerRange.Find.Text = "Some Text";
    footerRange.Find.Replacement.Text = "Replace Text";
    footerRange.Find.Execute(ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref replaceAll, ref missing, ref missing, ref missing, ref missing);
}

oDoc 是具有当前文档的“MSWord.Document”对象,即

oDoc = oMSWord.Documents.Open(ref "DocPath", ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing);

然后在当前 oDoc 对象的“部分”上应用循环。根据“部分”,您将获得页脚范围。然后您将能够找到并替换页脚中的文本。

于 2016-02-03T07:43:21.067 回答