当前位置: 代码迷 >> 综合 >> Qt快速读取Excel,QVariant?转QList MyType
  详细解决方案

Qt快速读取Excel,QVariant?转QList MyType

热度:7   发布时间:2023-10-15 18:40:53.0

参考好多博客,天下博客一大抄,有人不会抄!导致没有得到结果。

故此,写文档用于记录两部分内容:

1、Qt读取Excel的两种方法:1.1、逐单元格读取(慢),1.2、整体范围读取(快)

2、Qt读取Excel之后,数据存储在QVariant  var中,如何将 QVariant 中的数据,读进QList<QList<MyType> >,然后读进QList<MyType>。

3、Qt写入Excel的方法,还没有完成,后续补充。。。没法直接写 .xlsx文件,但是可以直接写 .csv文件,而且很方便。

链接如下:https://blog.csdn.net/qq_34732729/article/details/101070546

新建一个demo 界面有点丑,凑合着看,主要是记录代码

Qt快速读取Excel,QVariant 转QList MyType

在demo.pro文件中,加入如下代码:

QT       += core gui
QT       += axcontainer            # 添加此行代码

在mainwindow.h(也有人在mainwindow.cpp)中,添加相应的头文件:

#include<QAxObject>

文件构成如下:

Qt快速读取Excel,QVariant 转QList MyType   

方法的.h文件

// readExcel.htypedef struct orderInfo
{QString serialNum;int ID;QString product;int stockSum;int soldSum;double singlePrice;double totalPrice;
}orderInfo;class readExcel
{
public:readExcel();bool openFile_slow(QString fileName);bool openFile_fase(QString fileName);void castVariant2ListListVariant(QVariant &var, QList<orderInfo> &orderlst);private:orderInfo order;QList<orderInfo> order_lst;
};

 1.1、逐单元格读取(慢),一并转换到MyType

 1.2、逐单元格读取(快)

 2、 转换到MyType数据结构

