Qt编写数据导出到Excel及Pdf和打印数据
一、前言
用Qt开发已经九年了,期间用Qt做过不少的项目,在各种项目中有个功能很常用,尤其是涉及到数据记录存储的项目,那就是需要对查询的数据进行导出到Excel,或者导出到Pdf文件,或者直接打印查询的数据,其中导出数据到Excel最常见,基本上有三种方法。
方法一使用QAxObject,小数据量还可以,数据量一大直接懵逼,性能指数级下降,而且不支持跨平台,只能在WIN上玩一玩,对于大量的linux开发者来说,直接废了。
方法二使用第三方开源的QtXlsx,这个做的还是可以,使用人群也比较多,据说不依赖office组件跨平台的,缺点就是不支持xls格式,只支持高版本的xlsx,使用稍微比较繁琐,用户更多的需要的是直接一个函数传入对应的数据即可,越简单越好。
方法三使用csv格式作为导出数据,纯文本的数据存储格式,默认逗号作为分隔符,也可以指定其他符号作为分隔符,csv格式也是各种表格软件都支持的格式,相当轻便,作为各大系统或者平台和编程语言之间交互数据还是非常方便的,很多工业控制领域的软件都会采用这种格式,缺点就是太简单了,不能分组或者指定过滤条件特殊颜色显示等。
在对比了三种方式以后,决定自己造个轮子,主要是为了自身项目的需要写的,后面慢慢的客户需求多了,增加了通用常用场景的数据导出需求,目标要求至少包含三点:速度够快、使用够简洁、不依赖任何组件。
作品大全:https://qtchina.blog.csdn.net/article/details/97565652
二、功能特点
- 原创导出数据机制,不依赖任何office组件或者操作系统等第三方库,尤其是支持嵌入式linux。
- 10万行数据9个字段只需要2秒钟完成。
- 只需要四个步骤即可开始急速导出大量数据到Excel。
- 同时提供直接写入数据接口和多线程写入数据接口,不卡主界面。
- 可设置标题、副标题、表名。
- 可设置字段名称、列宽度。
- 可设置是否启用校验过滤数据、校验的列、校验规则、校验值,符合规则的特殊颜色显示。
- 可设置随机背景颜色及需要随机背景色的列集合。
- 支持分组输出数据,比如按照设备分组输出数据,方便查看。
- 可自定义行内容分隔符。
- 可追加数据形式写入数据,建议每次追加的数据小于10000条。
- 灵活性超高,可自由更改源码设置对齐方式、文字颜色、背景颜色等。
- 支持任意excel表格软件,包括但不限于excel2003/2007/2010/2013/2017/wps/openoffice等。
- 除了提供导出到Excel类以外,还提供导出到Pdf文件以及打印数据的类。
- 注释完善,详细完整的使用demo,支持QTableWidget、QTableView、数据库三种数据源。
- 纯Qt编写,支持任意Qt版本+任意编译器+任意系统。
三、效果图
四、使用方法
void frmDataThread::on_btnStart_clicked()
{
//设置进度条
currentCount = 0;
ui->progressBar->setRange(0, AppConfig::RowThread);
ui->progressBar->setValue(currentCount);
ui->btnStart->setEnabled(false);
//随机生成列名称和宽度
QList<QString> columnNames;
QList<int> columnWidths;
for (int j = 0; j < AppConfig::ColumnThread; j++) {
columnNames << QString("列%1").arg(j + 1);
columnWidths << 50;
}
//第一步:设置文件名标题等
//第二步:打开文件
//第三步:启动线程执行
DataContent dataContent;
dataContent.sheetName = "测试名称";
dataContent.title = "测试标题";
dataContent.columnNames = columnNames;
dataContent.columnWidths = columnWidths;
//dataContent.randomColor = true;
if (AppConfig::TypeThread == 0) {
fileName = QUIHelper::appPath() + "/db/thread.xls";
dataContent.fileName = fileName;
xls->setDataContent(dataContent);
xls->init();
xls->open();
xls->start();
} else {
fileName = QUIHelper::appPath() + "/db/thread.pdf";
dataContent.fileName = fileName;
pdf->setDataContent(dataContent);
pdf->init();
pdf->open(true);
pdf->start();
}
//立即执行一次
append();
}