文章目录
- 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仓库
码云