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

如何从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

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

---end---

C# : 操作Word文件的API - (将C# source中的xml注释转换成word文档)的更多相关文章

  1. PDF文件可以转换成txt文档吗

    PDF是一种便携式的文件格式,传送和阅读都非常方便,是Adobe公司开发的跨平台文件格式,它无论在哪种打印机上都可以保证精确的颜色和准确的打印效果.可是有点遗憾的是PDF格式一般不能在手机上打开,或者 ...

  2. ABBYY将JPEG文件转换成Word文档的方法

    日常工作中处理JPEG格式的图像文件时,有时需要转换成Word文档进行编辑,市场上应用而生了很多转换工具,相信不少人听说过OCR(光学字符识别)软件,可以用来转换图像文件,而在OCR软件中, ABBY ...

  3. 如何使用ABBYY FineReader 12将JPEG文件转换成Word文档

    日常工作中处理JPEG格式的图像文件时,有时需要转换成Word文档进行编辑,市场上应用而生了很多转换工具,相信不少人听说过OCR(光学字符识别)软件,可以用来转换图像文件,而在OCR软件中, ABBY ...

  4. ABBYY把pdf转换成word的方法

    有时候我们在网上下载的资料文献是PDF格式文档,遇到喜欢的字句总忍不住想要收藏起来,但是PDF文档不同于普通的Word文档可以直接进行复制粘贴,需要下载安装相关的编辑工具,才能对文字内容进行编辑.倒不 ...

  5. pdf转换成word转换器免费版

    在平时的办公中,我们只需要有一款比较好用的pdf转换成word转换器,就能提高我们的工作效率,但是国内外的pdf转换成word转换器应该怎么选呢?小编因为是文职工作者,所以在日常的实践中选出了ABBY ...

  6. HTML转换成word文档

    1工具类保存word文件 public class WordAction { public static void SaveAsWord(string fileName, string pFileNa ...

  7. 将Latex tex文档转换成 word文档(下)

    在上篇中我们介绍了一款将 tex 文件转换成 word 文件的工具 借用万能的搜索引擎,在 Google 上找到了更好的工具 它就是Pandoc 介绍 Pandoc 是由 John McaFarlan ...

  8. 将Latex tex文档转换成 word文档(上)

    有时候逼不得已,必须得将自己精心排版好的latex 文档 转换成word 给别人编辑 以下提供一个方法 下载 Tex2Word 工具,地址我的网盘 安装 解压后安装,使用默认安装路径 安装过程中.点击 ...

  9. 用java将简单的word文档换成pdf文档

    用java将简单的word文档换成pdf文档的方式很多,因为很多都没有实际测试过,所以这里就先泛泛的说一下 整体上来看分两种: 1.纯java代码实现,有很多优秀的开源软件可以用,比如poi,itex ...

随机推荐

  1. Oracle 课程三之表设计

    完成本课程的学习后,您应该能够: •普通堆表优点和缺点 •理解rowid •全局临时表优点.缺点和适用场景 •分区表的类型和原理.优点和缺点.适用场景 •表字段的高效设计 •sequence的设计   ...

  2. java web 学习八(HttpServletResponse对象2)

    一.HttpServletResponse常见应用——生成验证码 1.1.生成随机图片用作验证码 生成图片主要用到了一个BufferedImage类,

  3. 翻译【ElasticSearch Server】第一章:开始使用ElasticSearch集群(7)

    检索文档(Retrieving documents) 我们已经有文档存储在我们的实例.现在,让我们尝试检索它们: curl -XGET http://localhost:9200/blog/artic ...

  4. Keep the Customer Satisfied

    题意: n个订单,每个订单有完成需要的天数,和限制的天数,求最多能完成多少订单 分析: 先按限制日期升序排列,若当前订单不能完成,和上面已选中的订单中需要天数中最大的比较,若比它小,则替换他. #in ...

  5. HDU5758 Explorer Bo 树形dp

    我是参考这一篇写的:http://blog.csdn.net/fsss_7/article/details/52049474 一点感想:dp[i][0]代表以这个点为根的且总叶子数为偶数个叶子的答案 ...

  6. 《Python核心编程》 第十章 错误和异常

    10–1. 引发异常. 以下的哪个因素会在程序执行时引发异常? 注意这里我们问的并不是异常的原因. a) 用户 b) 解释器 c) 程序 d) 以上所有 e) 只有 b) 和 c) f) 只有 a) ...

  7. Unbutu网卡驱动安装(Intel内置网卡8086:15b8)

    工作中需要在新的实验平台上安装unbuntu14.04操作系统,系统安装好之后发现无法连接网络,分析后是由于缺少网卡驱动的原因. 下面把分析问题的过程及安装网卡驱动步骤介绍如下: 查看PCI信息 su ...

  8. IOS下arm64汇编疑问

    之前所有关于32位下的纯汇编.s代码,在编译arm64的时候,很多错误,不得已只能用C代码. 但是arm_neon.h内部类C接口的汇编,基本上没有问题.不敢完全保证,还有待确认.关于arm64位的汇 ...

  9. Hive自定义UDAF详解

    遇到一个Hive需求:有A.B.C三列,按A列进行聚合,求出C列聚合后的最小值和最大值各自对应的B列值.这个需求用hql和内建函数也可完成,但是比较繁琐,会解析成几个MR进行执行,如果自定义UDAF便 ...

  10. 在C++中定义常量的两种方法的比较

    常量是定以后,在程序运行中不能被改变的标识符.C++中定义常量可以用#define .const 这两种方法.例如:#define PRICE 10 //定义单价常量10const int PRICE ...