如何将文档链接到不同的结构化模板

时间:2016-03-07 10:13:48

标签: c# templates ms-word office-interop

我尝试自动化更改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;
            }
        }

1 个答案:

答案 0 :(得分:1)

对于特定示例,您需要先从其他模板导入样式,然后执行查找/替换以替换应用的样式。我从你的代码中看到你已经得到了第一部分(aDoc.CopyStylesFromTemplate(template); aDoc.ApplyDocumentTheme(theme); aDoc.UpdateStyles();)。

许多人没有意识到Word的查找/替换功能是它也可以用于格式化。获得必要语法的最佳方法是在宏中记录成功的查找/替换,然后将VBA移植到C#。在UI中:

  1. Ctrl + H打开“替换”对话框
  2. 将光标置于“查找内容”框中,单击“更多”,然后单击“格式”,选择“样式”
  3. 选择要查找并已替换的样式的名称
  4. 点击“替换为”框
  5. 再次使用“格式/样式”选择要使用的样式
  6. 点击“全部替换”。
  7. enter image description here

    这是我得到的结果:

    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. 我获得整个文档的范围
    2. 为Range创建一个Find对象并使用
    3. 引用查找的样式;我展示了两种可能性
    4. 在使用Find.Execute之前,您可以列出查找的几乎所有属性。也可以为每个对象创建object个对象,truefalse只需要一个对象,然后在Find.Execute中列出这些“by ref”。据我所知,这只是个人偏好的问题。我这样做是为了将VBA最简单的“翻译”转换为C#代码。
    5. 在任何情况下,Find.Execute都会“记住”这些设置,因此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);