最近完成了一个使用VC++ 操作word生成扫描报告的功能,在这里将过程记录下来,开发环境为visual studio 2008

导入接口

首先在创建的MFC项目中引入word相关组件

右键点击 项目 --> 添加 --> 新类,在弹出的对话框中选择Typelib中的MFC类。

然后在弹出的对话框中选择文件,从文件中导入MSWORD.OLB组件。

这个文件的路径一般在C:\Program Files (x86)\Microsoft Office\Office14 中,注意:最后一层可能不一定是Office14,这个看机器中安装的office 版本。

选择之后会要求我们决定导入那些接口,为了方便我们导入所有接口。

导入之后可以看到项目中省成本了很多代码文件,这些就是系统生成的操作Word的相关类。

这里编译可能会报错,error C2786: “BOOL (HDC,int,int,int,int)”: __uuidof 的操作数无效

解决方法:

修改对应头文件

  1. #import "C:\\Program Files\\Microsoft Office\\Office14\\MSWORD.OLB" no_namespace

为:

  1. #import "C:\\Program Files\\Microsoft Office\\Office14\\MSWORD.OLB" no_namespace raw_interfaces_only \
  2. rename("FindText","_FindText") \
  3. rename("Rectangle","_Rectangle") \
  4. rename("ExitWindows","_ExitWindows")

再次编译,错误消失

常见接口介绍

要了解一些常见的类,我们首先需要明白这些接口的层次结构:

  1. Application(WORD 为例,只列出一部分)
  2.   Documents(所有的文档)
  3. Document(一个文档)
  4. ......
  5.   Templates(所有模板)
  6. Template(一个模板)
  7. ......
  8.   Windows(所有窗口)
  9. Window
  10. Selection
  11. View
  12.   Selection(编辑对象)
  13. Font
  14. Style
  15. Range

这些组件其实是采用远程调用的方式调用word进程来完成相关操作。

  • Application:相当于一个word进程,每次操作之前都需要一个application对象,这个对象用于创建一个word进程。
  • Documents:相当于word中打开的所有文档,如果用过word编辑多个文件,那么这个概念应该很好理解
  • Templates:是一个模板对象,至于word模板,不了解的请自行百度
  • Windows:word进程中的窗口
  • Selection:编辑对象。也就是我们要写入word文档中的内容。一般包括文本、样式、图形等等对象。

回忆一下我们手动编写word的情景,其实使用这些接口是很简单的。我们在使用word编辑的时候首先会打开word程序,这里对应在代码里面就是创建一个Application对象。然后我们会用word程序打开一个文档或者新建一个文档。这里对应着创建Documents对象并从中引用一个Document对象表示一个具体的文档。当然这个Document对象可以是新建的也可以是打开一个现有的。接着就是进行相关操作了,比如插入图片、插入表格、编写段落文本等等了。这些都对应着创建类似于Font、Style、TypeText对象,然后将这些对象进行添加的操作了。

说了这么多。这些接口这么多,我怎么知道哪个接口对应哪个对象呢,而且这些参数怎么传递呢?其实这个问题很好解决。我们可以手工进行相关操作,然后用宏记录下来,最后我们再将宏中的VB代码转化为VC代码即可。

相关操作

