首页 文学文摘 时政新闻 科技科普 经济法律 健康生活 管理财经 教育教学 文化艺术 社科历史

通过VC程序操纵Word的实现方法

作者:张雪咏 马红涛 赵建峰 来源:电子技术与软件工程

摘 要本文介绍了通过Visual C++操纵Word的思想,通过实例演示了具体的方法和步骤,实现了将记事本格式的文件通过VC软件自动写入Word文档,可以显著提高工作效率。

【关键词】VC 操纵Word

我们在做保护装置功能测试时,程序根据测试用例生成的测试结果是记事本格式,而我们要提交的报告是Word文档。以前我们在写测试报告时,总是手工将测试用例及结果输入到Word表格中,因为测试用例可能比较多,而且正式报告中的要求的表格格式和程序生成的记事本文档中的测试结果格式不太一致, 这样做有两个缺点:1、浪费时间。2、容易出错。鉴于此,开发了一个转换程序,这个转换程序可以对记事本文档中的测试结果进行分析,再将其自动输入到Word中去。

1 实现基础

Word本身是一个实现了自动化的COM(Component Object Model)组件,它提供给我们很多接口,我们可以通过它对外提供的编程接口来访问和操作Word文档,为我们通过VC等软件编写的程序服务。

我们可以通过两种方式来在VC中操纵Word:

(1)使用Office自带的类型库。

(2)使用COM的Automation技术。

我们做的该转换程序用第一种方法在VC中操纵Word,即使用Office自带的类型库。下面简单介绍一下类型库:

Word本身提供了一个文件,叫做对象库(Object library)或类型库(Type library),里边包含了有关的对象、属性、方法和事件,以及应用程序的常量信息。我们可以通过对象浏览器(Object Browser或 OLEView)工具来在此文件中查看信息,以及浏览它所描述的对象。我们可以通过导出Word对象库,在自己编写的程序中调用。

2 Office层次结构

为了逻辑更清晰,层次更清楚的操作Office,微软将Office按逻辑功能划分为如下所示的属性结构:

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

Documents(所有的文档)

Document(单个的文档)

......

Templates(所有的模板)

Template(单个的模板)

......

Windows(所有的窗口)

Window(单个窗口)

Selection(编辑对象)

View(视图)

Selection(编辑对象)

Font(字体)

Style(格式)

Range(范围)

......

......

熟悉逻辑层次之后,就可以正确操作Office了。举一个简单的例子,如果给出的VB脚本语句(该语句可通过录制宏获取)为:

application.ActiveDocument.SaveAs "D:\test.doc"

从这个语句我们可以看出该操作过程分以下步骤:

(1)获取Application对象;

(2)从Application对象中取得ActiveDocument活动文档属性;

(3)调用Document的“另存为”函数SaveAs,参数为字符串类型的文件名称。

下面简单介绍一下“宏”,因为“宏”在完成这个转换程序过程中起到了很大的作用。在WORD中(以Office2010为例),调出菜单“视图\宏\录制宏(R)”,这时候它将开始记录你在 WORD 中所有菜单和键盘的操作,把所有的操作过程保存起来。这些宏是VB脚本程序,将其转换为VC代码,便可在VC程序中实现对Word的操作,如图1所示。

3 基本操作步骤

(1)通過VC应用程序向导创建一个 MFC 的程序工程。

(2)使用Ctrl+W快捷键打开ClassWizard类向导。

(3)点击”Add Class...”,从下拉菜单中选择”From a type Library...”,在 Office安装目录中找到需要使用的类型库。

(4)选择类型库文件后,在弹出的对话窗中继续按照功能选择需要添加的类。也可以不考虑,全部添加进去。

(5)对COM进行初始化。第一种方法,找到应用程序对象App的InitInstance()函数,在其中调用 AfxOleInit()初始化函数;第二种方法,在需要调用COM功能的程序入口地方使用CoInitialize(NULL),调用结束后使用CoUninitialize()。

(6)在需要调用 Office 功能函数的 cpp实现文件中包含相关头文件

#include //为方便操作 VARIANT类型的变量,需使用CComVariant模板类

#include "XXX.h" //具体头文件名称,由装载类型库的文件名决定。

//如使用 msword.olb类型库,头文件为msword.h(实现在一doc文件中插入另一个word文件)

(7)开始在VC程序中调用Word的功能。

4 举例说明

4.1 通过接口函数对Word进行操作时使用的数据类型

