原创 vc中对word的操作

2011-3-18 11:51 5795 11 11 分类: 软件与OS

最近程序中涉及到对word的操作,生成检测报告,摸索了一个多星期。查找到了些资料,学到了些方法:第一:操作word必须要做的步骤;第二:巧妙的方法;第三:现成的操作实例。


第一:操作word必须要做的步骤


为了更有逻辑,更有层次地操作 Office,Microsoft 把应用(Application)按逻辑功能划分为如下的树形结构


Application(WORD 为例,只列出一部分)


Documents(所有的文档)


Document(一个文档)


......


Templates(所有模板)


Template(一个模板)


......


Windows(所有窗口)


Window


Selection


View


Selection(编辑对象)


Font


Style


Range


......


......


只有了解了逻辑层次,我们才能正确的操纵 Office。举例来讲,如果给出一个VBScript语句是:


application.ActiveDocument.SaveAs "c:\abc.doc" 那么,我们就知道了,这个操作的过程是:第一步,取得Application;第二步,从Application中取得ActiveDocument;第三步,调用 Document 的函数 SaveAs,参数是一个字符串型的文件名。


1)基本步骤


(1)创建(或打开已有的)一个 MFC 的程序工程


(2)Ctrl+W 执行 ClassWizard(本文按照 VC6 操作,例子程序也是在VC6 下编写测试的)


(3)Add Class...\From a type Library... 在 Office 目录中,找到你想使用的类型库。(我使用的是 Office2000,其Word 的类型库文件,保存在 C:\Program Files\Microsoft Office\Office\MSWORD9.OLB)根据你 Office 的版本,可以使用下表列出的类型库文件




Office 版本和类型


类型库文件


Office 版本和类型


类型库文件


Access 97


Msacc8.olb


PowerPoint 2000


Msppt9.olb


Jet Database 3.5


DAO350.dll


Word 2000


Msword9.olb


Binder 97


Msbdr8.olb


Access 2002


Msacc.olb


Excel 97


Excel8.olb


Excel 2002


Excel.exe


Graph 97


Graph8.olb


Graph 2002


Graph.exe


Office 97


Mso97.dll


Office 2002


MSO.dll


Outlook 97


Msoutl97.olb


Outlook 2002


MSOutl.olb


PowerPoint 97


Msppt8.olb


PowerPoint 2002


MSPpt.olb


Word 97


Msword8.olb


Word 2002


MSWord.olb


Access 2000


Msacc9.olb


Office Access 2003


Msacc.olb


Jet Database 3.51


DAO360.dll


Office Excel 2003


Excel.exe


Binder 2000


Msbdr9.olb


Graph 2003


Graph.exe


Excel 2000


Excel9.olb


Office 2003


MSO.dll


Graph 2000


Graph9.olb


Office Outlook 2003


MSOutl.olb


Office 2000


Mso9.dll


Office PowerPoint 2003


MSPpt.olb


Outlook 2000


Msoutl9.olb


Office Word 2003


MSWord.olb


(4)选择类型库文件后,在弹出的对话窗中继续选择要添加的类。具体选择什么类,要看你将来在程序中打算调用什么功能。当然,你也可以不用考虑这么多,用鼠标和Shift键配合,全部选择也可以。


(5)初始化COM。方法一,找到App的InitInstance()函数,在其中添加 AfxOleInit()函数的调用;方法二,在需要调用COM功能的地方 CoInitialize(NULL),调用完毕后 CoUninitialize()。


(6)在你需要调用 Office 功能函数的 cpp 文件中


#include <atlbase.h> // 为了方便操作 VARIANT 类型变量,使用CComVariant 模板类
#include "头文件.h"
// 具体的头文件名,是由装载类型库的文件名决定的。(鼠标双点包装类的文件,就可以看到)
// 比如使用 msword9.olb类型库,那么头文件是 msword9.h


(7)好了,现在开始写程序吧。另外要说明的是,步骤3和4,其实也可以使用 #import 方式引入类型库。


第二:巧妙的方法