为了方便在项目中使用,这里创建一个类用于封装Word的相关操作

  1. class CCreateWordReport
  2. {
  3. private:
  4. CApplication m_wdApp;
  5. CDocuments m_wdDocs;
  6. CDocument0 m_wdDoc;
  7. CSelection m_wdSel;
  8. CRange m_wdRange;
  9. CnlineShapes m_wdInlineShapes;
  10. CnlineShape m_wdInlineShape;
  11. public:
  12. CCreateWordReport();
  13. virtual ~CCreateWordReport();
  14. public:
  15. //操作
  16. //**********************创建新文档*******************************************
  17. BOOL CreateApp(); //创建一个新的WORD应用程序
  18. BOOL CreateDocuments(); //创建一个新的Word文档集合
  19. BOOL CreateDocument(); //创建一个新的Word文档
  20. BOOL Create(); //创建新的WORD应用程序并创建一个新的文档
  21. void ShowApp(); //显示WORD文档
  22. void HideApp(); //隐藏word文档
  23. //**********************打开文档*********************************************
  24. BOOL OpenDocument(CString fileName);//打开已经存在的文档。
  25. BOOL Open(CString fileName); //创建新的WORD应用程序并打开一个已经存在的文档。
  26. BOOL SetActiveDocument(short i); //设置当前激活的文档。
  27. //**********************保存文档*********************************************
  28. BOOL SaveDocument(); //文档是以打开形式,保存。
  29. BOOL SaveDocumentAs(CString fileName);//文档以创建形式,保存。
  30. BOOL CloseDocument();
  31. void CloseApp();
  32. //**********************文本书写操作*****************************************
  33. void WriteText(CString szText); //当前光标处写文本
  34. void WriteNewLineText(CString szText, int nLineCount = 1); //换N行写字
  35. void WriteEndLine(CString szText); //文档结尾处写文本
  36. void WholeStory(); //全选文档内容
  37. void Copy(); //复制文本内容到剪贴板
  38. void InsertFile(CString fileName); //将本地的文件全部内容写入到当前文档的光标处。
  39. void InsertTable(int nRow, int nColumn, CTable0& wdTable);
  40. //**********************图片插入操作*****************************************
  41. void InsertShapes(CString fileName);//在当前光标的位置插入图片
  42. //**********************超链接插入操作*****************************************
  43. void InsertHyperlink(CString fileLink);//超级链接地址,可以是相对路径。
  44. //***********************表格操作表格操作**********************************
  45. BOOL InsertTableToMarkBook(const CString csMarkName, int nRow, int nColumn, CTable0& wdTable); //表格行数与列数
  46. BOOL WriteDataToTable(CTable0& wdTable, int nRow, int nColumn, const CString &csData); //往表格中写入输入
  47. };
  1. BOOL CCreateWordReport::CreateApp()
  2. {
  3. if (FALSE == m_wdApp.CreateDispatch("word.application"))
  4. {
  5. AfxMessageBox("Application创建失败,请确保安装了word 2000或以上版本!", MB_OK|MB_ICONWARNING);
  6. return FALSE;
  7. }
  8. return TRUE;
  9. }
  10. BOOL CCreateWordReport::CreateDocuments()
  11. {
  12. if (FALSE == CreateApp())
  13. {
  14. return FALSE;
  15. }
  16. m_wdDocs = m_wdApp.get_Documents();
  17. if (!m_wdDocs.m_lpDispatch)
  18. {
  19. AfxMessageBox("Documents创建失败!", MB_OK|MB_ICONWARNING);
  20. return FALSE;
  21. }
  22. return TRUE;
  23. }
  24. BOOL CCreateWordReport::CreateDocument()
  25. {
  26. if (!m_wdDocs.m_lpDispatch)
  27. {
  28. AfxMessageBox("Documents为空!", MB_OK|MB_ICONWARNING);
  29. return FALSE;
  30. }
  31. COleVariant varTrue(short(1),VT_BOOL),vOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
  32. CComVariant Template(_T("")); //没有使用WORD的文档模板
  33. CComVariant NewTemplate(false),DocumentType(0),Visible;
  34. m_wdDocs.Add(&Template,&NewTemplate,&DocumentType,&Visible);
  35. //得到document变量
  36. m_wdDoc = m_wdApp.get_ActiveDocument();
  37. if (!m_wdDoc.m_lpDispatch)
  38. {
  39. AfxMessageBox("Document获取失败!", MB_OK|MB_ICONWARNING);
  40. return FALSE;
  41. }
  42. //得到selection变量
  43. m_wdSel = m_wdApp.get_Selection();
  44. if (!m_wdSel.m_lpDispatch)
  45. {
  46. AfxMessageBox("Select获取失败!", MB_OK|MB_ICONWARNING);
  47. return FALSE;
  48. }
  49. //得到Range变量
  50. m_wdRange = m_wdDoc.Range(vOptional,vOptional);
  51. if(!m_wdRange.m_lpDispatch)
  52. {
  53. AfxMessageBox("Range获取失败!", MB_OK|MB_ICONWARNING);
  54. return FALSE;
  55. }
  56. return TRUE;
  57. }
  58. BOOL CCreateWordReport::Create()
  59. {
  60. if (FALSE == CreateDocuments())
  61. {
  62. return FALSE;
  63. }
  64. return CreateDocument();
  65. }
  66. BOOL CCreateWordReport::OpenDocument(CString fileName)
  67. {
  68. if (!m_wdDocs.m_lpDispatch)
  69. {
  70. AfxMessageBox("Documents为空!", MB_OK|MB_ICONWARNING);
  71. return FALSE;
  72. }
  73. COleVariant vTrue((short)TRUE),
  74. vFalse((short)FALSE),
  75. vOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR),
  76. vZ((short)0);
  77. COleVariant vFileName(_T(fileName));
  78. //得到document变量
  79. m_wdDoc = m_wdDocs.Open(
  80. vFileName, // FileName
  81. vTrue, // Confirm Conversion.
  82. vFalse, // ReadOnly.
  83. vFalse, // AddToRecentFiles.
  84. vOptional, // PasswordDocument.
  85. vOptional, // PasswordTemplate.
  86. vOptional, // Revert.
  87. vOptional, // WritePasswordDocument.
  88. vOptional, // WritePasswordTemplate.
  89. vOptional, // Format. // Last argument for Word 97
  90. vOptional, // Encoding // New for Word 2000/2002
  91. vOptional, // Visible
  92. /*如下4个是word2003需要的参数。本版本是word2000。*/
  93. vOptional, // OpenAndRepair
  94. vZ, // DocumentDirection wdDocumentDirection LeftToRight
  95. vOptional, // NoEncodingDialog
  96. vOptional
  97. );
  98. if (!m_wdDoc.m_lpDispatch)
  99. {
  100. AfxMessageBox("Document获取失败!", MB_OK|MB_ICONWARNING);
  101. return FALSE;
  102. }
  103. //得到selection变量
  104. m_wdSel = m_wdApp.get_Selection();
  105. if (!m_wdSel.m_lpDispatch)
  106. {
  107. AfxMessageBox("Select获取失败!", MB_OK|MB_ICONWARNING);
  108. return FALSE;
  109. }
  110. //得到全部DOC的Range变量
  111. m_wdRange = m_wdDoc.Range(vOptional,vOptional);
  112. if(!m_wdRange.m_lpDispatch)
  113. {
  114. AfxMessageBox("Range获取失败!", MB_OK|MB_ICONWARNING);
  115. return FALSE;
  116. }
  117. return TRUE;
  118. }
  119. BOOL CCreateWordReport::Open(CString fileName)
  120. {
  121. if (FALSE == CreateDocuments())
  122. {
  123. return FALSE;
  124. }
  125. return OpenDocument(fileName);
  126. }
  127. BOOL CCreateWordReport::SetActiveDocument(short i)
  128. {
  129. COleVariant vIndex(_T(i)),vOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
  130. m_wdDoc.AttachDispatch(m_wdDocs.Item(vIndex));
  131. m_wdDoc.Activate();
  132. if (!m_wdDoc.m_lpDispatch)
  133. {
  134. AfxMessageBox("Document获取失败!", MB_OK|MB_ICONWARNING);
  135. return FALSE;
  136. }
  137. //得到selection变量
  138. m_wdSel = m_wdApp.get_Selection();
  139. if (!m_wdSel.m_lpDispatch)
  140. {
  141. AfxMessageBox("Select获取失败!", MB_OK|MB_ICONWARNING);
  142. return FALSE;
  143. }
  144. //得到全部DOC的Range变量
  145. m_wdRange = m_wdDoc.Range(vOptional,vOptional);
  146. if(!m_wdRange.m_lpDispatch)
  147. {
  148. AfxMessageBox("Range获取失败!", MB_OK|MB_ICONWARNING);
  149. return FALSE;
  150. }
  151. // HideApp();
  152. return TRUE;
  153. }
  154. BOOL CCreateWordReport::SaveDocument()
  155. {
  156. if (!m_wdDoc.m_lpDispatch)
  157. {
  158. AfxMessageBox("Document获取失败!", MB_OK|MB_ICONWARNING);
  159. return FALSE;
  160. }
  161. m_wdDoc.Save();
  162. return TRUE;
  163. }
  164. BOOL CCreateWordReport::SaveDocumentAs(CString fileName)
  165. {
  166. if (!m_wdDoc.m_lpDispatch)
  167. {
  168. AfxMessageBox("Document获取失败!", MB_OK|MB_ICONWARNING);
  169. return FALSE;
  170. }
  171. COleVariant covOptional((long)DISP_E_PARAMNOTFOUND,VT_ERROR);
  172. COleVariant varZero((short)0);
  173. COleVariant varTrue(short(1),VT_BOOL);
  174. COleVariant varFalse(short(0),VT_BOOL);
  175. COleVariant vFileName(_T(fileName));
  176. m_wdDoc.SaveAs(
  177. vFileName,
  178. covOptional,
  179. covOptional,
  180. covOptional,
  181. covOptional,
  182. covOptional,
  183. covOptional,
  184. covOptional,
  185. covOptional,
  186. covOptional,
  187. covOptional,
  188. covOptional,
  189. covOptional,
  190. covOptional,
  191. covOptional,
  192. covOptional
  193. );
  194. return TRUE;
  195. }
  196. BOOL CCreateWordReport::CloseDocument()
  197. {
  198. COleVariant vTrue((short)TRUE),
  199. vFalse((short)FALSE),
  200. vOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
  201. m_wdDoc.Close(vFalse, // SaveChanges.
  202. vTrue, // OriginalFormat.
  203. vFalse // RouteDocument.
  204. );
  205. m_wdDoc.AttachDispatch(m_wdApp.get_ActiveDocument());
  206. if (!m_wdDoc.m_lpDispatch)
  207. {
  208. AfxMessageBox("Document获取失败!", MB_OK|MB_ICONWARNING);
  209. return FALSE;
  210. }
  211. //得到selection变量
  212. m_wdSel = m_wdApp.get_Selection();
  213. if (!m_wdSel.m_lpDispatch)
  214. {
  215. AfxMessageBox("Select获取失败!", MB_OK|MB_ICONWARNING);
  216. return FALSE;
  217. }
  218. //得到全部DOC的Range变量
  219. m_wdRange = m_wdDoc.Range(vOptional,vOptional);
  220. if(!m_wdRange.m_lpDispatch)
  221. {
  222. AfxMessageBox("Range获取失败!", MB_OK|MB_ICONWARNING);
  223. return FALSE;
  224. }
  225. return TRUE;
  226. }
  227. void CCreateWordReport::CloseApp()
  228. {
  229. COleVariant vTrue((short)TRUE),
  230. vFalse((short)FALSE),
  231. vOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
  232. m_wdDoc.Save();
  233. m_wdApp.Quit(vFalse, // SaveChanges.
  234. vTrue, // OriginalFormat.
  235. vFalse // RouteDocument.
  236. );
  237. //释放内存申请资源
  238. m_wdInlineShape.ReleaseDispatch();
  239. m_wdInlineShapes.ReleaseDispatch();
  240. //m_wdTb.ReleaseDispatch();
  241. m_wdRange.ReleaseDispatch();
  242. m_wdSel.ReleaseDispatch();
  243. //m_wdFt.ReleaseDispatch();
  244. m_wdDoc.ReleaseDispatch();
  245. m_wdDocs.ReleaseDispatch();
  246. m_wdApp.ReleaseDispatch();
  247. }
  248. void CCreateWordReport::WriteText(CString szText)
  249. {
  250. m_wdSel.TypeText(szText);
  251. }
  252. void CCreateWordReport::WriteNewLineText(CString szText, int nLineCount /* = 1 */)
  253. {
  254. int i;
  255. if (nLineCount <= 0)
  256. {
  257. nLineCount = 0;
  258. }
  259. for (i = 0; i < nLineCount; i++)
  260. {
  261. m_wdSel.TypeParagraph();
  262. }
  263. WriteText(szText);
  264. }
  265. void CCreateWordReport::WriteEndLine(CString szText)
  266. {
  267. m_wdRange.InsertAfter(szText);
  268. }
  269. void CCreateWordReport::WholeStory()
  270. {
  271. m_wdRange.WholeStory();
  272. }
  273. void CCreateWordReport::Copy()
  274. {
  275. m_wdRange.CopyAsPicture();
  276. }
  277. void CCreateWordReport::InsertFile(CString fileName)
  278. {
  279. COleVariant vFileName(fileName),
  280. vTrue((short)TRUE),
  281. vFalse((short)FALSE),
  282. vOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR),
  283. vNull(_T(""));
  284. /*
  285. void InsertFile(LPCTSTR FileName, VARIANT* Range, VARIANT* ConfirmConversions, VARIANT* Link, VARIANT* Attachment);
  286. */
  287. m_wdSel.InsertFile(
  288. fileName,
  289. vNull,
  290. vFalse,
  291. vFalse,
  292. vFalse
  293. );
  294. }
  295. void CCreateWordReport::InsertShapes(CString fileName)
  296. {
  297. COleVariant vTrue((short)TRUE),
  298. vFalse((short)FALSE),
  299. vOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
  300. m_wdInlineShapes=m_wdSel.get_InlineShapes();
  301. m_wdInlineShape=m_wdInlineShapes.AddPicture(fileName,vFalse,vTrue,vOptional);
  302. }
  303. void CCreateWordReport::InsertHyperlink(CString fileLink)
  304. {
  305. COleVariant vAddress(_T(fileLink)),vSubAddress(_T(""));
  306. CRange aRange = m_wdSel.get_Range();
  307. CHyperlinks vHyperlinks(aRange.get_Hyperlinks());
  308. vHyperlinks.Add(
  309. aRange, //Object,必需。转换为超链接的文本或图形。
  310. vAddress, //Variant 类型,可选。指定的链接的地址。此地址可以是电子邮件地址、Internet 地址或文件名。请注意,Microsoft Word 不检查该地址的正确性。
  311. vSubAddress, //Variant 类型,可选。目标文件内的位置名,如书签、已命名的区域或幻灯片编号。
  312. vAddress, //Variant 类型,可选。当鼠标指针放在指定的超链接上时显示的可用作“屏幕提示”的文本。默认值为 Address。
  313. vAddress, //Variant 类型,可选。指定的超链接的显示文本。此参数的值将取代由 Anchor 指定的文本或图形。
  314. vSubAddress //Variant 类型,可选。要在其中打开指定的超链接的框架或窗口的名字。
  315. );
  316. aRange.ReleaseDispatch();
  317. vHyperlinks.ReleaseDispatch();
  318. }

