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

打印 上一主题 下一主题

主题 977|帖子 977|积分 2931

0 背景

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

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



  • 1,输入下列指令安装:
  1. mkdir build
  2. cd build
  3. cmake ../QXlsx/ -DCMAKE_INSTALL_PREFIX=... -DCMAKE_BUILD_TYPE=Release
  4. cmake --build .
  5. cmake --install .
复制代码
在CMakeLists.txt中添加如下内容:
  1. find_package(QXlsxQt5 REQUIRED) # or QXlsxQt6
  2. target_link_libraries(myapp PRIVATE QXlsx::QXlsx)
复制代码


  • 2,下面是无需安装的两种使用方法:
使用cmake的子目录在 CMakeLists.txt:
  1. add_subdirectory(QXlsx)
  2. target_link_libraries(myapp PRIVATE QXlsx::QXlsx)
复制代码
使用 cmake FetchContent 在 CMakeLists.txt:
  1. FetchContent_Declare(
  2.   QXlsx
  3.   GIT_REPOSITORY https://github.com/QtExcel/QXlsx.git
  4.   GIT_TAG        sha-of-the-commit
  5.   SOURCE_SUBDIR  QXlsx
  6. )
  7. FetchContent_MakeAvailable(QXlsx)
  8. 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中添加如下代码;
  1. QXLSX_PARENTPATH=./         # current QXlsx path is . (. means curret directory)
  2. QXLSX_HEADERPATH=./QXlsx/header/  # current QXlsx header path is ./header/
  3. QXLSX_SOURCEPATH=./QXlsx/source/  # current QXlsx source path is ./source/
  4. include(./QXlsx/QXlsx.pri)
复制代码


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



  • 4,添加如下头文件,就可以开始项目编写;
  1. #include "xlsxdocument.h"
  2. #include "xlsxchartsheet.h"
  3. #include "xlsxcellrange.h"
  4. #include "xlsxchart.h"
  5. #include "xlsxrichstring.h"
  6. #include "xlsxworkbook.h"
复制代码
测试程序:
  1. // main.cpp#include <QCoreApplication>#include "xlsxdocument.h"
  2. #include "xlsxchartsheet.h"
  3. #include "xlsxcellrange.h"
  4. #include "xlsxchart.h"
  5. #include "xlsxrichstring.h"
  6. #include "xlsxworkbook.h"
  7. 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,在数据库中创建表格;
  1. DROP TABLE IF EXISTS `login_information`;
  2. CREATE TABLE `login_information`  (
  3.   `account` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
  4.   `password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
  5.   PRIMARY KEY (`account`) USING BTREE
  6. ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = DYNAMIC;
复制代码


  • 3,创建数据库连接;
方法:
  1. static bool CreateConnection(){
  2.     //        qDebug()<<"查看目前可用驱动";
  3.     //        QStringList drivers = QSqlDatabase::drivers();
  4.     //        for(auto driver: drivers){
  5.     //            qDebug()<<driver<<" ";
  6.     //        }
  7.     //设置数据库驱动
  8.     QSqlDatabase mysqlDB = QSqlDatabase::addDatabase("QMYSQL", "mysql_connection1");
  9.     mysqlDB.setHostName("192.168.0.104");
  10.     mysqlDB.setUserName("root");
  11.     mysqlDB.setPassword("password");
  12.     mysqlDB.setPort(8889);
  13.     mysqlDB.setDatabaseName("test_db");
  14.     //根据系统环境设计数据库路径
  15.     // Q_OS_LINUX:Q_OS_WIN: Q_OS_MAC   Q_OS_WIN32
  16.     //如果远程mysql数据库没有打开
  17.     if(!mysqlDB.open()){
  18.         return false;
  19.     }else{
  20.         // #ifdef Q_OS_WIN
  21.         mysqlDB.exec("SET NAMES 'GBK'");
  22.         // #endif
  23.         // #ifdef Q_OS_MAC
  24.         // #endif
  25.     }
  26.     //QSqlDatabase sqliteDB = QSqlDatabase::addDatabase("QSQLITE", "sqlite_connection1");
  27.     // #ifdef Q_OS_WIN //Q_OS_WIN32
  28.     //     qDebug()<<"QCoreApplication::applicationDirPath():"<<QCoreApplication::applicationDirPath();
  29.     //     sqliteDB.setDatabaseName(QCoreApplication::applicationDirPath() + QString("/database/LocalSystemDatabse.db"));
  30.     // #endif
  31.     //如果本地sqlite数据库没有打开
  32.     // if(!sqliteDB.open()){
  33.     //     QMessageBox* databaseInformationBox = new QMessageBox(QMessageBox::Critical, ("信息提示"),  ("不能建立本地数据库连接!"), QMessageBox::Yes);
  34.     //     auto button =  databaseInformationBox->exec();
  35.     //     if(button == QMessageBox::Yes){
  36.     //         databaseInformationBox->deleteLater();
  37.     //     }
  38.     //     return false;
  39.     // }
  40.     return true;
  41. }
复制代码
调用:
  1. //main中创建数据库连接
  2. int main(int argc, char *argv[])
  3. {
  4.     QCoreApplication a(argc, argv);
  5.     //连接数据库
  6.     if (!CreateConnection()){
  7.         qDebug()<<"数据库连接失败";
  8.     }
  9.     return a.exec();
  10. }
复制代码


  • 4,把excel中的数据导入到数据库中;
  1. bool exportExcel2Database(QStringList filePaths,  QString xlsxName, QString sqlSentence){
  2.     QList<bool> execResultList;//操作的结果集
  3.     bool execResult = false;
  4.     QSqlDatabase db = QSqlDatabase::database("mysql_connection1");
  5.     QSqlQuery query(db);
  6.     if(db.transaction()){
  7.         foreach(QString filePath, filePaths) {
  8.             QXlsx::Document xlsx(filePath);
  9.             if(!xlsx.selectSheet(xlsxName)){/*在当前打开的xlsx文件中,找一个名字为ziv的sheet*/
  10.                 //xlsx.addSheet(xlsxName);//找不到的话就添加一个名为ziv的sheet
  11.                 qDebug()<<"没有对应的xlsx表";
  12.                 return false;
  13.             }else{
  14.             }
  15.             QQueue<QString> tableFieldQueue;
  16.             QHash<QString, QVariantList> tableAlterFiledValue;
  17.             for(int row = 1; row <= xlsx.dimension().rowCount(); row++) {
  18.                 // 获取每行的数据并插入到数据库中
  19.                 for(int col = 1; col <= xlsx.dimension().columnCount();col++){
  20.                     if(row == 1){
  21.                         tableFieldQueue.enqueue(xlsx.read(row, col).toString());
  22.                     }else{
  23.                         tableAlterFiledValue[tableFieldQueue[col-1]].append(xlsx.read(row, col));
  24.                     }
  25.                 }
  26.             }
  27.             query.prepare(sqlSentence);
  28.             foreach (QString tableFiled, tableFieldQueue) {
  29.                 query.addBindValue(tableAlterFiledValue[tableFiled]);
  30.             }
  31.             execResult = query.execBatch();
  32.             execResultList.append(execResult);
  33.             if(!execResult) {//批量执行数据插入
  34.                 qDebug() <<  query.lastError().databaseText();
  35.             }
  36.         }
  37.         foreach (bool result, execResultList) {
  38.             if(result == false){
  39.                 if(!db.rollback())
  40.                 {
  41.                     qDebug() << "数据库回滚失败"<<db.lastError().databaseText(); //回滚
  42.                 }else{
  43.                     qDebug()<<"数据库回滚成功";
  44.                 }
  45.                 return false;
  46.             }
  47.         }
  48.         if(db.commit()){
  49.             return true;
  50.         }else{
  51.             return false;
  52.         }
  53.     }
  54.     return false;
  55. }
复制代码
调用:
  1.     QStringList filePaths;
  2.     filePaths<<"D:/test/账号信息.xlsx";
  3.     //考试细节步骤
  4.     QString sql2 = QString("INSERT INTO  login_information(account, password)  VALUES (?, ?)");
  5.     QString xlsxName2 = "账号信息";
  6.     // qDebug()<<sql2;
  7.     if(exportExcel2Database(filePaths, xlsxName2, sql2)){
  8.         qDebug()<<"导入成功";
  9.     }else{
  10.         qDebug()<<"导入失败";
  11.     }
复制代码
,
3 把mysql数据库的数据写入到excel



  • 1,创建数据库连接,同上;
  • 2,把数据库中表的数据导出到excel中;
  1. bool exportData2XLSX(QString fileName, QString tableName)
  2. {
  3.     QXlsx::Document xlsx;
  4.     QXlsx::Format format1;/*设置标题单元的样式*/
  5.     format1.setFontSize(12);/*设置字体大小*/
  6.     format1.setHorizontalAlignment(QXlsx::Format::AlignHCenter);/*横向居中*/
  7.     //format1.setBorderStyle(QXlsx::Format::BorderThin);/*边框样式*/
  8.     //format1.setFontBold(true);/*设置加粗*/
  9.     if(!xlsx.selectSheet("表格数据")){/*在当前打开的xlsx文件中,找一个名字为ziv的sheet*/
  10.         xlsx.addSheet("表格数据");//找不到的话就添加一个名为ziv的sheet
  11.     }
  12.     QSqlDatabase db = QSqlDatabase::database("mysql_connection1");
  13.     QString tmpSql = QString("SELECT * FROM %1").arg(tableName);
  14.     QSqlQuery query(db);
  15.     if(query.exec(tmpSql)){
  16.         //表头列
  17.         QSqlRecord queryRecord(query.record());
  18.         qDebug()<<"queryRecord.count():"<<queryRecord.count();
  19.         for(int colNum = 0; colNum < queryRecord.count(); colNum++){
  20.             //qDebug() <<  queryRecord.fieldName(colNum);
  21.             xlsx.write(1, colNum+1,  queryRecord.fieldName(colNum),format1);
  22.         }
  23.         //表格数据
  24.         int rowNum = 2;
  25.         while(query.next()){
  26.             for(int colNum = 0; colNum < queryRecord.count(); colNum++){
  27.                 xlsx.write(rowNum, colNum + 1, query.value(colNum),format1);
  28.             }
  29.             rowNum++;
  30.         }
  31.     }else{
  32.         return false;
  33.     }
  34.     if(fileName.isEmpty())
  35.         return false;
  36.     xlsx.saveAs(fileName);//保存文件
  37.     return true;
  38. }
复制代码
调用:
  1. int main(int argc, char *argv[])
  2. {
  3.     QCoreApplication a(argc, argv);
  4.     //连接数据库
  5.     if (!CreateConnection()){
  6.         qDebug()<<"数据库连接失败";
  7.     }
  8.    
  9.     QString tableName = "login_information";
  10.     QString fileName = "D:/账号.xlsx";
  11.     if(exportData2XLSX(fileName, tableName)){
  12.         qDebug()<<"导入excel成功";
  13.     }else{
  14.         qDebug()<<"导入excel失败";
  15.     }
  16.    
  17.     return a.exec();
  18. }
复制代码
4 完整代码

  1. #include <QCoreApplication>#include "create_connection.h"#include "xlsxdocument.h"
  2. #include "xlsxchartsheet.h"
  3. #include "xlsxcellrange.h"
  4. #include "xlsxchart.h"
  5. #include "xlsxrichstring.h"
  6. #include "xlsxworkbook.h"
  7. #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)
  8. {
  9.     QXlsx::Document xlsx;
  10.     QXlsx::Format format1;/*设置标题单元的样式*/
  11.     format1.setFontSize(12);/*设置字体大小*/
  12.     format1.setHorizontalAlignment(QXlsx::Format::AlignHCenter);/*横向居中*/
  13.     //format1.setBorderStyle(QXlsx::Format::BorderThin);/*边框样式*/
  14.     //format1.setFontBold(true);/*设置加粗*/
  15.     if(!xlsx.selectSheet("表格数据")){/*在当前打开的xlsx文件中,找一个名字为ziv的sheet*/
  16.         xlsx.addSheet("表格数据");//找不到的话就添加一个名为ziv的sheet
  17.     }
  18.     QSqlDatabase db = QSqlDatabase::database("mysql_connection1");
  19.     QString tmpSql = QString("SELECT * FROM %1").arg(tableName);
  20.     QSqlQuery query(db);
  21.     if(query.exec(tmpSql)){
  22.         //表头列
  23.         QSqlRecord queryRecord(query.record());
  24.         qDebug()<<"queryRecord.count():"<<queryRecord.count();
  25.         for(int colNum = 0; colNum < queryRecord.count(); colNum++){
  26.             //qDebug() <<  queryRecord.fieldName(colNum);
  27.             xlsx.write(1, colNum+1,  queryRecord.fieldName(colNum),format1);
  28.         }
  29.         //表格数据
  30.         int rowNum = 2;
  31.         while(query.next()){
  32.             for(int colNum = 0; colNum < queryRecord.count(); colNum++){
  33.                 xlsx.write(rowNum, colNum + 1, query.value(colNum),format1);
  34.             }
  35.             rowNum++;
  36.         }
  37.     }else{
  38.         return false;
  39.     }
  40.     if(fileName.isEmpty())
  41.         return false;
  42.     xlsx.saveAs(fileName);//保存文件
  43.     return true;
  44. }
  45. 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仓库
码云

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

我爱普洱茶

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表