VC用OLE方式读写Excel
前几天要做一个项目,需要读取Excel中的数据。从网上查资料发现,主要是有两种方式。一是把Excel表当成数据库使用ODBC读写,这样操作起来就跟操作Access数据库似的。但这种方式效率比较低。另一种方法是OLE技术(Object Linking and Embedding,对象连接与嵌入)。OLE是一种面向对象的技术,利用这种技术可开发可重复使用的软件组件(COM)。本文主要介绍使用OLE技术对Excel读写的方法。
本文中使用的环境是Windows XP,VS2008,Excel2007。
1) 在你建立的VC工程中点击“项目”->“添加类”->“TypeLib中的MFC类”->点击“确定”
2) 这时会出现一个“从类型库添加类向导”对话框,选中“文件”选项,然后选择文件位置:C:\Program Files\Microsoft Office\Office12\EXCEL.EXE 将接口列表中的_Application,_Workbook,_Worksheet,Range,Ranges,Workbooks,Worksheets等接口添加到右侧。点击“完成”。
3) 给VC工程添加一个新的C++类,命名为CExcel。在excel.h文件中添加以下头文件:
#include "CApplication.h"
#include "CRange.h"
#include "CRanges.h"
#include "CWorkbook.h"
#include "CWorkbooks.h"
#include "CWorksheet.h"
#include "CWorksheets.h"
4)依次打开以上添加的7个头文件,把每个文件中的#import "C:\\Program Files\\Microsoft Office\\Office12\\EXCEL.EXE" no_namespace 这一行注释掉(否则后面会报错)。另外要把CRange.h文件中第335行VARIANT DialogBox()中的DialogBox换个名字,例如可以换成ExcelDialogBox()。
至此准备工作完毕,剩下的就是把对Excel的操作封装成一个类了。首先创建一个Excel服务器,然后就是根据各个头文件中提供的函数,打开Excel,获取workbook,获取worksheet,选择某个单元格,获取该单元格的值。或者是选择某一片区域(Range)然后将该区域内的值输出在一个二维数组里。
#include "CApplication.h" #include "CRange.h" #include "CRanges.h" #include "CWorkbook.h" #include "CWorkbooks.h" #include "CWorksheet.h" #include "CWorksheets.h" #pragma once class CExcel { public: CExcel(void); ~CExcel(void); void OpenExcel(CString path); void OpenSheet(CString SheetName); CString GetCellValue(long row,long col); CString GetCellValueByName(CString rowName,CString colName); private: CApplication app; CWorkbooks books; CWorkbook book; CWorksheets sheets; CWorksheet sheet; CRange range; LPDISPATCH lpDisp; };
#include "StdAfx.h" #include "Excel.h" CExcel::CExcel(void) { if(!app.CreateDispatch(_T("Excel.Application"),NULL)) { AfxMessageBox(_T("启动Excel服务器失败!")); } lpDisp = NULL; } CExcel::~CExcel(void) { app.ReleaseDispatch(); books.ReleaseDispatch(); book.ReleaseDispatch(); sheets.ReleaseDispatch(); sheet.ReleaseDispatch(); range.ReleaseDispatch(); } void CExcel::OpenExcel(CString path) { books.AttachDispatch(app.get_Workbooks(),1); COleVariant varPath(path); book.AttachDispatch(books.Add(varPath)); } void CExcel::OpenSheet(CString SheetName) { sheets.AttachDispatch(book.get_Sheets(),TRUE); COleVariant var2(SheetName); sheet.AttachDispatch(sheets.get_Item(var2),TRUE); } CString CExcel::GetCellValue(long row,long col) { _variant_t varRow(row); _variant_t varCol(col); COleVariant value; range.AttachDispatch(sheet.get_Cells(),TRUE); value=range.get_Item(varRow,varCol); //返回的类型是VT_DISPATCH 这是一个指针 range.AttachDispatch(value.pdispVal,TRUE); VARIANT value2=range.get_Text(); CString strValue=value2.bstrVal; return strValue; } CString CExcel::GetCellValueByName(CString rowName,CString colName) { COleVariant value; CString strValue; long row=0,col=0; long re_row=0,re_col=0; range.AttachDispatch(sheet.get_Cells(),TRUE); for (row=1,col=1;col<range.get_Column();col++) { value=range.get_Item(_variant_t(row),_variant_t(col)); //返回的类型是VT_DISPATCH 这是一个指针 range.AttachDispatch(value.pdispVal,TRUE); VARIANT value2=range.get_Text(); CString strValue=value2.bstrVal; if (strValue==colName) break; } re_col=col; for (row=1,row=1;row<range.get_Row();row++) { value=range.get_Item(_variant_t(row),_variant_t(col)); //返回的类型是VT_DISPATCH 这是一个指针 range.AttachDispatch(value.pdispVal,TRUE); VARIANT value2=range.get_Text(); CString strValue=value2.bstrVal; if (strValue==rowName) break; } re_row=row; return GetCellValue(re_row,re_col); }