vc将数据库数据导出到Excel?

mei1977mei 2010-02-21 08:40:35
Excel的ActiveX Automate提供的_Application、Workbooks、_Workbook、Worksheets、_Worksheet、Range这些类 msdn中查不到这些类?
用什么办法可以知道这些类的函数以及具体用法?
...全文
877 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
WizardK 2010-02-21
  • 打赏
  • 举报
回复
看看这个,对EXCEL的操作已经是很陈旧的事情了,你不如直接参考别人的成熟经验。
http://www.codeproject.com/KB/office/BasicExcel.aspx
周成风 2010-02-21
  • 打赏
  • 举报
回复
我自己之前整理过的,希望对你有帮助。

1、首先打开类向导(MFC ClassWizard) 选择Add Class按钮中的 From a type library...找到
Office 目录下的文件 EXCEL9.OLB (Excel 2000)、Excel.Exe(Excel 2000以后)并打开。
2、在Confirm Class中的类框中选择你所需的类(EXCEL中的对象)后按OK按钮后依次添加 _Application 、Workbooks 、_Workbook 、Worksheets 、_Worksheet 和 Range类。
(以上这两步可以不做,只要存在Excel9.h和Excel9.cpp两个文件即可)。
3、将Excel9.h和Excel9.cpp拷贝到工程目录下,并加入到工程中。
4、加入头文件 #include "comdef.h"
#include "Excel9.h"
5、初始化COM库
if(CoInitialize(NULL)!=0)
{
AfxMessageBox("初始化COM支持库失败!");
exit(1);
}
释放COM库
CoUninitialize();

也可以直接利用MFC中的AfxOleInit()函数进行COM库的初始化,程序结束时将自动释放
6、主要代码
if(CoInitialize(NULL)!=0)
{
AfxMessageBox("初始化COM支持库失败!");
exit(1);
}

//定义Excel六层对象
_Application ExcelApp;
Workbooks wbsMybooks;
_Workbook wbMybook;
Worksheets wssMysheets;
_Worksheet wsMysheet;
Range rgMyrange;

//利用模板文件建立新文档
CString sExcelFile,sPath;
//获取主程序所在路径,存在sPath中
GetModuleFileName(NULL,sPath.GetBufferSetLength (MAX_PATH+1),MAX_PATH);
sPath.ReleaseBuffer ();
int nPos;
nPos=sPath.ReverseFind ('\\'); //从后往前查找字符\\,范返回位置
sPath=sPath.Left (nPos);
sExcelFile = sPath +"\\解释结果";

//创建Excel 2000服务器(启动Excel)
if (!ExcelApp.CreateDispatch("Excel.Application",NULL))
{
AfxMessageBox("创建Excel服务失败!");
exit(1);
}
ExcelApp.SetVisible(false);

//得到WorkBooks
wbsMybooks.AttachDispatch(ExcelApp.GetWorkbooks(),TRUE);
wbMybook.AttachDispatch(wbsMybooks.Add((_variant_t)sExcelFile));
//得到WorkSheets
wssMysheets.AttachDispatch(wbMybook.GetWorksheets(),TRUE);
wsMysheet.AttachDispatch(wssMysheets.GetItem((_variant_t)1));
//得到全部Cells,此时,rgMyRge是cells的集合,此时为读取数据时
rgMyrange.AttachDispatch(wsMysheet.GetCells(),TRUE);
//当为保存数据时,定义为
VARIANT start;
start.vt = VT_BSTR;
start.bstrVal = ::SysAllocString(L"A1");
VARIANT stop;
stop.vt = VT_BSTR;
stop.bstrVal = ::SysAllocString(L"D10");
rgMyrange = wsMysheet.GetRange(start,stop);

rgMyrange.SetItem((_variant_t)1,(_variant_t)1,(_variant_t)"井号");
rgMyrange.SetItem((_variant_t)1,(_variant_t)2,(_variant_t)"顶深");
rgMyrange.SetItem((_variant_t)1,(_variant_t)3,(_variant_t)"厚度");
rgMyrange.SetItem((_variant_t)1,(_variant_t)4,(_variant_t)"属性");

sExcelFile = sPath + "\\解释结果";
wsMysheet.SaveAs(sExcelFile,vtMissing,vtMissing,vtMissing,vtMissing,
vtMissing,vtMissing,vtMissing,vtMissing);

ExcelApp.Quit();//退出
//释放对象
rgMyrange.ReleaseDispatch();
wsMysheet.ReleaseDispatch();
wssMysheets.ReleaseDispatch();
wbMybook.ReleaseDispatch();
wbsMybooks.ReleaseDispatch();
ExcelApp.ReleaseDispatch();

CoUninitialize();
7、 运行程序时,必须在程序当前目录下存在一个解释结果.xls的文件,这个文件是一个模版。
_WorkBook类的Add函数中需要的参数就是这个文件的全路径,利用这个模版在内存中进行处理,最后利用_WorkSheet类的SaveAs函数保存结果。
8、 常用的其他方法。
ExcelApp.SetCaption();设置Excel标题。
wsMysheet.SetName();设置表单标题。
9、 利用安全数组读取数据,速度更快
//用来保存信息的数组
VARIANT arr;
arr.vt = VT_ARRAY | VT_VARIANT;
SAFEARRAYBOUND sab[2];
sab[0].lLbound = 1; sab[0].cElements = 10;
sab[1].lLbound = 1; sab[1].cElements = 4;
arr.parray = SafeArrayCreate(VT_VARIANT, 2, sab);

