如何 link 文档到不同的结构化模板

How to link document to different structured template

我正在尝试自动化更改 word 文件的文档模板的过程。

如果模板结构相似,即它们都使用 heading1,则当文档链接到新模板时,它会起作用。

不过模板结构完全不同,heading1已经不用了,现在是section1。如何用代码更改这些部分的标题?类似于 if(heading1) rename to section1;

我正在使用 Interop.Word 来执行这些操作。

下面是我使用的代码:

public string UpdateDocumentWithNewTemplate(string document, string theme, string template, Word.Application wordApp)
        {
            try
            {
                object missing = System.Reflection.Missing.Value;
                Word.Document aDoc = null;
                object notReadOnly = false;
                object isVisible = false;
                wordApp.Visible = false;
                // create objects from variables for wordApp
                object documentObject = document;

                // open existing document
                aDoc = wordApp.Documents.Open(ref documentObject, ref missing, ref notReadOnly, ref missing, ref missing,
                    ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref isVisible,
                    ref missing, ref missing, ref missing, ref missing);
                aDoc.Activate();

                // set template and theme to overwrite the existing styles
                aDoc.CopyStylesFromTemplate(template);
                aDoc.ApplyDocumentTheme(theme);
                aDoc.UpdateStyles();

                // save the file with the changes
                aDoc.SaveAs(ref documentObject, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing,
                    ref missing, ref missing, ref missing, ref missing, ref missing, ref missing);

                // close the document
                aDoc.Close(ref missing, ref missing, ref missing);
                if (aDoc != null)
                    System.Runtime.InteropServices.Marshal.ReleaseComObject(aDoc);
                aDoc = null;

                return documentObject.ToString();
            }
            catch (Exception exception)
            {
                return "Error: " + exception;
            }
        }

对于具体示例,您需要先从其他模板导入样式,然后执行Find/Replace 替换应用的样式。我从你的代码中看到你有第一部分 (aDoc.CopyStylesFromTemplate(template); aDoc.ApplyDocumentTheme(theme); aDoc.UpdateStyles();).

许多人没有意识到 Word 的 Find/Replace 功能是它还可以处理格式设置。获得必要语法的最佳方法是在宏中记录成功的 Find/Replace,然后将 VBA 移植到 C#。在 UI:

  1. Ctrl+H 打开替换对话框
  2. 将光标放在 "Find what" 框中,单击 "More",然后单击 "Format",然后选择 "Style"
  3. Select您要查找并已替换的样式名称
  4. 单击 "Replace with" 框
  5. 再次使用 Format/Style 选择您要使用的样式
  6. 点击"Replace All"。

这是我得到的结果:

Selection.Find.ClearFormatting
Selection.Find.Style = ActiveDocument.styles("Heading 1")
Selection.Find.Replacement.ClearFormatting
Selection.Find.Replacement.Style = ActiveDocument.styles("section2")
With Selection.Find
    .Text = ""
    .Replacement.Text = ""
    .Forward = True
    .wrap = wdFindContinue
    .Format = True
    .MatchCase = False
    .MatchWholeWord = False
    .MatchByte = False
    .CorrectHangulEndings = False
    .HanjaPhoneticHangul = False
    .MatchWildcards = False
    .MatchSoundsLike = False
    .MatchAllWordForms = False
End With
Selection.Find.Execute Replace:=wdReplaceAll

您应该使用 Range,而不是 Selection。因此 C# 代码看起来类似于以下代码块。注意如何

  1. 我得到了整个文档的Range
  2. 为范围创建一个 Find 对象并使用它
  3. 为查找参考样式;我展示两种可能性
  4. 在使用 Find.Execute 之前,您可以列出 Find 的几乎所有属性。也可以为每个对象创建 object 个对象,truefalse 只需要一个对象,然后在 Find.Execute 中列出这些 "by ref"。据我所知,这只是个人喜好问题。我这样做是为了 VBA 到 C# 代码中最直接的 "translation"。
  5. 无论如何,Find.Execute"remembers"这些设置,所以ref missing然后可以用于所有你没有专门设置的参数。在这种情况下,方法中只专门使用"replace all"命令。

        Word.Document doc = wdApp.ActiveDocument;
        Word.Range rngFind = doc.Content;
        Word.Find fd = rngFind.Find;
        fd.ClearFormatting();
        Word.Style stylFind = doc.Styles["Heading 1"];
        fd.set_Style(stylFind);
        fd.Replacement.ClearFormatting();
        fd.Replacement.set_Style(doc.Styles["section2"]);
        fd.Text = "";
        fd.Replacement.Text = "";
        fd.Forward = true;
        fd.Wrap = Word.WdFindWrap.wdFindStop;
        fd.Format = true;
        fd.MatchCase = false;
        fd.MatchWholeWord = false;
        fd.MatchByte = false;
        fd.CorrectHangulEndings = false;
        fd.HanjaPhoneticHangul = false;
        fd.MatchWildcards = false;
        fd.MatchSoundsLike = false;
        fd.MatchAllWordForms = false;
        object replaceAll = Word.WdReplace.wdReplaceAll;
        object missing = Type.Missing;
        fd.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);