zoukankan      html  css  js  c++  java
  • C# : 操作Word文件的API

    这篇博客将要讨论的是关于:

    如何从C#的source以及注释, 生成一份Word格式的关于各个类,函数以及成员变量的说明文档.

    他的大背景如下......

    最近的一个项目使用C#, 分N个模块,

    在项目的里程碑的时候, 日本的总公司要检查我们的成果物.

    成果物包括源代码, 概要设计式样书(SD,System Design), 详细设计式样书(PD, Program Design), 自动化测试等等.

    源代码必须要符合编码规范(每个函数都要有注释, 方法变量的命名规则等...)

    这些检查都很正常, 唯独一个比较辣手,那就是PD(一份Word文档).

    PD中主要分两部分, 第一部分是UML图,

    要求在UML图中,必须记载每一个变量名,函数名等等, 且必须与source完全一致.

    这一点好办到, 只需要使用UML工具的逆向工程从source生成UML图即可.

    PD中还需要的另一部分便是: 要为每一个类, 每一个变量, 每一个方法提供一个详细的说明(包括公有的和私有的一切)

    以方法为例, 要求大概形如下面这样(类, 变量, 属性等类似):

    这些关于方法,变量详细的记载, 同样要求与源代码一致(包括函数名, 参数, 函数注释等等)

    在第一次做成这些文档和代码的时候还好些, 我们从一个地方拷贝到另一个地方, 他们初始是一致的,

    然而接下来repeat的噩梦就开始了,两边同时维护, 总有漏下的,

    而且需要花费很大的时间(尤其是检查),

    有些时候, 日本方面的认真程度是我们中国人无法想象的,

    比如从一份上百页的文档中, 他们能挑出某一个函数参数的大小写与source不一致这样的问题.

    一个check不周,就有可能指摘.

    关于问题, 已经介绍了差不多,

    总之, 本着DRY原则,

    同时也为了保证我们的这份word文档能够忠实于我们的source,

    我想做的是: 从Source自动生成这份Word文档

    为此要解决两个问题

    1. 从Source中拿到相应的数据

    2. 将相应的数据写到Word中.

    对于第一个问题 ,

    visual studio中, [右键一个项目 -> property -> Build -> Output]处有一个叫做[XML documentation file]的选项,

    勾上他之后, 在build的时候, 就会同时生成一个xml文件, 这个文件中包含各个类的方法,成员变量, 以及他们的xml注释.

    关于这个问题, 还可以参考下面两个项目, 他们帮助我们生成MSDN Style的帮助文档.

    Sandcastle - Documentation Compiler for Managed Class Libraries

    Sandcastle Help File Builder

    (我多么希望我们不需要维护这么一份word文件, 就使用上面的工具帮助我们生成MSDN Style的帮助文档就好....)

    (然而总会有一些我们搞不定的人, 拥有一些和我们不同的喜好, 还好, 我们可以满足大家, 用程序生成这份文档吧....^-^)

    对于第二个问题 ,也就是如何用程序生成这份word文档,

    在网上搜了一下, 使用word画表格的例子比较少(表格多的操作都用excel去了)

    于是结合网上搜索的结果, 我写了下面的demo程序,

    能够生成前面贴图效果的word文档(实际上, 前面的那个图, 就是对下面程序的输出做的一个截屏)

    下面的代码只有一个函数,

    在入口处设置一个断点, 边执行边看word文件的效果, 想了解word automation的,应该可以了解一个大概.

    在调查的过程中, 我发现下面的三个连接提供的示例代码比较有用, 贴到下面供大家参考(第一篇讲解的尤为详细).

    Word automation using C#  @C#Corner

    Word automation using C#  @social.msdn.microsoft.com

    HOW TO:利用 Visual C# .NET 使 Word 自动新建文 档  @MSDN

    How to automate Microsoft Word to perform Mail Merge from Visual C#  @MSDN

    Automating Word Tables for Data Insertion and Extraction @MSDN

    如果你使用的是其他语言, 但也需要维护一份这样的word文档的话,

    大都可以使用类似的方法解决,

    比如如果是java, javadoc同样可以帮助我们生成xml文档(而不仅仅局限于大家熟知的html), 然后我们从这个xml文档转换成我们需要的格式.

    过程中要用到JELDoclet , 详细做法参考这个链接Tip: Javadoc as XML @IBM DeveloperWorks

    C#代码  收藏代码
    1. class WordAuto  
    2. {  
    3.     Word.Application wApp;  
    4.     Word._Document wDoc;  
    5.     Object oMissing = System.Reflection.Missing.Value;  
    6.     Object oFalse = false;  
    7.       
    8.   
    9.     public void CreateFile()  
    10.     {  
    11.         Word.Selection wSelection;  
    12.         Word.MailMerge wMailMerge;  
    13.         Word.MailMergeFields wMergeFields;  
    14.         Word.Table wTable;  
    15.         int rowsNum = 12;  
    16.         string StrToAdd;  
    17.   
    18.         // Create an instance of Word  and make it visible.  
    19.         wApp = new Word.Application();  
    20.         wApp.Visible = true;  
    21.   
    22.         // Add a new document.  
    23.         wDoc = wApp.Documents.Add(ref oMissing, ref oMissing, ref oMissing, ref oMissing);  
    24.         wDoc.Select();  
    25.           
    26.         wSelection = wApp.Selection;  
    27.         wSelection.ClearFormatting();  
    28.           
    29.   
    30.         wSelection.Paragraphs.OutlineLevel = Word.WdOutlineLevel.wdOutlineLevel2;  
    31.         wSelection.Font.Size = 20;  
    32.         wSelection.Font.ColorIndex = Word.WdColorIndex.wdBlack;  
    33.         wSelection.Font.Bold = 1;  
    34.         wSelection.TypeText("my first method");  
    35.         wApp.Selection.TypeParagraph();  
    36.         wSelection.Paragraphs.OutlineLevel = Word.WdOutlineLevel.wdOutlineLevelBodyText;  
    37.         wSelection.ClearFormatting();  
    38.         wSelection.Font.ColorIndex = Word.WdColorIndex.wdBlack;  
    39.         wSelection.TypeText("content of first......");  
    40.           
    41.   
    42.         wTable = wDoc.Tables.Add(wSelection.Range, rowsNum, 4, ref oMissing, ref oMissing);  
    43.         wTable.Rows[1].Cells.Shading.BackgroundPatternColorIndex = Word.WdColorIndex.wdGray25;  
    44.         //wTable.Columns[1].SetWidth(51, Word.WdRulerStyle.wdAdjustNone);  
    45.         wTable.Columns[1].SetWidth(70, Word.WdRulerStyle.wdAdjustProportional);  
    46.         wTable.Columns[3].SetWidth(70, Word.WdRulerStyle.wdAdjustProportional);  
    47.         wTable.Borders.Enable = 1;  
    48.   
    49.   
    50.         wTable.Rows[1].Cells[1].Merge(wTable.Rows[1].Cells[4]);  
    51.         wTable.Rows[1].Cells[1].Range.InsertAfter("MyNameSpace.MyClass#MyMethod() : MyRetureType");  
    52.         for (int i = 6; i <= rowsNum; i++)  
    53.         {  
    54.             wTable.Rows[i].Cells[2].Merge(wTable.Rows[i].Cells[4]);  
    55.         }  
    56.         wTable.Rows[6].Cells[1].Range.InsertAfter("详细定义");  
    57.         wTable.Rows[7].Cells[1].Range.InsertAfter("事前条件");  
    58.         wTable.Rows[8].Cells[1].Range.InsertAfter("事后条件");  
    59.         wTable.Rows[9].Cells[1].Range.InsertAfter("不变制约");  
    60.         wTable.Rows[10].Cells[1].Range.InsertAfter("非机能制约");  
    61.         wTable.Rows[11].Cells[1].Range.InsertAfter("备考");  
    62.         wTable.Rows[12].Cells[1].Range.InsertAfter("异常");  
    63.           
    64.         wTable.Rows[2].Cells[1].Range.InsertAfter("函数输入");  
    65.         wTable.Rows[2].Cells[2].Range.InsertAfter("key::string");  
    66.         wTable.Rows[2].Cells[3].Range.InsertAfter("概要");  
    67.         wTable.Rows[2].Cells[4].Range.InsertAfter("my key to....");  
    68.         wTable.Rows[3].Cells[3].Range.InsertAfter("制约");  
    69.         wTable.Rows[3].Cells[4].Range.InsertAfter("key != null");  
    70.   
    71.         wTable.Rows[4].Cells[1].Range.InsertAfter("函数输出");  
    72.         wTable.Rows[4].Cells[2].Range.InsertAfter("-");  
    73.         wTable.Rows[4].Cells[3].Range.InsertAfter("概要");  
    74.         wTable.Rows[5].Cells[3].Range.InsertAfter("制约");  
    75.           
    76.         Cell startCell1 = wTable.Rows[2].Cells[1];  
    77.         Cell endCell1   = wTable.Rows[3].Cells[1];  
    78.         Cell startCell2 = wTable.Rows[2].Cells[2];  
    79.         Cell endCell2   = wTable.Rows[3].Cells[2];  
    80.   
    81.         Cell startCell3 = wTable.Rows[4].Cells[1];  
    82.         Cell endCell3 = wTable.Rows[5].Cells[1];  
    83.         Cell startCell4 = wTable.Rows[4].Cells[2];  
    84.         Cell endCell4 = wTable.Rows[5].Cells[2];  
    85.   
    86.   
    87.         startCell1.Merge(endCell1);  
    88.         startCell2.Merge(endCell2);  
    89.         startCell3.Merge(endCell3);  
    90.         startCell4.Merge(endCell4);  
    91.   
    92.   
    93.         // Go to the end of the document.  
    94.         Object oConst1 = Word.WdGoToItem.wdGoToLine;  
    95.         Object oConst2 = Word.WdGoToDirection.wdGoToLast;  
    96.         wApp.Selection.GoTo(ref oConst1, ref oConst2, ref oMissing, ref oMissing);  
    97.   
    98.         wSelection.InsertBreak();  
    99.         wSelection.Paragraphs.OutlineLevel = Word.WdOutlineLevel.wdOutlineLevel2;  
    100.         wSelection.Font.ColorIndex = Word.WdColorIndex.wdBlack;   
    101.         wSelection.Font.Size = 20;  
    102.         wSelection.Font.Bold = 1;  
    103.         wSelection.TypeText("my second method");  
    104.         wApp.Selection.TypeParagraph();  
    105.         wSelection.Paragraphs.OutlineLevel = Word.WdOutlineLevel.wdOutlineLevelBodyText;  
    106.         wSelection.ClearFormatting();  
    107.         wSelection.Font.ColorIndex = Word.WdColorIndex.wdBlack;  
    108.         wSelection.TypeText("content of second......");  
    109.   
    110.         //another table  
    111.         wTable = wDoc.Tables.Add(wSelection.Range, rowsNum, 4, ref oMissing, ref oMissing);  
    112.         wTable.Borders.Enable = 1;  
    113.   
    114.         ////............  
    115.           
    116.         wDoc.SaveAs("c:\word_auto.doc");  
    117.         wDoc.Close(false);  
    118.         wApp.Quit();  
    119.         wApp = null;  
    120.     }  
    121. }  

    ---end---

  • 相关阅读:
    SSLZYC NOIP
    SSLZYC 懒惰的奶牛①
    SSLZYC 小麦高度
    Pythonlog() 函数
    详细解读Python中的__init__()方法
    详细解读Python中的__init__()方法
    Linux软件安装中RPM与YUM 区别和联系
    Linux软件安装中RPM与YUM 区别和联系
    【我的物联网成长记】设备如何进行选型?
    【我的物联网成长记】设备如何进行选型?
  • 原文地址:https://www.cnblogs.com/gc2013/p/3837862.html
Copyright © 2011-2022 走看看