这样我们就封装好了一些基本的操作,其实这些操作都是我自己根据网上的资料以及VB宏转化而来得到的代码。

特殊操作

在这里主要介绍一些比较骚的操作,这也是这篇文章主要有用的内容,前面基本操作网上都有源代码直接拿来用就OK了,这里的骚操作是我在项目中使用的主要操作,应该有应用价值。先请各位仔细想想,如果我们要根据前面的代码,从0开始完全用代码生成一个完整的报表是不是很累,而且一般报表都会包含一些通用的废话,这些话基本不会变化。如果将这些写到代码里面,如果后面这些话变了,我们就要修改并重新编译,是不是很麻烦。所以这里介绍的第一个操作就是利用模板和书签在合适的位置插入内容。

书签的使用

首先我们在Word中的适当位置创建一个标签,至于如何创建标签,请自行百度。然后在代码中的思路就是在文档中查找我们的标签,再获取光标的位置,最后就是在该位置处添加相应的内容了,这里我们举一个在光标位置插入文本的例子:

  1. void CCreateWordReport::WriteTextToBookMark(const CString& csMarkName, const CString& szText)
  2. {
  3. CBookmarks bks = m_wdDoc.get_Bookmarks(); //获取文档中的所有书签
  4. CBookmark0 bk;
  5. COleVariant bk_name(csMarkName);
  6. bk = bks.Item(&bk_name); //查询对应名称的书签
  7. CRange hRange = bk.get_Range(); //获取书签位置
  8. if (hRange != NULL)
  9. {
  10. hRange.put_Text(szText); //在该位置处插入文本
  11. }
  12. //最后不要忘记清理相关资源
  13. hRange.ReleaseDispatch();
  14. bk.ReleaseDispatch();
  15. bks.ReleaseDispatch();
  16. }

