標籤:
可以通過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寬字元串BSTR15 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就可以讀取下一行的內容
C++讀取excel特定行列中的資料