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

 

源码下载

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