# 一、使用方法
### 1.1 第一步:引入组件
- 组件中所有代码文件是一个整体,不支持单个代码文件拆分使用,因为很多通用的方法都放在一个代码文件中,复用很多代码。
- datehead是本组件用到的头文件以及通用的数据结构体。
- datahelper是通用的校验列函数和数据导出打印函数。
- datacreat用于创建html格式的数据,用来导出到pdf和打印数据。
- datacsv用于导入导出文件csv格式。
- dataxls是数据导出到xls的核心。
- dataprint是数据导出到pdf和打印数据。
1. 将core_dataout整个目录拷贝到你的项目文件夹同级目录。
2. 打开你的项目的pro文件,引入组件。
```cpp
INCLUDEPATH += $$PWD/../core_dataout
include ($$PWD/../core_dataout/core_dataout.pri)
```
3. 此时在项目树状结构图中可以看到 core_dataout 组件代码。
### 1.2 第二步:获取数据
- 无论是导出到xls还是pdf或者打印,前提是都要拿到需要处理的数据集合。
- 拿到数据的方式基本上两种,一种是数据库查询比如QSqlTableModel,一种是界面控件取数据比如QTableView、QTableWidget、QStandardItemModel。
- QTableView一般有两种数据源,一个是QSqlTableModel,一个是QStandardItemModel。
- 数据集合按照一行行数据来,中间用英文的 分号 ; 隔开,最后统一放到QStringList中。
#### 1.2.1 示例QSqlTableModel
```cpp
void frmDataOut2::on_btnLoad_clicked()
{
model->setTable("MsgInfo");
model->select();
ui->tableView->setModel(model);
for (int i = 0; i < columnCount; i++) {
model->setHeaderData(i, Qt::Horizontal, columnNames.at(i));
ui->tableView->setColumnWidth(i, columnWidths.at(i));
}
}
QStringList frmDataOut2::getContent()
{
QStringList content;
QString sql = QString("select * from MsgInfo limit %1").arg(100);
QSqlQuery query;
if (!query.exec(sql)) {
return content;
}
//循环遍历数据
while (query.next()) {
QStringList list;
for (int i = 0; i < column; i++) {
list << query.value(i).toString();
}
content << list.join(";");
}
return content;
}
```
#### 1.2.2 示例QStandardItemModel
```cpp
void frmSimple::on_btnLoad_clicked()
{
//清空数据
model->clear();
//设置列数及列标题和列宽
model->setColumnCount(column);
for (int i = 0; i < column; ++i) {
model->setHeaderData(i, Qt::Horizontal, columnNames.at(i));
ui->tableView->setColumnWidth(i, columnWidths.at(i));
}
//循环添加行数据
for (int i = 0; i < row; ++i) {
//循环添加一行的列
QList<QStandardItem *> items;
for (int j = 0; j < column; ++j) {
QStandardItem *item = new QStandardItem;
item->setText(QString("行%1_列%2").arg(i + 1).arg(j + 1));
items << item;
}
model->appendRow(items);
}
ui->tableView->setModel(model);
}
QStringList frmSimple::getContent()
{
//从 QTableView 获取数据
QStringList content;
for (int i = 0; i < row; ++i) {
QStringList list;
for (int j = 0; j < column; ++j) {
list << model->item(i, j)->text();
}
//每行数据作为一个整体字符串分割存入
content << list.join(";");
}
return content;
}
```
#### 1.2.3 示例QTableWidget
```cpp
void frmDataOut1::on_btnLoad_clicked()
{
QStringList list;
list << "防区上线" << "防区离线" << "防区旁路" << "防区报警" << "防区故障";
ui->tableWidget->clearContents();
for (int i = 0; i < rowCount; i++) {
//随机生成告警内容
int index = rand() % 4;
QTableWidgetItem *item1 = new QTableWidgetItem(QString::number(i + 1));
QTableWidgetItem *item2 = new QTableWidgetItem("防区" + QString::number(i + 1));
QTableWidgetItem *item3 = new QTableWidgetItem("主机上报");
QTableWidgetItem *item4 = new QTableWidgetItem(list.at(index));
QTableWidgetItem *item5 = new QTableWidgetItem(DATETIME);
item5->setTextAlignment(Qt::AlignCenter);
ui->tableWidget->setItem(i, 0, item1);
ui->tableWidget->setItem(i, 1, item2);
ui->tableWidget->setItem(i, 2, item3);
ui->tableWidget->setItem(i, 3, item4);
ui->tableWidget->setItem(i, 4, item5);
}
}
QStringList frmDataOut1::getContent()
{
QStringList content;
for (int i = 0; i < row; i++) {
QStringList list;
for (int j = 0; j < column; j++) {
list << ui->tableWidget->item(i, j)->text();
}
content << list.join(";");
}
return content;
}
```
### 1.3 第三步:设置数据
- 无论是导出到xls还是pdf或者打印,都需要设置数据结构体,传入列名、列宽、数据集合等信息。
- 如果是导出到xls还需要设置文件名及表名。
- 如果是导出到pdf需要设置文件名。
- 打印不需要设置文件名和表名。
```cpp
void frmSimple::on_btnXls_clicked()
{
//设置结构体数据
DataContent dataContent;
//填充内容
dataContent.content = getContent();
//设置列名列宽
dataContent.columnNames = columnNames;
dataContent.columnWidths = columnWidths;
//设置文件名
dataContent.fileName = "d:/0.xls";
//设置表名
dataContent.sheetName = "测试信息";
//调用静态函数保存
DataXls::saveXls(dataContent);
//打开刚才导出的文件
QUIHelper::openFile(dataContent.fileName, "导出测试信息");
}
void frmSimple::on_btnPdf_clicked()
{
//设置结构体数据
DataContent dataContent;
//填充内容
dataContent.content = getContent();
//设置列名列宽
dataContent.columnNames = columnNames;
dataContent.columnWidths = columnWidths;
//设置文件名
dataContent.fileName = "d:/0.pdf";
//调用静态函数保存
DataPrint::savePdf(dataContent);
//打开刚才导出的文件
QUIHelper::openFile(dataContent.fileName, "导出测试信息");
}
void frmSimple::on_btnPrint_clicked()
{
//设置结构体数据
DataContent dataContent;
//填充内容
dataContent.content = getContent();
//设置列名列宽
dataContent.columnNames = columnNames;
dataContent.columnWidths = columnWidths;
//调用静态函数打印
DataPrint::print(dataContent);
}
```
### 1.4 第四步:执行操作
- 数据导入导出组件dataout提供了统一的数据结构体用来设置数据和其他参数。
- 封装了统一的静态函数DataXls::saveXls用来导出到xls、DataPrint::savePdf用来导出到pdf、DataPrint::print用来打印数据。
- 支持各种详细复杂的参数设置以及海量数据导出多线程操作,具体参见详细使用demo。
```cpp
//调用静态函数保存到xls
DataXls::saveXls(dataContent);
//调用静态函数保存到pdf
DataPrint::savePdf(dataContent);
//调用静态函数打印数据
DataPrint::print(dataContent);
```
## 二、功能特点
1. 组件同时集成了导出数据到csv、xls、pdf和打印数据。
2. 所有操作全部提供静态方法无需new,数据和属性等各种参数设置采用结构体数据,极为方便。
3. 同时支持QTableView、QTableWidget、QStandardItemModel、QSqlTableModel等数据源。
4. 提供静态方法直接传入QTableView、QTableWidget控件,自动识别列名、列宽和数据内容。
5. 每组功能都提供单独的完整的示例,注释详细,非常适合各阶段Qter程序员。
6. 原创导出数据机制,不依赖任何office组件或者操作系统等第三方库,支持嵌入式linux。
7. 速度超快,9个字段10万行数据只需要2秒钟完成。
8. 只需要四个步骤即可开始急速导出海量数据比如100W条记录到Excel。
9. 同时提供直接写入数据接口和多线程写入数据接口,不卡主界面。
10. 可设置标题、副标题、表名。
11. 可设置导出数据的字段名、列名、列宽。
12. 可设置末尾列自动拉伸填充,默认拉伸更美观。
13. 可设置是否启用校验过滤数据,启用后符合规则的数据特殊颜色显示。
14. 可指定校验的列、校验规则、校验值、校验值数据类型。
15. 校验规则支持 精确等于==、大于>、大于等于>=、小于<、小于等于<=、不等于!=、包含contains。
16. 校验值数据类型支持 整型int、浮点型float、双精度型double,默认文本字符串类型。
17. 可设置随机背景颜色及需要随机背景色的列集合。
18. 支持分组输出数据,比如按照设备分组输出数据,方便查看。
19. 可设置csv分隔符、行内容分隔符、子内容分隔符。
20. 可设置边框宽度、自动填数据类型,默认自动数据类型开启。
21. 可设置是否开启数据单元格样式,默认不开启,不开启可以节约大概30%的文件体积。
22. 可设置横向排版、纸张边距等,比如导出到pdf以及打印数据。
23. 支持图文混排导出数据到pdf以及打印数据,自动分页。
24. 灵活性超高,可自由更改源码设置对齐方式、文字颜色、背景颜色等。
25. 支持任意excel表格软件,包括但不限于excel2003-2021、wps、openoffice等。
26. 纯Qt编写,支持任意Qt版本+任意编译器+任意系统。
## 三、体验地址
1. 体验地址:[https://pan.baidu.com/s/1ZxG-oyUKe286LPMPxOrO2A](https://pan.baidu.com/s/1ZxG-oyUKe286LPMPxOrO2A) 提取码:o05q 文件名:bin_dataout.zip
2. 国内站点:[https://gitee.com/feiyangqingyun](https://gitee.com/feiyangqingyun)
3. 国际站点:[https://github.com/feiyangqingyun](https://github.com/feiyangqingyun)
4. 个人主页:[https://blog.csdn.net/feiyangqingyun](https://blog.csdn.net/feiyangqingyun)
5. 知乎主页:[https://www.zhihu.com/people/feiyangqingyun/](https://www.zhihu.com/people/feiyangqingyun/)
## 四、效果图
使用Qt实现PDF编辑器,您需要完成以下步骤:
1. 安装Qt:您需要在计算机上安装Qt框架。您可以从Qt官网下载并安装最新版本的Qt。
2. 创建一个Qt项目:使用Qt Creator创建一个新的Qt项目。在“新建项目”对话框中,选择“应用程序”模板并选择适当的应用程序类型。
3. 添加PDF库:为了能够编辑PDF文档,您需要添加一个PDF库到您的项目中。Qt提供了一个名为“QPdf”的PDF库,您可以通过在.pro文件中添加以下行来添加它:
```
QT += core gui widgets printsupport
```
4. 创建PDF编辑器界面:使用Qt Creator创建一个用户界面。您可以添加各种控件,例如文本框、按钮和菜单,以实现编辑PDF文档的功能。
5. 实现PDF编辑功能:使用Qt的PDF库来打开、保存和编辑PDF文档。您可以使用QPdfDocument类来打开和关闭PDF文档,使用QPdfWriter类来保存PDF文档。
6. 测试和调试:在完成开发后,您需要对您的PDF编辑器进行测试和调试。您可以使用Qt Creator的调试工具来查找和修复错误。
以上是使用Qt实现PDF编辑器的基本步骤。当然,具体实现方式还需要根据您的需求和实际情况进行调整和修改。
文的文字及图片来源于网络,仅供学习、交流使用,不具有任何商业用途,,版权归原作者所有,如有问题请及时联系我们以作处理
作者:州的先生
原文链接: https://zmister.com/archives/1607.html
将 HTML 网页转换为 PDF 是很多人常见的一个需求,在浏览器上,我们可以通过浏览器的“打印”功能直接将网页打印输出为 PDF。
但是如果有多个网页就不好办了。
文章目录
网络上存在很多将 HTML 转换为 PDF 的软件和工具。比较著名的有 Carelib、wkhtmltopdf。
wkhtmltopdf 真是一个优秀的 HTML 转换 PDF 工具。其借助 Qt 的 WebKit 渲染引擎,将 HTML 文档渲染导出为 PDF 文档或图像。
功能十分完善,但是由于使用的渲染引擎是 Qt 的 WebKit,其没法对 ES6 的 JavaScript 代码提供支持,导致一些采用 ES6 编写的 HTML 页面渲染不出实际的效果来,导致州的先生最终放弃了它。
Carelib 是一个电子书管理软件,其中提供了各类文档的转换工具,所以可以借助其电子书转换工具来实现 HTMl 到 PDF 的转换。
这些都是用于桌面环境的二进制软件,如果要在 Python 中使用,要么使用 Popen() 方法调用这些二进制软件的命令,要么使用一些第三方的封装模块,比如: pdfkit 、 pypandoc 等,这些第三方模块通过集成调用上述二进制软件,封装了一些方便 Python 调用的接口。
上面介绍的那些 Python 第三方模块虽然可以很好的进行 HTML 到 PDF 的转换工作,但是都需要额外在计算机上安装其他的二进制软件,很多小伙伴并不喜欢这种调用方式。
不依赖于二进制软件的实现,有如下的方案:
这是一个基于 ReportLab、html5lib、PyPDF2 等 Python 模块构建的 HTML 到 PDF 转换模块。能够很好的支持 HTML5 、CSS2.1 和部分 CSS3 语法。
因为是基于 Report Lab 模块进行的开发,其对中文的支持在某些环境下会有问题。而且由于开发人员的变更,模块的功能出现了一些断层。但是仍然是一个非常棒的 HTML 转 PDF 模块。
这是一个用于 HTML 和 CSS 的可视化渲染引擎,可以将 HTML 文档导出为打印标准的 PDF 文件。
xhtml2pdf 模块也曾推荐使用这个模块来进行 HTML 转换 PDF 的工作。
这个模块功能很强大、效果很出色,但是,模块的依赖项太多了:
州的先生至今没有在 Windows 电脑上安装成功过!
在上述两种方案中,二进制程序的可控制性稍有不足,而纯 Python 实现的渲染解析则在功能上和依赖上不是有友好。
处理上述两种方案,我们还能采用第三种方式进行 HTMl 到 PDF 的转换。那就是借助 Web 自动化测试的浏览器内核和 Qt for Python 的 Web 引擎 来实现。
使用 Python 的小伙伴经常会使用 Selenium、pyppeteer 这两个 Web 自动化测试的模块来进行数据采集和 Web 自动化测试工作。
这两个模块都是用来驱动一个真实的浏览器来进行网页的操作。正是基于此,我们可以调用浏览器中打印相关的 API 接口,来实现 HTML 转 PDF 的功能。
例如,在 pyppeteer 中可以按照下面示例的方式,打开一个 HTML 文档,然后将其转换为 PDF 文档:
在 Qt5 中,Qt 使用新的 Chromium 内核代替了老旧的 WebKit 作为 Web 的渲染引擎。使得在 Qt 中进行可以现代化的浏览器开发。
借助于 Qt 的 Python 实现(PyQt5 系列 和 PySide2 系列),我们可以直接调用 Qt 中的 Web 引擎相关的接口。
其中 QtWebEngineWidgets 子模块中的 QWebEngineView() 类提供了 printToPdf 方法供我们将网页打印为 PDF 文档,所以基于此,我们也可以使用 PyQt5 或 PySide2 进行 HTML 转换 PDF,示例如下所示:
*请认真填写需求信息,我们会在24小时内与您取得联系。