使用VSTO自动生成word文档
最近第一次用VSTO(Visual Studio Tools For Office),写了一个自动生成word报告的小程序,感觉VSTO非常难用。主要是对office对象模型不熟悉,不理解很多类、方法、属性的含义,word里面很简单的操作却不知道如何找到相应的类和方法去实现。在VS里面没办法直接看到VSTO的注释,查MSDN又很不方便。后来总算是找到了一个相对快捷的方法,其实VBA和VSTO使用的是一套对象模型,只要把需要实现的操作录制成宏,对照着VBA的代码就很容易写出相应的C#程序了。
下面举几个小例子。
输入标题:在当前光标处插入一段文字并设置成Heading 1样式,居中
在VBA中录制的宏如下:
Selection.TypeText Text:="Test Title"Selection.Style = ActiveDocument.Styles("Heading 1")Selection.ParagraphFormat.Alignment = wdAlignParagraphCenter
Selection.TypeParagraph
相应的C#代码:
//因为set_Style()要求传ref object参数,所以不能直接传stringobject style_Heading1 = "Heading 1";
WordApp = new ApplicationClass();WordApp.Selection.TypeText("Test Title");//设置样式WordApp.Selection.ParagraphFormat.set_Style(ref style_Heading1);//居中WordApp.Selection.ParagraphFormat.Alignment = WdParagraphAlignment.wdAlignParagraphCenter;
//换行WordApp.Selection.TypeParagraph();
插入一个三行两列的表格,在第一行第一列填入今天的日期,设置样式,根据内容自动调整,去掉标题行
VBA:
ActiveDocument.Tables.Add Range:=Selection.Range, NumRows:=3, NumColumns:= _
2, DefaultTableBehavior:=wdWord9TableBehavior, AutoFitBehavior:= _
wdAutoFitFixed
With Selection.Tables(1)If .Style <> "Table Grid" Then
.Style = "Table Grid"End If
.ApplyStyleHeadingRows = True .ApplyStyleLastRow = False .ApplyStyleFirstColumn = True .ApplyStyleLastColumn = False .ApplyStyleRowBands = True .ApplyStyleColumnBands = FalseEnd With
Selection.Tables(1).Style = "Medium Shading 1 - Accent 5"Selection.Tables(1).ApplyStyleHeadingRows = Not Selection.Tables(1). _ApplyStyleHeadingRows
Selection.InsertDateTime DateTimeFormat:="M/d/yyyy", InsertAsField:=False, _
DateLanguage:=wdEnglishUS, CalendarType:=wdCalendarWestern, _
InsertAsFullWidth:=FalseSelection.Tables(1).AutoFitBehavior (wdAutoFitContent)
C#:注意最后需要调用WordApp.Selection.EndKey把光标移到表格之后,否则在插入表格后光标还在表格之前
WordDoc = WordApp.Documents.Add(ref nothing, ref nothing, ref nothing, ref nothing);
//表格要使用的样式object style_Table1 = "Medium Shading 1 - Accent 1";
object wdStory = WdUnits.wdStory;//添加表格Table table = WordDoc.Tables.Add(WordApp.Selection.Range, 3, 2, ref nothing, ref nothing);
//设置样式table.set_Style(ref style_Table1);//去掉标题行table.ApplyStyleHeadingRows = false;//在第一行第一列插入日期//注意:word中表格的行列起始下标都是1table.Cell(1, 1).Range.Text = DateTime.Today.ToShortDateString();
//根据内容自动调整table.AutoFitBehavior(WdAutoFitBehavior.wdAutoFitContent);
//将光标移到表格后WordApp.Selection.EndKey(ref wdStory, ref nothing);
在纵向页面中插入一个横向的页面
VBA:
Selection.InsertBreak Type:=wdSectionBreakNextPage
WordBasic.TogglePortrait Tab:=3, PaperSize:=0, TopMargin:="1.25", _BottomMargin:="1.25", LeftMargin:="1", RightMargin:="1", Gutter:="0", _
PageWidth:="11", PageHeight:="8.5", Orientation:=1, FirstPage:=0, _
OtherPages:=0, VertAlign:=0, ApplyPropsTo:=0, FacingPages:=0, _
HeaderDistance:="0.5", FooterDistance:="0.5", SectionStart:=2, _
OddAndEvenPages:=0, DifferentFirstPage:=0, Endnotes:=0, LineNum:=0, _
StartingNum:=1, FromText:=wdAutoPosition, CountBy:=0, NumMode:=0, _
TwoOnOne:=0, GutterPosition:=0, LayoutMode:=0, CharsLine:=39, LinesPage:= _
36, CharPitch:=220, LinePitch:=360, DocFontName:="+Body Asian", _DocFontSize:=11, PageColumns:=1, TextFlow:=0, FirstPageOnLeft:=0, _
SectionType:=1, FolioPrint:=0, ReverseFolio:=0, FolioPages:=1
Selection.InsertBreak Type:=wdSectionBreakNextPage
WordBasic.TogglePortrait Tab:=3, PaperSize:=0, TopMargin:="1", _BottomMargin:="1", LeftMargin:="1.25", RightMargin:="1.25", Gutter:="0", _
PageWidth:="8.5", PageHeight:="11", Orientation:=0, FirstPage:=0, _
OtherPages:=0, VertAlign:=0, ApplyPropsTo:=0, FacingPages:=0, _
HeaderDistance:="0.5", FooterDistance:="0.5", SectionStart:=2, _
OddAndEvenPages:=0, DifferentFirstPage:=0, Endnotes:=0, LineNum:=0, _
StartingNum:=1, FromText:=wdAutoPosition, CountBy:=0, NumMode:=0, _
TwoOnOne:=0, GutterPosition:=0, LayoutMode:=0, CharsLine:=58, LinesPage:= _
24, CharPitch:=220, LinePitch:=360, DocFontName:="+Body Asian", _DocFontSize:=11, PageColumns:=1, TextFlow:=0, FirstPageOnLeft:=0, _
SectionType:=1, FolioPrint:=0, ReverseFolio:=0, FolioPages:=1
去掉冗余代码,C#很简单:
object sectionBreak = WdBreakType.wdSectionBreakNextPage;//插入分节符WordApp.Selection.InsertBreak(ref sectionBreak);//将当前页面调整为横向WordApp.Selection.PageSetup.Orientation = WdOrientation.wdOrientLandscape;
//再插入分节符WordApp.Selection.InsertBreak(ref sectionBreak);//将当前页面调整为纵向WordApp.Selection.PageSetup.Orientation = WdOrientation.wdOrientPortrait;
设置项目符号(默认)及自定义的编号(Hello 1, Hello 2,……)
VBA:
With ListGalleries(wdBulletGallery).ListTemplates(1).ListLevels(1).NumberFormat = ChrW(61623)
.TrailingCharacter = wdTrailingTab
.NumberStyle = wdListNumberStyleBullet
.NumberPosition = InchesToPoints(0.25)
.Alignment = wdListLevelAlignLeft
.TextPosition = InchesToPoints(0.5)
.TabPosition = wdUndefined
.ResetOnHigher = 0
.StartAt = 1
With .Font.Bold = wdUndefined
.Italic = wdUndefined
.StrikeThrough = wdUndefined
.Subscript = wdUndefined
.Superscript = wdUndefined
.Shadow = wdUndefined
.Outline = wdUndefined
.Emboss = wdUndefined
.Engrave = wdUndefined
.AllCaps = wdUndefined
.Hidden = wdUndefined
.Underline = wdUndefined
.Color = wdUndefined
.Size = wdUndefined
.Animation = wdUndefined
.DoubleStrikeThrough = wdUndefined
.Name = "Symbol"End With
.LinkedStyle = ""End With
ListGalleries(wdBulletGallery).ListTemplates(1).Name = ""Selection.Range.ListFormat.ApplyListTemplateWithLevel ListTemplate:= _
ListGalleries(wdBulletGallery).ListTemplates(1), ContinuePreviousList:= _
False, ApplyTo:=wdListApplyToWholeList, DefaultListBehavior:= _wdWord10ListBehavior
Selection.TypeText Text:="A1"Selection.TypeParagraph
Selection.TypeText Text:="A2"Selection.TypeParagraph
Selection.TypeText Text:="A3"Selection.TypeParagraph
Selection.Range.ListFormat.RemoveNumbers NumberType:=wdNumberParagraph
With ListGalleries(wdNumberGallery).ListTemplates(1).ListLevels(1) .NumberFormat = "%1.".TrailingCharacter = wdTrailingTab
.NumberStyle = wdListNumberStyleArabic
.NumberPosition = InchesToPoints(0.25)
.Alignment = wdListLevelAlignLeft
.TextPosition = InchesToPoints(0.5)
.TabPosition = wdUndefined
.ResetOnHigher = 0
.StartAt = 1
With .Font.Bold = wdUndefined
.Italic = wdUndefined
.StrikeThrough = wdUndefined
.Subscript = wdUndefined
.Superscript = wdUndefined
.Shadow = wdUndefined
.Outline = wdUndefined
.Emboss = wdUndefined
.Engrave = wdUndefined
.AllCaps = wdUndefined
.Hidden = wdUndefined
.Underline = wdUndefined
.Color = wdUndefined
.Size = wdUndefined
.Animation = wdUndefined
.DoubleStrikeThrough = wdUndefined
.Name = ""End With
.LinkedStyle = ""End With
ListGalleries(wdNumberGallery).ListTemplates(1).Name = ""Selection.Range.ListFormat.ApplyListTemplateWithLevel ListTemplate:= _
ListGalleries(wdNumberGallery).ListTemplates(1), ContinuePreviousList:= _
False, ApplyTo:=wdListApplyToWholeList, DefaultListBehavior:= _wdWord10ListBehavior
With ListGalleries(wdNumberGallery).ListTemplates(1).ListLevels(1) .NumberFormat = "Hello %1".TrailingCharacter = wdTrailingTab
.NumberStyle = wdListNumberStyleArabic
.NumberPosition = InchesToPoints(0.25)
.Alignment = wdListLevelAlignLeft
.TextPosition = InchesToPoints(0.5)
.TabPosition = wdUndefined
.ResetOnHigher = 0
.StartAt = 1
With .Font.Bold = wdUndefined
.Italic = wdUndefined
.StrikeThrough = wdUndefined
.Subscript = wdUndefined
.Superscript = wdUndefined
.Shadow = wdUndefined
.Outline = wdUndefined
.Emboss = wdUndefined
.Engrave = wdUndefined
.AllCaps = wdUndefined
.Hidden = wdUndefined
.Underline = wdUndefined
.Color = wdUndefined
.Size = wdUndefined
.Animation = wdUndefined
.DoubleStrikeThrough = wdUndefined
.Name = ""End With
.LinkedStyle = ""End With
ListGalleries(wdNumberGallery).ListTemplates(1).Name = ""Selection.Range.ListFormat.ApplyListTemplateWithLevel ListTemplate:= _
ListGalleries(wdNumberGallery).ListTemplates(1), ContinuePreviousList:= _
False, ApplyTo:=wdListApplyToWholeList, DefaultListBehavior:= _wdWord10ListBehavior
Selection.TypeText Text:="B1"Selection.TypeParagraph
Selection.TypeText Text:="B2"Selection.TypeParagraph
Selection.TypeText Text:="B3"Selection.TypeParagraph
Selection.Range.ListFormat.RemoveNumbers NumberType:=wdNumberParagraph
SubVBA看着很复杂,实际上很多代码都浪费在只需使用默认值的参数上。C#就很简单:
//应用默认项目符号WordApp.Selection.Range.ListFormat.ApplyBulletDefault(ref nothing);WordApp.Selection.TypeText("A1");WordApp.Selection.TypeParagraph();
WordApp.Selection.TypeText("A2");WordApp.Selection.TypeParagraph();
WordApp.Selection.TypeText("A3");WordApp.Selection.TypeParagraph();
//使用完记得取消掉WordApp.Selection.Range.ListFormat.ApplyBulletDefault(ref nothing);//应用编号WordApp.Selection.Range.ListFormat.ApplyNumberDefault(ref nothing);//自定义格式WordApp.Selection.Range.ListFormat.ListTemplate.ListLevels[1].NumberFormat = "Hello %1:";WordApp.Selection.TypeText("B1");WordApp.Selection.TypeParagraph();
WordApp.Selection.TypeText("B2");WordApp.Selection.TypeParagraph();
WordApp.Selection.TypeText("B3");WordApp.Selection.TypeParagraph();
//取消编号WordApp.Selection.Range.ListFormat.ApplyNumberDefault(ref nothing);
浙公网安备 33010602011771号