使用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参数,所以不能直接传string
object 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 = False
End 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:=False
Selection.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中表格的行列起始下标都是1
table.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
Sub

VBA看着很复杂,实际上很多代码都浪费在只需使用默认值的参数上。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);
posted on 2009-06-02 21:56  palo  阅读(6236)  评论(3编辑  收藏  举报