C++读取excel特定行列中的数据

 

可以通过COM API调用才是正解,不过需要编写COM接口类,Excel对象库的接口太多了……不过可以用工具自动生成。

我最近也在用VC操作Excel,在VC中可以这样做,在任何一个cpp文件中加入下面三行:

1 #import "C:\Program Files\Common Files\Microsoft Shared\OFFICE11\MSO.DLL" rename("RGB","rgb") rename("DocumentProperties", "document_properties")
2 #import "C:\Program Files\Common Files\Microsoft Shared\VBA\VBA6\VBE6EXT.OLB"
3 #import "D:\Program Files\Microsoft Office\OFFICE11\EXCEL.EXE" rename("RGB","rgb") rename("DialogBox", "dialog_box")

然后编译。

注意,这样编译是通不过的,不过没关系,在Debug目录中你会看到mso.tlh、mso.tli、vb6ext.tlh、vb6ext.tli、excel.tlh、excel.tli六个文件,它们就是VC编译器通过类型库信息自动生成的接口类型定义和一些辅助类。把它们复制到你的源代码目录,然后打开vb6ext.tlh,进行修改:

1 #include <comdef.h>
2 #include "mso.tlh" //加入这一行
3  
4 namespace VBIDE 
5 {
6 using namespace Office;//加入这一行
7 ...

再修改excel.tlh文件:

1 #include <comdef.h>
2 #include "mso.tlh" //加入这一行
3 #include "vbe6ext.tlh" //加入这一行
4  
5 namespace Excel 
6 {
7 using namespace VBIDE;//加入这一行

这时把那三行#import删除,换成#include "excel.tlh"就可以用了:

 1 #include "stdafx.h"
 2 #include "excel.tlh"
 3 #include <iostream>
 4  
 5 int _tmain(int argc, _TCHAR* argv[])
 6  
 7 {
 8     CoInitializeEx( 0, COINIT_APARTMENTTHREADED );
 9     Excel::_ApplicationPtr xApp;
10     xApp.CreateInstance(__uuidof(Excel::Application));
11     Excel::_WorkbookPtr xBook = xApp->Workbooks->Open(L"test.xsl");
12     Excel::_WorksheetPtr xSheet = xBook->ActiveSheet;
13      
14     _bstr_t text = xSheet->Range[L"A1"][vtMissing]->Text;//读取单元格内容,_bstr_t封装了COM宽字符串BSTR
15     std::cout << static_cast<char const *>(text);//_bstr_t类定义了到char const *的类型转换,会把unicode字符串转换为当前代码页的多字节编码字符串
16     return 0;
17 }

 

把Excel作为数据库直接通过ODBC方式读取

 1 #include <odbcinst.h>
 2 #include <afxdb.h>
 3  
 4  
 5 CString strXlsFileName = "X:\\XXX.xls";
 6 CString strSql;
 7 strSql.Format(L"DRIVER={MICROSOFT EXCEL DRIVER (*.xls)};DSN='';FIRSTROWHASNAMES=1;READONLY=FALSE;CREATE_DB=\"%s\";DBQ=%s", strXlsFileName, strXlsFileName);
 8  
 9 CDatabase *pCDatabase = new CDatabase;   
10 pCDatabase->OpenEx(strSql, CDatabase::noOdbcDialog);
11  
12 CString strSheetName = "你要操作的表名称";
13 CString strSql;
14 strSql.Format(L"SELECT * FROM [%s$A1:IV65536]", strSheetName);   
15  
16 CRecordset *pCRecordset = new CRecordset(pCDatabase);
17 pCRecordset->Open(CRecordset::forwardOnly, strSql, CRecordset::readOnly);
18  
19 CString strField;
20 pCRecordset->GetFieldValue((short)0, strField);//读取第1行第1列的单元格内容
21 pCRecordset->GetFieldValue((short)3, strField);//第1行第4列
22 pCRecordset->MoveNext();//游标指向下一行,再用GetFieldValue就可以读取下一行的内容

 

posted @ 2015-03-17 16:31  醉游  阅读(7463)  评论(0编辑  收藏  举报