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 文档并自动化文档将数据添加到单元格。
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