您的位置:首页 > 编程语言 > C语言/C++

VC++操作Excel

2015-05-27 09:51 295 查看
摘要:使用Microsoft Office所带的控件来实现代码操作excel表格。

开发环境:操作系统是Microsoft Windows7 32bit,Office办公套装是Microsoft Office 2003,编程环境是Microsoft Visual Studio 6.0。

使用背景:我最近有个项目中要生成报表,是将数据库中的发证数据查询出来导出到Excel表格中以便打印,所以上网找了这方面的内容,具体内容如下,如错误还请指证。

从平常我们操作一般文件上来看,无非是打开文件,操作文件(读取,写入),然后关闭打开的文件。
操作Excel也就是和操作普通文件将其打开,然后写入/读出数据,然后关闭等操作哦。以下是个例子程序:

操作Excel具体如下:因为Excel格式是微软固有的私有格式,如果我想自己操作Excel是完全不可能,所以只有通过微软给我们COM组件接口来操作。这些COM类型列表如下:

《VC++/MFC操作Office必需的类型库参考》

说明:如果需要在VC++/MFC开发程序操作word/excel等office元素,那么需要对必要的类型库进行导入.下面是office系列的类型库参考,导入类型库时候请选择正确的类型库进行导入.

应用程序

类型库
Microsoft Access 97
Msacc8.olb
Microsoft Jet Database 3.5
DAO350.dll
Microsoft Binder 97
Msbdr8.olb
Microsoft Excel 97
Excel8.olb
Microsoft Graph 97
Graph8.olb
Microsoft Office 97
Mso97.dll
Microsoft Outlook 97
Msoutl97.olb
Microsoft PowerPoint 97
Msppt8.olb
Microsoft Word 97
Msword8.olb
Microsoft Access 2000
Msacc9.olb
Microsoft Jet Database 3.51
DAO360.dll
Microsoft Binder 2000
Msbdr9.olb
Microsoft Excel 2000
Excel9.olb
Microsoft Graph 2000
Graph9.olb
Microsoft Office 2000
Mso9.dll
Microsoft Outlook 2000
Msoutl9.olb
Microsoft PowerPoint 2000
Msppt9.olb
Microsoft Word 2000
Msword9.olb
Microsoft Access 2002
Msacc.olb
Microsoft Excel 2002
Excel.exe
Microsoft Graph 2002
Graph.exe
Microsoft Office 2002
MSO.dll
Microsoft Outlook 2002
MSOutl.olb
Microsoft PowerPoint 2002
MSPpt.olb
Microsoft Word 2002
MSWord.olb
Microsoft Office Access 2003
Msacc.olb
Microsoft Office Excel 2003
Excel.exe
Microsoft Office Graph 2003
Graph.exe
Microsoft Office 2003
MSO.dll
Microsoft Office Outlook 2003
MSOutl.olb
Microsoft Office PowerPoint 2003
MSPpt.olb
Microsoft Office Word 2003
MSWord.olb
注意:这些类型库的默认位置是:
Office 版本
路径
Office 97
C:/Program Files/Microsoft Office/Office
Office 2000
C:/Program Files/Microsoft Office/Office
Office XP
C:/Program Files/Microsoft Office/Office10
Office 2003
C:/Program Files/Microsoft Office/Office11
下面是例子的使用:

首先创建一个程序(我的例子是一个MFC的单文档程序),在程序的入口处和出口处先作初始化COM库,来加载我们需要COM的支持:

在程序入口处CXXXApp:: InitInstance()函数AfxEnableControlContainer();语句之后加入下面几行:

if (CoInitialize(NULL) != 0)

{

AfxMessageBox(“初始化COM支持库失败!”);

exit(1);

}

假如这个条件不通过就不能运行起程序。

在程序的退出释放资源处,也就是与初始化对应的地方:CXXXApp:: ExitInstance()函数return语句之前加入下面这句话:

CoUninitialize();
//来释放COM支持库。

