//屏蔽 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 文档并自动化文档将数据添加到单元格。
- 启动 Microsoft Visual Studio .NET。在文件菜单上,单击新建,然后单击项目。 在项目类型下面单击Visual C++ 项目,然后单击模板下面的MFC 应用程序。 将该项目命名为 Embed_Word。
- 显示 MFC 应用程序向导时,请按照下列步骤操作:
- 单击应用程序类型,然后选择单文档。
- 单击复合文档支持,然后选择容器。
- 单击完成以接受所有其他默认设置。
- 从 Word 对象库添加接口。为此,请按照下列步骤操作:
- 在项目菜单上,单击添加类。
- 从模板列表中选择类型库中的 MFC 类,然后单击打开。 将显示“从类型库添加类向导”。
- 在可用类型库列表中,找到 Microsoft Word 版本 对象库。 Word 2000 的版本是 9.0,Word 2002 的版本是 10.0。
- 添加下面的接口:
- _Document
- Range
- 单击完成。
- 将下面一行代码添加到 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