VC Office 自动化(Word、Excel)

VC_OFFICE 同时被 2 个专栏收录
0 篇文章 0 订阅
27 篇文章 0 订阅

Micriosoft官网说明:

http://support.microsoft.com/kb/248019/en-us


 //屏蔽  vc用ole调用word,excel时“服务器正在运行中”的对话框
 AfxOleGetMessageFilter()->EnableBusyDialog(FALSE);//!!!!
 AfxOleGetMessageFilter()->SetBusyReply(SERVERCALL_RETRYLATER);
 AfxOleGetMessageFilter()->EnableNotRespondingDialog(TRUE);
 AfxOleGetMessageFilter()->SetMessagePendingDelay (-1);
 AfxEnableControlContainer();

 
创建嵌入 Word 文档的 MFC 应用程序

创建嵌入Word文档的MFC应用程序

引用地址(嵌入EXCEL):http://support.microsoft.com/kb/184663/zh-cn?spid=3003&sid=1131

下列步骤介绍如何嵌入一个 Word 文档并自动化文档将数据添加到单元格。

  1. 启动 Microsoft Visual Studio .NET。在文件菜单上,单击新建,然后单击项目。 在项目类型下面单击Visual C++ 项目,然后单击模板下面的MFC 应用程序。 将该项目命名为 Embed_Word。
  2. 显示 MFC 应用程序向导时,请按照下列步骤操作:
    1. 单击应用程序类型,然后选择单文档
    2. 单击复合文档支持,然后选择容器
    3. 单击完成以接受所有其他默认设置。
  3. 从 Word 对象库添加接口。为此,请按照下列步骤操作:
    1. 项目菜单上,单击添加类
    2. 从模板列表中选择类型库中的 MFC 类,然后单击打开。 将显示“从类型库添加类向导”。
    3. 在可用类型库列表中,找到 Microsoft Word 版本 对象库。 Word 2000 的版本是 9.0,Word 2002 的版本是 10.0。
    4. 添加下面的接口:
      • _Document
      • Range
    5. 单击完成
  4. 将下面一行代码添加到 Cntritem.h 中,用作 CEmbed_WordCntrItem 类的公共成员函数:
LPDISPATCH GetIDispatch();

       5.将 GetIDispatch 方法添加到 Cntritem.cpp 中,如下所示:
GetIDispatch 方法添加到 Cntritem.cpp 中,如下所示:

/*******************************************************************
*   This method returns the IDispatch* for the application that is linked to
*   this container.
********************************************************************/ 
LPDISPATCH CEmbed_WordCntrItem::GetIDispatch()
{
	//The this and m_lpObject pointers must be valid for this function
	//to work correctly. The m_lpObject is the IUnknown pointer to
	// this object.
	ASSERT_VALID(this);

	ASSERT(m_lpObject != NULL);

	LPUNKNOWN lpUnk = m_lpObject;

	//The embedded application must be running in order for the rest
	//of the function to work.
	Run();

	//QI for the IOleLink interface of m_lpObject.
	LPOLELINK lpOleLink = NULL;
	if (m_lpObject->QueryInterface(IID_IOleLink,
		(LPVOID FAR*)&lpOleLink) == NOERROR)
	{
		ASSERT(lpOleLink != NULL);
		lpUnk = NULL;

		//Retrieve the IUnknown interface to the linked application.
		if (lpOleLink->GetBoundSource(&lpUnk) != NOERROR)
		{
			TRACE0("Warning: Link is not connected!\n");
			lpOleLink->Release();
			return NULL;
		}
		ASSERT(lpUnk != NULL);
	}

	//QI for the IDispatch interface of the linked application.
	LPDISPATCH lpDispatch = NULL;
	if (lpUnk->QueryInterface(IID_IDispatch, (LPVOID FAR*)&lpDispatch)
		!=NOERROR)
	{
		TRACE0("Warning: does not support IDispatch!\n");
		return NULL;
	}

	//After you verify that it is valid, return the IDispatch
	//interface to the caller.
	ASSERT(lpDispatch != NULL);
	return lpDispatch;
}

