qt中数据库和excel互导数据————附带详细步骤和代码

news2024/11/16 0:05:04

文章目录

  • 0 背景
  • 1 准备QXlsx环境
    • 1.1 cmake安装使用
    • 1.2 qmake使用
  • 2 把excel数据导出到mysql数据库
  • 3 把mysql数据库的数据写入到excel
  • 4 完整代码
  • 5 项目代码仓库

0 背景

因为需要批量导入和导出数据,所以需要用到excel。实现把数据库的数据导入到excel中,把excel中的数据导出到数据库。这里使用了开源代码库QXlsx。

1 准备QXlsx环境

官网中的qmake的使用方法,cmake的使用方法。

1.1 cmake安装使用

  • 1,输入下列指令安装:
mkdir build
cd build
cmake ../QXlsx/ -DCMAKE_INSTALL_PREFIX=... -DCMAKE_BUILD_TYPE=Release
cmake --build .
cmake --install .

在CMakeLists.txt中添加如下内容:

find_package(QXlsxQt5 REQUIRED) # or QXlsxQt6
target_link_libraries(myapp PRIVATE QXlsx::QXlsx)
  • 2,下面是无需安装的两种使用方法:

使用cmake的子目录在 CMakeLists.txt:

add_subdirectory(QXlsx)
target_link_libraries(myapp PRIVATE QXlsx::QXlsx)

使用 cmake FetchContent 在 CMakeLists.txt:

FetchContent_Declare(
  QXlsx
  GIT_REPOSITORY https://github.com/QtExcel/QXlsx.git
  GIT_TAG        sha-of-the-commit
  SOURCE_SUBDIR  QXlsx
)
FetchContent_MakeAvailable(QXlsx)
target_link_libraries(myapp PRIVATE QXlsx::QXlsx)

如果 QT_VERSION_MAJOR没有设置, QXlsx’s的 CMakeLists.txt 将尝试自己寻找 Qt 版本(5 或 6)。

1.2 qmake使用

下载QXsx的github项目代码。

  • 1,把QXsx项目中的代码(选中的三个项目)复制到自己项目下;

在这里插入图片描述

复制到自己项目下(新建一个QXlxs文件夹,存储文件):
在这里插入图片描述

在这里插入图片描述

  • 2,在pro中添加如下代码;
QXLSX_PARENTPATH=./         # current QXlsx path is . (. means curret directory)
QXLSX_HEADERPATH=./QXlsx/header/  # current QXlsx header path is ./header/
QXLSX_SOURCEPATH=./QXlsx/source/  # current QXlsx source path is ./source/
include(./QXlsx/QXlsx.pri)

  • 3,编译文件后,会自动把文件添加到项目中(绿色的那一部分);

  • 4,添加如下头文件,就可以开始项目编写;
#include "xlsxdocument.h"
#include "xlsxchartsheet.h"
#include "xlsxcellrange.h"
#include "xlsxchart.h"
#include "xlsxrichstring.h"
#include "xlsxworkbook.h"

测试程序:

// main.cpp

#include <QCoreApplication>

#include "xlsxdocument.h"
#include "xlsxchartsheet.h"
#include "xlsxcellrange.h"
#include "xlsxchart.h"
#include "xlsxrichstring.h"
#include "xlsxworkbook.h"
using namespace QXlsx;

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QXlsx::Document xlsx;
    xlsx.write("A1", "Hello Qt!"); // write "Hello Qt!" to cell(A,1). it's shared string.
    xlsx.saveAs("Test.xlsx"); // save the document as 'Test.xlsx'

    return 0;
    // return a.exec();
}

2 把excel数据导出到mysql数据库

  • 1,准备要导入的账号和密码的excel表(第一行为数据库的字段名,必须一样;如果数据库中字段值不能为空,excel中数据也不能为空);
    在这里插入图片描述
    账号信息.xlsx

在这里插入图片描述
数据库中的login_information表

  • 2,在数据库中创建表格;
DROP TABLE IF EXISTS `login_information`;
CREATE TABLE `login_information`  (
  `account` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
  `password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
  PRIMARY KEY (`account`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = DYNAMIC;

  • 3,建立数据库连接;

方法:

static bool CreateConnection(){
    //        qDebug()<<"查看目前可用驱动";
    //        QStringList drivers = QSqlDatabase::drivers();
    //        for(auto driver: drivers){
    //            qDebug()<<driver<<" ";
    //        }

    //设置数据库驱动
    QSqlDatabase mysqlDB = QSqlDatabase::addDatabase("QMYSQL", "mysql_connection1");
    mysqlDB.setHostName("192.168.0.104");
    mysqlDB.setUserName("root");
    mysqlDB.setPassword("password");
    mysqlDB.setPort(8889);
    mysqlDB.setDatabaseName("test_db");

    //根据系统环境设计数据库路径
    // Q_OS_LINUX:Q_OS_WIN: Q_OS_MAC   Q_OS_WIN32

    //如果远程mysql数据库没有打开
    if(!mysqlDB.open()){
        return false;
    }else{

        // #ifdef Q_OS_WIN
        mysqlDB.exec("SET NAMES 'GBK'");
        // #endif
        // #ifdef Q_OS_MAC

        // #endif
    }

    //QSqlDatabase sqliteDB = QSqlDatabase::addDatabase("QSQLITE", "sqlite_connection1");

    // #ifdef Q_OS_WIN //Q_OS_WIN32
    //     qDebug()<<"QCoreApplication::applicationDirPath():"<<QCoreApplication::applicationDirPath();
    //     sqliteDB.setDatabaseName(QCoreApplication::applicationDirPath() + QString("/database/LocalSystemDatabse.db"));
    // #endif

    //如果本地sqlite数据库没有打开
    // if(!sqliteDB.open()){
    //     QMessageBox* databaseInformationBox = new QMessageBox(QMessageBox::Critical, ("信息提示"),  ("不能建立本地数据库连接!"), QMessageBox::Yes);
    //     auto button =  databaseInformationBox->exec();
    //     if(button == QMessageBox::Yes){
    //         databaseInformationBox->deleteLater();
    //     }
    //     return false;
    // }

    return true;

}

调用:

//main中创建数据库连接
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    //连接数据库
    if (!CreateConnection()){
        qDebug()<<"数据库连接失败";
    }
    return a.exec();
}
  • 4,把excel中的数据导入到数据库中;
bool exportExcel2Database(QStringList filePaths,  QString xlsxName, QString sqlSentence){
    QList<bool> execResultList;//操作的结果集
    bool execResult = false;
    QSqlDatabase db = QSqlDatabase::database("mysql_connection1");
    QSqlQuery query(db);
    if(db.transaction()){
        foreach(QString filePath, filePaths) {
            QXlsx::Document xlsx(filePath);

            if(!xlsx.selectSheet(xlsxName)){/*在当前打开的xlsx文件中,找一个名字为ziv的sheet*/
                //xlsx.addSheet(xlsxName);//找不到的话就添加一个名为ziv的sheet
                qDebug()<<"没有对应的xlsx表";
                return false;
            }else{

            }

            QQueue<QString> tableFieldQueue;
            QHash<QString, QVariantList> tableAlterFiledValue;

            for(int row = 1; row <= xlsx.dimension().rowCount(); row++) {
                // 获取每行的数据并插入到数据库中
                for(int col = 1; col <= xlsx.dimension().columnCount();col++){
                    if(row == 1){
                        tableFieldQueue.enqueue(xlsx.read(row, col).toString());

                    }else{
                        tableAlterFiledValue[tableFieldQueue[col-1]].append(xlsx.read(row, col));
                    }
                }
            }

            query.prepare(sqlSentence);
            foreach (QString tableFiled, tableFieldQueue) {
                query.addBindValue(tableAlterFiledValue[tableFiled]);
            }

            execResult = query.execBatch();
            execResultList.append(execResult);
            if(!execResult) {//批量执行数据插入
                qDebug() <<  query.lastError().databaseText();
            }

        }

        foreach (bool result, execResultList) {
            if(result == false){
                if(!db.rollback())
                {
                    qDebug() << "数据库回滚失败"<<db.lastError().databaseText(); //回滚
                }else{
                    qDebug()<<"数据库回滚成功";
                }
                return false;
            }

        }

        if(db.commit()){
            return true;
        }else{
            return false;
        }
    }
    return false;
}

调用:

    QStringList filePaths;
    filePaths<<"D:/test/账号信息.xlsx";

    //考试细节步骤
    QString sql2 = QString("INSERT INTO  login_information(account, password)  VALUES (?, ?)");
    QString xlsxName2 = "账号信息";
    // qDebug()<<sql2;

    if(exportExcel2Database(filePaths, xlsxName2, sql2)){
        qDebug()<<"导入成功";
    }else{
        qDebug()<<"导入失败";
    }

,

3 把mysql数据库的数据写入到excel

  • 1,建立数据库连接,同上;

  • 2,把数据库中表的数据导出到excel中;

bool exportData2XLSX(QString fileName, QString tableName)
{

    QXlsx::Document xlsx;
    QXlsx::Format format1;/*设置标题单元的样式*/
    format1.setFontSize(12);/*设置字体大小*/
    format1.setHorizontalAlignment(QXlsx::Format::AlignHCenter);/*横向居中*/
    //format1.setBorderStyle(QXlsx::Format::BorderThin);/*边框样式*/
    //format1.setFontBold(true);/*设置加粗*/

    if(!xlsx.selectSheet("表格数据")){/*在当前打开的xlsx文件中,找一个名字为ziv的sheet*/
        xlsx.addSheet("表格数据");//找不到的话就添加一个名为ziv的sheet
    }

    QSqlDatabase db = QSqlDatabase::database("mysql_connection1");
    QString tmpSql = QString("SELECT * FROM %1").arg(tableName);
    QSqlQuery query(db);
    if(query.exec(tmpSql)){
        //表头列
        QSqlRecord queryRecord(query.record());
        qDebug()<<"queryRecord.count():"<<queryRecord.count();
        for(int colNum = 0; colNum < queryRecord.count(); colNum++){
            //qDebug() <<  queryRecord.fieldName(colNum);
            xlsx.write(1, colNum+1,  queryRecord.fieldName(colNum),format1);
        }

        //表格数据
        int rowNum = 2;
        while(query.next()){
            for(int colNum = 0; colNum < queryRecord.count(); colNum++){
                xlsx.write(rowNum, colNum + 1, query.value(colNum),format1);
            }
            rowNum++;
        }
    }else{
        return false;
    }

    if(fileName.isEmpty())
        return false;

    xlsx.saveAs(fileName);//保存文件

    return true;
}

调用:


int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    //连接数据库
    if (!CreateConnection()){
        qDebug()<<"数据库连接失败";
    }
    
    QString tableName = "login_information";
    QString fileName = "D:/账号.xlsx";
    if(exportData2XLSX(fileName, tableName)){
        qDebug()<<"导入excel成功";
    }else{
        qDebug()<<"导入excel失败";
    }
    
    return a.exec();
}

4 完整代码

#include <QCoreApplication>

#include "create_connection.h"

#include "xlsxdocument.h"
#include "xlsxchartsheet.h"
#include "xlsxcellrange.h"
#include "xlsxchart.h"
#include "xlsxrichstring.h"
#include "xlsxworkbook.h"

#include <QSqlError>
#include <QQueue>
#include <QHash>
#include <QSqlRecord>

bool exportExcel2Database(QStringList filePaths,  QString xlsxName, QString sqlSentence){
    QList<bool> execResultList;
    bool execResult = false;
    QSqlDatabase db = QSqlDatabase::database("mysql_connection1");
    QSqlQuery query(db);
    if(db.transaction()){
        foreach(QString filePath, filePaths) {
            QXlsx::Document xlsx(filePath);

            if(!xlsx.selectSheet(xlsxName)){/*在当前打开的xlsx文件中,找一个名字为ziv的sheet*/
                //xlsx.addSheet(xlsxName);//找不到的话就添加一个名为ziv的sheet
                qDebug()<<"没有对应的xlsx表";
                return false;
            }else{

            }

            QQueue<QString> tableFieldQueue;
            QHash<QString, QVariantList> tableAlterFiledValue;

            for(int row = 1; row <= xlsx.dimension().rowCount(); row++) {
                // 获取每行的数据并插入到数据库中
                for(int col = 1; col <= xlsx.dimension().columnCount();col++){
                    if(row == 1){
                        tableFieldQueue.enqueue(xlsx.read(row, col).toString());

                    }else{
                        tableAlterFiledValue[tableFieldQueue[col-1]].append(xlsx.read(row, col));
                    }
                }
            }

            query.prepare(sqlSentence);
            foreach (QString tableFiled, tableFieldQueue) {
                query.addBindValue(tableAlterFiledValue[tableFiled]);
            }

            execResult = query.execBatch();
            execResultList.append(execResult);
            if(!execResult) {//批量执行数据插入
                qDebug() <<  query.lastError().databaseText();
            }

        }

        foreach (bool result, execResultList) {
            if(result == false){
                if(!db.rollback())
                {
                    qDebug() << "数据库回滚失败"<<db.lastError().databaseText(); //回滚
                }else{
                    qDebug()<<"数据库回滚成功";
                }
                return false;
            }

        }

        if(db.commit()){
            return true;
        }else{
            return false;
        }
    }
    return false;
}

bool exportData2XLSX(QString fileName, QString tableName)
{

    QXlsx::Document xlsx;
    QXlsx::Format format1;/*设置标题单元的样式*/
    format1.setFontSize(12);/*设置字体大小*/
    format1.setHorizontalAlignment(QXlsx::Format::AlignHCenter);/*横向居中*/
    //format1.setBorderStyle(QXlsx::Format::BorderThin);/*边框样式*/
    //format1.setFontBold(true);/*设置加粗*/

    if(!xlsx.selectSheet("表格数据")){/*在当前打开的xlsx文件中,找一个名字为ziv的sheet*/
        xlsx.addSheet("表格数据");//找不到的话就添加一个名为ziv的sheet
    }

    QSqlDatabase db = QSqlDatabase::database("mysql_connection1");
    QString tmpSql = QString("SELECT * FROM %1").arg(tableName);
    QSqlQuery query(db);
    if(query.exec(tmpSql)){
        //表头列
        QSqlRecord queryRecord(query.record());
        qDebug()<<"queryRecord.count():"<<queryRecord.count();
        for(int colNum = 0; colNum < queryRecord.count(); colNum++){
            //qDebug() <<  queryRecord.fieldName(colNum);
            xlsx.write(1, colNum+1,  queryRecord.fieldName(colNum),format1);
        }

        //表格数据
        int rowNum = 2;
        while(query.next()){
            for(int colNum = 0; colNum < queryRecord.count(); colNum++){
                xlsx.write(rowNum, colNum + 1, query.value(colNum),format1);
            }
            rowNum++;
        }
    }else{
        return false;
    }

    if(fileName.isEmpty())
        return false;

    xlsx.saveAs(fileName);//保存文件

    return true;
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    //连接数据库
    if (!CreateConnection()){
        qDebug()<<"数据库连接失败";
    }
    
    QString tableName = "login_information";
    QString fileName = "D:/账号.xlsx";
    if(exportData2XLSX(fileName, tableName)){
        qDebug()<<"导入excel成功";
    }else{
        qDebug()<<"导入excel失败";
    }

    return a.exec();
}

5 项目代码仓库

代码仓库(欢迎star):

github仓库
码云

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1883483.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

matrix-breakout-2-morpheus靶场

1 信息收集 1.1 主机发现 arp-scan -l 1.2 端口与服务扫描 发现开放22、80、81端口 2 访问服务 2.1 访问80端口 查看源代码 2.2 访问81端口 3 目录扫描 3.1 dirsearch目录扫描 dirsearch -u 192.168.1.14 发现robots.txt文件和javascript文件 访问文件 http://192.168…

linux网络命令:httpie详解-简单易用的命令行 HTTP 客户端

目录 一、命令概述 二、基本特点 1、直观和友好的命令语句 2、内置 JSON 支持 3、支持多种请求方法 4、支持 HTTPS、代理和授权验证 5、支持多种请求数据格式 6、自定义 headers 头 7、持久 sessions 存储 8、插件支持 三、安装 1、对于基于 Debian 的系统&#xf…

【你也能从零基础学会网站开发】关系型数据库中的表(Table)设计结构以及核心组成部分

&#x1f680; 个人主页 极客小俊 ✍&#x1f3fb; 作者简介&#xff1a;程序猿、设计师、技术分享 &#x1f40b; 希望大家多多支持, 我们一起学习和进步&#xff01; &#x1f3c5; 欢迎评论 ❤️点赞&#x1f4ac;评论 &#x1f4c2;收藏 &#x1f4c2;加关注 关系型数据库中…

idea 项目互联网转内网开发 依赖报错问题 maven问题

场景&#xff1a; 这个问题困扰好久&#xff0c;通过分析后&#xff0c;发现是maven配置问题&#xff0c;废话不多说&#xff0c;上干活。 问题描述 项目互联网从转内网开发&#xff0c;提前下载好repository&#xff0c;跟项目一起导入内网&#xff0c;导入后&#xff0c;发…

Jasper Report详细使用教程

1、编写jrxml文件 1.1 新建项目 使用Jaspersoft Studio来创建一个项目&#xff0c;如图所示&#xff0c;新建一个项目&#xff0c;步骤&#xff1a; File -> New -> Project->JasperReportsProject 1.2 新建一个Jasper Report模板 找到你新建的项目。步骤&#xff1a;…

昇思25天学习打卡营第6天|简单的深度学习模型实战 - 函数式自动微分

自动微分(Automatic Differentiation)是什么&#xff1f;微分是函数在某一处的导数值&#xff0c;自动微分就是使用计算机程序自动求解函数在某一处的导数值。自动微分可用于计算神经网络反向传播的梯度大小&#xff0c;是机器学习训练中不可或缺的一步。 这些公式难免让人头大…

抛弃 Neofetch?众多优秀替代方案等你体验!

目录 抛弃 Neofetch&#xff1f;众多优秀替代方案等你体验Neofetch 的替代品FastfetchscreenFetchmacchina 抛弃 Neofetch&#xff1f;众多优秀替代方案等你体验 NeoFetch 是用 Bash 3.2 编写的命令行系统信息工具&#xff0c;该项目的主要开发人员已将 GitHub 存储库存档&…

【C++11:右值引用,列表初始化】

统一列表初始化&#xff1a; 构造函数的函数名与函数体之间增加一个列表&#xff0c;用于对成员初始化 在实例化对象时&#xff0c;支持单/多参数的隐式转化&#xff0c;同时也可以省略符号&#xff0c;让代码更简洁 右值的引用 左值&#xff1a; 左值与右值的重要区别就是能…

用代码实现加载中动图 loading.gif

效果 仅使用htmlcss&#xff0c;效果如下所示 代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><title>加载中</title><style>.el-loading-spinner .circular {height: 42px;width: 42px;…

7.1作业

初始化 /******rcc章节初始化********/ |//1.使能gpiob组控制器 |RCC->MP_AHB4ENSETR |(0X1<<1); |//2.使能gpiog组控制器 |RCC-&…

【TB作品】矩阵键盘电话拨号,ATMEGA16单片机,Proteus仿真 atmega16矩阵键盘电话拨号

atmega16矩阵键盘电话拨号 c代码和仿真图&#xff1a; 使用ATmega16实现矩阵键盘电话拨号功能 项目背景 在电子设计和嵌入式系统开发中&#xff0c;矩阵键盘是常见的人机交互方式。它可以实现较多按键的输入&#xff0c;同时节省单片机的I/O资源。结合LCD显示和蜂鸣器&am…

四城联动 | 亚控KingSCADA4.0信创版发布会圆满收官

圆满收官 随着科技的飞速发展&#xff0c;智能制造和工业自动化已成为推动产业升级的重要力量。在这样的背景下&#xff0c;北京亚控科技发展有限公司&#xff08;以下简称“亚控科技”&#xff09;于2024年6月18日至27日&#xff0c;分别在沈阳、大连、长春和哈尔滨四地成功举…

【PYG】Planetoid中边存储的格式,为什么打印前十条边用edge_index[:, :10]

edge_index 是 PyTorch Geometric 中常用的表示图边的张量。它通常是一个形状为 [2, num_edges] 的二维张量&#xff0c;其中 num_edges 表示图中边的数量。每一列表示一条边&#xff0c;包含两个节点的索引。 实际上这是COO存储格式&#xff0c;官方文档里也有写&#xff0c;…

暑假假期规划 离不开宝藏待办计划管理工具

暑假来临&#xff0c;两个月的自由时间&#xff0c;如何过得充实而有意义&#xff0c;成了我最近思考的问题。毕竟&#xff0c;一个合理的假期规划&#xff0c;不仅能让我的假期生活更加丰富多彩&#xff0c;还能为新学期的到来做好充分的准备。 我幻想着在这个暑假里&#xf…

激光雷达数据处理

激光雷达技术以其高精度、高效率的特点&#xff0c;已经成为地表特征获取、地形建模、环境监测等领域的重要工具。掌握激光雷达数据处理技能&#xff0c;不仅可以提升工作效率&#xff0c;还能够有效提高数据的质量和准确性&#xff0c;为决策提供可靠的数据支持。 第一章、激…

【漏洞复现】和丰多媒体信息发布系统 QH.aspx 任意文件上传漏洞

0x01 产品简介 和丰多媒体信息发布系统也称数字标牌&#xff08;Digital Signage&#xff09;&#xff0c;是指通过大屏幕终端显示设备&#xff0c;发布商业、财经和娱乐信息的多媒体专业视听系统&#xff0c;常被称为除纸张媒体、电台、电视、互联网之外的“第五媒体”。该系…

centos 安装zabbix 6.4.16 server client

Zabbix Server 采用源码包部署&#xff0c;数据库采用 MySQL8.0 版本&#xff0c;zabbix-web 使用 nginxphp 来实现。具体信息如下&#xff1a; 软件名 版本 安装方式 Zabbix Server 6.4.16 源码安装 Zabbix Agent 6.4.16 源码安装 MySQL 8.0.28 yum安装 Nginx 1.…

赛氪网:企业竞赛组织平台新选择,一键操作助力赛事成功举办

在数字化时代&#xff0c;传统的赛事报名方式已经逐渐难以满足组织者和参赛者的需求。企业如何寻找一种既方便又高效的赛事报名工具&#xff1f;赛氪网平台凭借其便捷的操作流程、完善的管理功能和技术保障&#xff0c;成为众多企业和高校举办竞赛时的首选。 赛氪网作为一款先…

祝贺《华为战略管理法:DSTE实战体系》被《中国企业家》杂志评为企业家枕边书50本之一(宏观战略类书籍)

祝贺《华为战略管理法&#xff1a;DSTE实战体系》被《中国企业家》杂志评为企业家枕边书50本之一 2024年4月23日&#xff08;周二&#xff09;下午13:00&#xff0c;《中国企业家》杂志如期举办“每天都是读书日”线下活动。 《中国企业家》杂志携手商界大咖共同推选50本枕边书…

算法刷题之路之链表初探(二)Leecode21合并两个有序链表

算法刷题之路之链表初探&#xff08;二&#xff09; 今天来学习的算法题是leecode141环形链表&#xff0c;是一道简单的入门题&#xff0c;话不多说&#xff01;直接上&#xff01; 条件&#xff08;Leecode21&#xff09; 重点&#xff01;&#xff01;&#xff01; 我直接把…