QT使用QAxWidget在多线程中读取Excel数据
(1)本次工程创建于Qt Creator,因此需要配置对应的 .pro 文件,为其引入 Active Qt库。
QT += axcontainer
(2)为增加对QAxObject的支持,需要引入对应的头文件
#include "ActiveQt/qaxobject.h"
#include <objbase.h>
(3)为解决返回QAxObject为空的问题,需要在创建QAxObject()之前调用如下代码
CoInitializeEx(NULL, COINIT_MULTITHREADED);
m_pExcel = new(std::nothrow) QAxObject();
由于我们项目中使用的是多线程,而QAxObject默认是在单线程下使用的,如果不用上面代码提前声明多线程, 会导致获取的excel的QAxObject都是NULL。
(4)为保证读取文件时,定义文件目录的准确性,这里统一使用 ’\' 进行分隔,同时使用如下方式进行格式化
work_books->dynamicCall("Open (const QString&)", QDir::toNativeSeparators(m_strPath));
(5)文件的结束符应该在文件整个读取完毕后使用,如果不关闭会影响进程的运行速度
work_book->dynamicCall("Close(Boolean)", false); //关闭文件
m_pExcel->dynamicCall("Quit(void)"); //退出
详细读取代码如下:
int i=0;
QString sheetName="";
QAxObject* m_pExcel;
QString m_strPath;
m_strPath = "Excil文件路径";
//判断路径是否正确
if(!QFile::exists(m_strPath))
{
return;
}
CoInitializeEx(NULL, COINIT_MULTITHREADED);
m_pExcel = new(std::nothrow) QAxObject();
//判断对象创建是否成功
if (NULL == m_pExcel) {
return;
}
//创建Excel服务
m_pExcel->setControl("Excel.Application");
//设置当前窗口的显示状态:true 表示操作文件时可见,false表示为不可见
m_pExcel->dynamicCall("SetVisible(bool)", false);
//设置是否显示报警
m_pExcel->setProperty("DisplayAlerts", false);
//创建工作表
QAxObject *work_books = m_pExcel->querySubObject("WorkBooks");
//在工作表中打开文件
work_books->dynamicCall("Open (const QString&)", QDir::toNativeSeparators(m_strPath));
//获取当前工作表
QAxObject *work_book = m_pExcel->querySubObject("ActiveWorkBook");
//获取当前工作表中所有的sheet表
QAxObject *work_sheets = work_book->querySubObject("Sheets");
//获取sheet表的数量
int sheet_count = work_sheets->property("Count").toInt();
//在QT读取Excel时,sheet及sheet的行和列的起始地址都是从1开始的
for (i = 1; i <= sheet_count; ++i)
{
//获取sheet(i)
QAxObject *work_sheet = work_book->querySubObject("Sheets(int)", i);
//获取sheet中的所有数据
QAxObject *used_range = work_sheet->querySubObject("UsedRange");
//获取sheet中的所有行数据
QAxObject *rows = used_range->querySubObject("Rows");
//获取行数
int row_count = rows->property("Count").toInt();
//获取sheet表的表名
sheetName = work_sheet->property("Name").toString();
//这里第一行是表头,数据从第二行开始
for(int i = 2; i<=row_count; ++i)
{
int row_1_data = work_sheet->querySubObject("Cells(int,int)", i, 1)->property("Value").toUInt();
int row_2_data = work_sheet->querySubObject("Cells(int,int)", i, 2)->property("Value").toUInt();
char * row_3_data = (char*)work_sheet->querySubObject("Cells(int,int)", i, 3)->property("Value").toString().toStdString().c_str();
if (sheetName == QStringLiteral("三年一班"))//表名为"三年一班"的话执行一下操作
{
vYX.push_back(info);
}
else
{
continue;
}
}
}
work_book->dynamicCall("Close(Boolean)", false); //关闭文件
m_pExcel->dynamicCall("Quit(void)"); //退出