转换程序通过接口对Word进行操作(即通过接口使用组件)时,应使用的数据类型说明如下:

Word是一个实现了自动化的COM组件。COM产生的目的之一就是跨语言,它使用的数据类型应该具有跨语言的特性,而VARIANT数据类型正具有这种特性。从C语言的角度讲,VARIANT其实是一个结构,结构中用一个域表示该变量是什么类型的数据,同时真正的数据存在Union空间中。举例说明如下:

(1)用VARIANT表示一个4字节长的整数

VARIANT vtest1; vtest1.vt=VT_I4; vtest1.Val=100;

(2)用 VARIANT 表示布尔值“真”

VARIANT vtest2; vtest2.vt=VT_BOOL; vtest2.boolVal=VARIANT_TRUE;

(3)用VARIANT表示字符串

VARIANT vtest3; vtest3.vt=VT_BSTR; vtest3.bstrVal=SysAllocString(L"Hello,Word已经打开了");

上面的操作过程看起来很麻烦,我们可以使用已有的包装类CComVariant、COleVariant、_variant_t。上面几个问题可以书写成这样:

CComVariant vtest1(100),vtest2(true),vtest3("Hello, Word已经打开了");

在该转换程序中,通过接口使用组件时,就是用的包装类CComVariant。

4.2 实现中的技巧

在书写调用Office函数的过程中,函数的参数较难确定,通常参数均为VARIANT变体类型指针,具体应如何确定呢?推荐两种方法:第一种是查阅有关VBA相关书籍;第二种是查看Office自带“宏”功能,本文推荐采用第二种方法,将需要实现的功能,在Office环境中操作,通过宏录制下来,分析录制后的函数和参数,就可以在VC程序中进行使用了。举一个简单例子:

以下是在Word2010中录制的另存文件的宏:

ActiveDocument.SaveAs2 FileName:="test.docx", FileFormat:= _wdFormatXMLDocument, LockComments:=False, Password:="", AddToRecentFiles _:=True, WritePassword:="", ReadOnlyRecommended:=False, EmbedTrueTypeFonts _:=False, SaveNativePictureFormat:=False, SaveFormsData:=False, _SaveAsAOCELetter:=False, CompatibilityMode:=14

该宏在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, VARIANT* Encoding, VARIANT* InsertLineBreaks, VARIANT* AllowSubstitutions, VARIANT* LineEnding, VARIANT* AddBiDiMarks)

将以上内容对照分析后,我们可以看出来,第一个参数 FileName是字符串类型 VARIANT(VT_BSTR), 第二个参数 FileFormat:= _wdFormatXMLDocument为表示保存时指定文件类型的常量,是 DWORD 双字类型VARIANT(VT_I4),常量的数值可写成一个宏,通过调用函数AfxMessageBox显示就能够知道,第三个参数LockComments是布尔类型VARIANT(VT_BOOL)等等。

5 程序实现

此转换程序分为两个模块:

5.1 数据准备模块,此模块提供了准备向Word输入的数据

为了将记事本文件中的测试用例转化为预期格式,必须通过分析记事本中测试用例数据获得以下信息:

(1)测试用例名称----保存在类成员变量TestName中。

(2)结果文件名称----保存在类成员变量strFileName中。

(3)被测模块参数个数----保存在类成员变量paraNum中。

(4)被测模块输出结果个数----保存在类成员变量resulAnticipated中。

(5)测试用例长度----保存在类成员变量caseLength中。

(6)測试用例数目----保存在类成员变量caseNum中。

(7)正常测试用例个数----保存在类成员变量NormalTestNum中。

(8)边界测试用例个数----保存在类成员变量BorderTestNum中。

(9)异常测试用例个数----保存在类成员变量ExcepTestNum中。

(10)测试用例数据----保存在类成员变量TestCase字符串数组中。

5.2 Word操作模块,此模块用准备好的数据对Word进行操作

//打开模版

CComVariant FileName(lpBuffer);

CComVariant ConfirmConversions(false), ReadOnly(false), AddToRecentFiles(false), PasswordDocument(_T("")),

PasswordTemplate(_T("")),Revert(false), WritePasswordDocument(_T("")), WritePasswordTemplate(_T("")),Format(0),Encoding,Visible,OpenAndRepair(0),DocumentDirection,NoEncodingDialog,XMLTransform(_T(""));