{

CoUninitialize();

}

这样我们就完成了对COM支持库的代码已经完成。

下面要从Office的安装目录中找到对VC操作excel文件的动态库,在某些版本下这个文件是Excel8.olb或者Excel9.olb,在我的版本中是excel.exe这个exe也是动态库的形式,是微软公司主要的文件结果之一。

(和使用普通的COM组件一样)选择VC++的View菜单里面的ClassWizad命令,会弹出一个对话框;然后点击Add Class…按钮选择From a type library,会弹出一个打开对话框,从这里打开Office安装目录下…/Office11/EXCEL.EXE文件,从里面选择几个要用到的类:_Application, Workbooks, _Wrokbook,
Worksheets, _WorkSheet, Range,点击OK按钮。会在程序中生成一个excel.h和excel.cpp文件,这些文件中包含了刚才我们选择的几个类的代码。下面介绍一下这几个类:

在VC++操纵Excel的exe动态库里面有好多个对象模型,就是刚才在创建过程中看到的那个列表,但是经常用到的有这么几个:_Application, Workbooks, _Wrokbook, Worksheets, _WorkSheet, Range,Charts和_Chart,最后面的两个是用来操作图表的,我没有用到所以这里也就不记录了。

(a)._Application:这里的Application就是Excel本身,众所周知,一个Excel可以包含多个工作簿,每个工作簿又可以包含多个工作表,而每个工作表又可以包含多个区域或者图表,所以这里他们是树型的结构关系,而application最基本的一个功能就是找到它的子项工作簿。果然,我们在引入我们程序的Application类中看到了这样的成员函数:GetWorkbooks()。既然application就是excel,那么打开程序,退出程序,显示/隐藏程序这些基本的操作都可以在这个类的成员函数中找到,果不其然。

(b).Workbooks:这个对象是一个容器对象,它里面存放着所有打开的工作簿。因此,我们可以猜测它一定有添加,查找,打开/关闭工作簿的功能。(本程序中使用excel的一个xlt模板来生成一个xls文件就是使用了这个容器对象的添加功能。)

(c)._Workbook:这是一个工作簿,也就相当于一个xls文件。Excel可以同时打开多个工作簿,所以工作簿之间必定能够互相切换,每个工作簿可以关联工作表容器并获得工作表的索引。

(d).Worksheets:也是一个容器对象,和Workbooks类似。

(e)._Worksheet:这个就是我们看到的工作表,比如Sheet1,sheet2等等。

(f).Rang:就是我们看到的能选中的方框的大小。而我们所要作的操作基本上是以区域为单位进行的。

介绍完这些,我们就来看看一个例子程序吧,就是使用使用微软给我们提供的组件来操作Excel