6.将下面一行代码添加到 Embed_wordview.h 中,用作 CEmbed_WordView 类的公共方法:

void EmbedAutomateWord();

7.将下面一行代码添加到 Embed_wordview.cpp 中:

#include "CDocument0.h"
#include "CRange.h"

/********************************************************************
*   This method encapsulates the process of embedding an Word
*   document in a View object and automating that document to add
*   some text.
********************************************************************/ 
void CEmbed_WordView::EmbedAutomateWord()
{
   //Change the cursor so that the user knows that something exciting is going
   //on.
   BeginWaitCursor();

   CEmbed_WordCntrItem* pItem = NULL;
   TRY
   {
   	//Get the document that is associated with this view, and be sure that it is
   	//valid.
   	CEmbed_WordDoc* pDoc = GetDocument();
   	ASSERT_VALID(pDoc);

   	//Create a new item associated with this document, and be sure that it is
   	//valid.
   	pItem = new CEmbed_WordCntrItem(pDoc);
   	ASSERT_VALID(pItem);

   	// Get the Class ID for the Word document.
   	// This is used in creation.
   	CLSID clsid;
   	if(FAILED(::CLSIDFromProgID(L"Word.document",&clsid)))
   		//Any exception will do. You just need to break out of the
   		//TRY statement.
   		AfxThrowMemoryException();

   	// Create the Word embedded item.
   	if(!pItem->CreateNewItem(clsid))
   		//Any exception will do. You just need to break out of the
   		//TRY statement.
   		AfxThrowMemoryException();

   	//Make sure that the new CContainerItem is valid.
   	ASSERT_VALID(pItem);

   	// Start the server to edit the item.
   	pItem->DoVerb(OLEIVERB_SHOW, this);

   	// As an arbitrary user interface design, this sets the
   	// selection to the last item inserted.
   	m_pSelection = pItem;   // Set selection to the last inserted item.
   	pDoc->UpdateAllViews(NULL);

   	//Query for the dispatch pointer for the embedded object. In
   	//this case, this is the Word document.
   	LPDISPATCH lpDisp;
   	lpDisp = pItem->GetIDispatch();

   	//Add text to the embedded Word document.
   	CDocument0 wdDoc;
   	CRange wdRange;

   	//set CDocument0 wdDoc to use lpDisp, the IDispatch* of the
   	//actual document.
   	wdDoc.AttachDispatch(lpDisp);


   	//Get a CRange object for the document.
   	wdRange = wdDoc.Range(COleVariant( (long)DISP_E_PARAMNOTFOUND, VT_ERROR ),
         COleVariant( (long)DISP_E_PARAMNOTFOUND, VT_ERROR ) );

   	//Fill the range with the string "Hello, World!"
   	wdRange.put_Text( "Hello, World!" );
   }

   //Clean up if something went wrong.
   CATCH(CException, e)
   {
   	if (pItem != NULL)
   	{
   		ASSERT_VALID(pItem);
         pItem->Delete();
   	}
   	AfxMessageBox(IDP_FAILED_TO_CREATE);
   }
   END_CATCH

   	//Set the cursor back to normal so the user knows exciting stuff
   	//is no longer happening.
   	EndWaitCursor();
}

8.将 Embed_wordview.cpp 中的 CEmbed_WordView::OnInsertObject 的代码替换为以下代码:

void CEmbed_WordView::OnInsertObject()
{
	EmbedAutomateWord();
}

 

备注:EmbedAutomateWord 只是OnInsertObject 的一种特殊情况,它使用户可以从可用 OLE 对象列表中选择对象来插入到应用程序中。 您将重写该行为,因为此演示不需要这种行为。