docs.Open(&FileName,&ConfirmConversions,&ReadOnly,&AddToRecentFiles,&PasswordDocument,&PasswordTemplate,&Revert,&WritePasswordDocument,&WritePasswordTemplate,&Format,&Encoding,&Visible,&OpenAndRepair,&DocumentDirection,&NoEncodingDialog,&XMLTransform);

//替换模块名称

CComVariant FindText3(moduluName);

CComVariant ReplaceWith3(TestName);

CComVariant MatchCase3(false), MatchWholeWord3(false), MatchWildcards3(false),MatchSoundsLike3(false), MatchAllWordForms3(false), Forward3(true), Wrap3(1), Format3(false), Replace3(2), MatchKashida3,MatchDiacritics3,MatchAlefHamza3, MatchControl3;

find3.Execute(&FindText3,&MatchCase3,&MatchWholeWord3,&MatchWildcards3,&MatchSoundsLike3,&MatchAllWordForms3,&Forward3,&Wrap3,&Format3,&ReplaceWith3,&Replace3,&MatchKashida3,&MatchDiacritics3,&MatchAlefHamza3,&MatchControl3);

//保存测试报告

CComVariant FileName6(lpBuffer);

CComVariant FFormat6(0); CcomVariant LComments6(false),PW6(_T(""));

CComVariant AddToRecentFiles6(true),WritePW6(_T(""));

CComVariant ReadOnlyRecommended6(false),EmbedTrueTypeFonts6(false);

CComVariant SaveNPictureFormat6(false),SaveFormData6(false);

CComVariant SaveAsAOCEL6(false);

CComVariant Encoding6, InsertLBreaks6, AllowSub6, LineEnding6, AddBiDiMarks6;

saveDoc.SaveAs(&FileName6,&FFormat6,&LComments6,&PW6,&AddToRecentFiles6,&WritePW6,&ReadOnlyRecommended6,

&EmbedTrueTypeFonts6,&SaveNPictureFormat6,&SaveFormData6,&SaveAsAOCEL6,&Encoding6,&InsertLBreaks6,&AllowSub6,&LineEnding6,&AddBiDiMarks6);

CComVariant SaveCHG(false),ORGFormat,RDocument;

saveDoc.Close(&SaveCHG, &ORGFormat, &RDocument);

如图2、3所示。

6 结束语

本文通过VC对Word的操纵,实现了将记事本格式内容自动写入Word格式文件中,简化了报告的填写过程,极大的提高了工作效率。

参考文献

[1]朱敏,沈同圣,王学伟,周晓东.VC++与VBA结合实现复杂报表[J].计算机应用与软件,2005(02).

[2]熊瑜容,柴毅,王淑娟,王嘉骐.基于VC++的Word文档自动生成技术[J].计算机时代,2010(01).

[3]陈特放,方斌.VC平台下基于OLE的Word自动化操作应用[J].计算机应用与软件,2009(09).

[4]王怒涛,李大凯,李丹,王超.VC++的Word文档中的表与图自动生成技术[J].石油工业计算机应用,2015(02).

[5]岳亮.在VC中利用WORD生成图文报告[J].电脑编程技巧与维护,2002(05).

[6]雷晓荣,雷凌云,冯宏.VC中用Word生成随钻测量报告的一种方法[J].微处理机,2010(04).

[7]徐格宁,冯晓蕾,陶元芳,杨瑞刚.基于COM+ VC+ Word技术的产品设计说明书自动化研究[J].中国工程机械学报,2009(03).

[8]姜照林.用VC實现Word文档自动化[J].嘉兴学院学报,2007(03).

[8]闫新珠,王秀芹.在VC中利用Word生成测量报告[J].地矿测绘,2006(01).

[9]申屠浩,鲍可进.用VC++语言创建WORD文档[J].计算机工程与设计,2004(06).

[10]刘春雷,吴重光.用VC实现Word自动化操作的研究与应用[J].计算机工程与设计,2004(09).

[11]孙鑫,余安萍编著.VC++深入详解[M].北京:电子工业出版社,2006.

作者简介

张雪咏(1979-),女,大学本科学历。工程师,主要从事继电保护及自动化产品的测试技术、测试方法的研究和测试工作。

马红涛(1980-),男,工程师,主要从事继电保护及自动化产品的测试技术、测试方法的研究和测试工作。

赵建峰(1981-),女,工程师,主要从事继电保护及自动化产品的测试技术、测试方法的研究和测试工作。

作者单位

许继电气股份有限公司 河南省许昌市 461000