<span style="white-space:pre">	</span>{
<span style="white-space:pre">	</span>_Application _app;
_Workbook _workBook;
_Worksheet _workSheet;
Worksheets workSheets;
Workbooks workBooks;
Range range;
Range copyFrom;
Range copyTo;

if(!_app.CreateDispatch("Excel.Application", NULL))
{
MessageBox("创建Excel服务失败!", "信息提示", MB_OK);
return;
}
//利用模板建立新文档
workBooks.AttachDispatch(_app.GetWorkbooks());
_workBook.AttachDispatch(workBooks.Add(_variant_t(vFileName)));//你可以自己创建一个模板,并自由设定目录
//得到worksheets
workSheets.AttachDispatch(_workBook.GetWorksheets());
//得到workSheet
_workSheet.AttachDispatch(workSheets.GetItem(_variant_t("sheet1")));
//得到拷贝的母板
copyFrom.AttachDispatch(_workSheet.GetRange(_variant_t("A3"), _variant_t("Q6")));
copyTo.AttachDispatch(_workSheet.GetRange(_variant_t("A61"), _variant_t("A61")));
//得到全部的cells
range.AttachDispatch(_workSheet.GetCells());

///////////////////////////////////////////////////////////////////////////////////////////////////
// 上边是头

/*
中间要做的工作有这两项:设置数据和拷贝格式
设置数据就是将数据库中查询出来的数据写入表格,拷贝格式就是将表格拷贝到别的地方。
*/
//写入数据
range.SetItem(_variant_t((long)3), _variant_t((long)1), _variant_t("写入数据了"));
range.SetItem(_variant_t((long)5), _variant_t((long)1), _variant_t("重新写入数据了"));
//拷贝一段区域到另外的一段区域
copyFrom.Copy(_variant_t(copyTo));
range.SetItem(_variant_t((long)61), _variant_t((long)1), _variant_t("123"));

//显示excel表格
_app.SetVisible(TRUE);
//保存为文件
_app.SetDisplayAlerts(FALSE);	//隐藏弹出的对话框
_workSheet.SaveAs("d://Test.xls",vtMissing,vtMissing,vtMissing,vtMissing,
vtMissing,vtMissing,vtMissing,vtMissing,vtMissing);
_app.Quit();
//下边是尾
///////////////////////////////////////////////////////////////////////////////////////////////////
copyFrom.ReleaseDispatch();
copyTo.ReleaseDispatch();
range.ReleaseDispatch();
_workSheet.ReleaseDispatch();
workSheets.ReleaseDispatch();
_workBook.ReleaseDispatch();
workSheets.ReleaseDispatch();
_app.ReleaseDispatch();
<span style="white-space:pre">	</span>}


其它:下面是网上一个人封装的一个类大家可以参考一下(当然不如BasicExcel了哈哈,下期讲这个类哈)

