在實際應用中,編程者往往喜歡程序能自動生成word說明文檔,說明程序運 行的狀況或運行的結果;或者程序能提取數據庫的內容生成word表格,使用戶能 方便的查看和修改,打印。但是VC++中調用word的確不容易,特別是對word中各 種函數的使用,本文以作者的工作經驗詳細介紹一下如何調用word和進行word表 格的填寫,有同樣需求的編友也可查看一下MSDN中的Automation Microsoft Office 97 and Microsoft office 2000。下面介紹以Microsoft Office 2000 Word為例。
類型庫
一個類型庫是一個提供COM對象功能信息的文件或文件的一部分,而且類型庫 包含了有關類的信息。注意,類型庫並不存儲實際的對象,而只是存儲有關這些 對象的信息。類型庫詳細說明了一個自動化客戶機為對象需要調用的方法和屬性 的信息,比如說它詳細的描述了接受或返回的值。
每一個Microsoft Office應用程序都在一個dll文件中提供了多種類型庫資源 ,這種dll文件叫做目標庫(*.olb)。下面的表列出了Microsoft Office 97和 Microsoft office 2000類型庫文件的名字。
Microsoft Access Msacc8.olb Msacc9.olb Microsoft Excel Excel8.olb Excel9.olb Microsoft Graph Graph8.olb Graph9.olb Microsoft Outlook® Msoutl8.olb
Note: Use Msoutl85.olb for Outlook 98
Msoutl9.olb Microsoft PowerPoint® Msppt8.olb Msppt9.olb Microsoft Word Msword8.olb Msword9.olb在VC++調用word中,我們需要導入msword9.olb才能使用word中的各種功能。
用VC++創建一個自動化客戶機
The COleDispatchDriver Class
vc提供了一個COleDispatchDriver類來處理自動化對象的IDispatch接口,關 於COleDispatchDrive類的屬性和函數請讀者自行查閱類庫,這裡就不再贅述。
1.創建一個新的Dialog-Base MFC AppWizard Exe工程名為 "WordAutomation";注意在MFC AppWizard - Step 2 of 4中的 Automaiton選項上打上勾,如下圖所示:
圖一 使用AppWizard生成基於對話框的的工程,如上所示選上Automation選 項。
2.在View菜單中,點擊ClassWizard,然後進入Automation標簽中點擊Add Class,選擇From A Type Library。找到Microsoft Office 2000類型庫 msword.olb,選擇_Application,_Document,_Documents,Selection四個類, 如有其他需要(例如畫表也可選擇其他的類)。
圖二 使用ClassWizard從類型庫中創建所需的類
這個過程會在工程中創建兩個新的文件:msword8.h和msword8.cpp,這些文件 構成了word類型庫的所選擇的類和類的成員函數。在ClassView視圖中查看從 word類型庫生成的所有的類,然後雙擊_Application類來查看它的定義,你就會 注意到_Application類是來源於COleDispatchDriver。 // _Application wrapper class
class _Application : public COleDispatchDriver
{
......
}
至於這些類和成員函數的功能和用法,我有一個簡便的方法,那就 是使用word中工具菜單中的宏的錄制功能,把你所想要進行的操作先用宏錄制下 來,然後查看這些宏代碼,你就會清楚要使用哪個類,哪些成員函數和成員函數 應該帶些什麼參數了。雖然這些代碼都是用VB寫的,但你可以很容易的轉換成 VC++中的代碼。
圖三 進行word寫的VBA宏代碼
VC++會自動地在WordAutomation.cpp中的 CWordAutomationApp::InitInstance()中生成如下的代碼,使得COM的服務能有 效。 if (!AfxOleInit())
{
AfxMessageBox(IDP_OLE_INIT_FAILED);
return FALSE;
}
3.接下來選擇對話框資源IDD_WORDAUTOMATION_DIALOG,在對話框中 增加一個按鈕命名為IDC_WORD_NEW,在按鈕的處理函數中增加如下的代碼: COleVariant vTrue((short)TRUE),
vFalse((short)FALSE),
vOpt((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
//開始一個新的Microsoft Word 2000實例
_Application oWordApp;
if (!oWordApp.CreateDispatch("Word.Application", NULL))
{
AfxMessageBox("CreateDispatch failed.", MB_OK | MB_SETFOREGROUND);
return;
}
//創建一個新的word文檔
Documents oDocs;
_Document oDoc;
oDocs = oWordApp.GetDocuments();
oDoc = oDocs.Add(vOpt, vOpt, vOpt, vOpt);
//如果是word 98,則應該帶兩個參數,如oDocs.Add(vOpt, vOpt)
//把文本添加到word文檔
Selection oSel;
oSel = oWordApp.GetSelection();
oSel.TypeText("one");
oSel.TypeParagraph();
oSel.TypeText("two");
oSel.TypeParagraph();
oSel.TypeText("three");
//保存word文檔
_Document oActiveDoc;
oActiveDoc = oWordApp.GetActiveDocument();
oActiveDoc.SaveAs(COleVariant("c:\\doc1.doc"),
COleVariant((short)0),
vFalse, COleVariant(""), vTrue, COleVariant(""),
vFalse, vFalse, vFalse, vFalse, vFalse);
//退出word應用程序
oWordApp.Quit(vOpt, vOpt, vOpt);
4.在WoreAutomation.cpp中 增加包含頭文件msword9.h。
#include "msword9.h" // 或者在word98中是 "msword8.h"
注意:增加的頭文件應該在 stdafx.h文件之後,否則就會導致編譯錯誤。
利用VC++進行word表格的填寫
我們先利用word的宏的錄制功能,把所要進行的表格填寫的操作錄制下來, 查看VBA的代碼如下所示:
圖四 進行word表格填寫的VBA宏代碼
其中MoveDown為Selection類所定義對象的成員函數,Unit:=wdParagraph, Count:=1為其所帶參數的值。wdParagraph宏的數值是多少,可使用宏的調試器 在調試中查出。在VC++中MoveDown所帶參數為三個,在VBA的幫助中我們可以查 到第三個參數不寫會有一個默認值,但在VC++中這個參數不能省略,怎麼知道它 數值是多少呢?我們可以照葫蘆畫瓜把它寫進宏中,Extend:=wdMove,再在調試 中查出,其余的類推。
再次選擇對話框資源IDD_WORDAUTOMATION_DIALOG,在對話框中增加一個按鈕 命名為IDC_WORD_TABLEWRITE,在按鈕的處理函數中增加如下的代碼: BeginWaitCursor();
COleVariant vTrue((short)TRUE), vFalse((short)FALSE),
vOpt((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
_Application m_App;//定義Word提供的應用程序對象;
Documents m_Docs;//定義Word提供的文檔對象;
Selection m_Sel;//定義Word提供的選擇對象;
m_Docs.ReleaseDispatch();
m_Sel.ReleaseDispatch();
m_App.m_bAutoRelease=true;
if(!m_App.CreateDispatch("Word.Application"))
{
AfxMessageBox("創建Word2000服務失敗!");
exit(1);
}
//下面是定義VARIANT變量;
COleVariant varFilePath("word表格.doc");
COleVariant varstrNull("");
COleVariant varZero((short)0);
COleVariant varTrue(short(1),VT_BOOL);
COleVariant varFalse(short(0),VT_BOOL);
m_Docs.AttachDispatch(m_App.GetDocuments());//將Documents類對象 m_Docs和Idispatch接口關聯起來;
m_Docs.Open(varFilePath,varFalse,varFalse,varFalse,
varstrNull,varstrNull,varFalse,varstrNull,
varstrNull,varTrue,varTrue,varTrue);
//打開Word文檔;
m_Sel.AttachDispatch(m_App.GetSelection());//將Selection類對象 m_Sel和Idispatch接口關聯起來;
m_Sel.MoveDown(COleVariant((short)4),COleVariant((short) 1),COleVariant((short)0));
m_Sel.MoveDown(COleVariant((short)5),COleVariant((short) 1),COleVariant((short)0));
m_Sel.TypeText("123456789");
m_Sel.MoveRight(COleVariant((short)1),COleVariant((short) 1),COleVariant((short)0));
m_Sel.TypeText("李明");
m_Sel.MoveRight(COleVariant((short)1),COleVariant((short) 1),COleVariant((short)0));
m_Sel.TypeText("25");
m_Sel.MoveRight(COleVariant((short)1),COleVariant((short) 1),COleVariant((short)0));
m_Sel.TypeText("技術員");
m_Sel.MoveRight(COleVariant((short)1),COleVariant((short) 1),COleVariant((short)0));
m_Sel.TypeText("本科");
m_Sel.MoveRight(COleVariant((short)1),COleVariant((short) 1),COleVariant((short)0));
m_Sel.TypeText("上海市虹口區民主路315號");
//save word file
_Document oActiveDoc;
oActiveDoc = m_App.GetActiveDocument();
oActiveDoc.SaveAs(COleVariant("c:\\填寫後表格.doc"),
COleVariant((short)0),
vFalse, COleVariant(""), vTrue, COleVariant (""),
vFalse, vFalse, vFalse, vFalse, vFalse);
m_Docs.ReleaseDispatch();//斷開關聯;
m_Sel.ReleaseDispatch();
//退出WORD
m_App.Quit(vOpt, vOpt, vOpt);
m_App.Quit(vOpt, vOpt, vOpt);
m_App.ReleaseDispatch();
EndWaitCursor();
MessageBox("word表格填寫完畢!","提示 ",MB_ICONEXCLAMATION);
注意:要運行本文提供的源程序,需 要預先安裝Microsoft Word 2000。
本文配套源碼