vc中嵌入excel的链接
http://support.microsoft.com/kb/307473
http://support.microsoft.com/kb/311546/en-us
解决问题的链接
本逐步式指南可用于自动执行嵌入的 Microsoft Office 文档。按照下面的过程使用 VC + + MFC 容器作为 ActiveX 文档容器已激活的 Excel 工作表。该代码包含示例获取文档的服务器到一个 IDispatch 接口指针的方法,并演示如何自动嵌入的 Excel 工作表。使用 Office 应用程序作为 ActiveX 文档服务器
ActiveX 文档容器可以包含多个 Office 文档中,但可以一次显示一个文档。当激活 Office 文档时,Office 文档的服务器应用程序的菜单合并到容器的菜单中。ActiveX 文档容器自动激活所显示的文档。这不同于常规的 OLE 文档嵌入。传统的嵌入或链接要求最终用户之前合并菜单激活的文档。"新"的工作表中嵌入在容器中时则将它视为一个 ActiveX 对象。任何最终用户操作不需要 Excel 菜单与容器的菜单合并在一起。
创建 MFC 容器应用程序自动执行 ActiveX 文档
若要生成示例应用程序,可以自动嵌入的 Excel 工作表,请执行以下步骤:- 启动 Microsoft Visual Studio.NET。在文件菜单上,指向新建,然后单击项目。在项目类型下单击Visual C++ 项目,,并选择MFC 应用程序模板。AutomateEmbed为项目命名。对 C:\...root 文件夹中保存该项目。
-
在 MFC 应用程序向导,请按照下列步骤:
- 单击应用程序类型,然后选择单个文档。
- 单击复合文档支持,然后选择容器。
- 检查活动文档容器。
- 单击完成接受剩余的默认设置。
-
从 Excel 对象库添加接口。若要执行此操作,请按照下列步骤操作:
- 在项目菜单上,单击添加类。
- 从模板列表中,选择从类型库的 MFC 类,然后单击打开。此时将显示从类型库添加类向导。
- 在可用的类型库的列表中,找到Microsoft Excelversion对象库,其中version是 9.0 Excel 2000 或 Excel 2002 的 10.0。
-
添加下面的接口:_Application
_Workbook
_Worksheet
范围
工作表单击完成。
-
在解决方案资源管理器的解决方案AutomateEmbed区域中,您将看到的树视图,其中包括以下:
源代码文件
头文件
资源文件展开资源文件节点,然后双击AutomateEmbed.RC以将其打开。 - 双击要查看的两个菜单的菜单: IDR_CNTR_INPLACE和IDR_MAINFRAME。
- 双击 IDR_CNTR_INPLACE。将打开图形 菜单设计器 窗口,显示在 文件 菜单。底部的 文件 菜单是一个空白 CommandBarButton 包含 此处输入 的图例。标题键入AutomateExcel。
-
用鼠标右键单击新标题为 CommandBarButton 中,然后单击添加事件处理程序运行事件处理程序向导。
Set this: To this:
处理程序说明的内容为:"调用后,选择菜单项或命令按钮"。
---------------------------------------------------------
Command Name ID_FILE_AUTOMATEEXCEL
Message Type Command
Function Handler Name OnFileAutomateExcel
Class List CAutomateEmbedView - 单击添加并编辑CAutomateEmbedView.cpp 文件的代码中插入主干处理程序。
- 在解决方案资源管理器中,双击AutomateEmbedView.cpp在代码窗口中打开该文件。
-
键入或粘贴以下代码文件的顶部:
// AutomateEmbedView.cpp : implementation of the CAutomateEmbedView class
//
#include "stdafx.h"
#include "AutomateEmbed.h"
#include "AutomateEmbedDoc.h"
#include "CntrItem.h"
#include "AutomateEmbedView.h"
#include "CWorkbook.h"
#include "CWorksheet.h"
#include "CWorksheets.h"
#include "CRange.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CAutomateEmbedView -
在 AutomateEmbedView.h 文件中的 CAutomateEmbedView 中加入一个新的公共成员函数:
HRESULT GetDocIDispatch( LPDISPATCH* ppDisp );
-
在 AutomateEmbedView.cpp 文件的底部,替换骨架的消息处理程序的 CAutomateEmbedView::OnFileAutomateExcel 用下面的代码:
// CAutomateEmbedView message handlers
void CAutomateEmbedView::OnFileAutomateExcel()
{
// Query for the IDispatch pointer for the embedded object.
// In this case it is Excel worksheet.
LPDISPATCH lpDisp;
HRESULT hr = GetDocIDispatch(&lpDisp); // Your own new function.
// If you got an IDispatch, then use it to Automate Excel
if(SUCCEEDED(hr))
{
CWorkbook oBook;
CWorksheets oSheets;
CWorksheet oSheet;
CRange oRange;
// Set_Workbook oBook to use lpDisp, the IDispatch* of the
// embedded/Embedded workbook.
oBook.AttachDispatch(lpDisp);
// Then, get the first worksheet in the workbook.
oSheets = oBook.get_Worksheets();
oSheet = oSheets.get_Item(COleVariant((long)1));
// Get the Range object corresponding to Cell A1.
oRange = oSheet.get_Range(COleVariant(TEXT("A1")), COleVariant(TEXT("A1")));
// Fill the range with the string "Hello World".
oRange.put_Value(COleVariant((long)DISP_E_PARAMNOTFOUND, VT_ERROR), COleVariant(TEXT("Hello World")));
//NOTE: If you are automating Excel 2000 the Range.SetValue requires only one
// argument. The first parameter in the Excel 2002 syntax in the line above is for the data type,
// and is optional. It is not permitted by Excel 2000 or earlier versions of Excel.
} // End if
} // End of method
/*****************************************************************************
* *
* GetDocIDispatch - This method determines if the document is embedded *
* or linked, and acquires an IDispatch pointer to the embedded/linked *
* document's server application for use in Automation. *
* The document must be activated for this method to succeed. *
* *
* Parameters: ppDisp = The address of an LPDISPATCH to be filled with *
* the IDispatch pointer of the embedded/linked document's server. *
* *
* Returns: S_OK if successful, otherwise an HRESULT reporting the error. *
* *
*****************************************************************************/
HRESULT CAutomateEmbedView::GetDocIDispatch(LPDISPATCH* ppDisp)
{
//HRESULT hr = S_OK;
HRESULT hr = E_UNEXPECTED; // If no document then return no ppDisp.
IOleLink* lpLink = NULL;
IMoniker* lpMoniker = NULL;
IRunningObjectTable* lpROT = NULL;
IUnknown* lpUnk = NULL;
if(!m_pSelection)
{
return hr;
}
// First, try to get an IOleLink interface from the document.
// If successful, this indicates that the document is linked as
// opposed to embedded.
hr = m_pSelection->m_lpObject->QueryInterface(IID_IOleLink, (void**)&lpLink);
if(SUCCEEDED(hr))
{
// Get the moniker of the source document for this link.
// You need this to find the ActiveX Document Server.
hr = lpLink->GetSourceMoniker(&lpMoniker);
if(SUCCEEDED(hr))
{
// For linked documents, search the Running Object Table
// for the relevant server. Do this through the
// IRunningObjectTable interfce, which you can get through
// an API call.
hr = GetRunningObjectTable(0,&lpROT);
if(SUCCEEDED(hr))
{
// Search the Running Object Table for the ActiveX
// Document Server of this document. You'll get back an
// IUnknown pointer to the server.
hr = lpROT->GetObject( lpMoniker, &lpUnk );
if(SUCCEEDED(hr))
{
// Finally, get the IDispatch pointer from the
// IUnknown pointer.
hr = lpUnk->QueryInterface(IID_IDispatch, (void**)ppDisp);
}
}
}
}
else
{
// If that fails, try for a direct IDispatch pointer. This
// indicates that the document is embedded, not linked.
hr = m_pSelection->m_lpObject->QueryInterface(IID_IDispatch, (void**)ppDisp);
}
// Clean up interface pointers you may have acquired along the way.
if(lpLink)
lpLink->Release();
if(lpMoniker)
lpMoniker->Release();
if(lpROT)
lpROT->Release();
if(lpUnk)
lpUnk->Release();
return hr;
} - 编译并运行该应用程序。如果您收到编译器错误,请参阅"疑难解答"部分。
- 容器窗体上单击编辑,然后单击插入对象。
- 在插入新对象列表框中,选择一个新的 Excel 工作表。空容器中显示的 Excel 工作表,Excel 菜单将与容器的菜单合并。
- 从容器中的文件菜单上,单击AutomateExcel。在单元格 A1 中显示字符串"Hello World"。
- 在文件菜单上,单击新建以清除工作表。不保存该工作表。
- 在新文档中,将插入现有 Excel 工作簿 (由文件创建)。
- 在文件菜单上,单击AutomateExcel。"Hello World"将显示在工作表中的单元格 A1 中。