<span style="white-space:pre">	</span>.h文件:
<span style="white-space:pre">	</span>#include "comdef.h"
<span style="white-space:pre">	</span>#include "excel.h"
<span style="white-space:pre">	</span>class ExcelFile
<span style="white-space:pre">	</span>{
<span style="white-space:pre">	</span>public:
<span style="white-space:pre">		</span>void ShowInExcel(bool bShow);
<span style="white-space:pre">		</span>CString GetCell(int iRow, int iColumn);
<span style="white-space:pre">		</span>int     GetCellInt(int iRow, int iColumn);
<span style="white-space:pre">		</span>int GetRowCount();
<span style="white-space:pre">		</span>int GetColumnCount();
<span style="white-space:pre">		</span>bool LoadSheet(int iIndex);
<span style="white-space:pre">		</span>CString GetSheetName(int iIndex);
<span style="white-space:pre">		</span>static void InitExcel();
<span style="white-space:pre">		</span>static void ReleaseExcel();
<span style="white-space:pre">		</span>int GetSheetCount();
<span style="white-space:pre">		</span>bool Open(CString FileName);
<span style="white-space:pre">		</span>ExcelFile();
<span style="white-space:pre">		</span>virtual ~ExcelFile();
<span style="white-space:pre">	</span>protected:
<span style="white-space:pre">	</span>private:
<span style="white-space:pre">	</span>static _Application m_ExcelApp;

<span style="white-space:pre">	</span>Workbooks    m_Books;
<span style="white-space:pre">	</span>_Workbook    m_Book;
<span style="white-space:pre">	</span>Worksheets   m_sheets;
<span style="white-space:pre">	</span>_Worksheet   m_sheet;
<span style="white-space:pre">	</span>Range        m_Rge;
<span style="white-space:pre">	</span>};
<span style="white-space:pre">	</span>.cpp文件:
<span style="white-space:pre">	</span>ExcelFile::ExcelFile()
<span style="white-space:pre">	</span>{
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>ExcelFile::~ExcelFile()
<span style="white-space:pre">	</span>{
<span style="white-space:pre">		</span>m_Rge.ReleaseDispatch();
<span style="white-space:pre">		</span>m_sheet.ReleaseDispatch();
<span style="white-space:pre">		</span>m_sheets.ReleaseDispatch();
<span style="white-space:pre">		</span>m_Book.ReleaseDispatch();
<span style="white-space:pre">		</span>m_Books.ReleaseDispatch();
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>void ExcelFile::InitExcel()
<span style="white-space:pre">	</span>{
<span style="white-space:pre">		</span>//创建Excel 2000服务器(启动Excel)
<span style="white-space:pre">		</span>if (!m_ExcelApp.CreateDispatch("Excel.Application",NULL))
<span style="white-space:pre">		</span>{
<span style="white-space:pre">			</span>AfxMessageBox("创建Excel服务失败!");
<span style="white-space:pre">			</span>exit(1);
<span style="white-space:pre">		</span>}
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>void ExcelFile::ReleaseExcel()
<span style="white-space:pre">	</span>{
<span style="white-space:pre">		</span>m_ExcelApp.ReleaseDispatch();
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>bool ExcelFile::Open(CString FileName)
<span style="white-space:pre">	</span>{
<span style="white-space:pre">		</span>//打开excel文件
<span style="white-space:pre">		</span>//利用模板文件建立新文档
<span style="white-space:pre">		</span>m_Books.AttachDispatch(m_ExcelApp.GetWorkbooks(),true);
<span style="white-space:pre">		</span>LPDISPATCH lpDis = NULL;
<span style="white-space:pre">		</span>lpDis = m_Books.Add(_variant_t(FileName)); // 如何判断文件是否打开?
<span style="white-space:pre">		</span>if (lpDis)
<span style="white-space:pre">		</span>{
<span style="white-space:pre">			</span>m_Book.AttachDispatch(lpDis);
<span style="white-space:pre">			</span>//得到Worksheets
<span style="white-space:pre">			</span>m_sheets.AttachDispatch(m_Book.GetWorksheets(),true);
<span style="white-space:pre">			</span>return true;
<span style="white-space:pre">		</span>}
<span style="white-space:pre">		</span>return false;
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>int ExcelFile::GetSheetCount()
<span style="white-space:pre">	</span>{
<span style="white-space:pre">		</span>return m_sheets.GetCount();
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>CString ExcelFile::GetSheetName(int iIndex)
<span style="white-space:pre">	</span>{
<span style="white-space:pre">		</span>_Worksheet sheet;
<span style="white-space:pre">		</span>sheet.AttachDispatch(m_sheets.GetItem(_variant_t((long)iIndex)),true);
<span style="white-space:pre">		</span>CString name = sheet.GetName();
<span style="white-space:pre">		</span>sheet.ReleaseDispatch();
<span style="white-space:pre">		</span>return name;
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>bool ExcelFile::LoadSheet(int iIndex)
<span style="white-space:pre">	</span>{
<span style="white-space:pre">		</span>LPDISPATCH lpDis = NULL;
<span style="white-space:pre">		</span>m_Rge.ReleaseDispatch();
<span style="white-space:pre">		</span>m_sheet.ReleaseDispatch();
<span style="white-space:pre">		</span>lpDis = m_sheets.GetItem(_variant_t((long)iIndex));
<span style="white-space:pre">		</span>if (lpDis)
<span style="white-space:pre">		</span>{
<span style="white-space:pre">	</span>m_sheet.AttachDispatch(lpDis,true);
<span style="white-space:pre">	</span>m_Rge.AttachDispatch(m_sheet.GetCells(), true);
<span style="white-space:pre">	</span>return true;
<span style="white-space:pre">		</span>}
<span style="white-space:pre">		</span>return false;
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>int ExcelFile::GetColumnCount()
<span style="white-space:pre">	</span>{
<span style="white-space:pre">		</span>Range range;
<span style="white-space:pre">		</span>Range usedRange;
<span style="white-space:pre">		</span>usedRange.AttachDispatch(m_sheet.GetUsedRange(), true);
<span style="white-space:pre">		</span>range.AttachDispatch(usedRange.GetColumns(), true);
<span style="white-space:pre">		</span>int count = range.GetCount();
<span style="white-space:pre">		</span>usedRange.ReleaseDispatch();
<span style="white-space:pre">		</span>range.ReleaseDispatch();
<span style="white-space:pre">		</span>return count;
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>int ExcelFile::GetRowCount()
<span style="white-space:pre">	</span>{
<span style="white-space:pre">		</span>Range range;
<span style="white-space:pre">		</span>Range usedRange;
<span style="white-space:pre">		</span>usedRange.AttachDispatch(m_sheet.GetUsedRange(), true);
<span style="white-space:pre">		</span>range.AttachDispatch(usedRange.GetRows(), true);
<span style="white-space:pre">		</span>int count = range.GetCount();
<span style="white-space:pre">		</span>usedRange.ReleaseDispatch();
<span style="white-space:pre">		</span>range.ReleaseDispatch();
<span style="white-space:pre">		</span>return count;
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>CString ExcelFile::GetCell(int iRow, int iColumn)
<span style="white-space:pre">	</span>{
<span style="white-space:pre">		</span>Range range;
<span style="white-space:pre">		</span>range.AttachDispatch(m_Rge.GetItem (COleVariant((long)iRow),COleVariant((long)iColumn)).pdispVal, true);
<span style="white-space:pre">	</span>COleVariant vResult =range.GetValue2();
<span style="white-space:pre">		</span>CString str;
<span style="white-space:pre">		</span>if(vResult.vt == VT_BSTR)       //字符串
<span style="white-space:pre">		</span>{
<span style="white-space:pre">			</span>str=vResult.bstrVal;
<span style="white-space:pre">		</span>}
<span style="white-space:pre">		</span>else if (vResult.vt==VT_INT)
<span style="white-space:pre">		</span>{
<span style="white-space:pre">	</span>str.Format("%d",vResult.pintVal);
<span style="white-space:pre">		</span>}
<span style="white-space:pre">		</span>else if (vResult.vt==VT_R8)     //8字节的数字
<span style="white-space:pre">		</span>{
<span style="white-space:pre">			</span>str.Format("%f",vResult.dblVal);
<span style="white-space:pre">			</span>//str.Format("%.0f",vResult.dblVal);
<span style="white-space:pre">			</span>//str.Format("%1f",vResult.fltVal);
<span style="white-space:pre">		</span>}
<span style="white-space:pre">		</span>else if(vResult.vt==VT_DATE)    //时间格式
<span style="white-space:pre">		</span>{
<span style="white-space:pre">			</span>SYSTEMTIME st;
<span style="white-space:pre">			</span>VariantTimeToSystemTime(vResult.date, &st);
<span style="white-space:pre">		</span>}
<span style="white-space:pre">		</span>else if(vResult.vt==VT_EMPTY)   //单元格空的
<span style="white-space:pre">		</span>{
<span style="white-space:pre">		</span>str="(NULL)";
<span style="white-space:pre">		</span>}
<span style="white-space:pre">		</span>range.ReleaseDispatch();
<span style="white-space:pre">		</span>return str;
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>int ExcelFile::GetCellInt(int iRow, int iColumn)
<span style="white-space:pre">	</span>{
<span style="white-space:pre">		</span>Range range;
<span style="white-space:pre">		</span>range.AttachDispatch(m_Rge.GetItem(COleVariant((long)iRow),COleVariant((long)iColumn)).pdispVal, true);
<span style="white-space:pre">		</span>COleVariant vResult =range.GetValue2();
<span style="white-space:pre">		</span>int num;
<span style="white-space:pre">		</span>num = (int)vResult.date;
<span style="white-space:pre">		</span>range.ReleaseDispatch();
<span style="white-space:pre">		</span>return num;
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>void ExcelFile::ShowInExcel(bool bShow)
<span style="white-space:pre">	</span>{
<span style="white-space:pre">		</span>m_ExcelApp.SetVisible(bShow);
<span style="white-space:pre">	</span>}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: