Java开发 PDF文件生成方案
业务需求背景
业务端需要能够将考试答卷内容按指定格式呈现并导出为pdf格式进行存档,作为紧急需求插入。导出内容存在样式复杂性,包括特定的字体(中文)、字号、颜色,页面得有页眉、页码,数据需要进行表格聚合处理,并且需要动态处理边框、单元格、数据文本格式化等,整体功能上线时间紧迫。

第一版方案实现:前端显示 + 后端 Selenium 调用浏览器打印
为能够尽快上线此功能,团队经讨论确定第一版方案以满足需求。
实现原理 该方案核心在于借助浏览器的渲染能力,通过 Selenium 库搭配 Chrome Headless 无头浏览器模拟用户操作,具体步骤如下:
-
前端页面设计:前端开发人员根据业务需求,构建一个完整的网页模板,确保所有样式和布局都符合预期。
-
后端调用与打印:后端服务器通过Selenium库启动Chrome Headless浏览器,加载前端生成的页面链接。然后调用浏览器的打印功能,将页面转换为PDF格式并保存到指定路径供用户下载。
优点
-
快速实现:由于前端页面已经具备完善的样式和布局,后端只需负责调用和转换,因此可以较快上线。
-
充分利用现有资源:借助浏览器本身的渲染引擎,避免了额外的开发工作量。
缺点
-
性能瓶颈:每次导出都需要启动浏览器实例,消耗较多系统资源,尤其在高并发场景下容易出现性能问题。
-
潜在风险:集成第三方浏览器服务会引入额外的依赖项,从而增加系统的复杂性和不可靠性。这种外部依赖可能导致系统在面对第三方服务的故障、维护或更新时出现不稳定的情况,进而影响整体的服务质量和用户体验。
第二版方案实现:后端生成 Excel 再转成 PDF
由于存在潜在风险和性能瓶颈,需要将现有方案优化为后端生成。
具体实现
Java Excel转PDF POI+Itext5-CSDN博客
转换方案
当前市面上Excel转Pdf方案分为两类:
一:成熟的商业产品,可以直接调转换方法一键生成PDF
二:开源方案,可以写入PDF,但是不支持直接转换,也不提供转换方案,可行的方案通常为第三方自行编写的Util类开源

