Qt操作Excel
1. 库的下载与安装
由于xlsxwriter
库是跨平台的,支持读写操作的,所以我选择该第三方库来操作excel
该库的镜像地址如下:
https://gitcode.com/gh_mirrors/qt/QtXlsxWriter/overview?utm_source=csdn_github_accelerator
克隆命令为:
git clone https://gitcode.com/gh_mirrors/qt/QtXlsxWriter.git
克隆完成后有两种使用方式,我只记录一种:往工程里导pri的方式,这种方式使用简单粗暴,但是需要每一个工程都放进去。
1.1 建文件夹
第一步:在项目的目录下新建一个xlsxwriter的文件夹,在其内部再新建一个src的子文件夹;
第二步:将克隆下来的src文件夹里的内容复制到上一步新建的文件夹中;
第三步:在工程文件pro文件中加入pri文件,即
include(XlsxWriter/src/xlsx/qtxlsx.pri)
工程就变成了这样目录
就可以在其他文件引用相应的头文件
2. Qt具体操作Excel方式
直接把代码放过来一行一行注释自己看
#include "dailyreport.h" #include "ui_dailyreport.h" #include "xlsxdocument.h" #include "xlsxformat.h" #include "readfile.h" void DailyReport::on_pushButton_chaxun_3_clicked() { selectedMonth = ui->dateEdit->date(); // 假设你的界面上有一个日期选择器 generateDailyReport(selectedMonth); } void DailyReport::generateDailyReport(const QDate &daily) { SQLHelper sqlhelper; sqlhelper.openDataBase(); QSqlQuery sqlquery; QString queryString = QString("SELECT DateTime, liuliang FROM shuiwei WHERE DATE(DateTime) = '%1'").arg(daily.toString("yyyy-MM-dd")); if (!sqlquery.exec(queryString)) { QMessageBox::critical(this,"错误","数据查询失败"); return; } QMap<QDate, QMap<int, QList<float>>> hourlyData; while (sqlquery.next()) { QDateTime datetime = sqlquery.value("DateTime").toDateTime(); float liuliang = sqlquery.value("liuliang").toFloat(); QDate date = datetime.date(); // 获取日期 // qDebug() << date; int hour = datetime.time().hour(); // 获取小时 // qDebug() << hour; hourlyData[date][hour].append(liuliang); } // qDebug() << hourlyData; displayHourlyDataInTable(hourlyData); } void DailyReport::displayHourlyDataInTable(const QMap<QDate, QMap<int, QList<float> > > &hourlyData) { model->clear(); // 设置表头 QStringList horizontalHeader; horizontalHeader << "序号" << "监测日期" << "监测时间" << "实测数据(m³/s)" << "累计流量(m³)" << "生态流量异常原因"; model->setHorizontalHeaderLabels(horizontalHeader); // 向模型填充数据 int row = 0; for (auto dayIt = hourlyData.begin(); dayIt != hourlyData.end(); dayIt++, row++) { const QDate &date = dayIt.key(); // 获取外层键 也就是日期 QDate("2024-09-03") const QMap<int, QList<float>> &hoursData = dayIt.value(); // 获取值 QMap(0, (8.149)) // QStandardItem *dateItem = new QStandardItem(date.toString("yyyy-MM-dd")); for (int hour = 0; hour < 24; hour++) { QStandardItem *timeItem = new QStandardItem(QString("%1:00").arg(hour,2,10,QChar('0'))); QStandardItem *hours = new QStandardItem(QString::number(hour + 1)); QStandardItem *dateItem = new QStandardItem(date.toString("yyyy-MM-dd")); model->setItem(hour,0, hours); // 强转 model->setItem(hour, 1, dateItem); // 第一列 日期 model->setItem(hour,2,timeItem); timeItem->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter); hours->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter); dateItem->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter); if (hoursData.contains(hour)) { const float &data = hoursData[hour][0]; QString data_string = QString::number(data,'f',4); QStandardItem *hourlyData = new QStandardItem(data_string); model->setItem(hour,3,hourlyData); hourlyData->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter); const float &data_total = data_string.toFloat() * 3600; QStandardItem *hourlyData_total = new QStandardItem(QString::number(data_total,'f',2)); model->setItem(hour,4,hourlyData_total); hourlyData_total->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter); } else { QStandardItem hourItem("N/A"); model->setItem(row, hour + 1, &hourItem); } } } } void DailyReport::initTableView() { ui->tableView->setModel(model); ui->tableView->resizeColumnsToContents(); ui->tableView->setEditTriggers(QAbstractItemView::NoEditTriggers); //设置表格的单元为只读属性,即不能编辑 ui->tableView->verticalHeader()->hide(); //隐藏行头 ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); //设置列的宽度 ui->tableView->setSelectionBehavior(QAbstractItemView::SelectRows); // 设置表格的选择行为为选择整行 而不是单个单元格 } void DailyReport::exportToXls(QStandardItemModel *model, const QString &fileName, const QString &powerName, const QString &exportDate) { // 创建excel表对象 QXlsx::Document xls; // 创建标题格式的对象 QXlsx::Format format_title; // 设置水平居中 format_title.setHorizontalAlignment(QXlsx::Format::AlignHCenter); // 设置垂直居中 format_title.setVerticalAlignment(QXlsx::Format::AlignVCenter); // 设置字体大小 format_title.setFontSize(36); // 设置字体加粗 format_title.setFontBold(true); // 写excel xls.write("A1","生态流量日报表"); // 合并单元格 xls.mergeCells("A1:F7",format_title); // 创建电站名称格式对象 QXlsx::Format format_powerName; // 设置水平居中 format_powerName.setHorizontalAlignment(QXlsx::Format::AlignHCenter); // 设置垂直居中 format_powerName.setVerticalAlignment(QXlsx::Format::AlignVCenter); // 设置字体大小 format_powerName.setFontSize(36); // 设置边框 format_powerName.setBorderStyle(QXlsx::Format::BorderStyle::BorderThin); // 写入数据 xls.write("A8",QString("%1(%2)").arg(powerName).arg(exportDate)); // 合并单元格 A8:F14 xls.mergeCells("A8:F14",format_powerName); // 创建表头的格式对象 QXlsx::Format format_TableTitle; // 设置垂直居中 format_TableTitle.setVerticalAlignment(QXlsx::Format::AlignVCenter); // 设置水平居中 format_TableTitle.setHorizontalAlignment(QXlsx::Format::AlignHCenter); // 设置字体大小 format_TableTitle.setFontSize(22); // 设置字体加粗 format_TableTitle.setFontBold(true); // 设置行高 第几行 行高 注意这里用的是xls对象 xls.setRowHeight(15,47.4); // 设置边框样式 format_TableTitle.setBorderStyle(QXlsx::Format::BorderStyle::BorderThin); // 设置列宽 第几列 宽度 xls.setColumnWidth(1,11.33); xls.setColumnWidth(2,25.22); xls.setColumnWidth(3,21.00); xls.setColumnWidth(4,34.78); xls.setColumnWidth(5,29.33); xls.setColumnWidth(6,54.33); // 写入数据 第几行 第几列 内容 格式 xls.write(15,1,"序号",format_TableTitle); xls.write(15,2,"监测日期",format_TableTitle); xls.write(15,3,"监测时间",format_TableTitle); xls.write(15,4,"实测流量(m³/s)",format_TableTitle); xls.write(15,5,"累计流量(m³)",format_TableTitle); xls.write(15,6,"生态流量异常原因",format_TableTitle); // 创建表格内容的单元格格式 QXlsx::Format format_Table; // 设置字体大小 format_Table.setFontSize(22); // 设置垂直居中 format_Table.setVerticalAlignment(QXlsx::Format::AlignVCenter); // 设置水平居中 format_Table.setHorizontalAlignment(QXlsx::Format::AlignHCenter); // 设置边框格式 format_Table.setBorderStyle(QXlsx::Format::BorderStyle::BorderThin); // 循环遍历模型中的数据 for (int row = 0; row < model->rowCount(); row++) { for (int col = 0; col < model->columnCount(); col++) { // 获取具体格子的数据 QModelIndex index = model->index(row, col); // 转换格式 QString data = index.data(Qt::DisplayRole).toString(); // 向excel写入数据 xls.write(row+16,col+1,data,format_Table); // 调整行高 xls.setRowHeight(row + 16, 47.4); } } QXlsx::Format format_bottom; format_bottom.setHorizontalAlignment(QXlsx::Format::AlignLeft); format_bottom.setVerticalAlignment(QXlsx::Format::AlignVCenter); format_bottom.setFontSize(22); xls.write("A40"," 部门负责人: 值长: 值班人员: ",format_bottom); xls.mergeCells("A40:F47"); // 保存文件 xls.saveAs(fileName + ".xlsx"); } void DailyReport::on_save_clicked() { if (model->rowCount() == 0) { QMessageBox::critical(this,"错误","没有要导出的数据"); return; } if (!model) { QMessageBox::critical(this,"错误","数据模型未准备好"); return; } // 提示用户选择保存位置和文件名 QString fileName = QFileDialog::getSaveFileName(this,tr("Save File"),QDir::homePath(),tr("xls Files (*.xls);;All Files (*)")); if (fileName.isEmpty()) { return; } ReadFile readFile; // 调用导出函数保存数据到CSV文件 // exportToCSV(model, fileName); exportToXls(model,fileName,readFile.powerName, selectedMonth.toString("yyyy-MM-dd")); }
最终效果
3. 好的参考网站
这个博客给出了官方的例子 包括生成图像
https://blog.csdn.net/u014779536/article/details/111769792
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