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

如何从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. IOS开发:监听来电状态的改变。

    #import <CoreTelephony/CTCallCenter.h> #import <CoreTelephony/CTCall.h> @property(nonato ...

  2. hdu 1008 注意同层情况

    #include<iostream> using namespace std; int main() { int n; ]; while(cin>>n) { ,m=; ) br ...

  3. Xamarin android PreferenceActivity 实现应用程序首选项设置(一)

    应用程序首选项屏幕 类似系统设置界面. PreferenceActivity 是另一种类型的Activity,通过PreferenceActivity 可以以最少量的工作显示某些Preference列 ...

  4. 学习php常用算法

    <?php /*学用php算法*/ /*1.冒泡法 *思路分析:在要排序的一组数中,对当前还未排好的序列, *从前往后对相邻的两个数依次进行比较和调整,让较大的数往下沉,较小的往上冒. *即,每 ...

  5. 诞生于饭桌上的jcSQL语言

    相信每个Coder都有心在自己求学阶段可以写一门自己的语言,无论是毕业设计,还是课余爱好:不管是为了提升B格,还是想练手,抑或对其他语言不满,想自己撸一个,只要坚持下去了,都是不错的理由. 现在正值暑 ...

  6. 考试easy该,学习如何做?

    我的两个学生(场和任)都讲了他们周末參加的一个认证考试不考大题考小题的事情.由感而发: 话说不用大题考,大概是不敢用大题考. 老师的教.和学生的学中.存在的一些问题得不到解决,整体讲,学生的学习效果没 ...

  7. Dynamics CRM 自定义上传附件的图片悬浮层显示

    CRM中的附件是以流的形式保存在了数据库中,这样做的一个坏处是一旦系统运行时间久,附件上传的多了势必会导致数据库极速扩大,即影响系统的运行效率也对后期的迁移维护带来了不必要的麻烦.所以很多的客户都会要 ...

  8. gentoo kvm qemu

    首先使用 grep --color -E "vmx|svm" /proc/cpuinfo 检查 cpu 能不能支持虚拟化,注意 biso 里面要开启虚拟化. 内核开启相应选项 [* ...

  9. @RequestMapping使用须知

    ----------------------siwuxie095 @RequestMapping 使用须知 使用 @RequestMapping 注解映射请求路径 即 你可以使用 @RequestMa ...

  10. [z]dbms_stats.lock_table_stats对于没有统计信息的表分区同样有效

    常见的分区表DDL如 split partition.add partition都会生成没有统计信息的表分区table partition,长期以来我对dbms_stats.lock_table_st ...