PS.如果希望插入的是EXCEL,那么需要如下变动:
 第三步:用类似方法添加EXCEL的接口文件。
 第七步:将“Word.Document”改为“Excel.sheet”。
程序中其它地方的设置:
1.在“stdafx.h”中#include 相应的OLE接口文件。
2.注释掉相应的OLE接口文件中#import行
3.EXCEL程序编译出错更改:
出错位置那个函数的函数名前面添加一个下划线。
 

 

===============================================================================================================================

我的是2003的,不知道你能不能用,我正好也在做这个,有问题大家多交流交流,除了存数据制作表格,我还需要画一个图表
void CAutoExcelView::OnExcelWrite()
{
 // TODO: Add your command handler code here
 //*****
 //变量定义
 _Application app;   
 Workbooks books;
 _Workbook book;
 Worksheets sheets;
 _Worksheet sheet;
 Range range;
 Range iCell;
 LPDISPATCH lpDisp;   
 COleVariant vResult;
 COleVariant
        covTrue((short)TRUE),
        covFalse((short)FALSE),
        covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);   
 
 
 //*****
 //初始化COM的动态连接库
 if(!AfxOleInit()) 
 {
        AfxMessageBox("无法初始化COM的动态连接库!");
        return ;
     }  
 
 
 //*****
 //创建Excel 2003服务器(启动Excel)
 if(!app.CreateDispatch("Excel.Application"))
 {
  AfxMessageBox("无法启动Excel服务器!");
    return;
 }
 
 app.SetVisible(TRUE);          //使Excel可见
 app.SetUserControl(TRUE);      //允许其它用户控制Excel
 

 //*****  
 //打开c:\\1.xls
   books.AttachDispatch(app.GetWorkbooks());
   lpDisp = books.Open("C:\\1.xls",     
   covOptional, covOptional, covOptional, covOptional, covOptional,
   covOptional, covOptional, covOptional, covOptional, covOptional,
   covOptional, covOptional, covOptional, covOptional);   
 
    
 //*****
 //得到Workbook
 book.AttachDispatch(lpDisp);
 
 
 //*****
 //得到Worksheets
 sheets.AttachDispatch(book.GetWorksheets());
 
 
 //*****
 //得到当前活跃sheet
 //如果有单元格正处于编辑状态中,此操作不能返回,会一直等待
 lpDisp=book.GetActiveSheet();
 sheet.AttachDispatch(lpDisp);
 

 //*****
 //读取已经使用区域的信息,包括已经使用的行数、列数、起始行、起始列
 Range usedRange;
 usedRange.AttachDispatch(sheet.GetUsedRange());
 range.AttachDispatch(usedRange.GetRows());
 long iRowNum=range.GetCount();                   //已经使用的行数
 
 range.AttachDispatch(usedRange.GetColumns());
 long iColNum=range.GetCount();                   //已经使用的列数
 
 long iStartRow=usedRange.GetRow();               //已使用区域的起始行,从1开始
 long iStartCol=usedRange.GetColumn();            //已使用区域的起始列,从1开始
 
 
 //*****
 //读取第一个单元格的值
 range.AttachDispatch(sheet.GetCells());
 range.AttachDispatch(range.GetItem (COleVariant((long)1),COleVariant((long)1)).pdispVal );