表格的使用

在word报表中表格应该是一个重头戏,表格中常用的接口如下:

  • CTables0: 表格集合
  • CTable0: 某个具体的表格,一般通过CTables来创建CTable
  • CColumn: 表格列对象
  • CRow:表格行对象
  • CCel:表格单元格对象

创建表格一般的操作如下:

  1. void CCreateWordReport::InsertTable(int nRow, int nColumn, CTable0& wdTable)
  2. {
  3. VARIANT vtDefault;
  4. COleVariant vtAuto;
  5. vtDefault.vt = VT_INT;
  6. vtDefault.intVal = 1;
  7. vtAuto.vt = VT_INT;
  8. vtAuto.intVal = 0;
  9. CTables0 wordtables = m_wdDoc.get_Tables();
  10. wdTable = wordtables.Add(m_wdSel.get_Range(), nRow, nColumn, &vtDefault, &vtAuto);
  11. wordtables.ReleaseDispatch();
  12. }

往表格中写入内容的操作如下:

  1. BOOL CCreateWordReport::WriteDataToTable(CTable0& wdTable, int nRow, int nColumn, const CString &csData)
  2. {
  3. CCell cell = wdTable.Cell(nRow, nColumn);
  4. cell.Select(); //将光标移动到单元格
  5. m_wdSel.TypeText(csData);
  6. cell.ReleaseDispatch();
  7. return TRUE;
  8. }

合并单元格的操作如下:

  1. CTable0 wdTable;
  2. InsertTable(5, 3, wdTable); //创建一个5行3列的表格
  3. CCell cell = wdTable.Cell(1, 1); //获得第一行第一列的单元格
  4. //设置第二列列宽
  5. CColumns0 columns = wdTable.get_Columns();
  6. CColumn col;
  7. col.AttachDispatch(columns.Item(2));
  8. col.SetWidth(40, 1);
  9. cell.Merge(wdTable.Cell(5, 1)); //合并单元格,一直合并到第5行的第1列。
  10. cell.SetWidth(30, 1);
  11. cell.ReleaseDispatch();

合并单元格用的是Merge函数,该函数的参数是一个单元格对象,表示合并结束的单元格。这里合并类似于我们画矩形时提供的左上角坐标和右下角坐标

移动光标跳出表格

当时由于需要连续的生成多个表格,当时我将前一个表格的数据填完,光标位于最后一个单元格里面,这个时候如果再插入的时候会在这个单元格里面插入表格,这个时候需要我手动向下移动光标,让光标移除到表格外。移动光标的代码如下:

  1. m_wdSel.MoveDown(&COleVariant((short)wdLine), &COleVariant((short)1), &COleVariant((short)wdNULL));

这里wdLine 是word相关接口定义的,表示希望以何种单位来移动,这里我是以行为单位。后面的1表示移动1行。

