我尝试自动化更改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;
}
}
答案 0 :(得分:1)
对于特定示例,您需要先从其他模板导入样式,然后执行查找/替换以替换应用的样式。我从你的代码中看到你已经得到了第一部分(aDoc.CopyStylesFromTemplate(template); aDoc.ApplyDocumentTheme(theme); aDoc.UpdateStyles();
)。
许多人没有意识到Word的查找/替换功能是它也可以用于格式化。获得必要语法的最佳方法是在宏中记录成功的查找/替换,然后将VBA移植到C#。在UI中:
这是我得到的结果:
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#代码看起来像下面的代码块。注意
Find
对象并使用Find.Execute
之前,您可以列出查找的几乎所有属性。也可以为每个对象创建object
个对象,true
和false
只需要一个对象,然后在Find.Execute
中列出这些“by ref”。据我所知,这只是个人偏好的问题。我这样做是为了将VBA最简单的“翻译”转换为C#代码。在任何情况下,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);