当前位置: 首页 > article >正文

Java开发 PDF文件生成方案

业务需求背景

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

第一版方案实现:前端显示 + 后端 Selenium 调用浏览器打印

为能够尽快上线此功能,团队经讨论确定第一版方案以满足需求。

实现原理 该方案核心在于借助浏览器的渲染能力,通过 Selenium 库搭配 Chrome Headless 无头浏览器模拟用户操作,具体步骤如下:

  1. 前端页面设计:前端开发人员根据业务需求,构建一个完整的网页模板,确保所有样式和布局都符合预期。

  2. 后端调用与打印:后端服务器通过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(免费) - 天航星 - 博客园

实现原理 此方案分为三个主要步骤:

  1. 填充 Excel 模版:将已有的Excel模版进行数据填充,写入Excel中

  2. 写入 Excel 文件:由于表格内容格式过于复杂,且需要根据不同数据动态合并单元格等情况,无法使用模版填充,使用Apache POI库,按照规定的格式写入Excel文件。在此过程中,需对每个单元格进行格式设置,如数据类型、对齐方式、边框、合并等,以确保数据展示规整有序。

  3. 转换为 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,而非整张试卷一次性写入。


http://www.kler.cn/a/460537.html

相关文章:

  • vue2、element的el-select 选项框的宽度设置、文本过长问题
  • P5289 [十二省联考 2019] 皮配 做题记录
  • vue v-for 数据增加页面不刷新
  • 前端路由layout布局处理以及菜单交互(三)
  • Docker--Docker Container(容器) 之 操作实例
  • 从单点 Redis 到 1 主 2 从 3 哨兵的架构演进之路
  • 开源前端框架都有哪些
  • cmake always build
  • 开源AI智能名片2+1链动模式O2O商城小程序在流量留存与转化中的深度应用与优化策略
  • RabbitMQ基础篇之Java客户端 Work Queues
  • 电子电气架构 --- 什么是自动驾驶技术中的域控制单元(DCU)?
  • 【Paper Tips】随记1-word版打印公式
  • Mesh网格数据结构2-半边结构
  • 32. 找最小数
  • 集成开发环境——keil c51 和 keil mdk的安装及融合
  • 【详解】AndroidWebView的加载超时处理
  • 【YashanDB知识库】sys登录提示账户被锁,怎么处理?
  • 【AUTOSAR 基础软件】Can模块详解(Can栈之驱动模块)
  • 深入了解 Zookeeper:原理与应用
  • 小白投资理财 - 看懂 EPS 每股收益
  • Windows11 的开发
  • 【SpringBoot】深度解析 Spring Boot 拦截器:实现统一功能处理的关键路径
  • debian安装Nginx
  • [羊城杯 2024]不一样的数据库_2
  • QGIS移动图元功能
  • 纯血鸿蒙ArkUI相对布局详解