// vResult =range.GetValue(VTS_VARIANT);
 CString str;
 if(vResult.vt == VT_BSTR)       //字符串
 {
  str=vResult.bstrVal;
 }
 else if (vResult.vt==VT_R8)     //8字节的数字
 {
  str.Format("%f",vResult.dblVal);
 }
 /*else if(vResult.vt==VT_DATE)    //时间格式
 {
  SYSTEMTIME st;
     VariantTimeToSystemTime(&vResult.date, &st);
 }*/
 else if(vResult.vt==VT_EMPTY)   //单元格空的
 {
  str="";
 } 
 
 
 //*****
 //读取第一个单元格的对齐方式,数据类型:VT_I4
 //读取水平对齐方式
 range.AttachDispatch(sheet.GetCells());
 iCell.AttachDispatch((range.GetItem (COleVariant(long(1)), COleVariant(long(1)))).pdispVal);
 vResult.lVal=0;
 vResult=iCell.GetHorizontalAlignment();
 if(vResult.lVal!=0)
 {
  switch (vResult.lVal)
  {
  case 1:      //默认
   break;
  case -4108:  //居中
   break;
  case -4131 : //靠左
   break;
  case -4152 : //靠右
   break;
  }
 
 }
 
 //垂直对齐方式
 iCell.AttachDispatch((range.GetItem (COleVariant(long(1)), COleVariant(long(1)))).pdispVal);
 vResult.lVal=0;
 vResult=iCell.GetVerticalAlignment();
 if(vResult.lVal!=0)
 {
  switch (vResult.lVal)
  {
  case -4160 :  //靠上
   break;
  case -4108 :  //居中
   break;
  case -4107 :  //靠下
   break;
  }
 
 }
 
 
 //*****
 //设置第一个单元格的值"HI,EXCEL!"
 //str=_TEXT("20,30,40,50");
 range.SetItem(COleVariant(long(2)),COleVariant(long(1)),COleVariant("100")); //行,列,数
 range.SetItem(COleVariant(long(2)),COleVariant(long(2)),COleVariant("24"));
 range.SetItem(COleVariant(long(2)),COleVariant(long(3)),COleVariant("134"));
 range.SetItem(COleVariant(long(2)),COleVariant(long(4)),COleVariant("34"));
 
 

 //*****
 //设置第一个单元格字体颜色:红色
 /*Font font;
 range.AttachDispatch(sheet.GetCells());
 range.AttachDispatch((range.GetItem (COleVariant(long(1)), COleVariant(long(1)))).pdispVal);
 font.SetColor(COleVariant((long)0xFF0000));*/ 
 
 
 //*****
 //合并单元格的处理
 //包括判断第一个单元格是否为合并单元格,以及将第一个单元格进行合并
 /*Range unionRange;
 range.AttachDispatch(sheet.GetCells());
 unionRange.AttachDispatch(range.GetItem (COleVariant((long)1),COleVariant((long)1)).pdispVal );
 
 vResult=unionRange.GetMergeCells();   
 if(vResult.boolVal==-1)             //是合并的单元格   
 {
  //合并单元格的行数
  range.AttachDispatch (unionRange.GetRows ());
  long iUnionRowNum=range.GetCount ();
  
  //合并单元格的列数
  range.AttachDispatch (unionRange.GetColumns ());
  long iUnionColumnNum=range.GetCount ();  
 
  //合并区域的起始行,列
  long iUnionStartRow=unionRange.GetRow();       //起始行,从1开始
  long iUnionStartCol=unionRange.GetColumn();    //起始列,从1开始
 
 }
 else if(vResult.boolVal==0)  
 {//不是合并的单元格}
 
 //将第一个单元格合并成2行,3列
 range.AttachDispatch(sheet.GetCells());
 unionRange.AttachDispatch(range.GetItem (COleVariant((long)1),COleVariant((long)1)).pdispVal );
 unionRange.AttachDispatch(unionRange.GetResize(COleVariant((long)2),COleVariant((long)3)));
 unionRange.Merge(COleVariant((long)0));   //合并单元格*/
 
 
 //*****
 //将文件保存为2.xls
 book.SaveAs(COleVariant("C:\\2.xls"),covOptional,covOptional,
  covOptional,covOptional,covOptional,0,
  covOptional,covOptional,covOptional,covOptional,covOptional); 
 
 
 //*****
 //关闭所有的book,退出Excel
 book.Close (covOptional,COleVariant("1.xls"),covOptional);
 books.Close();     
 app.Quit();        

 
}

来源: http://www.cxy.me/bbs/view20-13980-1.htm

 


 


 

  • 1
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值