您的位置:首页 > 编程语言 > C语言/C++

怎么用C++生成WORD文档,详细步骤 - (参考基础上原创)

2010-10-17 02:40 543 查看
(前年11月就说要写这篇技术日志了,一直拖到今天,直到自己觉得再不写会忘掉的时候。唉,现在自己果然是很懒啊,争取以后能一个星期写一篇,我是不是应该到CSDN去写呢?总是感觉在校内写技术日志不伦不类……)
---------------------------------------

首先,把我参考的两个地址放上来,博主写到很好,我这里只是把学到的东西做记录自己备查而已。

用Visual C++操纵MS Word:

http://www.cnblogs.com/scq2099yt/archive/2008/01/07/1028697.html

MFC/VC++调用word进行报表制作:

http://www.cnblogs.com/scq2099yt/archive/2008/01/07/1028717.html

 

其次,说说重点:

重点就是怎么把VBA_Sub MyReporter.bas里的VBA代码转换成WORD.OLE代码,上面的两篇文章写的很好,照着一步一步做就成了。

 

下面,一步一步开始吧:



1. 首先,要打开Word的宏记录功能。

备注:在Word中,使用VBA为脚本的宏,可以使文件具有一定逻辑处理功能。例如自动生成及处理数据等。

 



2. 然后创建一个新宏

 



3. 记录一个宏,在记录好以后,可以对宏进行简单的编辑,想调试看运行结果时,点击“运行”按钮。这一步很重要,在把这个VBA脚本翻译成C++可执行的代码前,这里的逻辑就是最后生成Word文档的逻辑,因此,要仔细调试,把其中没有必要的步骤去除,尽量精简生成文档的步骤。

 

4. 在最终获得一个这样的脚本后,就可以准备开始C++的编程了,这里,贴出我完成的脚本(为了不公开项目里的数据,这里我稍做改动,把数据相关的内容全部替换了)

Sub MyReporter()
    Documents.Add DocumentType:=wdNewBlankDocument ' //生成一个空文档
   
    Selection.TypeText Text:="某某报表" ' //输入第1行内容
    Selection.TypeParagraph ' //换行
    Selection.TypeText Text:="行1:" ' //输入第2行内容
    Selection.TypeParagraph ' //换行
    Selection.TypeText Text:="行2:" ' //输入第3行内容
    Selection.TypeParagraph ' //换行
    Selection.TypeText Text:="行3:" ' //输入第4行内容
    Selection.TypeParagraph ' //换行
    Selection.TypeText Text:="行4:" ' //输入第5行内容
    Selection.TypeParagraph ' //换行
    Selection.TypeText Text:="行5" ' //输入第6行内容
    Selection.TypeParagraph ' //换行
   
    ' //添加一个6行4列的表格,使用默认样式
    ActiveDocument.Tables.Add Range:=Selection.Range, NumRows:=6, NumColumns:= _
        4, DefaultTableBehavior:=wdWord9TableBehavior, AutoFitBehavior:= _
        wdAutoFitFixed
   
    ' //添加表的内容并设置表的格式
    ' //输入表内第1行内容
    Selection.TypeText Text:="列1" ' //输入第1列内容
    Selection.MoveRight Unit:=wdCharacter, Count:=1 ' //向右移动鼠标到下一列
    Selection.TypeText Text:="列2" ' //输入第2列内容
    Selection.MoveRight Unit:=wdCharacter, Count:=1 ' //向右移动鼠标到下一列
    Selection.TypeText Text:="列3" ' //输入第3列内容
    Selection.MoveRight Unit:=wdCharacter, Count:=1 ' //向右移动鼠标到下一列
    Selection.TypeText Text:="列4" ' //输入第4列内容
    ' //输入表内第2行内容
    Selection.Mo
