使用QAxObject在多線程下進行excel操作,將原來固定格式的文本文件,通過解析之後寫入到excel中。
- 效果圖
- 多線程使用
Worker *pWorker = new Worker();
connect(pWorker, SIGNAL(errorSignal(QString)), this, SLOT(onError(QString)));
connect(pWorker, SIGNAL(progressData(int, QString)), this, SLOT(onProgress(int, QString)));
connect(pWorker, SIGNAL(finish()), this, SLOT(onFinish()));
pWorker->setPath(m_pSrcEdit->text(), m_pDetEdit->text());
QThread *thread = new QThread;
pWorker->moveToThread(thread);
// 處理數據
connect(thread, SIGNAL(started()), pWorker, SLOT(startTrans()), Qt::QueuedConnection);
thread->start();
-
導出線程類實現
Worker.cpp
#include "Worker.h"
#include <QFile>
#include <QDebug>
#include <QApplication>
#include <QAxObject>
#include <QDir>
#include <QThread>
#include "qt_windows.h"
Worker::Worker(QObject *parent) : QObject(parent)
{
}
void Worker::setPath(QString src, QString det)
{
m_sSrcFileName = src;
m_sDetFileName = det;
}
void Worker::startTrans()
{
qDebug() << "child:" << QThread::currentThreadId();
if (/*m_sSrcFileName.isEmpty() ||*/ m_sDetFileName.isEmpty())
{
emit errorSignal(QStringLiteral("選擇文件不能爲空!"));
return;
}
//獲取數據
getData();
//寫入Excel
writeFristSheet();
}
void Worker::getData()
{
m_oData.clear();
// QFile file(m_sSrcFileName);
// if (!file.open(QFile::ReadOnly))
// {
// emit errorSignal(QStringLiteral("打開原始數據文件錯誤!"));
// return;
// }
// QString strAll = file.readAll();
// file.close();
QString str(QStringLiteral("正在解析數據..."));
emit progressData(0, str);
//demo中直接模擬數據,真正使用需要讀取文件,解析獲取數據
for (int i = 0; i < 100; ++i)
{
QList<QVariant> coluDate;
emit progressData(i*100 / 100 - 1, str);
for (int j = 0; j < 20; ++j) {
coluDate << QString::number(i) + "_" + QString::number(j);
}
m_oData << coluDate;
}
}
void Worker::writeFristSheet()
{
//多線程必須初始化
CoInitializeEx(NULL, COINIT_MULTITHREADED);
QString str(QStringLiteral("正在寫入Excel數據..."));
emit progressData(0, str);
QAxObject excel("Excel.Application");
QAxObject *work_books = excel.querySubObject("WorkBooks");
// QString s = qApp->applicationDirPath();
// work_books->dynamicCall("Open (const QString&)", s + "/temp.xlsx");
work_books->dynamicCall("Add");
QAxObject *work_book = excel.querySubObject("ActiveWorkBook");
QAxObject *work_sheet = work_book->querySubObject("Sheets(int)", 1); //Sheets(int)也可換用Worksheets(int)
if(m_oData.size() <= 0)
return;
if(NULL == work_sheet || work_sheet->isNull())
return;
int row = m_oData.size();
int col = m_oData.at(0).size();
for (int i = 1; i <= row; ++i)
{
int n = i*100.0/row;
emit progressData(n, str);
for (int j = 1; j <= col; ++j)
{
QAxObject *cell = work_sheet->querySubObject("Cells(int,int)", i, j);
cell->setProperty("Value", m_oData[i-1][j-1]);
}
}
work_book->dynamicCall("SaveAs(const QString&)", QDir::toNativeSeparators(m_sDetFileName)); //另存爲另一個文件
excel.dynamicCall("Quit(void)", false); //退出
emit finish();
// m_pLabel->setText(QStringLiteral("數據轉換完成!"));
}
Worker.h
#ifndef WORKER_H
#define WORKER_H
#include <QObject>
class Worker : public QObject
{
Q_OBJECT
public:
explicit Worker(QObject *parent = 0);
void setPath(QString src, QString det);
signals:
void finish();
void errorSignal(QString strMsg);
void progressData(int nValue, QString str);
private:
void getData();
void writeFristSheet();
public slots:
void startTrans();
private:
QList<QList<QVariant>> m_oData;
QString m_sSrcFileName;
QString m_sDetFileName;
};
#endif // WORKER_H