×
您的位置: 首页 > 编程笔记

用VC写word文件方法

Word 时间:2013-03-14  查看:329   收藏

问题:您能给我介绍点用Visual C++ 动态生成WORD文档资料吗?给个例子代码什么的。

解答:
一:

以下是创建这个MFC应用程序的步骤:
(1)使用AppWizard创建一个新的MFC AppWizard(EXE)工程,命名为"Embed_Word"
(2)选择单文档视图(SDI)结构,在第3步中需要选中Container,以提供容器支持。 其它都为默认。在ClassView中将产生如下类

应用类: CEmbed_WordApp in Embed_Word.h and Embed_Word.cpp
框架类: CMainFrame in MainFrm.h and MainFrm.cpp
文档类: CEmbed_WordDoc in Embed_WordDoc.h and Embed_WordDoc.cpp
视图类: CEmbed_WordView in Embed_WordView.h and Embed_WordView.cpp
容器类: CEmbed_WordCntrItem in CntrItem.h and CntrItem.cpp
(3)在View菜单中,选ClassWizard,选Automation选项卡,选Add Class,选择From a TypeLibrary, 在Office目录中选中Microsoft Word 97/2000 类型库Word8.olb或Word9.olb,会将把类型库中的所有类添加到你的工程中。这时,ClassView中会多出几十个类,可以通过这些类提供的接口来实现必要的功能。
(4)在CCntrItem.h中添加获取标准COM接口IDispach的函数:

LPDISPATCH GetIDispatch(); 其函数实现如下:

  1. LPDISPATCH CEmbed_WordCntrItem::GetIDispatch()
  2. {
  3. ASSERT_VALID(this);
  4. ASSERT(m_lpObject != NULL);
  5. LPUNKNOWN lpUnk = m_lpObject;
  6. Run();
  7. LPOLELINK lpOleLink = NULL;
  8. if(m_lpObject->QueryInterface(IID_IOleLink,(LPVOID FAR*)&lpOleLink)== NOERROR)
  9. {
  10. ASSERT(lpOleLink != NULL);
  11. lpUnk = NULL;
  12. if(lpOleLink->GetBoundSource(&lpUnk) != NOERROR)
  13. {
  14. TRACE0("Warning: Link is not connected! ");
  15. lpOleLink->Release();
  16. }
  17. ASSERT(lpUnk != NULL);
  18. }
  19. LPDISPATCH lpDispatch = NULL;
  20. if(lpUnk->QueryInterface(IID_IDispatch,(LPVOID FAR*)&lpDispatch) != NOERROR)
  21. {
  22. TRACE0("Waring: does not support IDispatch! ");
  23. return NULL;
  24. }
  25. ASSERT(lpDispatch != NULL);
  26. return lpDispatch;
  27. }

通过此函数来返回标准COM接口IDispatch。
(5)在Embed_WordView.cpp中添加对"MSWord8.h"的引用:#include "MSWord8.h",如使用Word2000,则包含对"MSWord9.h"的引用。 然后在视类CEmbed_WordView中添加函数EmbedAutomateExcel()

  1. void CEmbed_WordView::EmbedAutomateWord()
  2. {
  3. BeginWaitCursor();
  4. CEmbed_WordCntrItem* pItem = NULL;
  5. TRY
  6. {
  7. CEmbed_WordDoc* pDoc = GetDocument();
  8. ASSERT_VALID(pDoc);
  9. pItem = new CEmbed_WordCntrItem(pDoc);
  10. ASSERT_VALID(pItem);
  11. GetClientRect(&pItem->rect);
  12. CLSID clsid;
  13. if(FAILED(::CLSIDFromProgID(L"Word.document",&clsid)))
  14. AfxThrowMemoryException();
  15. if(!pItem->CreateNewItem(clsid))
  16. AfxThrowMemoryException();
  17. ASSERT_VALID(pItem);
  18. pItem->DoVerb(OLEIVERB_SHOW, this);
  19. m_pSelection = pItem;
  20. pDoc->UpdateAllViews(NULL);
  21. LPDISPATCH lpDisp;
  22. lpDisp = pItem->GetIDispatch();
  23. }
  24. CATCH(CException, e)
  25. {
  26. if (pItem != NULL)
  27. {
  28. ASSERT_VALID(pItem);
  29. pItem->Delete();
  30. }
  31. AfxMessageBox(IDP_FAILED_TO_CREATE);
  32. }
  33. END_CATCH
  34. EndWaitCursor();
  35. }

如果仔细研究过这段代码,会发现它同AppWizard自动生成的OnInsertObject()函数有着惊人的相似程度,看一下View类中的 OnInsertObject() 方法,对其中的注释引起了我们的兴趣,因为它和我们刚写的方法有惊人的相似。事实上,我们刚才写的只不过是OnInsertObject()的一个特例:OnInsertObject()允许用户从可用的OLE对象列表中选择其一插入到应用程序中。因为在此我们只需对Word进行自动化,所以派生了这一行为。
(6)为了在程序刚启动时便将Word嵌入到程序中来,还需在视类的OnInitialUpdate()函数中添加代码:

  1. void CEmbed_WordView:nInitialUpdate()
  2. {
  3. CView:nInitialUpdate();
  4. EmbedAutomateWord(); //将Word嵌入
  5. m_pSelection = NULL;
  6. }