4000
veDown Unit:=wdLine, Count:=1 ' //向下移动鼠标到下一行
    Selection.MoveLeft Unit:=wdCharacter, Count:=3 ' //向左移动鼠标到第1列
    Selection.TypeText Text:="列1" ' //输入第1列内容
    Selection.MoveRight Unit:=wdCharacter, Count:=3 '// 向右移动鼠标到第4列
    Selection.TypeText Text:="列4" ' //输入第4列内容
    ' //输入表内第3行内容
    Selection.MoveDown Unit:=wdLine, Count:=1 ' //向下移动鼠标到下一行
    Selection.MoveLeft Unit:=wdCharacter, Count:=3 ' //向左移动鼠标到第1列
    Selection.TypeText Text:="列1" ' //输入第1列内容
    Selection.MoveRight Unit:=wdCharacter, Count:=1 ' // 向右移动鼠标到第2列
    Selection.TypeText Text:="列2" '//输入第2列内容
    Selection.MoveRight Unit:=wdCharacter, Count:=1 ' // 向右移动鼠标到第3列
    Selection.TypeText Text:="列3" '//输入第3列内容
    Selection.MoveRight Unit:=wdCharacter, Count:=1  ' // 向右移动鼠标到第4列
    Selection.TypeText Text:="列4" '//输入第4列内容
    ' //输入表内第4行内容
    Selection.MoveDown Unit:=wdLine, Count:=1 ' //向下移动鼠标到下一行
    Selection.MoveLeft Unit:=wdCharacter, Count:=3 ' //向左移动鼠标到第1列
    Selection.TypeText Text:="列1" ' //输入第1列内容
    Selection.MoveRight Unit:=wdCharacter, Count:=3 ' //向右移动鼠标到第4列
    Selection.TypeText Text:="列4" ' //输入第4列内容
    ' //输入表内第5行内容
    Selection.MoveDown Unit:=wdLine, Count:=1 ' //向下移动鼠标到下一行
    Selection.MoveLeft Unit:=wdCharacter, Count:=3 ' //向左移动鼠标到第1列
    Selection.TypeText Text:="列1" ' //输入第1列内容
    Selection.MoveRight Unit:=wdCharacter, Count:=3 ' //向右移动鼠标到第4列
    Selection.TypeText Text:="列4" ' //输入第4列内容
    ' //输入表内第6行内容
    Selection.MoveDown Unit:=wdLine, Count:=1 ' //向下移动鼠标到下一行
    Selection.MoveLeft Unit:=wdCharacter, Count:=3 ' //向左移动鼠标到第1列
    Selection.TypeText Text:="列1" ' //输入第1列内容
    Selection.MoveRight Unit:=wdCharacter, Count:=3 ' //向右移动鼠标到第4列
    Selection.TypeText Text:="列4" ' //输入第4列内容
    ' //设置表的格式
    Selection.MoveUp Unit:=wdLine, Count:=5 ' //向上移动鼠标到表的第1行(目前鼠标在第1行第4列最后一个字符后)
    Selection.MoveLeft Unit:=wdCharacter, Count:=15 ' //向左移动鼠标到第1列的第1个字符前
    Selection.MoveDown Unit:=wdLine, Count:=5, Extend:=wdExtend ' //向下选取5行,共选取6行(执行这句后,第1列全部选中)
    Selection.MoveRight Unit:=wdCharacter, Count:=3, Extend:=wdExtend ' //向右选取3列,共选取4列(执行这句后,整个表被选中)
    Selection.ParagraphFormat.Alignment = wdAlignParagraphCenter ' //设置对齐方式为“居中”
   
    ' //开始设置表以前内容的格式
    Selection.MoveUp Unit:=wdLine, Count:=1 ' //向上移动鼠标到上一行
    Selection.ParagraphFormat.Alignment = wdAlignParagraphCenter '//设置此行为“居中”格式 
    Selection.MoveUp Unit:=wdLine, Count:=5 '// 向上移动鼠标到第1行
    Selection.ParagraphFormat.Alignment = wdAlignParagraphCenter '//设置标题行为“居中”格式
    Selection.EndKey Unit:=wdLine ' //将鼠标定位到第1行末
    Selection.HomeKey Unit:=wdLine, Extend:=wdExtend ' //将鼠标定位到第1行首,同时选取整行
    Selection.Font.Bold = wdToggle ' //设置标题行为“粗体”   
    Selection.Font.Size = 15 ' //设置标题行字号为15(小三号)
    Selection.MoveDown Unit:=wdLine, Count:=1 ' //向下移动鼠标到正文第1行
    Selection.HomeKey Unit:=wdLine ' //将鼠标定位到正文第1行首,(第2行行首)
    Selection.MoveDown Unit:=wdLine, Count:=11, Extend:=wdExtend ' //向下选取除标题行外的全部内容
    Selection.Font.Size = 12 ' //设置字号为12(小四号)
    Selection.WholeStory '// 选取全部内容
    Selection.Font.Name = "宋体" '// 设置全部内容为“宋体”
   
    ' //保存文件为《某某报表.doc》到默认位置,WORD的默认路径是“我的文档”
    ActiveDocument.SaveAs FileName:="某某报表.doc", FileFormat:= _
        wdFormatDocument, LockComments:=False, Password:="", AddToRecentFiles:= _
        True, WritePassword:="", ReadOnlyRecommended:=False, EmbedTrueTypeFonts:= _
        False, SaveNativePictureFormat:=False, SaveFormsData:=False, _
        SaveAsAOCELetter:=False
       
    ' 退出程序,关闭Word
    Application.Quit
