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

如何从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.DataAccess, Version=2.112.1.0, Culture=neutral, PublicKeyToken=89b483f429c47342"

    转载自原文 未能加载文件或程序集"Oracle.DataAccess, Version=2.112.1.0,..." 若本机的Oracle版本是32位系统,则在调用Oracle数据 ...

  2. Android中利用画图类和线程画出闪烁的心形

                                                        本文讲解主要涉及的知识点: 1.线程控制 2.画图类 3.心形函数 大家先看图片: <ig ...

  3. webdriver(python)学习笔记二

    自己开始一个脚本开始学习: # coding = utf-8 from selenium import webdriver browser = webdriver.Firefox() browser. ...

  4. 转-CMMI在中国之混乱-CMMI比ISO9000会更惨

    CMMI在中国之混乱-CMMI比ISO9000会更惨 自己接触CMM/CMMI已经有8年时间了,现在静心回顾一下,觉得CMMI在中国的命运会比ISO9000还悲惨. 一组现象或许让你我对此结论有更深入 ...

  5. makefile、gdb使用记录

    makefile的模板 all: rover server station rover: rover.c tcputil.o gcc rover.c tcputil.o -o rover -lpthr ...

  6. web.py网页模板中使用jquery

    由于$是web.py针对模板的保留字符,所以在模板文件内不能直接使用$("#id")的格式. 解决办法: 1.$$("#id")可以避免$被误解析 2.jque ...

  7. git使用中遇到的常见问题

    .gitignore 中添加的文件不能被忽略掉 这是因为我们误解了 .gitignore 文件的用途,该文件只能作用于 Untracked Files,也就是那些从来没有被 Git 记录过的文件(自添 ...

  8. gratitute

    韩信帮刘邦夺得天下,最终又得到了什么?姑且不问当初刘邦拜将是何心态?虽然他的所拜之相并不是的那边从芒砀山带下来的哥们或是在沛县时候一起打混的兄弟? 韩信在汉军营得以重用,在项羽处屈其才,此真正的原因在 ...

  9. Spark RDD概念学习系列之细谈RDD的弹性(十六)

    细谈RDD的弹性  所谓,弹性,是指在内存不够时可以与磁盘进行交换. 弹性之一:自动的进行内存和磁盘数据存储的切换   弹性之二:基于Lineage(血缘)的高效容错   弹性之三:Task如果失败会 ...

  10. 对"一维最大子数组和"问题的思考(homework-01)

    一维最大子数组和问题,即给定一个数组,在它所有的连续子数组的和中,求最大的那个和.“最大子数组和”是一个很好的IT面试考题,在<编程之美>一书中同时阐述了一维数组和二维数组的讨论.本篇博客 ...