在书写调用 Office 函数的过程中,最困难的是确定函数的参数,一般情况下,参数都是 VARIANT 类型的变量指针。那么到底具体我们应该怎么写那?推荐两个方法,其一是阅读有关 VBA 的书籍;其二,是使用 Office 中自带的“宏”功能。强烈推荐大家使用第二个方法,把你要完成的功能,在 Office 的操作环境中,用宏录制下来,然后观察分析录制后的函数和参数,就可以在 VC 中使用了。举一个例子:


ActiveDocument.SaveAs FileName:="Hello.doc", FileFormat:=wdFormatDocument _


, LockComments:=False, Password:="", AddToRecentFiles:=True, _


WritePassword:="", ReadOnlyRecommended:=False, EmbedTrueTypeFonts:=False, _


SaveNativePictureFormat:=False, SaveFormsData:=False, SaveAsAOCELetter:= _False


以上是在 Word 中录制的一个保存文件的宏,而在 VC 中对应的函数原型为 void _Document::SaveAs(VARIANT* FileName, VARIANT* FileFormat, VARIANT* LockComments,
VARIANT* Password, VARIANT* AddToRecentFiles, VARIANT* WritePassword,
VARIANT* ReadOnlyRecommended, VARIANT* EmbedTrueTypeFonts, VARIANT* SaveNativePictureFormat,
VARIANT* SaveFormsData, VARIANT* SaveAsAOCELetter)


分析对照后,我们就能看出,参数 FileName 是字符串 VARIANT(VT_BSTR),参数 LockComments 是布尔VARIANT(VT_BOOL),等等。参数 FileFormat := wdFormatDocument 是什么类型那?其实这是一个表示保存的时候指定文件类型的常量,而且显然是 DWORD 类型VARIANT(VT_I4)。那么常量的数值又是多少那?很简单,写一个宏,调用函数 MsgBox 显示一下不就都知道啦?!


上面的内容摘自:http://www.cnblogs.com/scq2099yt/archive/2008/01/07/1028697.html


下面的是另外一个:


http://blog.sciencenet.cn/home.php?mod=space&uid=43777&do=blog&id=318939


汪志军的关于技巧方面的经验:


第一步:主要利用VBA的录制宏功能,把想要的功能以VB代码呈现在眼前。打开宏录制,设置表格的底纹,然后停止宏录制。



打开上边Visual Basic这个,就可以看到宏代码了。



倒数第三行设置底纹图案的,倒数两行分别设置前景色和背景色。


 


    第二步,现在我装要设置CWzjOffice3.0例子中的最后一个表格的底纹,找到函数void CWzjWordTestDlg::OnButton1()


在wd.WriteCellText(2,4,"湖北"); 后面增加以下代码



在VB中函数的参数好多是用常量来表示的,但是在VC中不好使。但是可以直接用那些常量的值,在VB中调试运行再次运行宏代码的时候,查看一下常量的值就可以了,再在VC中用直接使用数值即可。


这里用到了一个新的类,Shading,我们需要加入。


   


    第三步,在VC例子中加入新的word类(Shading)


在VC中打开类向导,Add Class/ From a type library/选上MSWORD.OLB/找到Shading类,确定增加此类



再运行一下,如何,最后一个表格有底纹了吧



 


CWzjOffice类不可能满足所有朋友的需求,所以通常需要根据自己的要求改进。但是作者不可能也没有精力一一改进。其他的功能,按照上面的三步一般来说都可以改进出来的。所以大家自己动手,丰衣足食的好。


第三:现成的操作实例


         经过上面的摸索感觉想操作WORD做出一个理想的报告文档出来还是有些麻烦,通过搜索找到汪志军(感谢他的分享)和其他人提供的类,由于时c++写的,它把对word的操作都封装到函数中了。


提供了CWordTable//表格操作类和class CWordWriter//word操作类。


操作过程:


         CString picPath = "D:\\document\\Soft\\vc\\BiMagnetometer\\Debug\\nchulogo.bmp";//这里需要注意的是“\”要用双斜线"\\"


         CString strOutput;


         CWordWriter wd;


         wd.Create();


         wd.ShowApp();


         wd.SetAlignment(1); //设置文字为居中对齐


         wd.InsertShapes(picPath);


         wd.NewLine(1); //回车换行