//定义两个单元格,为读取Excel中的范围
VARIANT start;
start.vt = VT_BSTR;
start.bstrVal = ::SysAllocString(L"A1");

VARIANT stop;
stop.vt = VT_BSTR;
stop.bstrVal = ::SysAllocString(L"P40");

//通过函数读取Excel中的数据
Range rgResault;
rgResault=rgMyrange.GetRange(start,stop);

//将数据保存到安全数组中
arr = rgResault.GetValue2();

//从安全数组中读出数据
VARIANT tmp;
long indices[] = {1,1};
SafeArrayGetElement(arr.parray, indices, (void *)&tmp);
//判断安全数组中数据类型,并进行相应处理
CString strTmp;
double dblTmp;
if(tmp.vt ==VT_BSTR)
{
strTmp=tmp.bstrVal;
AfxMessageBox(strTmp);
}
else if(tmp.vt==VT_R8)
{
dblTmp=tmp.dblVal;
strTmp.Format("%f",dblTmp);
AfxMessageBox(strTmp);
}
else if(tmp.vt=VT_NULL)
{
strTmp="";
AfxMessageBox(strTmp);
}
rgResault.ReleaseDispatch(); //释放Range对象

10、 写入数据到Excel,利用安全数组。
VARIANT arr;
arr.vt = VT_ARRAY | VT_VARIANT;
SAFEARRAYBOUND sab[2];
sab[0].lLbound = 1; sab[0].cElements = 10;
sab[1].lLbound = 1; sab[1].cElements = 4;
arr.parray = SafeArrayCreate(VT_VARIANT, 2, sab);

for(int i=1;i<=10;i++)
{
for(int j=1;j<=4;j++)
{
long indices[]={i,j};
VARIANT strTmp;
strTmp.vt = VT_BSTR;
strTmp.bstrVal = ::SysAllocString(L"测试");
SafeArrayPutElement(arr.parray,indices,&strTmp);
}
}

rgMyrange.SetValue2(arr);

11、 当生成的Excel文件存在时,屏蔽保存提示
//屏蔽确定是否保存按妞
COleVariant covTrue((short)TRUE),covFalse((short)FALSE),covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
//关闭book,不保存
wbMybook.Close(covFalse,COleVariant(sExcelFile),covOptional);

12、 获得Excel文件中的有效行数和列数
rgMyrange.AttachDispatch(wsMysheet.GetUsedRange(),TRUE);
Range rgColumn,rgRow;
long lRows,lColumns;
rgRow.AttachDispatch(rgMyrange.GetRows(),TRUE);
rgColumn.AttachDispatch(rgMyrange.GetColumns(),TRUE);

//读取此Excel中的行数、列数
lRows = rgRow.GetCount();
lColumns = rgColumn.GetCount();

CString strtmp;
strtmp.Format("行数为%d,列数为%d",(int)lRows,(int)lColumns);
AfxMessageBox(strtmp);
rgColumn.ReleaseDispatch();
rgRow.ReleaseDispatch();

13、 合并单元格
//得到全部Cells,此时,rgMyRge是cells的集合
rgMyrange.AttachDispatch(wsMysheet.GetCells(),TRUE);
//合并单元格的处理
//包括判断第一个单元格是否为合并单元格,以及将第一个单元格进行合并
Range unionRange;
unionRange.AttachDispatch(rgMyrange.GetItem (COleVariant((long)8),COleVariant((long)3)).pdispVal );

VARIANT vResult;
vResult=unionRange.GetMergeCells(); //merge为合并的意思
if(vResult.boolVal==-1) //是合并的单元格
{
//合并单元格的行数
rgMyrange.AttachDispatch (unionRange.GetRows ());
long iUnionRowNum=rgMyrange.GetCount ();

//合并单元格的列数
rgMyrange.AttachDispatch (unionRange.GetColumns ());
long iUnionColumnNum=rgMyrange.GetCount ();

//合并区域的起始行,列
long iUnionStartRow=unionRange.GetRow(); //起始行,从开始
long iUnionStartCol=unionRange.GetColumn(); //起始列,从开始

}
else if(vResult.boolVal==0)
{ //不是合并的单元格}
//将第行,第列单元格合并成行,列
unionRange.AttachDispatch(unionRange.GetResize(COleVariant((long)2),COleVariant((long)3)));
unionRange.Merge(COleVariant((long)0)); //合并单元格
}

14、 复制Excel表格内容
int iPageCount = CalculateRowCount();
Range RangePosition = m_Range.GetRange(COleVariant("A1"), COleVariant("A1"));
Range RangeCopy = m_Range.GetRange((_variant_t)"A1",(_variant_t)"R29");

int iRowCopy = 31;
for(int i=0;i<iPageCount;i++)
{
RangeCopy.Copy(RangePosition.GetItem((_variant_t)iRowCopy,(_variant_t)1));
iRowCopy += 30;
}

15、 删除整行

CString strRow;
strRow.Format("A%d",iRowIndex);

LPDISPATCH lpDisp = m_Worksheet.GetRange((COleVariant)strRow,(COleVariant)strRow);
Range RangeDelete,entire_row;
RangeDelete.AttachDispatch(lpDisp);

lpDisp = RangeDelete.GetEntireRow(); // 得到整行
entire_row.AttachDispatch(lpDisp);
entire_row.Delete((_variant_t)xlUp); // 删除

entire_row.ReleaseDispatch();
RangeDelete.ReleaseDispatch();

4,011

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 数据库
社区管理员
  • 数据库
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