C++通過ADO讀寫Excel文件


介紹

有時候我們需要從excel表格里導入、導出數據。其中一種方式就是通過ADO的方式。在這里,excel文件被當作數據庫來處理,該方式不需要客戶端安裝Microsoft Excel,速度也夠快。

連接字符串

這里有兩種類型的連接字符串,第一種是針對xls格式的:

Provider=Microsoft.JET.OLEDB.4.0;Data Source=data.xls;Extended Properties="Excel 8.0"

第二種是針對xlsx格式的:

Provider=Microsoft.ACE.OLEDB.12.0;Data Source=data.xlsx;
Extended Properties="Excel 12.0 Xml" 

TESTHR定義

inline void TESTHR(HRESULT x) { if FAILED(x) _com_issue_error(x); };

寫入

首先創建一個連接字符串:

TESTHR(pCon.CreateInstance(__uuidof(Connection)));
TESTHR(pCon->Open(connStr, "", "", NULL)); 

然后創建Command對象和表,注意表名就是excel的頁:

TESTHR(pCmd.CreateInstance(__uuidof(Command)));
pCmd->ActiveConnection = pCon;       
pCmd->CommandText = "CREATE TABLE MySheet
    (A int, B varchar, C int, D int, E int, F int, G int, H int, I int, J varchar)";   
pCmd->Execute(NULL, NULL, adCmdText); 

創建Recordset並增加記錄:

TESTHR(pRec.CreateInstance(__uuidof(Recordset)));
pRec->Open("SELECT * FROM MySheet", _variant_t((IDispatch*)pCon), 
	adOpenKeyset, adLockOptimistic, adCmdText);

for(int i = 0; i < writeRows; ++i)
{
    TESTHR(pRec->AddNew());

    char str[11] = {0}; for(int j = 0; j < 10; ++j) str[j] = 'a' + (rand() % 26);

    pRec->Fields->GetItem("A")->Value = _variant_t(i);            
    pRec->Fields->GetItem("B")->Value = _variant_t(str);            
    pRec->Fields->GetItem("C")->Value = _variant_t(i);
    pRec->Fields->GetItem("D")->Value = _variant_t(i);
    pRec->Fields->GetItem("E")->Value = _variant_t(i);
    pRec->Fields->GetItem("F")->Value = _variant_t(i);
    pRec->Fields->GetItem("G")->Value = _variant_t(i);
    pRec->Fields->GetItem("H")->Value = _variant_t(i);
    pRec->Fields->GetItem("I")->Value = _variant_t(i);
    pRec->Fields->GetItem("J")->Value = _variant_t(str);            
}
TESTHR(pRec->Update());
TESTHR(pRec->Close());

讀取

創建和打開Recordset:

TESTHR(pRec.CreateInstance(__uuidof(Recordset)));       
TESTHR(pRec->Open("SELECT * FROM [Sheet1$]", connStr, 
	adOpenStatic, adLockOptimistic, adCmdText));

如果excel的頁不清楚,可以通過索引來查找:

TESTHR(pCon.CreateInstance(__uuidof(Connection)));
TESTHR(pCon->Open(connStr, "", "", NULL));
    
pSchema = pCon->OpenSchema(adSchemaTables);      

for(int i = 0; i < sheetIndex; ++i) pSchema->MoveNext();

std::string sheetName = 
	(char*)(_bstr_t)pSchema->Fields->GetItem("TABLE_NAME")->Value.bstrVal;

讀取單元格的值:

while(!pRec->adoEOF)
{
    for(long i = 0; i < pRec->Fields->GetCount(); ++i)
    {
        if(i > 0) stream << ";";                    
        _variant_t v = pRec->Fields->GetItem(i)->Value;
        if(v.vt == VT_R8)                                           
            stream << v.dblVal;
        if(v.vt == VT_BSTR)
            stream << (char*)(_bstr_t)v.bstrVal;                                
    }                                    
    stream << std::endl;
    pRec->MoveNext();
} 

參考資料

  1. How to Read and Write Excel Files in C++ via ADO
  2. C++ using adodb to read excel file in 64-bit windows 7?
  3. AccessDatabaseEngine#install instruction


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM