qt導出、操作excel(多線程)

使用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

 

源碼下載

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章