//检测报告


         wd.SetFont(25,"魏碑",RGB(128, 0, 0)); //设置字体(字号,字体名,颜色)


         wd.SetFont(1,0,0); //设置字体为粗体,不是斜体,没有下划线


         wd.WriteText("检 测 报 告"); //写文字


//检测设备,及时间


         wd.NewLine(1); //回车换行


         wd.SetAlignment(CWordWriter::Align_Left); //设置文字为左对齐


         wd.SetFont(12,"宋体",RGB(128, 0, 0)); //设置字体(字号"小四",字体名,颜色)


 


         SYSTEMTIME sysTime;


         GetLocalTime(&sysTime);


        


         CString strReportTime;


        


         strReportTime.Format("检测时间%d年-%d月-%d日",sysTime.wYear,sysTime.wMonth,sysTime.wDay);


        


         wd.WriteText("仪器型号:应力集中测试仪\t\t\t"); //写文字


         wd.WriteText(strReportTime); //写时间


         wd.MoveDown(1);


         //设置表格字体


         wd.SetFont(12, "宋体"); //小四


    wd.SetFont(0,0,0);//设置字体为非粗体


    wd.InsertTable(3,1); //创建一个3行1列的表格


         //第一行第一列中第一行的字符


         strOutput.Format("工件长度:%f mm\t\t\t检测距离:%f mm",m_Length,m_distance);


         wd.WriteCellText(1,1,strOutput);


         strOutput.Format("检测方法:磁记忆");


         wd.WriteNewLineText(strOutput,1);


         CWordTable cdfTb = wd.GetWordTable(1); // 操作第1个表


         cdfTb.SelectCell(1,1);


         cdfTb.SetBdLSty(TBBD::BorderLeft, TBBD::wdLineStyleNone);


         cdfTb.SetBdLSty(TBBD::BorderRight, TBBD::wdLineStyleNone);  


         //      wzjTb.SetBordersVis(FALSE); //边框全部隐藏


         cdfTb.SelectCell(2,1);


         cdfTb.SetBdLSty(TBBD::BorderLeft, TBBD::wdLineStyleNone);


         cdfTb.SetBdLSty(TBBD::BorderRight, TBBD::wdLineStyleNone);


         strOutput = "";


         wd.WriteNewLineText(strOutput,10);


         cdfTb.SelectCell(3,1);


         cdfTb.SetBdLSty(TBBD::BorderLeft, TBBD::wdLineStyleNone);


         cdfTb.SetBdLSty(TBBD::BorderRight, TBBD::wdLineStyleNone);  


         strOutput = "";


         wd.WriteNewLineText(strOutput,10);


         wd.MoveDown(1);


         strOutput.Format("%d:%d \t\t\\t\t检测人:",sysTime.wHour,sysTime.wMinute);


         wd.WriteText(strOutput);


 


         //文件保存


         CString strPath;


        


         char szFullPath[_MAX_PATH];


        


         ::GetModuleFileName(NULL,szFullPath,_MAX_PATH);//获取一个已装载模板的完整路径名称 hModule HMODULE 装载一个程序实例的句柄。如果该参数为NULL,该函数返回该当前应用程序全路径。   lpFileName LPTSTR 是你存放返回的名字的内存块的指针,是一个输出参数   nSize DWORD ,装载到缓冲区lpFileName的最大值


        


         ::PathRemoveFileSpecA(szFullPath);


 


         strPath.Format("%s\\检测报告_%d_%d_%d_%d",szFullPath,sysTime.wMonth,sysTime.wDay,sysTime.wHour,sysTime.wMinute);


 


         wd.SaveDocumentAs(strPath);


 


得到这样一份报告:


 attachment download


 


 


 


 


 


 


 



  检 测 报 告


仪器型号:应力集中检测仪                                        检测时间:




 


 


 


 


 


 


 


 


 


 


 


 


 


 


 


缺陷评价:


 


 


 


 


 


 


 


 


 


 


 


 


 


 


 


 


 


 


                                                  检测人:

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
11
关闭 站长推荐上一条 /1 下一条