精华内容
下载资源
问答
  • 使用VSTO自动生成word文档

    千次阅读 2012-07-06 16:50:56
    最近第一次用VSTO(Visual Studio Tools For Office),写了一个自动生成word报告的小程序,感觉VSTO非常难用。主要是对office对象模型不熟悉,不理解很多类、方法、属性的含义,word里面很简单的操作却不知道如何...

    http://www.cnblogs.com/palo/archive/2009/06/02/vsto_vba.html


    最近第一次用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);


    展开全文
  • 关于VBA编辑word自动生成报告

    万次阅读 2016-08-02 20:15:59
    关于VBA编辑word自动生成报告 这适合于图比较多,表比较多,并且报告格式单一,但每天需要大量出word报告的情况 -工具使用 -难点 -功能块 参考文件 工具 如图片所示,虽然版本可以不同,但库的类别相差...

    关于VBA编辑word自动生成报告

    item

    这适合于图比较多,表比较多,并且报告格式单一,但每天需要大量出word报告的情况

    -工具使用
    -难点
    -功能块

    参考文件

    工具

    如图片所示,虽然版本可以不同,但库的类别相差不大
    picture1

    难点

    • 输入划分

      一般word文档中的输入是 图和表,如果将输入按照对象类型来划分不同的文件夹,通过划分文件类型,降低了对象处理难度.由此需要1个函数来读取文件路径并存储。

    • 输入处理

      图和表都是需要插入到word文档的,可以不通过判断文件类型来处理。使用bookmark标记对象处在的位置,可以不考率对象类型,根据之前的文件夹划分对象,即可插入正确的对象类型。这里有个难点就是,如何根据word文档模板中的表名和图片名,自动的生成bookmark.(其实只要格式是固定的,自己做1个模板,定义不同表名与图片名的bookmark名字,也可以。这样就限定了使用。只要格式不一样,就需要手动创建word模板)

      举个例子说明,有Table 1: Information_1 和 Table 2: Information_2
      需要在这2行的位置之上插入1个bookmark。手动的做法是,鼠标点击该行上一行的起始位置, 点击菜单栏的 插入->书签->命名并添加书签名

    • 格式调整问题

      对于表格的格式调整,很麻烦。尤其是存在合并单元格的表格。当通过vba,从excel插入表格到对应的bookmark。表格的格式要与word页面想匹配,是个很大的问题。

      图片的格式调整就很容易,只需使输入图片的大小一致即可。 (一般报告的图片输入,都是大小一致的)

    功能块

    • openfilemethod() 用于打开文件夹的并计数文件个数

    以下2个方程可以实现openfilemethod() 方法(本人不知道VBA中怎么返回多个不同类型的参数,所以分了2个function), 30限定了插入对象个数,其实完全够了,毕竟1个word文档有30幅图很多了。Application.FileDialog(msoFileDialogOpen)是word vba开发手册中实现的方法。

    Function openfileway(bol As Boolean) As Variant
    Dim lngCount As Long
    Dim pathstr(1 To 30) As String
    With Application.FileDialog(msoFileDialogOpen)
    .AllowMultiSelect = bol’可以选择多个文件
    .Show
    For lngCount = 1 To .SelectedItems.Count
    pathstr(lngCount) = .SelectedItems(lngCount)
    Next lngCount
    End With
    openfileway = pathstr
    End Function

    Function openfilecount(ParamArray arr()) As Integer
    Dim i As Integer
    For i = 1 To 30
    If arr(0)(i) Like “” Then
    Exit For
    End If
    Next
    openfilecount = i - 1
    End Function

    • addpicture()用于插入图片

    Sub addpicture(i As Integer, s As Variant, dcwd As Word.document, ParamArray pathstr())
    Dim j As Integer
    For j = 1 To i
    If InStr(pathstr(0)(j), s) > 0 Then
    dcwd.InlineShapes.addpicture _
    Filename:=pathstr(0)(j), _
    LinkToFile:=False, SaveWithDocument:=True, _
    Range:=dcwd.bookmarks(s).Range
    End If
    Next
    End Sub

    • picturesize()可以调整图片大小

    Sub picturesize(dcwd As Word.document)
    Dim j As Integer
    For j = 1 To dcwd.InlineShapes.Count
    picheight = dcwd.InlineShapes(j).Height
    picwidth = dcwd.InlineShapes(j).Width
    dcwd.InlineShapes(j).Height = picheight * 0.75 ‘设置高度为0.75倍
    dcwd.InlineShapes(j).Width = picwidth * 0.75 ‘设置宽度为0.75倍
    dcwd.InlineShapes(j).Borders.OutsideLineStyle = wdLineStyleSingle
    Next j
    End Sub

    • exceltablepaste()用于插入table表

    Sub excelpaste(i As Integer, s As Variant, dcwd As Word.document, sheetname As String, srange As String, bookmark As String, ParamArray pathstr())
    Dim wbBook As Workbook
    Dim wsSheet As Worksheet
    Dim rnReport As Range

    'Initialize the Excel objects.
    Set wbBook = GetObject(workpath(workcount))
    Set wsSheet = wbBook.Worksheets(sheetname)
    Set rnReport = wsSheet.Range(srange)
     Set wdbmRange = dcwd.bookmarks(bookmark).Range
    'Turn off screen updating.
    Application.ScreenUpdating = False
    rnReport.Copy
    
    With wdbmRange
        .Select
        .PasteSpecial link:=False, _
                      DataType:=wdPasteRTF, _
                      Placement:=wdFloatOverText, _
                      DisplayAsIcon:=False
    End With
    
    
    Set wdbmRange = Nothing
    
    With Application
        .CutCopyMode = False
        .ScreenUpdating = True
    End With
    
    wbBook.Close '关闭打开的workbook,不然会有excel的进
    End Sub
    

    实现链接

    展开全文
  • 做了一个多月的C#生成Word文档的工作,我从一开始的对这个一窍不通,到现在的顺利完成...对于用C#来自动生成Word文档来说,最大的问题是微软提供的所有文档的源代码一般都是VBA编程的,没有C#的现成文档,最多也只是...

    做了一个多月的C#生成Word文档的工作,我从一开始的对这个一窍不通,到现在的顺利完成了这个功能模块,其中还是有点心得的。想想自己说不定以后还会用到,于是想吧这些心得写下来,以供自己以后的学习。同时也希望对那些正在或正要编程实现自动生成Word的朋友有些小小的帮助。

    对于用C#来自动生成Word文档来说,最大的问题是微软提供的所有文档的源代码一般都是VBA编程的,没有C#的现成文档,最多也只是一些How To文档。显然,VBA编程和C#是有一定区别的,VBA编程的风格和C#是完全不同的,它有着VB编程快捷的特性,可以省略参数,可以对Style对象赋值等的功能是C#所没有的。其次,在这个任务通过Word录制宏查看到的宏代码也是由VB代码显示的,我们必须要把这些宏代码转换到C#代码。所以,做这个任务的人必须先有一点VB的经验(最起码知道那些代码是在干什么)。
     
    下面是我自学C#生成Word文档的过程(首先必须安装好Word2003和.NET2003):

    一、下载Word的VBA编程参考手册和网上的在线资料
    微软大概觉得VB用的人太少了,想大力发展之,搞得Office编程的参考手册都是VBA编程,害的我不懂VB的人也不得不学。不过没办法,要做这个工作,微软的参考手册是不能少的,可以从http://msdn.microsoft.com/office/downloads/vba/default.aspx这个页面中下到相应的的Office(本人使用的是Word2003,但好像只用WordXP的参考手册)的VBA Language References(当然这个文档是全英文的,看她简直是我的噩梦)。没有必要看完这个参考手册,只要搜索需要的函数,然后看看就可以了。

    有了这个参考手册是远远不够的,我们需要去网上搜集大量的现成代码来看看才能快速的上手。下面是一个微软老大提供的关于C#生成Word的中文How To文档,感觉很好,分享一下http://support.microsoft.com/search/default.aspx?query=Word&catalog=LCID%3D2052&spid=1108&qryWt=&mode=r&cus=False。当然,微软提供的文档都是最基础的,我们只能在需要用到这个功能的时候才只得看看一看看,很全面,但没有一个包含所有东西的程序。所以,我们还得再在网上淘资料。终于我在http://www.codeproject.com/aspnet/wordapplication.asp建议:请看完Michela写的这篇文章后再看下面的我的心得,他那里介绍了怎么建立一个项目,如添加引用等,我就不再累赘了,有空的话都想把他的文章翻译过来 )。这个页面里找到了我所需要的:一个封装Word操作的类(他的Word版本好像是XP),虽然这个类的功能很少,但我们可以按照原则自己写代码,扩充类库。基本的原则是:把底层的Word操作封装在这个类中,外层通过调用此封装类实现对Word的操作。

    二、编程实现:通过查看Word宏代码完善自定义类库
     
    有了这样一个大致的框架以后,我们就可以开始用C#开始实现各种Word操作的功能。总的来说,这项工作不难,但很繁琐(要看你对Word操作的熟悉程度)。
     
    一般情况下,自动生成的Word文档会有一个模板Word文件(以.dot结尾,当然模板本身也可以是.doc的Word文档)。在这个模板中,我们先设计好要导出文档的总体框架,在那些需要插入文字的地方先做好书签。在这个工作中,我们最常用到的就是书签,使用书签的好处是方便快捷,Word文档中的差不多所有的定位都是通过书签来完成的。为了了解一个Word操作的具体编程实现,我们可以通过Word自带的宏编程:在进行想要了解的操作之前,先录制宏,操作完后再查看刚才录制的宏代码,这样我们就得到了进行这个操作的VB编码。如:我们需要查看Word生成一个Table表的动作是怎样的,我们可以先在进行插入Table前录制宏,然后在Word中进行一个插入Table的操作,再停止宏,这样我们就可以看到一个插入Table的宏代码了。下面就是一个插入最简单的Table的宏代码:
    ExpandedBlockStart.gifContractedBlock.gifSub Macro8()Sub Macro8()
    InBlock.gif
    '
    InBlock.gif'
     Macro8 Macro
    InBlock.gif'
     by 林辉(sharemeteor)
    InBlock.gif'
     宏在 2005-8-19 由 MC SYSTEM 录制
    InBlock.gif'
    InBlock.gif
        ActiveDocument.Tables.Add Range:=Selection.Range, NumRows:=2, NumColumns:= _
    InBlock.gif        
    4, DefaultTableBehavior:=wdWord9TableBehavior, AutoFitBehavior:= _
    InBlock.gif        wdAutoFitFixed
    InBlock.gif    
    With Selection.Tables(1)
    InBlock.gif        
    If .Style <> "网格型" Then
    InBlock.gif            .Style 
    = "网格型"
    InBlock.gif
            End If
    InBlock.gif        .ApplyStyleHeadingRows 
    = True
    InBlock.gif        .ApplyStyleLastRow 
    = True
    InBlock.gif        .ApplyStyleFirstColumn 
    = True
    InBlock.gif        .ApplyStyleLastColumn 
    = True
    InBlock.gif    
    End With
    ExpandedBlockEnd.gif
    End Sub
     
    了解这些后,我们就需要学会从VBA编程到C#实现之间的转变(这是我碰到的最大难题)。总结下来,两者间的函数名一般是相同的,但由于VB可以缺省参数而C#不行,所以我们必须同时了解那些缺省参数,并进行合理的填充。那些在VB代码中出现的参数也要进行适当的改变才能应用于C#中。比如打开一个Word文档的操作吧,Word的宏代码如下:
    ExpandedBlockStart.gifContractedBlock.gifSub Macro9()Sub Macro9()
    InBlock.gif
    ' Macro9 Macro
    InBlock.gif'
     by 林辉(sharemeteor)
    InBlock.gif'
     宏在 2005-8-19 由 MC SYSTEM 录制
    InBlock.gif'
    InBlock.gif
        Documents.Open FileName:="test.doc", ConfirmConversions:=FalseReadOnly:= _
    InBlock.gif        
    False, AddToRecentFiles:=False, PasswordDocument:="", PasswordTemplate:= _
    InBlock.gif        
    "", Revert:=False, WritePasswordDocument:="", WritePasswordTemplate:="", _
    InBlock.gif        
    Format:=wdOpenFormatAuto, XMLTransform:=""
    ExpandedBlockEnd.gif
    End Sub
    它只有11个参数,但在C#里需要16个参数值(Word2003中是16个参数,WordXP为15个)。在C#中,Word.ApplicationClass下的Documents属性和VB宏代码中的Documents对等,不过你需要获得Word.ApplicationClass的实例后才能用。
    None.gif// Open a file (the file must exists) and activate it
    None.gif
            public void Open( string strFileName)
    ExpandedBlockStart.gifContractedBlock.gif        
    dot.gif{
    InBlock.gif            
    object fileName = strFileName;
    InBlock.gif            
    object readOnly = false;
    InBlock.gif            
    object isVisible = true;
    InBlock.gif            
    object missing = System.Reflection.Missing.Value;
    InBlock.gif
    InBlock.gif            oDoc 
    = oWordApplic.Documents.Open(ref fileName, ref missing,ref readOnly, 
    InBlock.gif                
    ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, 
    InBlock.gif                
    ref missing, ref missing, ref isVisible,ref missing,ref missing,ref missing,ref missing);
    InBlock.gif
    InBlock.gif            oDoc.Activate();
    ExpandedBlockEnd.gif        }

    缺省参数一般可以通过赋System.Reflection.Missing.Value值就可以了。而那些VB代码中出现了的参数,我们必须先通过查找VBA Language References参考手册了解其具体的值(实际上这些参数都是枚举变量,其值大多数都是Object型的整数),然后再在C#中赋予相同的Object型的整数值。需要注意的是,C#中的参数一般都是引用型的,要加ref。

    这里有些方便的小技巧,在参考手册的Reference/Enumerations下可以找到那些参数的名称和其值,我们可以通过直接赋整数值实现,但在C#的Word类库中,Word.Wd***这个枚举量下都会有一个值和VB中的这个参数对应,所以建议用这些枚举值进行赋值。如VB有个参数叫wdAlignParagraphCenter,我们通过查参考手册知道它是WdParagraphAlignment下的枚举值,那么它在C#中的值为Word.WdParagraphAlignment.wdAlignParagraphCenter。

    三、编程中遇到的问题及解决
    在这个工作中,碰到点问题是难免的,只要你用心,相信只是的问题,肯定可以解决的。下面是我碰到的一些问题和我的解决办法,希望对大家有用。

    1. Style等对象不能赋值的问题
    感觉微软对Office的类库的设计可能存在问题,很多在VB中可以赋值的对象如Style,但在C#就是不能赋值。这引来了很多问题,如前面的产生Table的宏中就有“.Style = "网格型"”的语句,这在C#中是不可能用一条等价的语句来实现的。

    这里有两种解决办法,一种是干脆不用Style,另一种是间接实现Style的赋值。

    有些地方的Style是可以被替换的,如产生table的宏中的Style,它的Style只不过是是定义边框的样式,我们可以手工定义样式来替代Style,用下列函数实现产生一个Table:
    None.gif        public void RunMacroForTable(int rows,int columns)
    ExpandedBlockStart.gifContractedBlock.gif        
    dot.gif{
    InBlock.gif            
    object _DefaultTableBehavior = Word.WdDefaultTableBehavior.wdWord9TableBehavior;
    InBlock.gif            
    object _AutoFitBehavior = Word.WdAutoFitBehavior.wdAutoFitFixed;
    InBlock.gif            oWordApplic.ActiveDocument.Tables.Add(oWordApplic.Selection.Range,rows,columns,
    InBlock.gif                
    ref _DefaultTableBehavior,ref _AutoFitBehavior);
    InBlock.gif
    InBlock.gif            Word.Table table 
    = oWordApplic.Selection.Tables[1];
    InBlock.gif
    //            oWordApplic.Selection.Rows.HeightRule = Word.WdRowHeightRule.wdRowHeightAtLeast;
    InBlock.gif
                oWordApplic.Selection.Rows.Height = oWordApplic.CentimetersToPoints((float)0.75);
    InBlock.gif            
    //            if(table.Style != "网格型")
    InBlock.gif            
    //                table.Style = "网格型";
    ExpandedSubBlockStart.gifContractedSubBlock.gif
                对边框进行定义#region 对边框进行定义
    InBlock.gif            table.ApplyStyleHeadingRows 
    = true;
    InBlock.gif            table.ApplyStyleLastRow 
    = true;
    InBlock.gif            table.ApplyStyleFirstColumn 
    = true;
    InBlock.gif            table.ApplyStyleLastColumn 
    = true;
    InBlock.gif
    InBlock.gif            Word.Border border 
    = table.Borders[Word.WdBorderType.wdBorderLeft];
    InBlock.gif            border.LineStyle 
    = Word.WdLineStyle.wdLineStyleSingle;
    InBlock.gif            border.LineWidth 
    = Word.WdLineWidth.wdLineWidth150pt;
    InBlock.gif            border.Color 
    = Word.WdColor.wdColorAutomatic;
    InBlock.gif
    InBlock.gif            border 
    = table.Borders[Word.WdBorderType.wdBorderRight];
    InBlock.gif            border.LineStyle 
    = Word.WdLineStyle.wdLineStyleSingle;
    InBlock.gif            border.LineWidth 
    = Word.WdLineWidth.wdLineWidth150pt;
    InBlock.gif            border.Color 
    = Word.WdColor.wdColorAutomatic;
    InBlock.gif
    InBlock.gif            border 
    = table.Borders[Word.WdBorderType.wdBorderTop];
    InBlock.gif            border.LineStyle 
    = Word.WdLineStyle.wdLineStyleSingle;
    InBlock.gif            border.LineWidth 
    = Word.WdLineWidth.wdLineWidth150pt;
    InBlock.gif            border.Color 
    = Word.WdColor.wdColorAutomatic;
    InBlock.gif
    InBlock.gif            border 
    = table.Borders[Word.WdBorderType.wdBorderBottom];
    InBlock.gif            border.LineStyle 
    = Word.WdLineStyle.wdLineStyleSingle;
    InBlock.gif            border.LineWidth 
    = Word.WdLineWidth.wdLineWidth150pt;
    InBlock.gif            border.Color 
    = Word.WdColor.wdColorAutomatic;
    InBlock.gif
    InBlock.gif            border 
    = table.Borders[Word.WdBorderType.wdBorderHorizontal];
    InBlock.gif            border.LineStyle 
    = Word.WdLineStyle.wdLineStyleSingle;
    InBlock.gif            border.LineWidth 
    = Word.WdLineWidth.wdLineWidth075pt;
    InBlock.gif            border.Color 
    = Word.WdColor.wdColorAutomatic;
    InBlock.gif            
    InBlock.gif            border 
    = table.Borders[Word.WdBorderType.wdBorderVertical];
    InBlock.gif            border.LineStyle 
    = Word.WdLineStyle.wdLineStyleSingle;
    InBlock.gif            border.LineWidth 
    = Word.WdLineWidth.wdLineWidth075pt;
    InBlock.gif            border.Color 
    = Word.WdColor.wdColorAutomatic;
    InBlock.gif            
    InBlock.gif            border 
    = table.Borders[Word.WdBorderType.wdBorderDiagonalDown];
    InBlock.gif            border.LineStyle 
    = Word.WdLineStyle.wdLineStyleNone;
    InBlock.gif            border 
    = table.Borders[Word.WdBorderType.wdBorderDiagonalUp];
    InBlock.gif            border.LineStyle 
    = Word.WdLineStyle.wdLineStyleNone;
    InBlock.gif            table.Borders.Shadow 
    = false;
    ExpandedSubBlockEnd.gif            
    #endregion

    InBlock.gif
    InBlock.gif            oWordApplic.Options.DefaultBorderLineStyle 
    = Word.WdLineStyle.wdLineStyleSingle;
    InBlock.gif            oWordApplic.Options.DefaultBorderLineWidth 
    = Word.WdLineWidth.wdLineWidth150pt;
    InBlock.gif            oWordApplic.Options.DefaultBorderColor 
    = Word.WdColor.wdColorAutomatic;
    InBlock.gif
    InBlock.gif            oWordApplic.Selection.Rows.HeadingFormat 
    = (int)Word.WdConstants.wdToggle;
    InBlock.gif
    InBlock.gif            table.Rows.Alignment 
    = Word.WdRowAlignment.wdAlignRowCenter;
    ExpandedBlockEnd.gif        }

    但有些地方的Sytle就替换不了了,有一种方法可以间接实现对Style等不能在C#中赋值对象的赋值,那就是通过调用VB.NET的dll。不得不佩服微软的.NET框架,各个语言间可以随意的调用,用起来相当之方便。
    我们可以在VB.NET下面建个函数来调用那个语句,然后生成dll,C#项目只要引用这个dll,然后调用这个dll中的函数就可以了。下面是VB.NET下对Style赋值的函数(简单吧!C#里就是死活也不行)
    ExpandedBlockStart.gifContractedBlock.gifPublic Sub SetStyle()Sub SetStyle(ByVal header As StringByVal oWordApplic As Word.ApplicationClass)
    InBlock.gif        oWordApplic.Selection.Style 
    = oWordApplic.ActiveDocument.Styles(header)
    ExpandedBlockEnd.gif    
    End Sub
    其他那些不能在C#里赋值的对象都可以通过这种方法实现赋值。

    2.书签过多,一个一个定位麻烦的问题
    如果你的Word模板够庞大,可能会出现有50多个书签,而这些书签的位置只是填充一些简单数据的情况。如果我们编程时一个个的定位,然后一个个的填充数据肯定时非常麻烦的。这种情况下,我的解决办法是设置XML配置文档。

    我们可以设置一个XML文件,其中存放需要填充数据的书签(这些书签处只是做简单的插入文本)的名称。如下面是我的XML文件的详细内容:
    None.gif<?xml version="1.0" encoding="utf-8" ?> 
    None.gif
    <Forms>
    None.gif   
    <Form>
    None.gif        
    <Name>data</Name>
    None.gif        
    <Bookmarks>
    None.gif            
    <Bookmark>date1</Bookmark>
    None.gif            
    <Bookmark>date2</Bookmark>
    None.gif            
    <Bookmark>project</Bookmark>
    None.gif            
    <Bookmark>company</Bookmark>
    None.gif        
    </Bookmarks>
    None.gif   
    </Form>    
    None.gif   
    <Form>
    None.gif        
    <Name>company</Name>
    None.gif        
    <Bookmarks>
    None.gif            
    <Bookmark>recordnumber</Bookmark>
    None.gif            
    <Bookmark>customer</Bookmark>
    None.gif            
    <Bookmark>address</Bookmark>
    None.gif            
    <Bookmark>postcode</Bookmark>
    None.gif            
    <Bookmark>linkman</Bookmark>
    None.gif            
    <Bookmark>telephone</Bookmark>
    None.gif            
    <Bookmark>email</Bookmark>
    None.gif            
    <Bookmark>faxnumber</Bookmark>
    None.gif      
     </Bookmarks>
    None.gif   
    </Form>
    None.gif
    </Forms>
    我们可以把需要填充的数据都存放到一个Hashtable中,key为它们所对应的书签名,这样在C#中读取这个XML文件后,把同一Name下的所有Bookmark存放在一个ArrayList中,我们就可以统一地进行填充了,使用的函数的形式如:
    None.gifforeach(string bookmark in bookmarks)
    ExpandedBlockStart.gifContractedBlock.gif            
    dot.gif{
    InBlock.gif                
    switch(bookmark)
    ExpandedSubBlockStart.gifContractedSubBlock.gif                
    dot.gif{
    InBlock.gif                    
    case "company":
    InBlock.gif                        test.GotoBookMark(bookmark);
    InBlock.gif                        test.SetFontColor(Word.WdColor.wdColorDarkBlue);
    InBlock.gif                        test.SetFontName(
    "Times New Roman");
    InBlock.gif                        test.InsertText(hash[bookmark].ToString());
    InBlock.gif                        
    break;
    InBlock.gif                    
    case "catalog":
    InBlock.gif                        
    break;
    InBlock.gif                    
    case "modules":
    InBlock.gif                        
    break;
    InBlock.gif                    
    default:
    InBlock.gif                        test.GotoBookMark(bookmark);
    InBlock.gif                        test.InsertText(hash[bookmark].ToString());
    InBlock.gif                        
    break;
    ExpandedSubBlockEnd.gif                }

    ExpandedBlockEnd.gif            }
    这样,对于那些不需要做特殊化处理的书签,我们就统一的在default中进行了填充数据。

    3.页眉页脚中添文字的问题
    对于页眉页脚,需要注意的就是不要用书签去定位,因为页眉页脚和主文档的页面视图不一样,所以不能在普通的视图下直接定位到页眉页脚所在书签处。但只要你切换一下视图,一切就OK了。
    ExpandedBlockStart.gifContractedBlock.gif/**//// <summary>
    InBlock.gif        
    /// 设置页眉
    InBlock.gif        
    /// </summary>
    InBlock.gif        
    /// <param name="strBookmarkName">要设置页面中的一个书签</param>
    ExpandedBlockEnd.gif        
    /// <param name="text">页眉的文字</param>

    None.gif        public void SetHeader(string strBookmarkName,string text)
    ExpandedBlockStart.gifContractedBlock.gif        
    dot.gif{
    InBlock.gif            
    this.GotoBookMark(strBookmarkName);
    InBlock.gif            
    //            If ActiveWindow.View.SplitSpecial <> wdPaneNone Then
    InBlock.gif            
    //            ActiveWindow.Panes(2).Close
    InBlock.gif            
    //            End If
    InBlock.gif
                if(oWordApplic.ActiveWindow.View.SplitSpecial != Word.WdSpecialPane.wdPaneNone)
    InBlock.gif                oWordApplic.ActiveWindow.Panes[
    2].Close();
    InBlock.gif
    InBlock.gif            
    //            If ActiveWindow.ActivePane.View.Type = wdNormalView Or ActiveWindow. _
    InBlock.gif            
    //            ActivePane.View.Type = wdOutlineView Then
    InBlock.gif            
    //            ActiveWindow.ActivePane.View.Type = wdPrintView
    InBlock.gif            
    //            End If
    InBlock.gif
                if(oWordApplic.ActiveWindow.View.Type == Word.WdViewType.wdNormalView
    InBlock.gif                
    || oWordApplic.ActiveWindow.View.Type == Word.WdViewType.wdOutlineView)
    InBlock.gif                oWordApplic.ActiveWindow.ActivePane.View.Type 
    = Word.WdViewType.wdPrintView;
    InBlock.gif
    InBlock.gif            
    //            ActiveWindow.ActivePane.View.SeekView = wdSeekCurrentPageHeader
    InBlock.gif
                oWordApplic.ActiveWindow.ActivePane.View.SeekView = Word.WdSeekView.wdSeekCurrentPageHeader;
    InBlock.gif
    InBlock.gif            
    this.GoToTheEnd();
    InBlock.gif
    InBlock.gif
    //            this.GotoBookMark(strBookmarkName);
    InBlock.gif
                this.SetFontColor(Word.WdColor.wdColorDarkBlue);
    InBlock.gif            
    this.InsertText(text);
    InBlock.gif
    InBlock.gif            
    //            ActiveWindow.ActivePane.View.SeekView = wdSeekMainDocument
    InBlock.gif
                oWordApplic.ActiveWindow.ActivePane.View.SeekView = Word.WdSeekView.wdSeekMainDocument;
    ExpandedBlockEnd.gif        }

    None.gif
    这里,我先是通过书签定位到页眉所在页,这样比较方便,不用在页眉视图中再翻页定位。

    4.项目符号及多级项目符号的Style问题
    这个问题我的解决中有点问题,要和模板一起设置才能用,感觉不好,就不拿出来给大家看了,以免误导大家了02.gif

    5.添加特殊字符的问题
    当你要在文档中添加特殊文字的时候(如你想添加一个þ),不能直接通过简单的复制粘贴来实现(你根本没办法在.NET的IDE下看到þ)。这时,我们可以通过查找这个特殊字符的字体名称和代表的16进制编码来插入。我们可以查到þ所在的字符集是Wingdings,它的16进制编码是\u00fe,这时,我们就能对这个þ进行插入,具体代码如:
    None.giftest.SetFontName("Wingdings");
    None.giftest.SetFontColor(Word.WdColor.wdColorDarkBlue);
    None.giftest.InsertText(
    "\u00fe");
    其中,test是一个被封装的Word操作类的实例。

    转载于:https://www.cnblogs.com/luck200803/archive/2007/08/17/859844.html

    展开全文
  • 做了一个多月的C#生成Word文档的工作,我从一开始的对这个一窍不通,到现在的顺利完成了这个功能... 对于用C#来自动生成Word文档来说,最大的问题是微软提供的所有文档的源代码一般都是VBA编程的,没有C#的现成文档,最

    做了一个多月的C#生成Word文档的工作,我从一开始的对这个一窍不通,到现在的顺利完成了这个功能模块,其中还是有点心得的。想想自己说不定以后还会用到,于是想吧这些心得写下来,以供自己以后的学习。同时也希望对那些正在或正要编程实现自动生成Word的朋友有些小小的帮助

    对于用C#来自动生成Word文档来说,最大的问题是微软提供的所有文档的源代码一般都是VBA编程的,没有C#的现成文档,最多也只是一些How To文档。显然,VBA编程和C#是有一定区别的,VBA编程的风格和C#是完全不同的,它有着VB编程快捷的特性,可以省略参数,可以对Style对象赋值等的功能是C#所没有的。其次,在这个任务通过Word录制宏查看到的宏代码也是由VB代码显示的,我们必须要把这些宏代码转换到C#代码。所以,做这个任务的人必须先有一点VB的经验(最起码知道那些代码是在干什么)。
     
    下面是我自学C#生成Word文档的过程(首先必须安装好Word2003和.NET2003):

    一、下载Word的VBA编程参考手册和网上的在线资料
    微软大概觉得VB用的人太少了,想大力发展之,搞得Office编程的参考手册都是VBA编程,害的我不懂VB的人也不得不学。不过没办法,要做这个工作,微软的参考手册是不能少的,可以从http://msdn.microsoft.com/office/downloads/vba/default.aspx这个页面中下到相应的的Office(本人使用的是Word2003,但好像只用WordXP的参考手册)的VBA Language References(当然这个文档是全英文的,看她简直是我的噩梦)。没有必要看完这个参考手册,只要搜索需要的函数,然后看看就可以了。

    有了这个参考手册是远远不够的,我们需要去网上搜集大量的现成代码来看看才能快速的上手。下面是一个微软老大提供的关于C#生成Word的中文How To文档,感觉很好,分享一下http://support.microsoft.com/search/default.aspx?query=Word&catalog=LCID%3D2052&spid=1108&qryWt=&mode=r&cus=False。当然,微软提供的文档都是最基础的,我们只能在需要用到这个功能的时候才只得看看一看看,很全面,但没有一个包含所有东西的程序。所以,我们还得再在网上淘资料。终于我在http://www.codeproject.com/aspnet/wordapplication.asp建议:请看完Michela写的这篇文章后再看下面的我的心得,他那里介绍了怎么建立一个项目,如添加引用等,我就不再累赘了,有空的话都想把他的文章翻译过来 )。这个页面里找到了我所需要的:一个封装Word操作的类(他的Word版本好像是XP),虽然这个类的功能很少,但我们可以按照原则自己写代码,扩充类库。基本的原则是:把底层的Word操作封装在这个类中,外层通过调用此封装类实现对Word的操作。

    二、编程实现:通过查看Word宏代码完善自定义类库
     
    有了这样一个大致的框架以后,我们就可以开始用C#开始实现各种Word操作的功能。总的来说,这项工作不难,但很繁琐(要看你对Word操作的熟悉程度)。
     
    一般情况下,自动生成的Word文档会有一个模板Word文件(以.dot结尾,当然模板本身也可以是.doc的Word文档)。在这个模板中,我们先设计好要导出文档的总体框架,在那些需要插入文字的地方先做好书签。在这个工作中,我们最常用到的就是书签,使用书签的好处是方便快捷,Word文档中的差不多所有的定位都是通过书签来完成的。为了了解一个Word操作的具体编程实现,我们可以通过Word自带的宏编程:在进行想要了解的操作之前,先录制宏,操作完后再查看刚才录制的宏代码,这样我们就得到了进行这个操作的VB编码。如:我们需要查看Word生成一个Table表的动作是怎样的,我们可以先在进行插入Table前录制宏,然后在Word中进行一个插入Table的操作,再停止宏,这样我们就可以看到一个插入Table的宏代码了。下面就是一个插入最简单的Table的宏代码:
    Sub Macro8()
    '
    '
     Macro8 Macro
    '
     by 林辉(sharemeteor)
    '
     宏在 2005-8-19 由 MC SYSTEM 录制
    '
        ActiveDocument.Tables.Add Range:=Selection.Range, NumRows:=2, NumColumns:= _
            
    4, DefaultTableBehavior:=wdWord9TableBehavior, AutoFitBehavior:= _
            wdAutoFitFixed
        
    With Selection.Tables(1)
            
    If .Style <> "网格型" Then
                .Style 
    = "网格型"
            End If
            .ApplyStyleHeadingRows 
    = True
            .ApplyStyleLastRow 
    = True
            .ApplyStyleFirstColumn 
    = True
            .ApplyStyleLastColumn 
    = True
        
    End With
    End Sub
     
    了解这些后,我们就需要学会从VBA编程到C#实现之间的转变(这是我碰到的最大难题)。总结下来,两者间的函数名一般是相同的,但由于VB可以缺省参数而C#不行,所以我们必须同时了解那些缺省参数,并进行合理的填充。那些在VB代码中出现的参数也要进行适当的改变才能应用于C#中。比如打开一个Word文档的操作吧,Word的宏代码如下:
    Sub Macro9()
    ' Macro9 Macro
    '
     by 林辉(sharemeteor)
    '
     宏在 2005-8-19 由 MC SYSTEM 录制
    '
        Documents.Open FileName:="test.doc", ConfirmConversions:=FalseReadOnly:= _
            
    False, AddToRecentFiles:=False, PasswordDocument:="", PasswordTemplate:= _
            
    "", Revert:=False, WritePasswordDocument:="", WritePasswordTemplate:="", _
            
    Format:=wdOpenFormatAuto, XMLTransform:=""
    End Sub
    它只有11个参数,但在C#里需要16个参数值(Word2003中是16个参数,WordXP为15个)。在C#中,Word.ApplicationClass下的Documents属性和VB宏代码中的Documents对等,不过你需要获得Word.ApplicationClass的实例后才能用。
    // Open a file (the file must exists) and activate it
            public void Open( string strFileName)
            
    {
                
    object fileName = strFileName;
                
    object readOnly = false;
                
    object isVisible = true;
                
    object missing = System.Reflection.Missing.Value;

                oDoc 
    = oWordApplic.Documents.Open(ref fileName, ref missing,ref readOnly, 
                    
    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);

                oDoc.Activate();
            }

    缺省参数一般可以通过赋System.Reflection.Missing.Value值就可以了。而那些VB代码中出现了的参数,我们必须先通过查找VBA Language References参考手册了解其具体的值(实际上这些参数都是枚举变量,其值大多数都是Object型的整数),然后再在C#中赋予相同的Object型的整数值。需要注意的是,C#中的参数一般都是引用型的,要加ref。

    这里有些方便的小技巧,在参考手册的Reference/Enumerations下可以找到那些参数的名称和其值,我们可以通过直接赋整数值实现,但在C#的Word类库中,Word.Wd***这个枚举量下都会有一个值和VB中的这个参数对应,所以建议用这些枚举值进行赋值。如VB有个参数叫wdAlignParagraphCenter,我们通过查参考手册知道它是WdParagraphAlignment下的枚举值,那么它在C#中的值为Word.WdParagraphAlignment.wdAlignParagraphCenter。

    三、编程中遇到的问题及解决
    在这个工作中,碰到点问题是难免的,只要你用心,相信只是的问题,肯定可以解决的。下面是我碰到的一些问题和我的解决办法,希望对大家有用

    1. Style等对象不能赋值的问题
    感觉微软对Office的类库的设计可能存在问题,很多在VB中可以赋值的对象如Style,但在C#就是不能赋值。这引来了很多问题,如前面的产生Table的宏中就有“.Style = "网格型"”的语句,这在C#中是不可能用一条等价的语句来实现的。

    这里有两种解决办法,一种是干脆不用Style,另一种是间接实现Style的赋值。

    有些地方的Style是可以被替换的,如产生table的宏中的Style,它的Style只不过是是定义边框的样式,我们可以手工定义样式来替代Style,用下列函数实现产生一个Table:
            public void RunMacroForTable(int rows,int columns)
            
    {
                
    object _DefaultTableBehavior = Word.WdDefaultTableBehavior.wdWord9TableBehavior;
                
    object _AutoFitBehavior = Word.WdAutoFitBehavior.wdAutoFitFixed;
                oWordApplic.ActiveDocument.Tables.Add(oWordApplic.Selection.Range,rows,columns,
                    
    ref _DefaultTableBehavior,ref _AutoFitBehavior);

                Word.Table table 
    = oWordApplic.Selection.Tables[1];
    //            oWordApplic.Selection.Rows.HeightRule = Word.WdRowHeightRule.wdRowHeightAtLeast;
                oWordApplic.Selection.Rows.Height = oWordApplic.CentimetersToPoints((float)0.75);
                
    //            if(table.Style != "网格型")
                
    //                table.Style = "网格型";
                #region 对边框进行定义
                table.ApplyStyleHeadingRows 
    = true;
                table.ApplyStyleLastRow 
    = true;
                table.ApplyStyleFirstColumn 
    = true;
                table.ApplyStyleLastColumn 
    = true;

                Word.Border border 
    = table.Borders[Word.WdBorderType.wdBorderLeft];
                border.LineStyle 
    = Word.WdLineStyle.wdLineStyleSingle;
                border.LineWidth 
    = Word.WdLineWidth.wdLineWidth150pt;
                border.Color 
    = Word.WdColor.wdColorAutomatic;

                border 
    = table.Borders[Word.WdBorderType.wdBorderRight];
                border.LineStyle 
    = Word.WdLineStyle.wdLineStyleSingle;
                border.LineWidth 
    = Word.WdLineWidth.wdLineWidth150pt;
                border.Color 
    = Word.WdColor.wdColorAutomatic;

                border 
    = table.Borders[Word.WdBorderType.wdBorderTop];
                border.LineStyle 
    = Word.WdLineStyle.wdLineStyleSingle;
                border.LineWidth 
    = Word.WdLineWidth.wdLineWidth150pt;
                border.Color 
    = Word.WdColor.wdColorAutomatic;

                border 
    = table.Borders[Word.WdBorderType.wdBorderBottom];
                border.LineStyle 
    = Word.WdLineStyle.wdLineStyleSingle;
                border.LineWidth 
    = Word.WdLineWidth.wdLineWidth150pt;
                border.Color 
    = Word.WdColor.wdColorAutomatic;

                border 
    = table.Borders[Word.WdBorderType.wdBorderHorizontal];
                border.LineStyle 
    = Word.WdLineStyle.wdLineStyleSingle;
                border.LineWidth 
    = Word.WdLineWidth.wdLineWidth075pt;
                border.Color 
    = Word.WdColor.wdColorAutomatic;
                
                border 
    = table.Borders[Word.WdBorderType.wdBorderVertical];
                border.LineStyle 
    = Word.WdLineStyle.wdLineStyleSingle;
                border.LineWidth 
    = Word.WdLineWidth.wdLineWidth075pt;
                border.Color 
    = Word.WdColor.wdColorAutomatic;
                
                border 
    = table.Borders[Word.WdBorderType.wdBorderDiagonalDown];
                border.LineStyle 
    = Word.WdLineStyle.wdLineStyleNone;
                border 
    = table.Borders[Word.WdBorderType.wdBorderDiagonalUp];
                border.LineStyle 
    = Word.WdLineStyle.wdLineStyleNone;
                table.Borders.Shadow 
    = false;
                
    #endregion


                oWordApplic.Options.DefaultBorderLineStyle 
    = Word.WdLineStyle.wdLineStyleSingle;
                oWordApplic.Options.DefaultBorderLineWidth 
    = Word.WdLineWidth.wdLineWidth150pt;
                oWordApplic.Options.DefaultBorderColor 
    = Word.WdColor.wdColorAutomatic;

                oWordApplic.Selection.Rows.HeadingFormat 
    = (int)Word.WdConstants.wdToggle;

                table.Rows.Alignment 
    = Word.WdRowAlignment.wdAlignRowCenter;
            }

    但有些地方的Sytle就替换不了了,有一种方法可以间接实现对Style等不能在C#中赋值对象的赋值,那就是通过调用VB.NET的dll。不得不佩服微软的.NET框架,各个语言间可以随意的调用,用起来相当之方便。
    我们可以在VB.NET下面建个函数来调用那个语句,然后生成dll,C#项目只要引用这个dll,然后调用这个dll中的函数就可以了。下面是VB.NET下对Style赋值的函数(简单吧!C#里就是死活也不行
    Public Sub SetStyle(ByVal header As StringByVal oWordApplic As Word.ApplicationClass)
            oWordApplic.Selection.Style 
    = oWordApplic.ActiveDocument.Styles(header)
        
    End Sub
    其他那些不能在C#里赋值的对象都可以通过这种方法实现赋值。

    2.书签过多,一个一个定位麻烦的问题
    如果你的Word模板够庞大,可能会出现有50多个书签,而这些书签的位置只是填充一些简单数据的情况。如果我们编程时一个个的定位,然后一个个的填充数据肯定时非常麻烦的。这种情况下,我的解决办法是设置XML配置文档。

    我们可以设置一个XML文件,其中存放需要填充数据的书签(这些书签处只是做简单的插入文本)的名称。如下面是我的XML文件的详细内容:
    <?xml version="1.0" encoding="utf-8" ?> 
    <Forms>
       
    <Form>
            
    <Name>data</Name>
            
    <Bookmarks>
                
    <Bookmark>date1</Bookmark>
                
    <Bookmark>date2</Bookmark>
                
    <Bookmark>project</Bookmark>
                
    <Bookmark>company</Bookmark>
            
    </Bookmarks>
       
    </Form>    
       
    <Form>
            
    <Name>company</Name>
            
    <Bookmarks>
                
    <Bookmark>recordnumber</Bookmark>
                
    <Bookmark>customer</Bookmark>
                
    <Bookmark>address</Bookmark>
                
    <Bookmark>postcode</Bookmark>
                
    <Bookmark>linkman</Bookmark>
                
    <Bookmark>telephone</Bookmark>
                
    <Bookmark>email</Bookmark>
                
    <Bookmark>faxnumber</Bookmark>
          
      </Bookmarks>
       
    </Form>
    </Forms>
    我们可以把需要填充的数据都存放到一个Hashtable中,key为它们所对应的书签名,这样在C#中读取这个XML文件后,把同一Name下的所有Bookmark存放在一个ArrayList中,我们就可以统一地进行填充了,使用的函数的形式如:
    foreach(string bookmark in bookmarks)
                
    {
                    
    switch(bookmark)
                    
    {
                        
    case "company":
                            test.GotoBookMark(bookmark);
                            test.SetFontColor(Word.WdColor.wdColorDarkBlue);
                            test.SetFontName(
    "Times New Roman");
                            test.InsertText(hash[bookmark].ToString());
                            
    break;
                        
    case "catalog":
                            
    break;
                        
    case "modules":
                            
    break;
                        
    default:
                            test.GotoBookMark(bookmark);
                            test.InsertText(hash[bookmark].ToString());
                            
    break;
                    }

                }
    这样,对于那些不需要做特殊化处理的书签,我们就统一的在default中进行了填充数据。

    3.页眉页脚中添文字的问题
    对于页眉页脚,需要注意的就是不要用书签去定位,因为页眉页脚和主文档的页面视图不一样,所以不能在普通的视图下直接定位到页眉页脚所在书签处。但只要你切换一下视图,一切就OK了。
    /// <summary>
            
    /// 设置页眉
            
    /// </summary>
            
    /// <param name="strBookmarkName">要设置页面中的一个书签</param>
            
    /// <param name="text">页眉的文字</param>

            public void SetHeader(string strBookmarkName,string text)
            
    {
                
    this.GotoBookMark(strBookmarkName);
                
    //            If ActiveWindow.View.SplitSpecial <> wdPaneNone Then
                
    //            ActiveWindow.Panes(2).Close
                
    //            End If
                if(oWordApplic.ActiveWindow.View.SplitSpecial != Word.WdSpecialPane.wdPaneNone)
                    oWordApplic.ActiveWindow.Panes[
    2].Close();

                
    //            If ActiveWindow.ActivePane.View.Type = wdNormalView Or ActiveWindow. _
                
    //            ActivePane.View.Type = wdOutlineView Then
                
    //            ActiveWindow.ActivePane.View.Type = wdPrintView
                
    //            End If
                if(oWordApplic.ActiveWindow.View.Type == Word.WdViewType.wdNormalView
                    
    || oWordApplic.ActiveWindow.View.Type == Word.WdViewType.wdOutlineView)
                    oWordApplic.ActiveWindow.ActivePane.View.Type 
    = Word.WdViewType.wdPrintView;

                
    //            ActiveWindow.ActivePane.View.SeekView = wdSeekCurrentPageHeader
                oWordApplic.ActiveWindow.ActivePane.View.SeekView = Word.WdSeekView.wdSeekCurrentPageHeader;

                
    this.GoToTheEnd();

    //            this.GotoBookMark(strBookmarkName);
                this.SetFontColor(Word.WdColor.wdColorDarkBlue);
                
    this.InsertText(text);

                
    //            ActiveWindow.ActivePane.View.SeekView = wdSeekMainDocument
                oWordApplic.ActiveWindow.ActivePane.View.SeekView = Word.WdSeekView.wdSeekMainDocument;
            }

    这里,我先是通过书签定位到页眉所在页,这样比较方便,不用在页眉视图中再翻页定位。

    4.项目符号及多级项目符号的Style问题
    这个问题我的解决中有点问题,要和模板一起设置才能用,感觉不好,就不拿出来给大家看了,以免误导大家了

    5.添加特殊字符的问题
    当你要在文档中添加特殊文字的时候(如你想添加一个þ),不能直接通过简单的复制粘贴来实现(你根本没办法在.NET的IDE下看到þ)。这时,我们可以通过查找这个特殊字符的字体名称和代表的16进制编码来插入。我们可以查到þ所在的字符集是Wingdings,它的16进制编码是/u00fe,这时,我们就能对这个þ进行插入,具体代码如:
    test.SetFontName("Wingdings");
    test.SetFontColor(Word.WdColor.wdColorDarkBlue);
    test.InsertText(
    "/u00fe");
    其中,test是一个被封装的Word操作类的实例。

    如果大家反映强烈,我可以贴出我的代码,Web的和WinForm的都有。

    听说那个Michela的demo文件下载不下来,现贴上我以前下载的他的文件/Files/sharemeteor/WordApplication.rar
     
    展开全文
  • 做了一个多月的C#生成Word文档的工作,我从一开始的对这个一窍不通,到现在的顺利完成了... 对于用C#来自动生成Word文档来说,最大的问题是微软提供的所有文档的源代码一般都是VBA编程的,没有C#的现成文档,最多也只是
  • 采用Microsoft Basic 6.0 编程工具,利用VBA语言通过宏录制技术和嵌入控件及对象技术将Excel应用程序中的数据自动生成图表,并实现Excel工作簿和Word文档两个应用程序之间的数据无缝连接,进而通过Word文档的书签...
  • WORD vba使用方法

    2010-05-20 20:23:05
    本程序是基于WORD vba自动报告生成的一种方法,能够自动生成word文档,减少办公人员机械的劳动。
  • 学习Excel技术,关注微信公众号:excelperfect示例3:从Excel中提取数据生成不同的Word报表从前面的学习中,我们已经学会了使用书签将Excel中提取的数据放置到文档中指定的位置。下面的示例演示如何运用这些技巧,...
  • DBExportDoc V1.0 For MySQL(MySQL数据库表结构导出器)是一套用来完成将MySQL数据库中的表结构导出成Word文档,并输出标准的打印报表格式的软件。 软件采用Word中VBA开发完成,软件使用Word中的菜单操作,与Word...
  • 自动生成VBA窗体菜单

    2010-08-16 15:23:46
    自动生成VBA窗体菜单 '*************************** '* 菜单类 * '*************************** Option Explicit Private WithEvents MenuBar_MenuItem As MSForms.Label '菜单项 Private WithEvents WorkForm As...
  • 结合Word文档的模板技术, 巧妙运用 Word软件的“域”和“宏”两个功能, 应用VBA( Visual Basic for Applications) 编程, 研究了利用Visual Basic语言编写 的Word试验报告自动生成软件
  • 最近在做的项目,要实现自动生成合同,然后想通过vba进行对合同(word版)中的相同的地方进行批量的替换。 于是就通过标签的形式对word文档当中的字段进行替换操作。代码如下: Public Function ...
  • 不同格式的word文档合并为一个文件。 问题: 文件汇编,需要将70多个文件汇编成一个到一个文件里。最终汇编的方式是用word--插入--对象--文件中的文字。 但是由于原始文件有的设置了自动编号。插入后在合并后的...
  • 从SQL Server生成文档

    2018-12-28 21:36:30
    目录 介绍 文档生成方法1——VBA ...将SQL Server数据自动填充到Word和PDF文档模板中,用于合同、发票、信函等创建,为企业节省了数千小时。本文探讨了各种方法,并就如何根据您的要求选择最佳方法提供...
  • 解决方案优点缺点Jacob功能强大直接调用VBA接口,程序异常复杂;服务器必须是:windows系统+安装Office;服务器端自动化com接口容易产生死进程造成...跨平台只能生成rtf格式的文件,不是真正的word文件格式Java2w...
  • 使用第一种方式,可以自动导出要生产表的SQL语句,建表比较方便,而对于第二种方式,则可能需要手工建表,其实在WORD中可以用VBA完成对SQL语句的生成,如将下面格式的WORD数据字典生成SQL语句,就可以利用VBA进行 ...
  • 直接调用VBA接口,程序异常复杂;服务器必须是:windows系统+安装Office;服务器端自动化com接口容易产生死进程造成服务器宕机 Apache POI 对Excel的操作功能强大;跨平台 操作word的功能比较弱;必须针对doc...
  •  本试题库管理系统包含四个Word文档文件(其中带有VBA程序),只要将这些文件拷贝到任何装有Word系统的计算机中就可以直接使用,不需额外安装,不用时可直接删除,无需卸载,属于绿色软件。  (三)可以管理多媒体...
  • VBA杂记

    2015-01-02 22:04:43
    帮一个桥梁检测公司的同学写了一个自动生成报告的VBA程序,主要是设计一个程序,快速生成报告:将excel里的文字表格以及文件夹里的图片自动插入到word里,生成检测报告。其实就用latex排版类似 以前对word里的样式...
  • 宏是Office自带的一种高级脚本特性,通过VBA代码,可以在Office中去完成某项特定的任务,而不必再重复相同的动作,目的是让用户文档中的一些任务自动化。而宏病毒是一种寄存在文档或模板的宏中的计算机病毒。一旦...
  • 工程解密功能可以解除VBA工程不可查看的OFFICE工程文档,解除后重新打开文档可100%准确还原源代码,是VBA开发者的必备利器。采用字典补码查漏纠错技术实现台湾繁体系统中繁简转换与GB2BIG5转换准确率达100%,达到微软...
  • VBA编程

    千次阅读 2009-07-31 22:09:00
    利用VBA 编程,可以使许多日常的任务自动完成,使用户的工作更有效率。 11.7.1 在启动时显示打开对话框 一般情况下启动WordWord 会认为是创建一个新文档。如果只是想打开一个旧文档进行编辑,在Word 启动时显示...

空空如也

空空如也

1 2 3 4 5 6
收藏数 103
精华内容 41
关键字:

vba自动生成word文档