• 路径不要有中文,不要有任何奇怪的字符,如-横杠,也不行。即使是你用的默认路径,只要你项目所在的文件夹,从C:开始,一路中所有的子文件中,命名带任何除了英文、下划线、数字之外的字符,QT读取文件都会报错!!这个错误我查了好久,希望看过的人注意。
  • sheet的遍历是从1开始的!从1开始的!从1开始的!。不是从0,写0会报错,搞得你云里雾里,具体报的什么错我也忘记了,希望那些也遇到这些错误的人有缘可以看到我这个博客。
  • 后续补充:如果已知sheet的名字,可以直接定位到该Sheet,不需要遍历。这是一个改进。
  • 本文才用的打开一个sheet,一次性将其内容全部读入,而不是单个cell的读入,这样会更省时。
  1. .pro文件里添加
QT += axcontainer
TARGET = QtExcel
  1. 需要的头文件
#include <QAxObject>
#include <QVariantList>
#include <QVariant>
#include <windows.h>
#include <QTextStream>
  1. Note that: 读取excel等的操作都是以字符串为关键字来执行的,所以字符串内容注意不能错误,注意拼写和大小写等。
  2. 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;
Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