QT<3>导出数据为EXCL格式

一、效果演示

(1)查询SQlite数据库页面

其中数据库表中是用软件手动添加的,推荐一个软件,需要的话找我要安装包,也可以网页搜索 SQLite Expert Prefessional

(2)点击导出操作日志,选择保存文件位置和文件名

(3)保存后进入子线程中执行导出操作,不影响UI界面操作

二、详细代码

(1)获取tablewidget中表格数据。开始选择用QMap接收,所以就只获取表格后两列信息,用信号发到子线程中导出,报错显示信号与槽参数不能是QMap类型,又转成QVariantMap类型。

    QMap<QString, QString> keyValueMap;

    // 遍历表格并存储第二列和第三列信息到QMap容器
    for (int row = 0; row < ui->tableWidget->rowCount(); ++row) {
        QTableWidgetItem *keyItem = ui->tableWidget->item(row, 1); // 第二列
        QTableWidgetItem *valueItem = ui->tableWidget->item(row, 2); // 第三列
        if (keyItem && valueItem) {
            QString key = keyItem->text();
            QString value = valueItem->text();
            keyValueMap.insert(key, value);
        }
    }
    QVariantMap variantMap;
    for (auto it = keyValueMap.begin(); it != keyValueMap.end(); ++it) {
        variantMap.insert(it.key(), it.value());
    }

(2)开启子线程执行导出操作

(1)和(2)都是在保存操作日志按钮槽函数中,首先弹出选择保存位置和文件名的选择框,SaveThread是继承自QObject的一类,专用于执行子线程导出操作。使用movetoThread()方法添加到子线程中,发送保存的文件名(子线程用会用到)和tablewidget中表格的数据。

    QString fileName = QFileDialog::getSaveFileName(this,tr("Excle file"),QString("./test.xlsx"),tr("Excel Files(*.xlsx)")); //设置保存的文件名
    if(fileName != NULL)
    {
        SaveThread *work = new SaveThread();
        thread = new QThread;
        work->moveToThread(thread);
        connect(this,&OperatorRecord::thread_save,work,&SaveThread::SaveOperatorThread);
        connect(this,&OperatorRecord::thread_filename,work,&SaveThread::filenamethread);
        connect(work,&SaveThread::threadend,this,&OperatorRecord::savesuccess);
        thread_filename(fileName);
        thread_save(variantMap);
        thread->start();
    }

(3)子线程中导出操作,之前用QMap写好了,后改的QVariantMap,所以接收到又转为QMap类型。因为之前发来的表格数据只有后两列(时间和操作),创建excl表格时加了一列序号。完成之后发送子线程结束信号,销毁子线程释放内存。

void SaveThread::SaveOperatorThread(QVariantMap variantMap)
{
    QMap<QString, QString> keyValueMap;
    for (auto it = variantMap.begin(); it != variantMap.end(); ++it) {
        keyValueMap.insert(it.key(), it.value().toString());
    }

    QMap<QString, QString>::const_iterator iter = keyValueMap.constBegin();

    QAxObject* excel = new QAxObject("Excel.Application", this);
    excel->dynamicCall("SetVisible(bool)", false);
    excel->setProperty("DisplayAlerts", false);
    QAxObject* workbooks = excel->querySubObject("Workbooks");
    workbooks->dynamicCall("Add");
    QAxObject* workbook = excel->querySubObject("ActiveWorkbook");
    QAxObject* worksheet = workbook->querySubObject("Worksheets(int)", 1);

    int rowCount = keyValueMap.size();
    int columnCount = 3;

    // 写入标题
    for (int i = 1; i <= columnCount; i++) {
        QAxObject* cell = worksheet->querySubObject("Cells(int,int)", 1, i);
        cell->setProperty("RowHeight", 40);
        if (i == 1)
            cell->dynamicCall("SetValue(const QString&)", "序号");
        else if (i == 2)
            cell->dynamicCall("SetValue(const QString&)", "操作时间");
        else if (i == 3)
            cell->dynamicCall("SetValue(const QString&)", "操作");
    }

    // 写入数据
    int row = 2;
    for (auto it = keyValueMap.begin(); it != keyValueMap.end(); ++it) {
        QAxObject* cell = worksheet->querySubObject("Cells(int,int)", row, 1);
        cell->dynamicCall("SetValue(int)", row - 2);

        cell = worksheet->querySubObject("Cells(int,int)", row, 2);
        cell->dynamicCall("SetValue(const QString&)", it.key());

        cell = worksheet->querySubObject("Cells(int,int)", row, 3);
        cell->dynamicCall("SetValue(const QString&)", it.value());

        ++row;
    }

    // 保存文件
    workbook->dynamicCall("SaveAs(const QString&)", QDir::toNativeSeparators(save_filename));
    workbook->dynamicCall("Close()");
    excel->dynamicCall("Quit()");
    delete excel;
    excel = nullptr;

    threadend();//线程结束信号
}

void SaveThread::filenamethread(QString filename)
{
    save_filename = filename;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值