zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    Volatile关键字的解读
    JVM内存模型
    Redis为何是单线程的
    乐观锁&CAS问题
    String为什么要设置成Final类型
    后端开发之光!Django应用的容器化部署实践~
    一小时完成后台开发:DjangoRestFramework开发实践
    Django快速开发实践:Drf框架和xadmin配置指北
    Django应用部署:nginx+uwsgi方式
    Python踩坑:类与类对象类型参数传递与使用
  • 原文地址:https://www.cnblogs.com/lkpp/p/ReadandWriteExcelFilesCppviaADO.html
Copyright © 2011-2022 走看看