Qt生成PDF报告
文章目录
- 一、示意图
- 二、实现部分代码
- 总结
一、示意图


二、实现部分代码
//! 生成测试报告
void MainWindow::createPdf(QString filename, _pdf_msg_& msg, const QMap<QString, int>& ok, const QMap<QString, int>& err)
{//QDir dir;if(!dir.exists("PdfFiles")) qDebug()<<dir.mkdir("PdfFiles");//创建PDF文件QString file_path = filename;QFile pdfFile(file_path);bool isOpen = pdfFile.open(QIODevice::WriteOnly);if(!isOpen){QMessageBox::warning(this,"error", pdfFile.errorString());return;}QPdfWriter *pWriter = new QPdfWriter(&pdfFile);pWriter->setPageSize(QPagedPaintDevice::A4);pWriter->setResolution(300);pWriter->setPageMargins(QMarginsF(30, 30, 30, 30));QPainter *pPainter = new QPainter(pWriter);QFont font[5] = {QFont("宋体", 26, 60), QFont("宋体", 26, 61), QFont("宋体", 26, QFont::Normal), QFont("宋体", 26, QFont::Normal), QFont("宋体", 26, QFont::Normal)};font[0].setPixelSize(86);font[1].setPixelSize(61);font[2].setPixelSize(61);font[3].setPixelSize(42);font[4].setPixelSize(54);//qDebug()<<pPainter->viewport().width()<<" "<<pPainter->viewport().height();int nPDFWidth = pPainter->viewport().width();int nPDFHeight = pPainter->viewport().height();//标题int y = 10;pPainter->setFont(font[0]);pPainter->drawText(QRect(0, y, nPDFWidth, 100), Qt::AlignCenter, msg.title);//画两条横线y += 140;pPainter->setPen(QPen(QBrush(QColor(0, 0, 0)), 5));pPainter->drawLine(0, y, nPDFWidth, y);pPainter->drawLine(0, y + 18, nPDFWidth, y + 18);//y += 60;pPainter->setFont(font[2]);pPainter->drawText(QRect(100, y, nPDFWidth/2, 70), Qt::AlignVCenter | Qt::AlignLeft, QString("产品名称: %1").arg(msg.product_name));pPainter->drawText(QRect(nPDFWidth/2 + 100 , y, nPDFWidth/2 - 100, 70), Qt::AlignVCenter | Qt::AlignLeft, QString("产品ID: %1").arg(msg.product_id));y += 90;pPainter->drawText(QRect(100, y, nPDFWidth/2, 70), Qt::AlignVCenter | Qt::AlignLeft, QString("产品型号: %1").arg(msg.product_type));pPainter->drawText(QRect(nPDFWidth/2 + 100 , y, nPDFWidth/2 - 100, 70), Qt::AlignVCenter | Qt::AlignLeft, QString("测试时间: %1").arg(msg.test_time));//小标题y += 90;pPainter->setFont(font[1]);pPainter->drawText(QRect(0, y, nPDFWidth, 80), Qt::AlignVCenter | Qt::AlignLeft, "触点比较结果");//画表格y += 110;QStringList list;list<<"序号"<<"输出点位名称"<<"结果"<<"序号"<<"输出点位名称"<<"结果";//int idx = 1;int row = 0;int column = 0;if(caseType == CASETYPE::L3U){foreach(QString s, g_RelayContact_3U){if(s == "预留") list<<QString::number(idx)<<s<<"";else if(err.contains(s)) list<<QString::number(idx)<<s<<"不合格";else if(ok.contains(s)) list<<QString::number(idx)<<s<<"合格";else list<<QString::number(idx)<<s<<"未检测";++idx;}row = g_RelayContact_3U.length()/2+1;column = 6;}else{foreach(QString s, g_RelayContact_6U){if(s == "预留") list<<QString::number(idx)<<s<<"";else if(err.contains(s)) list<<QString::number(idx)<<s<<"不合格";else if(ok.contains(s)) list<<QString::number(idx)<<s<<"合格";else list<<QString::number(idx)<<s<<"未检测";++idx;}row = g_RelayContact_6U.length()/2+1;column = 6;}pdfDrawForm(pWriter, pPainter, y, 0, row, column, 80, font[3], list);//!//小标题y += 90;pPainter->setFont(font[1]);pPainter->drawText(QRect(0, y, nPDFWidth, 80), Qt::AlignVCenter | Qt::AlignLeft, "不合格点位");////画表格y += 110;list.clear();list<<"序号"<<"输出点位名称"<<"结果"<<"序号"<<"输出点位名称"<<"结果";//idx = 1;row = 0;column = 0;if(caseType == CASETYPE::L3U){for(auto it = err.begin(); it != err.end(); ++it){list<<QString::number(it.value())<<it.key()<<"不合格";}row = err.size()/2+1;column = 6;}else{for(auto it = err.begin(); it != err.end(); ++it){list<<QString::number(it.value())<<it.key()<<"不合格";}row =err.size()/2+1;column = 6;}pdfDrawForm(pWriter, pPainter, y, 0, row, column, 80, font[3], list);//pPainter->setFont(font[4]);pPainter->drawText(QRect(50, nPDFHeight, nPDFWidth/3, 80), Qt::AlignVCenter | Qt::AlignLeft, QString( "试验员: %1").arg(msg.tester_name));pPainter->drawText(QRect(nPDFWidth/3+50, nPDFHeight, nPDFWidth/3, 80), Qt::AlignVCenter | Qt::AlignLeft, QString( "检查员签字: "));pPainter->drawText(QRect(nPDFWidth/3*2, nPDFHeight, nPDFWidth/3, 80), Qt::AlignVCenter | Qt::AlignLeft, QString( "签字日期: "));//绘制完毕delete pPainter;delete pWriter;pdfFile.close();//通过其他PDF阅读器来打开PDFQDesktopServices::openUrl(QUrl::fromLocalFile(file_path));
}
void MainWindow::pdfDrawForm(QPdfWriter *pWriter, QPainter *paint, int& y, int horzBorder, int row, int column, int unitHeight, QFont &font, QStringList &list)
{paint->setFont(font);paint->setPen(QPen(QBrush(QColor(0, 0, 0)), 2));int Width = paint->viewport().width() - horzBorder * 2;int unitWidth = Width / column;for(int i=0;i<row;i++) {int x = horzBorder;for(int j=0;j<column;j++) {paint->drawText(QRect(x, y, unitWidth, unitHeight), Qt::AlignCenter, list[i*column + j]);paint->drawRect(QRect(x, y, unitWidth, unitHeight));x += unitWidth;}y += unitHeight;if(y > paint->viewport().height()){pWriter->newPage();y = 10;}}
}
总结
记录下用到的不常用知识点
相关文章:
Qt生成PDF报告
文章目录 一、示意图二、实现部分代码总结 一、示意图 二、实现部分代码 //! 生成测试报告 void MainWindow::createPdf(QString filename, _pdf_msg_& msg, const QMap<QString, int>& ok, const QMap<QString, int>& err) {//QDir dir;if(!dir.exis…...
Jenkins 安装全攻略:从入门到精通
目录 一:安装文件夹准备 1.打开,/home/admin目录 2.新建三个文件夹 二:安装tomcat 1.打开tomcat目录进行tomcat安装 2.解压tomcat文件 3.开放端口号 4.启动tomcat 5.浏览器访问tomcat 三:安装Maven 1.打开maven目录进行…...
迎重阳,话养老:平安养老险如何助力国民“养老梦”?
10月23日,我们将迎来传统节日重阳节,又称敬老节,自古就有祭祖、登高、赏菊三大风俗,流传至今,已成为人们孝老敬老的重要节日。 随着老龄化日益加深,在“敬老”的同时如何“备老”成为人民群众长期热议的话题…...
微信小程序获取用户信息
个人博客 微信小程序获取用户信息 个人微信公众号,求关注,求收藏,求指错。 文章概叙 本文主要讲的是小程序获取用户信息的,更新测试时间是2023-10-25 更改原因 首先,官网上的解释是这样的,为了安全合…...
Mysql 索引原理和优化方式
一、索引原理 什么是索引 索引是存储引擎用于快速找到记录的一种数据结构。可以联想到字典中的目录。 索引的分类 (1) Hash 索引 Hash 索引是比较常见的一种索引,他的单条记录查询的效率很高,时间复杂度为1。但是,…...
Ubuntu安装VM TOOLS解决虚拟机无法和WINDOWS粘贴复制问题
1:首先使用VMware Workstation安装一个Ubuntu的系统。 2:现在已经不建议安装VM TOOLS。建议安装OPEN-VM-TOOLS。 3:进入系统使用下面的命令安装。 sudo apt install open-vm-tools 4:提示下面错误,Package open-vm…...
【Docker】Docker Swarm介绍与环境搭建
为什么不建议在生产环境中使用Docker Compose 多机器如何管理?如何跨机器做scale横向扩展?容器失败退出时如何新建容器确保服务正常运行?如何确保零宕机时间?如何管理密码,Key等敏感数据? Docker Swarm介…...
国产CAN总线收发芯片DP1042 兼容替换TJA1042
说明 1 简述 DP1042是一款应用于 CAN 协议控制器和物理总线之间的接口芯片,可应用于卡车、公交、小汽车、工业控制等领域,支持 5Mbps CAN FD 灵活数据速率,具有在总线与 CAN 协议控制器之间进行差分信号传输的能力,完全兼容“ISO…...
[架构之路-243]:目标系统 - 纵向分层 - 架构是表面轮廓、内部骨架、未来蓝图,企业组织架构、信息系统架构、软件架构、应用程序就架构
目录 一、什么是架构 1.1 架构是表面轮廓 1.2 架构是内部骨架 1.3 架构是蓝图,是愿景 1.4 架构是数据流、控制流、管理流、同步流 1.5 数据、控制、同步、管理的比较 二、架构的层级 2.1 企业组织架构 2.2 企业系统架构 2.2 信息系统架构 2.3 软件架构 …...
【接口技术】定时计数器习题
1:8253芯片有______个端口地址。 【可选】 2 3 4 6 解答:4 2:8253芯片有______种工作方式。 【可选】 3 4 5 6 解答:6 3: 8253芯片内部有完全独立的______。 【可选】 6个16位计数通道 3个16位计数通道 6个8位计…...
DC电源模块的的散热结构合理布局
BOSHIDA DC电源模块的的散热结构合理布局 DC电源模块在工业控制、通讯、汽车电子等领域广泛应用。然而,随着功率密度不断提高,DC电源模块产生的热量也越来越大,散热问题变得越来越突出。为了保障电路的稳定性和可靠性,必须采取合…...
Fedora Linux 38下安装音频与视频的解码器和播放器
Fedora Linux 38 操作系统安装好后,默认是没有音频与视频的解码器的,音频与视频的播放体验非常差劲。但是第三方的软件源中有解码器和播放器的软件,需要我们自己手动安装。、 连接互联网,打开Shell命令行: 1. sudo d…...
边缘计算:云计算的延伸
云计算已经存在多年,并已被证明对大大小小的企业都有好处;然而,直到最近边缘计算才变得如此重要。它是指发生在网络边缘的一种数据处理,更接近数据的来源地。 这将有助于提高效率并减少延迟以及设备和云之间的数据传输成本。边缘…...
【经验分享】在Kylin桌面版操作系统中配置openGauss的ODBC数据源
引言 openGauss是一款开源的关系型数据库管理系统,它提供了强大的功能和性能,可以满足各种企业级应用的需求。与此同时,ODBC(Open Database Connectivity)是一个标准的数据库访问接口,它允许应用程序通过统…...
WSL——ubuntu中anaconda换源(conda、pip)
1、conda 打开Ubuntu,输入下列命令。 conda config --set show_channel_urls yes 在文件管理器地址栏,输入:\\wsl$。打开Ubuntu根路径,其中显示了.condarc文件。 以文本形式打开,并输入要换的源,保存即可。…...
IP地址在网络安全中的关键作用
IP地址(Internet Protocol Address)是互联网世界中的重要标识符,它在网络安全领域发挥着至关重要的作用。这些地址不仅帮助设备在网络上找到彼此,还在多个方面有助于维护网络的完整性、机密性和可用性。本文将探讨IP地址在网络安全…...
Android.mk 中覆盖应用包名
项目场景: 一般来讲应用包名都是配置在 AndroidManifest.xml 中的,但遇到特殊情况,需要修改源码中应用包名 通常都会先去改 AndroidManifest.xml package 但改为后编译发现一顿错误,原因是 java 类中已经指定了 R 文件包名&…...
如何最有效地使用ChatGPT:提问技巧与策略
前言 在如今信息技术高速发展的时代,像ChatGPT这样的大型自然语言处理模型为我们提供了一个强大的工具,以获取各种信息和答案。然而,要充分利用这一工具,您需要掌握一些提问技巧与策略,以确保获得最准确和有用的回答。…...
【JAVA学习笔记】40 - 抽象类、模版设计模式(抽象类的使用)
项目代码 https://github.com/yinhai1114/Java_Learning_Code/tree/main/IDEA_Chapter10/src/com/yinhai/abstract_ 一、抽象类的引入 很多时候在创建类的时候有一个父类,比如animal类,他的子类会有各种方法,为了复用需要进行方法的重写&…...
如何通过在线培训考试系统进行远程教育
随着互联网技术的不断发展,远程教育正在成为一种新型的学习方式,它使学生能够在任何地点、任何时间通过在线培训考试系统接受教育。 利用在线培训考试系统进行远程教育具有很大的灵活性。学生可以根据自己的时间和需求自由选择课程,无需受制…...
SEO_SEO优化常见误区及正确操作指南
SEO优化常见误区 在互联网时代,SEO(搜索引擎优化)已成为网站运营中不可或缺的一部分。很多人在实际操作中却常常犯下一些常见的SEO优化误区,这不仅影响了网站的流量,也可能导致搜索引擎的惩罚。下面我们将详细分析这些…...
[Linux][虚拟串口]x一个特殊的字节
目标:构建带上下文记忆的猫咪聊天机器人 先看代码: from langchain_openai import ChatOpenAI from langchain_core.prompts import ChatPromptTemplate from langchain_core.messages import SystemMessage,HumanMessage,AIMessage import os from dote…...
背包模型(求组合)?爬楼梯模型(求排列)?
普通背包模型和爬楼梯模型是非常相似的两个模型。 首先,我们定义一个**“抽象背包模型”**(注意这个抽象背包模型不是前面提到的普通背包模型):给定 n 个物品,装满容积为 m 的背包,求方案数/具体方案/等等…...
Phi-4-mini-reasoning效果展示:同参数量级中推理准确率超Llama3-8B实测对比
Phi-4-mini-reasoning效果展示:同参数量级中推理准确率超Llama3-8B实测对比 1. 开篇亮点:小模型的大智慧 Phi-4-mini-reasoning这款仅有3.8B参数的轻量级开源模型,正在重新定义我们对小模型能力的认知。作为专为数学推理、逻辑推导和多步解…...
Wan2.2-I2V-A14B私有部署镜像优势:零依赖冲突、开箱即用、免编译安装
Wan2.2-I2V-A14B私有部署镜像优势:零依赖冲突、开箱即用、免编译安装 1. 镜像核心价值与定位 Wan2.2-I2V-A14B私有部署镜像是专为文生视频场景打造的一站式解决方案。这个镜像最大的特点就是解决了AI模型部署中最让人头疼的环境配置问题,真正做到下载即…...
南北阁模型新玩法:一键部署极简WebUI,体验手机短信般AI对话
南北阁模型新玩法:一键部署极简WebUI,体验手机短信般AI对话 还在用那些界面老旧、反应迟钝的AI对话工具吗?每次发送问题后,只能盯着屏幕上的加载图标干等,几秒甚至十几秒后才能看到一大段文字“啪”地一下弹出来&…...
运算放大器与比较器的本质区别及应用指南
1. 运算放大器与比较器的本质区别在电子电路设计中,运算放大器(Op-Amp)和电压比较器(Comparator)是两种极为常见却又经常被混淆的器件。它们在外观符号上几乎一模一样:都有五个引脚——正负电源端、同相与反…...
Beyond Compare 5终极激活指南:免费获取永久授权密钥的完整教程
Beyond Compare 5终极激活指南:免费获取永久授权密钥的完整教程 【免费下载链接】BCompare_Keygen Keygen for BCompare 5 项目地址: https://gitcode.com/gh_mirrors/bc/BCompare_Keygen Beyond Compare 5作为业界领先的文件对比工具,其强大的功…...
Music Tag Web:智能音乐元数据管理工具解决音乐收藏混乱难题
Music Tag Web:智能音乐元数据管理工具解决音乐收藏混乱难题 【免费下载链接】music-tag-web 音乐标签编辑器,可编辑本地音乐文件的元数据(Editable local music file metadata.) 项目地址: https://gitcode.com/gh_mirrors/mu/…...
C语言文件操作:从键盘输入到文件保存的完整流程(附常见错误排查)
C语言文件操作实战:从键盘输入到文件保存的完整指南 在C语言开发中,文件操作是每个程序员必须掌握的技能。无论是保存用户配置、记录日志还是处理数据,文件读写都扮演着关键角色。本文将带你从零开始,通过一个完整的案例ÿ…...
