QT读取exel和容易出bug的注意点
路径不要有中文,即使是你用的默认路径,只要你项目所在的文件夹,从C:开始,一路中所有的子文件中,命名带任何除了英文、下划线、数字之外的字符,QT读取文件都会报错!!sheet的遍历是从1开始的!从1开始的!从1开始的!。不是从0,写0会报错,搞得你云里雾里,具体报的什么错我也忘记了,希望那些也遇到这些错误的人有缘可以看到我这个博客。本文才用的打开一个sheet,一次性将其内容全部读入,而不是单个c
·
- 路径不要有中文,不要有任何奇怪的字符,如
-横杠,也不行。即使是你用的默认路径,只要你项目所在的文件夹,从C:开始,一路中所有的子文件中,命名带任何除了英文、下划线、数字之外的字符,QT读取文件都会报错!!这个错误我查了好久,希望看过的人注意。 - sheet的遍历是从1开始的!从1开始的!从1开始的!。不是从0,写0会报错,搞得你云里雾里,具体报的什么错我也忘记了,希望那些也遇到这些错误的人有缘可以看到我这个博客。
- 后续补充:如果已知sheet的名字,可以直接定位到该Sheet,不需要遍历。这是一个改进。
- 本文才用的打开一个sheet,一次性将其内容全部读入,而不是单个cell的读入,这样会更省时。
- .pro文件里添加
QT += axcontainer
TARGET = QtExcel
- 需要的头文件
#include <QAxObject>
#include <QVariantList>
#include <QVariant>
#include <windows.h>
#include <QTextStream>
- Note that: 读取excel等的操作都是以字符串为关键字来执行的,所以字符串内容注意不能错误,注意拼写和大小写等。
- Qt处理excel 由于还设计什么多线程的知识,此处不太懂,总是就是还需要在代码收尾分别加一个初始化和关闭的代码,如下
HRESULT result = OleInitialize(nullptr);//initialize CoInitialize--used for single thread
if (result != S_OK && result != S_FALSE)
{
qDebug()<<QString("Could not initialize OLE (error %x)").arg(static_cast<unsigned int>(result));
}
readCsv();//放在打开excel操作前
OleUninitialize();//放在excel关闭后
以上所有代码整合后如下
#include <QAxObject>
#include <QVariantList>
#include <QVariant>
#include <windows.h>
#include <QTextStream>
int main()
{
HRESULT result = OleInitialize(nullptr);//initialize CoInitialize--used for single thread
if (result != S_OK && result != S_FALSE)
{
qDebug()<<QString("Could not initialize OLE (error %x)").arg(static_cast<unsigned int>(result));
}
readCsv();//放在打开excel操作前
QAxObject excel("Excel.Application");
QAxObject *workbooks=nullptr;
QAxObject *workbook=nullptr;
QAxObject *worksheets=nullptr;
QAxObject *worksheet=nullptr;
excel.dynamicCall("SetVisible(bool)",false);//打开excel过程中是否显示打开excel程序,否为不打开
workbooks=excel.querySubObject("WorkBooks");
workbook=workbooks->querySubObject("Open(QString&)","C:/test.xlsx");
worksheets=workbook->querySubObject("Sheets");
int sheetNum=worksheets->property("Count").toInt();
QString ourRequiredName("sheet2");
for(int i=1;i<sheetNum;i++)
{
worksheet=worksheets->querySubObject("Item(int)",i);
QString sheetName=worksheet->property("Name").toString();
if(sheetName==ourRequiredName)
{
QAxObject *usedRange=worksheet->querySubObject("UsedRange");
QVariant cellTemp=usedRange->dynamicCall("Value");
QVariantList cell=cellTemp.toList();//此时cell为一个二维List.
for(int j=0;j<cell.size();j++)//一行一行的读取
{
QVariantList item=cell.at(j).toList;//获得了第j行的数据
int test=item.at(0).toInt();//获得第j行的第1列数据,假设为int类型,后面可以再添加自己需要获得的信息
...
}
}
}
workbook->dynamicCall("CLose()");
excel.dynamicCall("Quit()");
OleUninitialize();//放在excel关闭后
return 0;
}
改进后代码
#include <QAxObject>
#include <QVariantList>
#include <QVariant>
#include <windows.h>
#include <QTextStream>
int main()
{
HRESULT result = OleInitialize(nullptr);//initialize CoInitialize--used for single thread
if (result != S_OK && result != S_FALSE)
{
qDebug()<<QString("Could not initialize OLE (error %x)").arg(static_cast<unsigned int>(result));
}
readCsv();//放在打开excel操作前
QAxObject excel("Excel.Application");
QAxObject *workbooks=nullptr;
QAxObject *workbook=nullptr;
QAxObject *worksheets=nullptr;
QAxObject *worksheet=nullptr;
excel.dynamicCall("SetVisible(bool)",false);//打开excel过程中是否显示打开excel程序,否为不打开
workbooks=excel.querySubObject("WorkBooks");
workbook=workbooks->querySubObject("Open(QString&)","C:/test.xlsx");
worksheets=workbook->querySubObject("Sheets");
int sheetNum=worksheets->property("Count").toInt();
QString ourRequiredName("sheet2");
worksheet=worksheets->querySubObject("Item(String)",ourRequiredName);
QAxObject *usedRange=worksheet->querySubObject("UsedRange");
QVariant cellTemp=usedRange->dynamicCall("Value");
QVariantList cell=cellTemp.toList();//此时cell为一个二维List.
for(int j=0;j<cell.size();j++)//一行一行的读取
{
QVariantList item=cell.at(j).toList;//获得了第j行的数据
int test=item.at(0).toInt();//获得第j行的第1列数据,假设为int类型,后面可以再添加自己需要获得的信息
...
}
workbook->dynamicCall("CLose()");
excel.dynamicCall("Quit()");
OleUninitialize();//放在excel关闭后
return 0;
更多推荐
所有评论(0)