qt中數據庫和excel互導數據————附帶詳細步驟和代碼

文章目錄

  • 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(QXlsxGIT_REPOSITORY https://github.com/QtExcel/QXlsx.gitGIT_TAG        sha-of-the-commitSOURCE_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_WINmysqlDB.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的sheetqDebug()<<"沒有對應的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的sheetqDebug()<<"沒有對應的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.pswp.cn/web/37782.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/37782.shtml
英文地址,請注明出處:http://en.pswp.cn/web/37782.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

圓圈序號1~10復制粘貼直接用

1. 空心圓圈數字序號&#xff1a; ①、②、③、④、⑤、⑥、⑦、⑧、⑨、⑩ 2. 實心圓圈數字序號&#xff1a; ?、?、?、?、?、?、?、?、?、? 3. 空心圓圈中文序號&#xff1a; 一、二、三、四、五、六、七、八、九、十

linux高級編程(線程)(1)

虛擬地址&#xff1a; 線程&#xff1a; 概念&#xff1a;線程是輕量級進程&#xff0c;一般是一個進程中的多個任務。 進程是系統中最小的資源分配單位。&#xff08;競爭計算機資源的最小單位&#xff09;&#xff08;進程能分配硬件資源&#xff0c;線程不行&#x…

解析QAnything啟動命令過程

一.啟動命令過程日志 啟動命令bash ./run.sh -c local -i 0 -b hf -m Qwen-1_8B-Chat -t qwen-7b-chat。輸入日志如下所示&#xff1a; rootMM-202203161213:/mnt/l/20230918_RAG方向/QAnything# bash ./run.sh -c local -i 0 -b hf -m Qwen-1_8B-Chat -t qwen-7b-chat From …

Leetcode Java學習記錄——棧和隊列 IDEA

文章目錄 棧和隊列stack Classqueue InterfaceDeque Interfaceadd 和 push Priority Queue -- Class題目 codestyleIDEA 操作快捷鍵選擇代碼生成類 棧和隊列 stack Class google stack java 8/12 empty() peek() pop() push(E item) search(Object o) 最近相關性會用到棧 …

湘潭大學軟件工程數據庫總結

文章目錄 前言試卷結構給學弟學妹的一些參考自己的一些總結 前言 自己可能很早很早之前就準備復習了&#xff0c;但是感覺還是沒有學到要點&#xff0c;主要還是沒啥緊迫的壓力&#xff0c;我們是三月份開學&#xff0c;那時候實驗室有朋友挺認真開始學習數據庫了&#xff0c;…

理性決策的藝術:從購房到擇偶的數學智慧;37% 規則,做出最佳決策的秘訣;用數學模型解決人生難題

在面對人生重大決策時&#xff0c;如購房或擇偶&#xff0c;我們常常感到迷茫和困惑。然而&#xff0c;如果我們能夠將這些看似復雜的問題簡化為數學模型&#xff0c;我們就能以更加理性和系統的方式做出決策。 37%規則 1950年代&#xff0c;當時幾位數學家開始研究這樣一個問…

值得收藏!盤點那些適合普通人方便又好用的AIGC工具!(下)

【導讀】接上一篇文章&#xff0c;盤點國內外適合普通人能夠輕松上手的AIGC工具&#xff08;上&#xff09;。今天又為大家整理了一些好用又方便的AI設計工具、AI辦公工具、AI編程工具、AI指令工具和AI檢測工具&#xff0c;如果有沒更新到的工具也歡迎大家評論區交流。 一 、A…

Kafka 入門指南

Kafka 入門指南 簡介 Kafka 是一個由 Apache 軟件基金會開發的開源流處理平臺。它最初由 LinkedIn 開發&#xff0c;并在 2011 年作為開源項目發布。Kafka 是一個分布式、可擴展、高吞吐量的消息隊列系統&#xff0c;廣泛應用于實時數據流處理場景。 主要概念 1. 主題 (Top…

C#/WPF 自制截圖工具

在日常使用電腦辦公時&#xff0c;我們經常遇到需要截圖然后保存圖片&#xff0c;我們往往需要借助安裝截圖工具才能實現&#xff0c;現在我們通過C#自制截圖工具&#xff0c;也能夠輕松進行截圖。 我們可以通過C#調用WindousAPI來實現截圖&#xff0c;實例代碼如下&#xff1a…

AI基本概念(人工智能、機器學習、深度學習)

人工智能 、 機器學習、 深度學習的概念和關系 人工智能 &#xff08;Artificial Intelligence&#xff09;AI- 機器展現出人類智慧機器學習 &#xff08;Machine Learning) ML, 達到人工智能的方法深度學習 &#xff08;Deep Learning&#xff09;DL,執行機器學習的技術 從范圍…

算法 —— 滑動窗口

目錄 長度最小的子數組 無重復字符的最長子串 最大連續1的個數 將x減到0的最小操作數 找到字符串中所有字母異位詞 長度最小的子數組 sum比target小就進窗口&#xff0c;sum比target大就出窗口&#xff0c;由于數組是正數&#xff0c;所以相加會使sum變大&#xff0c;相減…

關于redis的運維面試題-1

1. 什么是Redis&#xff1f; Redis&#xff08;Remote Dictionary Server&#xff09;是一個開源的內存數據結構存儲&#xff0c;通常用作數據庫、緩存和消息代理。它支持多種數據結構&#xff0c;如字符串&#xff08;strings&#xff09;、哈希&#xff08;hashes&#xff0…

大二暑假 + 大三上

希望&#xff0c;暑假能早睡早起&#xff0c;胸圍達到 95&#xff0c;腰圍保持 72&#xff0c;大臂 36&#xff0c;小臂 32&#xff0c;小腿 38&#x1f36d;&#x1f36d; 目錄 &#x1f348;暑假計劃 &#x1f339;每周進度 &#x1f923;寒假每日進度&#x1f602; &…

DiskGeniusV5.6.0.1565發布!

DiskGenius是一款功能強大的磁盤管理和數據恢復工具&#xff0c;V5.6.0.1565上線。新版本變化比較大&#xff0c;增加新的功能&#xff0c;修正已經問題&#xff0c;值得試一下。提醒大家&#xff0c;磁盤管理軟件涉及數據安全&#xff0c;請始終使用最新版本&#xff01; 下面…

JS hook

參照&#xff1a; JS 逆向之 Hook JS Hook 與 過 debugger 一、常用Hook 1. eval (function() {let _eval eval;eval function(val) {if (val.indexof(debugger) -1) {_eval_cache(obj);}} })(); 2. JSON.parse() (function () {var parse_ JSON.parse;JSON.parse …

C++ initializer_list類型推導

目錄 initializer_list C自動類型推斷 auto typeid decltype initializer_list<T> C支持統一初始化{ }&#xff0c;出現了一個新的類型initializer_list<T>&#xff0c;一切類型都可以用列表初始化。提供了一種更加靈活、安全和明確的方式來初始化對象。 class…

IO-Link OD介紹

IO-Link OD&#xff08;On-request Data&#xff0c;按需數據&#xff09;是IO-Link通信中的一種重要數據類型&#xff0c;主要用于參數讀寫、指令交互、事件上傳等動作。以下是關于IO-Link OD的結構、構成以及功能使用的詳細說明&#xff1a; 結構與構成 定義&#xff1a;OD…

堆排序(Heap Sort)

堆排序是一種高效的排序算法&#xff0c;它利用了堆的數據結構來實現。堆是一種特殊的完全二叉樹&#xff0c;分為最大堆和最小堆兩種類型。在最大堆中&#xff0c;父節點的值大于等于其子節點的值&#xff1b;而在最小堆中&#xff0c;父節點的值小于等于其子節點的值。 堆排…

【C命名規范】遵循良好的命名規范,提高代碼的可讀性、可維護性和可復用性

/******************************************************************** * brief param return author date version是代碼書寫的一種規范 * brief &#xff1a;簡介&#xff0c;簡單介紹函數作用 * param &#xff1a;介紹函數參數 * return&#xff1a;函數返回類型說明 * …

同一個excel表格,為什么在有的電腦上會顯示#NAME?

一、哪些情況會產生#NAME?的報錯 1.公式名稱拼寫錯誤 比如求和函數SUM&#xff0c;如果寫成SUN就會提示#NAME&#xff1f;報錯。 2.公式中的文本值未添加雙引號 如下圖&#xff1a; VLOOKUP(丙,A:B,2,0) 公式的計算結果會返回錯誤值#NAME?&#xff0c;這是因為公式中文本…