目录
前言
一、QXlsx 库简介
二、QT项目中添加QXlsx库
三、 基本用法示例
四、Excel报告导出方案
1.做一个excel模版
2.QT读取Excel模版
3. 将模版复制出来另存为一份
4.读取另存为的报告填充内容后保存
总结
前言
QXlsx 是一个开源的 Qt 库,可以在不依赖 Microsoft Office 的情况下读写 Excel 文件。应该每个小伙伴都能遇到用QT导出Excel的需求,一开始大致思路都是直接用代码画出整个Excel。但是这种做法遇到简单的Excel报表还好,如果是遇到复杂的,一点变动整个代码都要重写,这就比较麻烦了。最近重新开发一个项目,看到了公司前辈解决导出Excel报告的方案,比较简单灵活,发出来给大家分享一下,下面先给大家介绍一下QXlsx的用法,后面再提方案。
一、QXlsx 库简介
QXlsx 是一个基于 Qt 实现的读写 Excel 文件的库,支持.xlsx 格式,无需安装 Microsoft Office 或 COM 组件。它提供了类似于 QString、QList 的 API,易于学习和使用。
项目地址:https://github.com/QtExcel/QXlsx
项目准备:
1.安装 Qt 开发环境(Qt 5.6 及以上版本)
2.准备 Qt Creator 开发工具
3.从 GitHub 下载 QXlsx 源码,下载方法如下图所示
二、QT项目中添加QXlsx库
我们从github下载完的压缩包里面内容很多,但是我们项目中只需要那个QXlsx文件夹。
将 QXlsx文件夹复制到我们的项目中去,然后在xxx项目名.pro的最下方添加以下内容
include($$PWD/QXlsx/QXlsx.pri)
INCLUDEPATH += $$PWD/QXlsx
添加完成后,QXlsx库就会显示到我们的QT项目中了。
三、 基本用法示例
我直接把测试代码写在了mainwindow里面,点击按钮就生成一个excel文档,下面是实现代码。
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include "xlsxdocument.h"QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACEclass MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr);~MainWindow();private slots:void on_pushButton_clicked();private:Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QCoreApplication>MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);
}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::on_pushButton_clicked()
{// 创建一个新的Excel文档QXlsx::Document xlsx;xlsx.setColumnWidth(2,23,5);//设置2到23列宽度为5// 写入数据到单元格xlsx.write("A1", "Hello, QXlsx!");xlsx.write("A2", 123);xlsx.write("A3", 3.14);// 设置单元格格式QXlsx::Format format;format.setFontBold(true);//设置加粗format.setFontSize(20);//设置字号format.setBorderStyle(QXlsx::Format::BorderThin);//设置边框线xlsx.mergeCells("B2:C2");//合并单元格format.setFontColor(Qt::red);//字体颜色format.setHorizontalAlignment(QXlsx::Format::AlignHCenter);//水平居中format.setVerticalAlignment(QXlsx::Format::AlignVCenter);//竖直居中xlsx.write("B2", "666", format);xlsx.write("C2", "", format);// 保存文件if (xlsx.saveAs("example.xlsx")) {// qDebug() << "File saved successfully.";} else {// qDebug() << "Failed to save the file.";}
}
最后运行点击按钮,如果生成以下文件,导出基本上就成功了。
下面我们再打开excel文件验证一下内容是否和我们导出的一致。
四、Excel报告导出方案
现在聊一聊如何简单实现导出Excel报告,可以避免大量代码去画Excel,我们可以将Excel报告中大部分不变的表格框和文字先用WPS或者Office工具先整理出一个模版,然后需要填写的变量用 功能码+"特殊符号"去代替,比如:report1, 和 report2, 是我们需要填写的两个位置,我们在打开QT的时候去读取这个模版的所有内容,过滤出带逗号的单元格,把行列和功能码记录下来放到map中,这样我们在生成报告的时候,先把模版读取下来,直接通过功能码就可以找到对应应该填充的行列数进行填充,最后save as ,就可以完成Excel报告,这样我们修改Excel报告的时候就不用大规模的动代码了,这样说可能有小伙伴不明白,下面分步骤去讲一下。
1.做一个excel模版
XXXX报告 | ||||
标题1 | 标题2 | 标题3 | 标题4 | 标题5 |
标题2 | export1, | 固定内容 | export8, | export13, |
标题3 | export2, | export7, | export9, | export14, |
标题4 | export3, | 固定内容 | 固定内容 | export15, |
标题5 | export4, | export6, | export11, | export16, |
标题6 | export5, | 固定内容 | export12, | 固定内容 |
当然,简单的直接按行列填充的Excel直接生成就可以了,我说的是需要导出那种复杂的Excel报告,里面有的需要填固定内容,有的需要程序算出一个结果或者读取一个 值填充到对应位置,有的可能合并几个单元格填充一个变量的情况。我们就可以先用WPS等工具先做出一个模版,里面包含我们需要生成报告的所有内容,需要程序填充的内容用 功能码+特殊符号代替。
2.QT读取Excel模版
在程序.h中引用 #include "xlsxdocument.h"。
在程序.cpp中读取excel模版,并将模版中带逗号的单元格的行和列以及功能码记录下来,放到一个以功能码为键,以行列的struct为值的QHash全局变量中。
//读取excel模板if(ReportTemplate!=""){QXlsx::Document xldx1("template/模版.xlsx");findNonEmptyCells(xldx1,",");//调用下方代码}//找到模板中带,的单元格 记录下来
void mainwindow::findNonEmptyCells(QXlsx::Document& xlsx,const QString& searchText) {for(int row=1;row<xlsx.dimension().rowCount();row++){for(int col=1;col<xlsx.dimension().columnCount();col++){QXlsx::Cell *cell=xlsx.cellAt(row,col).get();if(cell && cell->value().type()==QVariant::String){QString text=cell->value().toString();if(text.contains(searchText)){text=text.remove(searchText);Report report;report.col=col;report.row=row;reportMap[text]=report;}}}}}//用到的结构体和QHashstruct Report{int row;int col;};QHash<QString,Report> reportMap;
3. 将模版复制出来另存为一份
QXlsx::Document xldx1("template/模版.xlsx");
QString filePath="xxx的报告.xlsx";
xldx1.saveAs(filePath);
4.读取另存为的报告填充内容后保存
bool mainwindow::findById(const QString &id,int &row,int &col){if(reportMap.contains(id)){Report report=reportMap[id];row=report.row;col=report.col;return true;}return false;
}QXlsx::Document xldx1("xxx的报告.xlsx");
QString id="report1";
QString val="要填充的内容";
int row;
int col;
if(findById(id,row,col)){//如果找到功能码 就填充内容
xldx1.write(row,col,val);
}
xldx1.save();
通过功能码去找QHash中是否存在对应的键值对,找到的话就把这个功能码应该填充的内容write进去。这样的做法是比较活,Excel报告需要调整的话直接改模版就行了,程序基本上不用动,当然我们可以将功能码根据自己的业务整理成一个ini配置文件,这样就更灵活了。
总结
如果只需要简单的Excel导出,那么前三个大标题的内容就可以满足需求,但是如果是比较复杂的Excel导出报告,我建议你参考一下我第四项的Excel报告导出方式更灵活一些。大家如果有更好的方案,也可以互相交流,互相进步。