End Sub

 

5. 这就是最后一步了,就是把上面的VBA编程C++可执行的代码。当然,在生成这个工程的时候,一定要添加外部的库,这里,在MFC中操作WORD2003的库使用的是 MSWORD.OLB ,一般情况下,可以在OFFICE所在的文件夹下,通过搜索获得。对于如何添加这个外部链接库,这里不做记录了,会MFC的人,这个是基本功。那么在生成MFC工程后,把上面的VBA代码,一条一条翻译成C++的代码就行了,以下是翻译的结果:

(把以下代码放到一个事件中,比如对一个Button的单击响应事件中,就可以运行了)

 //****待用的操作WORD的 常量
 const int wdCharacter = 1;
 const int wdLine = 5;
 const int wdAlignParagraphCenter = 1;
 const int wdExtend = 1;
 const int wdToggle = 9999998;
 const int wdFormatDocument = 0;
 const int wdWord9TableBehavior = 1;
  const int wdAutoFitFixed = 0;
 const int wdNULL = 0;
 const int wdNewBlankDocument = 0;
 const int wdWindowStateMinimize = 2;

 //****待用的操作WORD的 变量
 _Application wordApp;
    Documents wordDocs;
    _Document wordDoc;
    Selection wordSelection;
 Range wordRange;
 Tables wordTables;
 Table wordTable;
 Cell wordCell;
 Cells wordCells;
 _Font wordFont;
 Shading wordShading;
 Paragraphs wordParagraphs;

 //****创建word application实例,失败的话返回false
 if (!wordApp.CreateDispatch(_T("Word.Application")))
 {
  AfxMessageBox("Word CreateDispatch Failed!");  //显示错误信息
  return FALSE; //返回false
 }    
 
 wordDocs=wordApp.GetDocuments();//获得 documents 实例 

 //****添加新的空白文档(调用COM)
 //(参考自:http://www.cnblogs.com/scq2099yt/archive/2008/01/07/1028717.html
 CComVariant tpl(_T("")),Visble,DocType(0),NewTemplate(false);
 wordDoc=wordDocs.Add(&tpl,&NewTemplate,&DocType,&Visble);
 wordSelection=wordApp.GetSelection(); //获得 wordSelection 实例

 //****添加文字 
 wordSelection.TypeText("某某报表"); //输出1行
 wordSelection.TypeParagraph(); //换行
 wordSelection.TypeText("行1:"); //输出2行
 wordSelection.TypeParagraph(); //换行
 wordSelection.TypeText("行2:");  //输出3行
 wordSelection.TypeParagraph(); //换行
 wordSelection.TypeText("行3:"); //输出4行
 wordSelection.TypeParagraph(); //换行
 wordSelection.TypeText("行4:"); //输出5行
 wordSelection.TypeParagraph(); //换行
 wordSelection.TypeText("行5"); //输出6行
 wordSelection.TypeParagraph(); //换行
 
 //****插入表格
 wordTables=wordDoc.GetTables(); //获得表格
 wordRange = wordSelection.GetRange();
 //添加一个6行4列的表格,使用默认样式
 wordTables.Add(wordRange,
  6, // 行数
  4, // 列数
  COleVariant((short)wdWord9TableBehavior),
  COleVariant((short)wdAutoFitFixed));
 /*** 注意 COleVariant((short)XXX) 这个方法可以把int型转换为 VARIANT* 类型 ***/
 
 //添加表的内容并设置表的格式
 //输入表内第1行内容
 wordSelection.TypeText("列1"); //输入第1列内容
 wordSelection.MoveRight(COleVariant((short)wdCharacter),
  COleVariant((short)1),
  COleVariant((short)wdNULL)); //向右移动鼠标到下一列
 wordSelection.TypeText("列2"); //输入第2列内容
 wordSelection.MoveRight(COleVariant((short)wdCharacter),
  COleVariant((short)1),
  COleVariant((short)wdNULL)); //向右移动鼠标到下一列
 wordSelection.TypeText("列3"); //输入第3列内容
 wordSelection.MoveRight(COleVariant((short)wdCharacter),
  COleVariant((short)1),
  COleVariant((short)wdNULL)); //向右移动鼠标到下一列
 wordSelection.TypeText("列4"); //输入第4列内容 
 //输入表内第2行内容
 wordSelection.MoveDown(COleVariant((short)wdLine),
  COleVariant((short)1),
  COleVariant((short)wdNULL)); //向下移动鼠标到下一行
 wordSelection.MoveLeft(COleVariant((short)wdCharacter),
  COleVariant((short)3),
  COleVariant((short)wdNULL)); //向左移动鼠标到第1列
    wordSelection.TypeText("列1"); //输入第1列内容   
 wordSelection.MoveRight(COleVariant((short)wdCharacter),
  COleVariant((short)3),
  COleVariant((short)wdNULL)); //向右移动鼠标到第4列
 wordSelection.TypeText("列4"); //输入第4列内容
 //输入表内第3行内容
 wordSelection.MoveDown(COleVariant((short)wdLine),
  COleVariant((short)1),
  COleVariant((short)wdNULL)); //向下移动鼠标到下一行
 wordSelection.MoveLeft(COleVariant((short)wdCharacter),
  COleVariant((short)3),
  COleVariant((short)wdNULL)); //向左移动鼠标到第1列
    wordSelection.TypeText("列1"); //输入第1列内容   
 wordSelection.MoveRight(COleVariant((short)wdCharacter),
  COleVariant((short)1),
  COleVariant((short)wdNULL)); //向右移动鼠标到第2列
 wordSelection.TypeText("列2"); //输入第2列内容
 wordSelection.MoveRight(COleVariant((short)wdCharacter),
  COleVariant((short)1),
  COleVariant((short)wdNULL)); //向右移动鼠标到第3列
 wordSelection.TypeText("列3"); //输入第3列内容
 wordSelection.MoveRight(COleVariant((short)wdCharacter),
  COleVariant((short)1),
  COleVariant((short)wdNULL)); //向右移动鼠标到第4列
 wordSelection.TypeText("列4"); //输入第4列内容
 //输入表内第4行内容
 wordSelection.MoveDown(COleVariant((short)wdLine),
  COleVariant((short)1),
  COleVariant((short)wdNULL)); //向下移动鼠标到下一行
 wordSelection.MoveLeft(COleVariant((short)wdCharacter),
  COleVariant((short)3),
  COleVariant((short)wdNULL)); //向左移动鼠标到第1列
    wordSelection.TypeText("列1"); //输入第1列内容   
 wordSelection.MoveRight(COleVariant((short)wdCharacter),
  COleVariant((short)3),
  COleVariant((short)wdNULL)); //向右移动鼠标到第4列   
 wordSelection.TypeText("列4"); //输入第4列内容
 //输入表内第5行内容
 wordSelection.MoveDown(COleVariant((short)wdLine),
  COleVariant((short)1),
  COleVariant((short)wdNULL)); //向下移动鼠标到下一行
 wordSelection.MoveLeft(COleVariant((short)wdCharacter),
  COleVariant((short)3),
  COleVariant((short)wdNULL)); //向左移动鼠标到第1列
    wordSelection.TypeText("列1"); //输入第1列内容   
 wordSelection.MoveRight(COleVariant((short)wdCharacter),
  COleVariant((short)3),
  COleVariant((short)wdNULL)); //向右移动鼠标到第4列   
 wordSelection.TypeText("列4"); //输入第4列内容
 //输入表内第6行内容
 wordSelection.MoveDown(COleVariant((short)wdLine),
  COleVariant((short)1),
  COleVariant((short)wdNULL)); //向下移动鼠标到下一行
 wordSelection.MoveLeft(COleVariant((short)wdCharacter),
  COleVariant((short)3),
  COleVariant((short)wdNULL)); //向左移动鼠标到第1列
    wordSelection.TypeText("列1"); //输入第1列内容   
 wordSelection.MoveRight(COleVariant((short)wdCharacter),
  COleVariant((short)3),
  COleVariant((short)wdNULL)); //向右移动鼠标到第4列
 wordSelection.TypeText("列4"); //输入第4列内容
 //设置表的格式
 wordSelection.MoveUp(COleVariant((short)wdLine),
  COleVariant((short)5),
  COleVariant((short)wdNULL)); //向上移动鼠标到表的第1行(目前鼠标在第一行第4列最后一个字符后)
 wordSelection.MoveLeft(COleVariant((short)wdCharacter),
  COleVariant((short)15),
  COleVariant((short)wdNULL)); //向左移动鼠标到第1列的第1个字符前
 wordSelection.MoveDown(COleVariant((short)wdLine),
  COleVariant((short)5),
  COleVariant((short)wdExtend)); //向下选取5行,共选取6行(执行这句后,第1列全部选中)
 wordSelection.MoveRight(COleVariant((short)wdCharacter),
  COleVariant((short)3),
  COleVariant((short)wdExtend)); //向右选取3列,共选取4列(执行这句后,整个表被选中)
 wordParagraphs = wordSelection.GetParagraphFormat(); //获得对齐方式实例
 wordParagraphs.SetAlignment(wdAlignParagraphCenter); //设置表中的全部内容为“居中”
   
 //开始设置表以前内容的格式
 wordSelection.MoveUp(COleVariant((short)wdLine),
  COleVariant((short)1),
  COleVariant((short)wdNULL)); //向上移动鼠标到上一行
    wordParagraphs = wordSelection.GetParagraphFormat(); //获得对齐方式实例
 wordParagraphs.SetAlignment(wdAlignParagraphCenter); //设置此行为“居中”格式
    wordSelection.MoveUp(COleVariant((short)wdLine),
  COleVariant((short)5),
  COleVariant((short)wdNULL)); // 向上移动鼠标到第1行
 wordParagraphs = wordSelection.GetParagraphFormat(); //获得对齐方式实例
 wordParagraphs.SetAlignment(wdAlignParagraphCenter); //设置标题行为“居中”
 wordSelection.EndKey(COleVariant((short)wdLine),
  COleVariant((short)wdNULL)); //将鼠标定位到第1行末
 wordSelection.HomeKey(COleVariant((short)wdLine),
  COleVariant((short)wdExtend)); //将鼠标定位到第1行末
 wordFont = wordSelection.GetFont(); //获得字体实例
 wordFont.SetBold(wdToggle); //设置标题行为“粗体”    
 wordFont.SetSize(15.0); //设置标题行字号为15(小三号)
 wordSelection.MoveDown(COleVariant((short)wdLine),
  COleVariant((short)1),
  COleVariant((short)wdNULL)); //向下移动鼠标到正文第1行
 wordSelection.HomeKey(COleVariant((short)wdLine),
  COleVariant((short)wdNULL)); //将鼠标定位到正文第1行首,(第2行行首)
 wordSelection.MoveDown(COleVariant((short)wdLine),
  COleVariant((short)11),
  COleVariant((short)wdExtend)); //向下选取除标题行外的全部内容
 wordFont = wordSelection.GetFont(); //获得字体实例
 wordFont.SetSize(12.0); //设置标题行字号为12(小四号)
 wordSelection.WholeStory(); // 选取全部内容
 wordFont = wordSelection.GetFont(); //获得字体实例
 wordFont.SetName("宋体"); //设置全部内容为“宋体”

 //保存文件为《某某报表.doc》到默认位置,和此程序在一起
 CString fileName = "//某某报表.doc";
 CString fullFileName = GGetAppPath() + fileName;
 wordDoc.SaveAs(COleVariant(fullFileName), //FileName
  COleVariant((short)wdFormatDocument), //FileFormat
  COleVariant((short)FALSE), //LockComments
  COleVariant(""), //Password
  COleVariant((short)FALSE), //AddToRecentFiles
  COleVariant(""), //WritePassword
  COleVariant((short)FALSE), //ReadOnlyRecommended
  COleVariant((short)FALSE), //EmbedTrueTypeFonts
  COleVariant((short)FALSE), //SaveNativePictureFormat
  COleVariant((short)FALSE), //SaveFormsData
  COleVariant((short)FALSE), //SaveAsAOCELetter
  COleVariant((short)wdNULL), //Encoding
  COleVariant((short)FALSE), //InsertLineBreaks
  COleVariant((short)FALSE), //AllowSubstutitions,
  COleVariant((short)wdNULL), //LineEnding
  COleVariant((short)wdNULL) //AddBiDiMarks
  );
 
 //退出程序,关闭Word
 wordApp.Quit(COleVariant((short)wdNULL),
  COleVariant((short)wdNULL),
  COleVariant((short)wdNULL));

 return TRUE; // 生成成功,返回TRUE

 

6. 最后,编译,调试,运行,哈哈,最后,我生成了一个这样的表:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息