//readExcel.cpp
bool readExcel::openFile_slow(QString fileName)
{bool flag = false;QAxObject excel("Excel.Application");            //加载Excel驱动excel.setProperty("Visible", false);                    //不显示Excel界面,如果为true会看到启动的Excel界面QAxObject *work_books = excel.querySubObject("WorkBooks");          // 父类work_books->dynamicCall("Open (const QString&)", fileName);         //打开指定路径文件QString("D:/QtProject/ReadExcel/test.xlsx")QVariant title_value = excel.property("Caption");                                   // 获取标题QAxObject *work_book = excel.querySubObject("ActiveWorkBook");         // 激活当前工作簿QAxObject *work_sheets = work_book->querySubObject("Sheets");           // 获取工作表,sheets也可以换成WorkSheetsint sheet_count = work_sheets->property("Count").toInt();                    // 获取工作表数目for(int i = 1; i <= sheet_count; ++i)           // 从1开始计算{QAxObject *work_sheet = work_book->querySubObject("Sheets(int)", i);        // 挨个输出sheet表。由于此文件只有一个,所以只输出一个QString  work_sheet_name = work_sheet->property("Name").toString();            // 获取工作表名称QString message = QString("sheet") + QString::number(i, 10) + QString(" name");             // 整型,10进制
//        qDebug() << message << work_sheet_name;}// 开始读取if(sheet_count > 0){QAxObject *work_sheet = work_book->querySubObject("Sheets(int)", 1);        // 只输出第一个sheet表QAxObject *used_range = work_sheet->querySubObject("UsedRange");            // 范围QAxObject *rows = used_range->querySubObject("Rows");               // 行QAxObject *columns = used_range->querySubObject("Columns");     // 列int row_start = used_range->property("Row").toInt();            // 起始行
//        qDebug() << "start_row: " << row_start;     // 1int column_start = used_range->property("Columns").toInt();         // 起始列
//        qDebug() << "start_column: " << column_start;       // 0int row_count = rows->property("Count").toInt();            // 获取行数
//        qDebug() << "row_count : " << row_count;        // 输出行数int column_count = columns->property("Count").toInt();      // 获取列数
//        qDebug() << "column_count : " << column_count;      // 输出列数QAxObject *cell;        // 用于定位的指针QVariant cell_value;    // 存储值信息int j = 0;for(int i = row_start + 2; i <= row_count; ++i)     // 跳过首行和标题{j = column_start + 1;       // 由于列是从0开始,但是cells()不能输入0,所以得加1cell = work_sheet->querySubObject("Cells(int, int)", i, j);cell_value = cell->property("Value");       // 获取单元格内容order.serialNum = cell_value.toString();++j;cell = work_sheet->querySubObject("Cells(int, int)", i, j);cell_value = cell->property("Value");       // 获取单元格内容order.ID = cell_value.toInt();++j;cell = work_sheet->querySubObject("Cells(int, int)", i, j);cell_value = cell->property("Value");       // 获取单元格内容order.product = cell_value.toString();++j;cell = work_sheet->querySubObject("Cells(int, int)", i, j);cell_value = cell->property("Value");       // 获取单元格内容order.stockSum = cell_value.toInt();++j;cell = work_sheet->querySubObject("Cells(int, int)", i, j);cell_value = cell->property("Value");       // 获取单元格内容order.soldSum = cell_value.toInt();++j;cell = work_sheet->querySubObject("Cells(int, int)", i, j);cell_value = cell->property("Value");       // 获取单元格内容order.singlePrice = cell_value.toDouble();++j;cell = work_sheet->querySubObject("Cells(int, int)", i, j);cell_value = cell->property("Value");       // 获取单元格内容order.totalPrice = cell_value.toDouble();order_lst.push_back(order);}work_books->dynamicCall("Close()");flag = true;}return flag;
}// 快方法读取
bool readExcel::openFile_fase(QString fileName)
{bool flag = false;QAxObject excel("Excel.Application");            //加载Excel驱动excel.setProperty("Visible", false);                    //不显示Excel界面,如果为true会看到启动的Excel界面QAxObject *work_books = excel.querySubObject("WorkBooks");          // 父类work_books->dynamicCall("Open (const QString&)", fileName);         //打开指定路径文件QString("D:/QtProject/ReadExcel/test.xlsx")QVariant title_value = excel.property("Caption");                                   // 获取标题QAxObject *work_book = excel.querySubObject("ActiveWorkBook");         // 激活当前工作簿QAxObject *work_sheets = work_book->querySubObject("Sheets");           // 获取工作表,sheets也可以换成WorkSheetsint sheet_count = work_sheets->property("Count").toInt();                    // 获取工作表数目for(int i = 1; i <= sheet_count; ++i)           // 从1开始计算{QAxObject *work_sheet = work_book->querySubObject("Sheets(int)", i);        // 挨个输出sheet表。由于此文件只有一个,所以只输出一个QString  work_sheet_name = work_sheet->property("Name").toString();            // 获取工作表名称QString message = QString("sheet") + QString::number(i, 10) + QString(" name");             // 整型,10进制
//        qDebug() << message << work_sheet_name;}if(sheet_count > 0){QAxObject *work_sheet = work_book->querySubObject("Sheets(int)", 1);        // 只输出第一个sheet表QVariant var;if(work_sheet != NULL && !work_sheet->isNull()){QAxObject *used_range = work_sheet->querySubObject("UsedRange");            // 范围if(NULL == used_range || used_range->isNull()){return flag;}var = used_range->dynamicCall("Value");QList<QList<QVariant> > res;castVariant2ListListVariant(var, order_lst);      // 此函数将var读进QList<MyType>flag = true;delete used_range;}}return flag;
}// 转换
void readExcel::castVariant2ListListVariant(QVariant &var, QList<orderInfo> &orderlst)
{QVariantList varRows = var.toList();if(varRows.isEmpty()){return;}const int rowCount = varRows.size();QVariantList rowData;for(int i = 2; i < rowCount; ++i)       // 除去第一行注释和第二行表头{rowData = varRows[i].toList();order.serialNum = rowData.value(0).toString();order.ID = rowData.value(1).toInt();order.product = rowData.value(2).toString();order.stockSum = rowData.value(3).toInt();order.soldSum = rowData.value(4).toInt();order.singlePrice = rowData.value(5).toDouble();order.totalPrice = rowData.value(6).toDouble();orderlst.push_back(order);}
}

 主函数调用方法:

// mainwindow.cpp 方法如下
// 打开Excel
void MainWindow::on_pushButton_clicked()
{fileName = getFileName();ui->lineEdit->setText(fileName);
}// 慢方法读取Excel到var
void MainWindow::on_pushButton_2_clicked()
{QElapsedTimer mstimer;mstimer.start();readData.openFile_slow(fileName);        // 执行代码float time = (double)mstimer.nsecsElapsed()/(double)1000000;QString strTime = QString("%1").arg(time);ui->lineEdit_2->setText(strTime);
}// 快方法读取Excel到var
void MainWindow::on_pushButton_3_clicked()
{QElapsedTimer mstimer;mstimer.start();readData.openFile_fase(fileName);        // 执行代码float time = (double)mstimer.nsecsElapsed()/(double)1000000;QString strTime = QString("%1").arg(time);ui->lineEdit_3->setText(strTime);
}

成果如下:

Qt快速读取Excel,QVariant 转QList MyType

以上耗时,都加上了转换到MyType的时间,比较慢。如果不加,还是挺快的。

参考博客:

https://blog.csdn.net/x85371169/article/details/79268258

https://blog.csdn.net/qq_34732729/article/details/98864769

  相关解决方案