Linux下C++和GCC实现MySQL中的SQL查询结果集导出
2025-03-11 本文已影响0人
久别重逢已经那边v发
在Linux中用C++和GCC在MySQL 8数据库里实现将SQL查询语句的结果集用LibXL库导出为Excel 2007格式的文件,并且针对每一列的数据调整到合适宽度,并封装为函数。
#include <mysql_connection.h>
#include <mysql_driver.h>
#include <cppconn/driver.h>
#include <cppconn/exception.h>
#include <cppconn/resultset.h>
#include <cppconn/statement.h>
#include <libxl.h>
#include <vector>
#include <string>
#include <locale>
#include <codecvt>
using namespace std;
using namespace sql;
using namespace libxl;
// 字符串转宽字符串转换器
wstring string_to_wstring(const string& str) {
wstring_convert<codecvt_utf8<wchar_t>> converter;
return converter.from_bytes(str);
}
bool exportToExcel(const string& host, const string& user, const string& pass,
const string& db, int port, const string& query,
const string& filename) {
sql::mysql::MySQL_Driver* driver = nullptr;
sql::Connection* con = nullptr;
sql::Statement* stmt = nullptr;
sql::ResultSet* res = nullptr;
Book* book = xlCreateXMLBook();
if (!book) {
cerr << "Failed to initialize Excel book" << endl;
return false;
}
try {
// 初始化数据库连接
driver = sql::mysql::get_mysql_driver_instance();
con = driver->connect("tcp://" + host + ":" + to_string(port), user, pass);
con->setSchema(db);
// 执行查询
stmt = con->createStatement();
res = stmt->executeQuery(query);
// 获取元数据
ResultSetMetaData* meta = res->getMetaData();
int colCount = meta->getColumnCount();
vector<int> colWidths(colCount, 0);
// 创建Excel工作表
Sheet* sheet = book->addSheet("Data");
if (!sheet) {
cerr << "Failed to create sheet" << endl;
return false;
}
// 写入表头并计算初始宽度
for (int i = 0; i < colCount; ++i) {
wstring wcol = string_to_wstring(meta->getColumnLabel(i + 1));
sheet->writeStr(0, i, wcol.c_str());
colWidths[i] = static_cast<int>(wcol.length());
}
// 写入数据并跟踪最大列宽
int row = 1;
while (res->next()) {
for (int i = 0; i < colCount; ++i) {
string val = res->getString(i + 1);
wstring wval = string_to_wstring(val);
sheet->writeStr(row, i, wval.c_str());
// 更新最大列宽
if (wval.length() > colWidths[i]) {
colWidths[i] = static_cast<int>(wval.length());
}
}
++row;
}
// 设置列宽(包含10%的余量)
for (int i = 0; i < colCount; ++i) {
sheet->setCol(i, i, colWidths[i] * 1.1);
}
// 保存Excel文件
if (!book->save(filename.c_str())) {
cerr << "Error saving file: " << book->errorMessage() << endl;
return false;
}
} catch (SQLException& e) {
cerr << "MySQL Error: " << e.what() << endl;
cerr << "Error code: " << e.getErrorCode() << endl;
return false;
} catch (const exception& e) {
cerr << "General Error: " << e.what() << endl;
return false;
}
// 清理资源
delete res;
delete stmt;
delete con;
book->release();
return true;
}
使用示例:
int main() {
bool result = exportToExcel(
"localhost", // MySQL主机
"root", // 用户名
"password", // 密码
"testdb", // 数据库名
3306, // 端口
"SELECT * FROM products", // 查询语句
"output.xlsx" // 输出文件名
);
if (result) {
cout << "Export completed successfully" << endl;
} else {
cout << "Export failed" << endl;
}
return 0;
}
编译命令示例:
g++ -std=c++11 -o exporter exporter.cpp \
-I/usr/local/include/mysql-cppconn-8 \
-I/path/to/libxl/include \
-L/usr/local/lib -lmysqlcppconn \
-L/path/to/libxl/lib -lxl -Wl,-rpath,/path/to/libxl/lib
注意事项:
- 需要正确安装MySQL Connector/C++和LibXL库
- LibXL需要有效的授权许可证(试用版会在生成文件添加水印)
- 列宽计算基于字符数量,中文等宽字符可能需要调整系数
- 确保数据库连接参数正确且有足够权限
- 处理大数据量时需要适当的内存管理
这个实现:
- 封装为独立函数,参数包含所有必要配置
- 自动调整列宽并包含10%的余量
- 支持Unicode字符
- 包含基本错误处理
- 自动清理分配的资源
- 生成符合Excel 2007+标准的.xlsx文件