(7)为了使嵌入的工作区占满整个客户区可以通过修改OnDraw函数来实现:

  1. void CEmbed_WordView:nDraw(CDC* pDC)
  2. {
  3. CEmbed_WordDoc* pDoc = GetDocument();
  4. ASSERT_VALID(pDoc);
  5. if (m_pSelection == NULL)
  6. {
  7. POSITION pos = pDoc->GetStartPosition();
  8. m_pSelection = (CEmbed_WordCntrItem*)pDoc->GetNextClientItem(pos);
  9. }
  10. if (m_pSelection != NULL)
  11. {
  12. CRect rect;
  13. GetClientRect(&m_pSelection->rect);
  14. m_pSelection->OnGetItemPosition(rect);
  15. m_pSelection->Draw(pDC,rect);
  16. }
  17. }

二:
在VC中调用WORD(显示,修改,存盘,运行宏)
(1)使用AppWizard创建一个新的MFC AppWizard(EXE)工程,命名为"office"
(2)选择单文档视图(SDI)结构,在第3步中需要选中Container,以提供容器支持,并且选中active document container 其它都为默认
(3)在View菜单中,选ClassWizard,选Automation选项卡,选Add Class,选择From a TypeLibrary, 在Office目录中选中Microsoft Word 97/2000 类型库Word8.olb或Word9.olb,选中application,document,_document。单击ok
(4)给COfficeCntrItem添加一Public方法。LPDISPATCH GetIDispatch()

其源码如下:

  1. ASSERT_VALID(this);
  2. ASSERT(m_lpObject != NULL);
  3. LPUNKNOWN lpUnk = m_lpObject;
  4. Run();
  5. LPOLELINK lpOleLink = NULL;
  6. if (m_lpObject->QueryInterface(IID_IOleLink, (LPVOID FAR*)&lpOleLink) == NOERROR)
  7. {
  8. ASSERT(lpOleLink != NULL);
  9. lpUnk = NULL;
  10. if (lpOleLink->GetBoundSource(&lpUnk) != NOERROR)
  11. {
  12. TRACE0("Warning: Link is not connected! ");
  13. lpOleLink->Release();
  14. return NULL;
  15. }
  16. ASSERT(lpUnk != NULL);
  17. }
  18. LPDISPATCH lpDispatch = NULL;
  19. if (lpUnk->QueryInterface(IID_IDispatch, (LPVOID FAR*)&lpDispatch)!=NOERROR)
  20. {
  21. TRACE0("Warning: does not support IDispatch! ");
  22. return NULL;
  23. }
  24. ASSERT(lpDispatch != NULL);
  25. return lpDispatch;

(5)。在officeView.h添加#include "msword8.h" //如果是Word2000则为#include "msword9.h"

(6)。修改void COfficeView:nInsertObject(),源码如下:

  1. BeginWaitCursor();
  2. COfficeCntrItem* pItem = NULL;
  3. TRY
  4. {
  5. // Create new item connected to this document.
  6. COfficeDoc* pDoc = GetDocument();
  7. ASSERT_VALID(pDoc);
  8. pItem = new COfficeCntrItem(pDoc);
  9. ASSERT_VALID(pItem);
  10. // Initialize the item from the dialog data.
  11. /* if (!dlg.CreateItem(pItem))
  12. AfxThrowMemoryException(); // any exception will do
  13. ASSERT_VALID(pItem);*/
  14. CLSID clsid; //
  15. if(FAILED(::CLSIDFromProgID(L"Word.document",&clsid)))
  16. AfxThrowMemoryException();
  17. if(bOpenStatus) //如果是打开文档
  18. {
  19. if(!pItem->CreateFromFile (sFilename,clsid)) //打开已有文档
  20. AfxThrowMemoryException();
  21. }
  22. else //否则新建文档
  23. {
  24. if(!pItem->CreateNewItem(clsid)) //新建文档
  25. AfxThrowMemoryException();
  26. }
  27. ASSERT_VALID(pItem);
  28. pItem->Activate (OLEIVERB_SHOW,this);
  29. ASSERT_VALID(pItem);
  30. m_pSelection = pItem; // set selection to last inserted item
  31. pDoc->UpdateAllViews(NULL);
  32. // As an arbitrary user interface design, this sets the selection
  33. // to the last item inserted.
  34. // TODO: reimplement selection as appropriate for your application
  35. m_pSelection = pItem; // set selection to last inserted item
  36. pDoc->UpdateAllViews(NULL);
  37. }
  38. CATCH(CException, e)
  39. {
  40. if (pItem != NULL)
  41. {
  42. ASSERT_VALID(pItem);
  43. pItem->Delete();
  44. }
  45. AfxMessageBox(IDP_FAILED_TO_CREATE);
  46. }
  47. END_CATCH
  48. EndWaitCursor();
  49. (7)重载ID—FILE—SAVE,
  50. void COfficeView:nFileSave()
  51. {
  52. // TODO: Add your command handler code here
  53. TRY{
  54. LPDISPATCH lpDisp;
  55. lpDisp = m_pSelection->GetIDispatch();
  56. Documents docs;
  57. _Application app;
  58. _Document mydoc;
  59. Documents my;
  60. mydoc.AttachDispatch (lpDisp,TRUE);
  61. app=mydoc.GetApplication ();
  62. /* app.Run ("Macro3");*/
  63. mydoc.Activate ();
  64. BOOL password=mydoc.GetHasPassword ();
  65. mydoc.SetPassword ("love");
  66. password=mydoc.GetHasPassword ();
  67. COleVariant vFalse((short)FALSE);
  68. mydoc.SaveAs (COleVariant(filename),vFalse,vFalse, COleVariant(""),vFalse, //filename为一个以字符串表达的文件名 如"c:\love1.doc"
  69. COleVariant(""),vFalse,vFalse,vFalse,vFalse,vFalse);
  70. }
  71. CATCH(CException, e)
  72. {
  73. }
  74. END_CATCH
  75. }
  76. bulid,click insert object,and edit ,and save.maybe run macro.

 

0% (0)
0% (0)