由于商业产品收费很高,故使用开源组件。
商业产品:aspose、spire
开源组件:itextpdf
参考文档:
Java开发中Word转PDF文件5种方案横向评测_java word转pdf-CSDN博客
Java Excel转PDF(免费) - 天航星 - 博客园
实现原理 此方案分为三个主要步骤:
-
填充 Excel 模版:将已有的Excel模版进行数据填充,写入Excel中
-
写入 Excel 文件:由于表格内容格式过于复杂,且需要根据不同数据动态合并单元格等情况,无法使用模版填充,使用Apache POI库,按照规定的格式写入Excel文件。在此过程中,需对每个单元格进行格式设置,如数据类型、对齐方式、边框、合并等,以确保数据展示规整有序。
-
转换为 PDF 文件:使用iText库将生成的Excel文件转换为PDF格式。转换时需要调整PDF页面布局,包括页面大小、边距、字体、字号、颜色等样式属性,确保最终输出符合项目要求。
优点
-
格式一致性:Excel本身具有强大的表格处理能力,能够很好地保证数据格式的一致性和准确性。
-
易于调试:在Excel中更容易发现和修正问题,可以使用Offic等软件直观查看。
-
数据模版:可以使用模版的方式改变样式布局,减少代码改动。
缺点
-
效率低下:涉及两次转换过程,增加了处理时间和资源消耗。
异常
用itext转换pdf时,如果单元格内容过多,会出现该bug
com.itextpdf.text.DocumentException: java.lang.NullPointerException: Cannot read field \"llx\" because \"cell\" is null
在互联网中未出现的bug,经过研究后无法修复,但是目前市场上的成熟转换方案都是商业产品,免费或使用版本限制太多,无法满足需求,改用直接写入pdf方案。
解决方案
com.itextpdf.text.DocumentException: java.lang.NullPointerException: Cannot read field \“llx\“ becau-CSDN博客
第三版方案实现:纯后端 PDF 生成
由于上述 bug 经多人研究解决及替换方案均无果,只能改用直接写入 PDF 的方案。
实现步骤:
代码替换:由于原本方案实现的布局代码已经完善,数据构造和布局填充是分离的,使用新方案只需要修改poi处代码,改用itext的方式重新写入即可
避坑
-
单元格合并时机:使用 POI 方式时,代码逻辑为先填充表格全部单元格内容,最后判断单元格进行合并。在 iText 方案中,此逻辑会导致合并单元格跨页时,下一页合并单元格丢失效果。经研究发现,需在创建合并单元格的第一个单元格时就指定合并区域,余下被合并单元格不再写入 PdfPTable。
-
分批次写入document:当一次写入内容过多时,依然会抛出关于 “llx” 的 bug。需减少一次写入 document 的单元格数量,目前方案是每道题作为一个新的 PdfPTable,处理完成就写入一次 document,而非整张试卷一次性写入。
相关文章:
Java开发 PDF文件生成方案
业务需求背景 业务端需要能够将考试答卷内容按指定格式呈现并导出为pdf格式进行存档,作为紧急需求插入。导出内容存在样式复杂性,包括特定的字体(中文)、字号、颜色,页面得有页眉、页码,数据需要进行表格聚…...
数学期望和方差
数学期望(Mathematical Expectation)和方差(Variance)是概率论和统计学中两个非常重要的概念。下面将分别对这两个概念进行解释。 数学期望 数学期望是随机变量的平均值,它描述了随机变量的中心位置。对于离散随机变…...
【面试AI算法题中的知识点】方向涉及:ML/DL/CV/NLP/大数据...本篇介绍Tensor RT 的优化流程。
【面试AI算法题中的知识点】方向涉及:ML/DL/CV/NLP/大数据…本篇介绍Tensor RT 的优化流程。 【面试AI算法题中的知识点】方向涉及:ML/DL/CV/NLP/大数据…本篇介绍Tensor RT 的优化流程。 文章目录 【面试AI算法题中的知识点】方向涉及:ML/D…...
BLDC无感控制的驱动逻辑
如何知道转子已经到达预定位置,因为我们只有知道了转子到达了预定位置之后才能进行换相,这样电机才能顺滑的运转。转子位置检测常用的有三种方式。 方式一:通过过零检测,三相相电压与电机中性点电压进行比较。过零检测的优点在于…...
BP神经网络的反向传播算法
BP神经网络(Backpropagation Neural Network)是一种常用的多层前馈神经网络,通过反向传播算法进行训练。反向传播算法的核心思想是通过计算损失函数对每个权重的偏导数,从而调整权重,使得网络的预测输出与真实输出之间…...
[实用指南]如何将视频从iPhone传输到iPad
概括 将视频从 iPhone 传输到 iPad 时遇到问题?您可能知道一种方法,但不知道如何操作。此外,您要传输的视频越大,完成任务就越困难。那么如何将视频从 iPhone 传输到 iPad,特别是当您需要发送大视频文件时?…...
Linux Snipaste 截图闪屏/闪烁
防 csdn 不能看,Go to juejin Linux Snipaste 截图时窗口元素一闪一闪的无法正常使用。 解决此问题时系统环境为 Manjaro KDE6,不过我在其他发行版与 gnome 上也碰到了。 先放解决办法: # 启动 Snipaste 时去掉缩放参数 env -u QT_SCREEN_…...
【YOLOv5】源码(common.py)
该文件位于/models/common.py,提供了构建YOLOv5模型的各种基础模块,其中包含了常用的功能模块,如自动填充autopad函数、标准卷积层Conv、瓶颈层Bottleneck、C3、SPPF、Concat层等 参考笔记:【YOLOv3】 源码(common.py…...
Node 如何生成 RSA 公钥私钥对
一、引入crypto模块 crypto 为node 自带模块,无需安装 const crypto require(crypto);二、封装生成方法 async function generateRSAKeyPair() {return new Promise((resolve, reject) > {crypto.generateKeyPair(rsa, {modulusLength: 2048, // 密钥长度为 …...
瑞_Linux中部署配置Java服务并设置开机自启动
文章目录 背景Linux服务配置步骤并设置开机自启动附-Linux服务常用指令 🙊 前言:由于博主在工作时,需要将服务部署到 Linux 服务器上运行,每次通过指令启动服务非常麻烦,所以将 jar 包部署的服务设置开机自启动&#x…...
javaEE-多线程进阶-JUC的常见类
juc:指的是java.util.concurrent包,该包中加载了一些有关的多线程有关的类。 目录 一、Callable接口 FutureTask类 参考代码: 二、ReentrantLock 可重入锁 ReentrantLock和synchronized的区别: 1.ReentantLock还有一个方法:…...
Flume拦截器的实现
Flume conf文件编写 vim file_to_kafka.conf#定义组件 a1.sources r1 a1.channels c1#配置source a1.sources.r1.type TAILDIR a1.sources.r1.filegroups f1 a1.sources.r1.filegroups.f1 /Users/zhangjin/model/project/realtime-flink/applog/log/app.* # 设置断点续传…...
Swift Combine 学习(四):操作符 Operator
Swift Combine 学习(一):Combine 初印象Swift Combine 学习(二):发布者 PublisherSwift Combine 学习(三):Subscription和 SubscriberSwift Combine 学习(四&…...
leetcode 173.二叉搜索树迭代器栈绝妙思路
以上算法题中一个比较好的实现思路就是利用栈来进行实现,以下方法三就是利用栈来进行实现的,思路很好,很简练。进行next的时候,先是一直拿到左边的子树,直到null为止,这一步比较好思考一点,下一…...
df.groupby([pd.Grouper(freq=‘1M‘, key=‘Date‘), ‘Buyer‘]).sum()
df.groupby([pd.Grouper(freq1M, keyDate), Buyer]).sum() 用于根据特定的时间频率和买家(Buyer)对 DataFrame 进行分组,然后计算每个分组的总和。下面是对这行代码的逐步解释: df.groupby([...]):这个操作会根据传入的…...
LLM - 使用 LLaMA-Factory 部署大模型 HTTP 多模态服务 (4)
欢迎关注我的CSDN:https://spike.blog.csdn.net/ 本文地址:https://spike.blog.csdn.net/article/details/144881432 大模型的 HTTP 服务,通过网络接口,提供 AI 模型功能的服务,允许通过发送 HTTP 请求,交互…...
icp备案网站个人备案与企业备案的区别
个人备案和企业备案是在进行ICP备案时需要考虑的两种不同情况。个人备案是指个人拥有的网站进行备案,而企业备案则是指企业或组织名下的网站进行备案。这两者在备案过程中有一些明显的区别。 首先,个人备案相对来说流程较为简单。个人备案只需要提供个人…...
如何不修改模型参数来强化大语言模型 (LLM) 能力?
前言 如果你对这篇文章感兴趣,可以点击「【访客必读 - 指引页】一文囊括主页内所有高质量博客」,查看完整博客分类与对应链接。 大语言模型 (Large Language Model, LLM, e.g. ChatGPT) 的参数量少则几十亿,多则上千亿,对其的训…...
AF3 AtomAttentionEncoder类的init_pair_repr方法解读
AlphaFold3 的 AtomAttentionEncoder 类中,init_pair_repr 方法方法负责为原子之间的关系计算成对表示(pair representation),这是原子转变器(atom transformer)模型的关键组成部分,直接影响对蛋白质/分子相互作用的建模。 init_pair_repr源代码: def init_pair_repr(…...
DDoS攻击防御方案大全
1. 引言 随着互联网的迅猛发展,DDoS(分布式拒绝服务)攻击成为了网络安全领域中最常见且危害严重的攻击方式之一。DDoS攻击通过向目标网络或服务发送大量流量,导致服务器过载,最终使其无法响应合法用户的请求。本文将深…...
PlotJuggler颜色映射终极指南:如何创建惊艳的数据可视化效果
PlotJuggler颜色映射终极指南:如何创建惊艳的数据可视化效果 【免费下载链接】PlotJuggler The Time Series Visualization Tool that you deserve. 项目地址: https://gitcode.com/gh_mirrors/pl/PlotJuggler PlotJuggler是一款功能强大的时间序列数据可视化…...
游戏多开防封号?聊聊用天翼云低成本搭建SK5代理池的真实体验与避坑心得
游戏多开防封号实战:天翼云SK5代理池搭建全记录与深度优化指南 作为一名资深游戏多开玩家,我曾在《魔兽世界》怀旧服同时运营8个采集账号,结果三天内全军覆没——官方封号邮件里赫然写着"同一IP下异常多账号操作"。这次惨痛经历让…...
FanControl完全指南:5分钟掌握Windows风扇智能控制
FanControl完全指南:5分钟掌握Windows风扇智能控制 【免费下载链接】FanControl.Releases This is the release repository for Fan Control, a highly customizable fan controlling software for Windows. 项目地址: https://gitcode.com/GitHub_Trending/fa/Fa…...
一张照片秒变3D模型!用Splatter Image和3D高斯溅射快速上手单视图重建
从单张照片到3D模型:Splatter Image技术实战指南 想象一下,你刚在二手市场淘到一个绝版手办,想为它创建数字档案;或是设计师客户临时需要将一张产品照片转为3D模型。传统流程需要专业设备扫描或手工建模,耗时数小时甚…...
GTX1650也能跑!Windows11上OLLAMA+AnythingLLM本地部署Llama3保姆级教程
GTX1650也能跑!Windows11上OLLAMAAnythingLLM本地部署Llama3保姆级教程 老旧硬件也能玩转大模型?当GTX1650这样的入门级显卡遇上Llama3这类前沿AI模型,很多人第一反应可能是"跑不动"。但经过实测,只要合理配置和优化&am…...
别再为UI动画发愁了!用Spine+Unity 2021制作丝滑2D动画的保姆级流程
SpineUnity 2021:打造专业级2D UI动画的完整实战指南 在独立游戏开发领域,UI动画的质量往往决定着玩家的第一印象。那些流畅的按钮反馈、生动的界面过渡,不仅提升了产品质感,更直接影响着用户的留存率。然而对于资源有限的中小团队…...
DanKoe 视频笔记:人生经验课:给18岁自己的信
在本节课中,我们将学习一位28岁人士回顾过去,总结出的核心人生经验。这些经验旨在帮助年轻人,特别是那些感到迷茫、渴望超越平凡生活的人,建立自主性、明确目标并采取有效行动。我们将把这些经验整理成一套清晰的教程,…...
智能猫砂盆:除臭静音,养猫更省心!
行业痛点分析当前智能猫砂盆领域面临两大核心挑战:清洁残留与安全防护。传统自动铲屎机型在完成集便动作后,猫砂盆底部仍会残留约15%-20%的沾尿结团猫砂(数据表明:第三方实验室对6款主流机型测试结果),用户…...
MediaPipe模型优化:从性能瓶颈到实时推理的全流程解决方案
MediaPipe模型优化:从性能瓶颈到实时推理的全流程解决方案 【免费下载链接】mediapipe Cross-platform, customizable ML solutions for live and streaming media. 项目地址: https://gitcode.com/GitHub_Trending/med/mediapipe 问题发现:计算机…...
深度学习驱动的光谱超分辨率:技术演进与应用前景
1. 光谱超分辨率技术的前世今生 我第一次接触光谱超分辨率技术是在2015年,当时还在用传统的线性插值方法处理遥感图像。记得有次为了获取一片农田的高光谱数据,团队不得不动用昂贵的机载传感器,结果因为天气原因导致数据质量极差。正是这次经…...
