读取Excel表格数据,当数据量很大时,如果直接读取会造成ui界面卡顿,所以需要建立线程,在线程里读取数据。
一、建立继承QThread的读取数据类
建立读取数据线程,重写run()函数
.h文件如下:
#ifndef THREADREADDATA_H
#define THREADREADDATA_H
#include <QThread>
#include <QWaitCondition>
#include "ui_mainwindow.h"
class threadReadData : public QThread
{
Q_OBJECT
public:
explicit threadReadData(QObject *parent = nullptr);
~threadReadData() override;
void handleFunc();
QString filename;
signals:
void request(const QVariant var);
private:
void run() override;
};
#endif // THREADREADDATA_H
.cpp文件如下:
#include "threadreaddata.h"
#include <QFileDialog>
#include <QAxObject>
#include <QStandardPaths>
#include <QDebug>
threadReadData::threadReadData(QObject *parent):
QThread(parent)
{
}
threadReadData::~threadReadData()
{
quit();
}
void threadReadData::handleFunc()
{
if(!isRunning())
start();
}
void threadReadData::run()
{
//读取数据
QAxObject *excel = new QAxObject();//建立excel操作对象
excel->setControl("Excel.Application");//连接Excel控件
excel->setProperty("Visible", false);//显示窗体看效果,选择ture将会看到excel表格被打开
excel->setProperty("DisplayAlerts", true);//显示警告看效果
QAxObject *workbooks = excel->querySubObject("WorkBooks");//获取工作簿(excel文件)集合
qDebug()<<"filename:"<<filename;
workbooks->dynamicCall("Open(const QString&)", filename);//打开刚才选定的excel
QAxObject *workbook = excel->querySubObject("ActiveWorkBook");
QAxObject *worksheet = workbook->querySubObject("WorkSheets(int)",1);
QAxObject *usedRange = worksheet->querySubObject("UsedRange");//获取表格中的数据范围
QVariant var = usedRange->dynamicCall("Value");
workbook->dynamicCall( "Close(Boolean)", false );
excel->dynamicCall( "Quit(void)" );
delete excel;//关闭excel
emit request(var);
}
代码第39行,新建QVariant容器,将所有的数据读取到QVariant容器中保存,数据读取完毕后,关闭Excel表格,并将保存的数据发射出去。
二、实现【打开文件按钮】槽函数
通过QFileDialog::getOpenFileName()获取Excel文件名称,使用contains()函数判断文件类型是否正确,如果正确则启动数据读取线程函数m_thread.handleFunc()。
读取数据时,更新进度槽函数,当读取至99%时,等待数据读取完毕,然后进度条更新至100%。
读取数据槽函数如下:
void MainWindow::on_actionOpen_triggered()
{
QString FileName = QFileDialog::getOpenFileName(this,
tr("文件对话框"),
QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation),
tr("ALL files (*);;Excel Files(*.xlsx);;Text Files(*.txt)"));
// qDebug() << "filename:" << FileName;
ui->labelPath->setText(FileName);
m_thread.filename = FileName;
if(FileName.contains(".xlsx", Qt::CaseSensitive) != true)
{
qDebug()<<"地址错误!";
QMessageBox::information(nullptr, "地址错误", "地址错误,\n请重新选择!",
QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
return;
}
progressBarTimer.start();
ui->actionOpen->setEnabled(false);
ui->actionStart->setEnabled(false);
ui->actionPause->setEnabled(false);
ui->actionStop->setEnabled(false);
ui->actionForward->setEnabled(false);
ui->actionBackward->setEnabled(false);
ui->actionReset->setEnabled(false);
m_thread.handleFunc();
}
进度条槽函数如下:
void MainWindow::on_progressBar_valueChanged()
{
ui->progressBar->setValue(progressBarValue);
if(progressBarValue >= 100)
{
progressBarTimer.stop();
progressBarValue = 0;
ui->actionStart->setEnabled(true);
ui->pushButtonSource->setEnabled(true);
return;
}
if(progressBarValue < 99)
{
progressBarValue += 1;
}
}
这样就实现了线程读取Excel数据,ui界面不会卡顿。
关注微信公众号 小白技术栈 | lakalako,获取更多的内容,欢迎大家关注哦!