但是我发现在面临换页的时候一次移动根本移动不出来,这个时候我又添加了一行这样的代码移动两行。但是问题又出现了,这一系列表格后面跟着另一个大标题,多移动几次之后可能会造成它移动到大标题的位置,而破坏我原来定义的模板,这个时候该怎么办呢?我采取的办法是,判断当前光标是否在表格中,如果是则移动一行,知道出了表格。这里的代码如下:

  1. //移动光标,直到跳出表格外
  2. while (TRUE)
  3. {
  4. m_wdSel.MoveDown(&COleVariant((short)wdLine), &COleVariant((short)1), &COleVariant((short)wdNULL));
  5. m_wdSel.Collapse(&COleVariant((short)wdCollapseStart));
  6. if (!m_wdSel.get_Information((long)wdWithInTable).boolVal)
  7. {
  8. break;
  9. }
  10. }

样式的使用

在使用样式的时候当然也可以用代码来定义,但是我们可以采取另一种方式,我们可以事先在模板文件中创建一系列样式,然后在需要的时候直接定义段落或者文本的样式即可

  1. m_wdSel.put_Style(COleVariant("二级标题")); //在当前光标处的样式定义为二级标题样式,这里的二级标题样式是我们在word中事先定义好的
  2. m_wdSel.TypeText(csTitle); //在当前位置输出文本
  3. m_wdSel.TypeParagraph(); //插入段落,这里主要为了换行,这个时候光标也会跟着动
  4. m_wdSel.put_Style(COleVariant("正文")); //定义此处样式为正文样式
  5. m_wdSel.TypeText(csText;

插入图表

我自己尝试用word生成的图表样式还可以,但是用代码插入的时候,样式就特别丑,这里没有办法,我采用GDI+绘制了一个饼图,然后将图片插入word中。

  1. BOOL CCreateWordReport::DrawVulInforPic(const CString& csMarkName, int nVulCnt, int nVulCris, int nHigh, int nMid, int nLow, int nPossible)
  2. {
  3. CBookmarks bks = m_wdDoc.get_Bookmarks();
  4. COleVariant bk_name(csMarkName);
  5. CBookmark0 bk = bks.Item(&bk_name);
  6. bk.Select();
  7. CnlineShapes isps = m_wdSel.get_InlineShapes();
  8. COleVariant vFalse((short)FALSE);
  9. COleVariant vNull("");
  10. COleVariant vOptional((long)DISP_E_PARAMNOTFOUND,VT_ERROR);
  11. //创建一个与桌面环境兼容的内存DC
  12. HWND hWnd = GetDesktopWindow();
  13. HDC hDc = GetDC(hWnd);
  14. HDC hMemDc = CreateCompatibleDC(hDc);
  15. HBITMAP hMemBmp = CreateCompatibleBitmap(hDc, PICTURE_WIDTH + GLOBAL_MARGIN, PICTURE_LENGTH + 2 * GLOBAL_MARGIN + LENGED_BORDER_LENGTH);
  16. SelectObject(hMemDc, hMemBmp);
  17. //绘制并保存图表
  18. DrawPie(hMemDc, nVulCnt, nVulCris, nHigh, nMid, nLow, nPossible);
  19. COleVariant vTrue((short)TRUE);
  20. CnlineShape isp=isps.AddPicture("D:\\Program\\WordReport\\WordReport\\test.png",vFalse,vTrue,vOptional); //以图片的方式插入图表
  21. //设置图片的大小
  22. isp.put_Height(141);
  23. isp.put_Width(423);
  24. bks.ReleaseDispatch();
  25. bk.ReleaseDispatch();
  26. isps.ReleaseDispatch();
  27. isp.ReleaseDispatch();
  28. DeleteObject(hMemDc);
  29. DeleteDC(hMemDc);
  30. ReleaseDC(hWnd, hDc);
  31. return TRUE;
  32. }

最后,各个接口的参数可以参考下面的链接:

.net Word office组件接口文档


VC+++ 操作word的更多相关文章

  1. VC操作WORD文档总结

    一.写在开头 最近研究word文档的解析技术,我本身是VC的忠实用户,看到C#里面操作WORD这么舒服,同时也看到单位有一些需求,就想尝试一下,结果没想到里面的技术点真不少,同时网络上的共享资料很多, ...

  2. VC操作Excel之基本操作(颜色等)【转载】

    文章出处https://blog.csdn.net/form88/article/details/78566390 EXCEL里如何知道某种颜色的ColorIndex的值 ===fag::====== ...

  3. python操作word入门

    1.安装pywin32 http://sourceforge.net/projects/pywin32 在files里去找适合你的python版本.截止此文,最新版本是pywin32-219快捷路径: ...

  4. C#中操作Word(1)—— word对象模型介绍

    一.开发环境布置 C#中添加对Word的支持,只需添加对Microsoft.Office.Interop.Word的命名空间,如下图所示,右键点击“引用”,在弹出的“添加引用”对话框中选中COM标签页 ...

  5. C#操作Word的超详细总结

    本文中用C#来操作Word,包括: 创建Word: 插入文字,选择文字,编辑文字的字号.粗细.颜色.下划线等: 设置段落的首行缩进.行距: 设置页面页边距和纸张大小: 设置页眉.页码: 插入图片,设置 ...

  6. C#操作word模板插入文字、图片及表格详细步骤

    c#操作word模板插入文字.图片及表格 1.建立word模板文件 person.dot用书签 标示相关字段的填充位置 2.建立web应用程序 加入Microsoft.Office.Interop.W ...

  7. C#操作Word的辅助类(word2003) 修改完善版

    转自:http://blog.csdn.net/jiutao_tang/article/details/6567608 该类在他人编写的几个类基础上扩展完善而来,主要功能有: (1)插入文本 (2)插 ...

  8. 黄聪:C#操作Word表格的常见操作(转)

    几种常见C#操作Word表格操作有哪些呢?让我们来看看具体的实例演示: bool saveChange = false; //C#操作Word表格操作 object missing = System. ...

  9. c#操作word表格

    http://www.webshu.net/jiaocheng/programme/ASPNET/200804/6499.html <% if request("infoid" ...

随机推荐

  1. saltstack 动态pillar实现

    简介 pillar支持的数据存储方式有很多,mysql, mogo,json等.本篇介绍关于http存储方式. 首先简要说明整个流程:salt-master会去一个指定http发送get请求获取一个j ...

  2. leetcode-482-License Key Formatting

    题目描述: You are given a license key represented as a string S which consists only alphanumeric charact ...

  3. 2016级算法期末模拟练习赛-F.AlvinZH的青春记忆IV

    1086 AlvinZH的青春记忆IV 思路 难题,动态规划. 这是一道很有意思的题,因为它不仅卡了时间,也卡了空间,而且卡的很妙很迷. 光是理解题意已经有点难度,简化题意:两串数字序列,相等的数字定 ...

  4. Java NIO学习与记录(二):FileChannel与Buffer用法与说明

    FileChannel与Buffer用法与说明 上一篇简单介绍了NIO,这一篇将介绍FileChannel结合Buffer的用法,主要介绍Buffer FileChannel的简单使用&Buf ...

  5. java运行时的内存区域

    1.概述 java虚拟机在执行java程序的过程中会把它所管理的内存划分为若干个不同的数据区域. 这些区域都有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而存在,有些区域则依赖用户线 ...

  6. Access network

    1       State transfering A•Mobility:开机-搜寻PLMN/CELL来发现自己在网络中的位置•Attach request•Auth request•Auth res ...

  7. JavaSwing程序设计(目录)

    一.JavaSwing 概述 JavaSwing 图形界面概述 二.JavaSwing 基本组件 JLabel(标签) JButton(按钮) JTextField(文本框) JPasswordFie ...

  8. iterm自动登录ssh脚本

    经常在工作中需要切换到不同的服务器去部署,或者查看日志,每次登录都要去找对应的IP和地址,非常麻烦,最终决定使用iterm2+脚本来实现自动登录. 1.iterm2(下载安装不再介绍http://ww ...

  9. Visual Studio 跨平台開發實戰(5) - Xamarin Android 多頁面應用程式開發 (转帖)

    前言 大部份的Android 都具有實體或虛擬的Back鍵. 因此在處理多頁面應用程式時, 與先前所介紹的iOS Navigation controller 比較起來會簡單許多. 1. 開啟Visua ...

  10. js实现私有变量

    一.块级作用域 js中没有块级作用域的概念,可用匿名函数实现,由于匿名函数执行完一遍后,内部没有引用其变量对象的函数,其变量对象被清除,后面则引用不到其中的变量 (function(){ //块级作用 ...