异想家博采众长的客厅

Qt使用QAxObject快速批量读取Excel内容

2017.05.05

网上各种教程用的方法主要是如下这一句:

QAxObject * range = worksheet->querySubObject("Cells(int,int)", 1, 1 );

这种方法当然也行,可以一项一项地读,但是当读取数量很大的时候就很慢了,在我的电脑上测试读5000个数据大约168s左右。看资料找到一种批量读取的方法,经测试读10000行的数据才3s多,效果超级棒,充分发挥了QAxobject读取的优势。

核心代码在于这一句:

QAxObject *range = worksheet->querySubObject("Range(QString)", "B13:C1000");

用Range(QString)实现选取一大块区域,一次性读一个数组出来当然快啦。

附上完整的源码供大家交流学习:

pro中加一句:QT+=axcontainer

核心代码:

#include 
// 批量读取xls到map  
int readEnvXlsFile(QString FileName, QMap<QString,float> &map)  
{  
    QAxObject *excel = NULL;  
    QAxObject *workbooks = NULL;  
    QAxObject *workbook = NULL;  
    excel = new QAxObject("Excel.Application");  
    if (!excel)  
    {  
        qDebug() << "EXCEL对象丢失!";  
    }  
    excel->dynamicCall("SetVisible(bool)", false);  
    workbooks = excel->querySubObject("WorkBooks");  
    workbook = workbooks->querySubObject("Open(QString, QVariant)", FileName);  
    QAxObject * worksheet = workbook->querySubObject("WorkSheets(int)", 1);//打开第一个sheet  
    QAxObject * usedrange = worksheet->querySubObject("UsedRange");//获取该sheet的使用范围对象  
    QAxObject * rows = usedrange->querySubObject("Rows");  
    QAxObject * columns = usedrange->querySubObject("Columns");  
    int intRows = rows->property("Count").toInt();  
    int intCols = columns->property("Count").toInt();  
    qDebug() << "xls行数:"<<intRows;  
    qDebug() << "xls列数:"<<intCols;  
  
    // 批量载入数据,这里默认读取B13:C最后  
    QString Range = "B13:C" +QString::number(intRows);  
    QAxObject *allEnvData = worksheet->querySubObject("Range(QString)", Range);  
    QVariant allEnvDataQVariant = allEnvData->property("Value");  
    QVariantList allEnvDataList = allEnvDataQVariant.toList();  
  
    for(int i=0; i<= intRows-13; i++)  
    {  
        QVariantList allEnvDataList_i =  allEnvDataList[i].toList() ;  
        //qDebug()<< allEnvDataList_i[0].toString()<< allEnvDataList_i[1].toFloat();  
        map.insert(allEnvDataList_i[0].toString(),allEnvDataList_i[1].toFloat());  
    }  
    workbooks->dynamicCall("Close()");  
    return 0;  
}  

Update 2017-05-06: 看了一下百度的这一篇已经提到了此方法。