Java开发 PDF文件生成方案

news2025/1/4 19:18:57
业务需求背景

业务端需要能够将考试答卷内容按指定格式呈现并导出为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.coloradmin.cn/o/2270191.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CSS进阶和SASS

目录 一、CSS进阶 1.1、CSS变量 1.2、CSS属性值的计算过程 1.3、做杯咖啡 1.4、下划线动画 1.5、CSS中的混合模式(Blending) 二、SASS 2.1、Sass的颜色函数 2.2、Sass的扩展(extend)和占位符(%)、混合(Mixin) 2.3、Sass的数学函数 2.4、Sass的模块化开发 2.5、Sass…

GXUOJ-算法-补题:22级《算法设计与分析》第一次课堂练习

2.最大子数组和 问题描述 代码解答 #include<bits/stdc.h> using namespace std; const int N1005; int sum,n,a[N]; int res-1;int result(){for(int i0;i<n;i){if(sum<0) suma[i];else{suma[i];resmax(res,sum);}}return res; } int main(){cin>>n;for(i…

纵览!报表控件 Stimulsoft Reports、Dashboards 和 Forms 2025.1 新版本发布!

Stimulsoft 2025.1 新版发布&#xff0c;旨在增强您创建报告、仪表板和 PDF 表单的体验&#xff01;此最新版本为您带来了许多改进和新功能&#xff0c;使数据处理更加高效和用户友好。亮点包括对 .NET 9 的支持、Microsoft Analysis Services 的新数据适配器、发布向导中适用于…

Javascript-web API-day04

文章目录 01-实例化日期对象02-常见的日期对象方法03-年月日案例04-年月日简化05-得到时间戳06-倒计时07-关闭节点08-子节点09-增加节点10-克隆节点11-删除节点12-m端时间13-(swiper插件的使用)移动端轮播图游乐园项目 学成在线重构 01-实例化日期对象 <!DOCTYPE html> …

Formality:匹配(match)是如何进行的?

相关阅读Formalityhttps://blog.csdn.net/weixin_45791458/category_12841971.html?spm1001.2014.3001.5482 匹配点、对比点和逻辑锥 匹配指的是Formality工具尝试将参考设计中的每个匹配点与实现设计中的相应匹配点进行配对&#xff0c;这里的匹配点包括对比点(Compare Point…

浅谈电力监控系统在厂房电力工程中的设计与应用

安科瑞汪洋/汪小姐/汪女士---Acrelwy 摘要 &#xff1a;电力监控系统在厂房电力工程中的应用&#xff0c;稳步提升了电力系统管理的智能化、信息化水平&#xff0c;确保电力资源的合理化应用&#xff0c;满足工业生产的基本需求。为确保电力监控系统与厂房电力工程的有效结合&…

AIGC生图实战技巧分享

目录 引言 &#x1f343;安装与配置代码 &#x1f343;数据处理代码 &#x1f343;生图请求代码 引言 本文展示了 AIGC 生图相关的代码示例&#xff0c;包括安装与配置、数据处理以及生图请求等不同阶段的代码&#xff0c;清晰呈现了整个技术实现过程中代码层面的操作要点和…

Mac iTerm2集成DeepSeek AI

1. 去deepseek官网申请api key&#xff0c;DeepSeek 2. 安装iTerm2 AI Plugin插件&#xff0c;https://iterm2.com/ai-plugin.html&#xff0c;插件解压后直接放到和iTerms相同的位置&#xff0c;默认就在/Applications 下 3. 配置iTerm2 4. 重启iTerm2,使用快捷键呼出AI对话…

akamai3.0反爬教程逆向分析9个视频汇总

目录 一、akamai2.0文章二、akamai3.0每月疑似改版点二、9个视频汇总如下 一、akamai2.0文章 文章1cookie反爬之akamai_2.0-上文章2cookie反爬之akamai_2.0-上文章3cookie反爬之akamai_2.0-上文章中akamai2.0对应调试html与js文件 二、akamai3.0每月疑似改版点 详细文字与2.…

解决chatgpt(mac app登陆)出现报错:获取您的 SSO 信息时出错

由于我们是app登陆的&#xff0c;不能直接修改网站的链接&#xff0c;将 URL 的域名部分从 auth.openai.com 变更为 auth0.openai.com&#xff0c;然后加载新的地址&#xff0c;这时候应该就可以正常登录或注册了。 所以我们使用邮箱先载入auth0的地址&#xff0c;再更改自己的…

基于Springboot + vue实现的高校办公室行政事务管理系统

&#x1f942;(❁◡❁)您的点赞&#x1f44d;➕评论&#x1f4dd;➕收藏⭐是作者创作的最大动力&#x1f91e; &#x1f496;&#x1f4d5;&#x1f389;&#x1f525; 支持我&#xff1a;点赞&#x1f44d;收藏⭐️留言&#x1f4dd;欢迎留言讨论 &#x1f525;&#x1f525;&…

UE5通过蓝图节点控制材质参数

通过蓝图节点控制材质的参数 蓝图节点 在材质上设置标量值 和 在材质上设置向量参数值 Set Scalar Parameter Value on Materials Set Vector Parameter Value on Materials 这两个蓝图节点都可以在蓝图中&#xff0c;控制材质的参数值和向量值

DeepSeek-VL2

《DeepSeek-VL2: Mixture-of-Experts Vision-Language Models for Advanced Multimodal Understanding》是 DeepSeek-AI 团队发布的关于视觉语言模型 DeepSeek-VL2 的论文&#xff0c;以下是对该论文的详细介绍&#xff1a; 研究背景与动机 多模态理解的重要性&#xff1a;在当…

【第二部分--Python之基础】03 容器类型的数据

Python内置的数据类型如序列&#xff08;列表、元组等&#xff09;、集合和字典等可以容纳多项数据&#xff0c;我们称它们为容器类型的数据。 序列 序列&#xff08;sequence&#xff09;是一种可迭代的、元素有序的容器类型的数据。 序列包括列表&#xff08;list&#xff…

大型概念模型:在句子表示空间中的语言建模

《Large Concept Models: Language Modeling in a Sentence Representation Space》这篇论文介绍了一种新的语言模型方法&#xff0c;它在句子表示空间中进行建模。该方法旨在改进传统语言模型的局限性&#xff0c;通过捕捉更高级别的语义信息来提高自然语言处理任务的表现。 模…

日期时间选择(设置禁用状态)

目录 1.element文档需要 2.禁用所有过去的时间 3.设置指定日期的禁用时间 <template><div class"block"><span class"demonstration">起始日期时刻为 12:00:00</span><el-date-pickerv-model"value1"type"dat…

Mac 安装Mysql启动Mysql以及数据库的常规操作

Mac 安装Mysql启动Mysql以及数据库的常规操作 一、mysql的安装 1、登录官方网站:dev.mysql.com/downloads/mysql/ 二、查看系统架构 uname -m 在MAC中&#xff1a; 如果输出结果是 x86_64&#xff0c;则表示你的系统是 x86-64 架构。 如果输出结果是 arm64&#xff0c;则表示…

2011-2020年各省粗离婚率数据

2011-2020年各省粗离婚率数据 1、时间&#xff1a;2011-2020年 2、来源&#xff1a;国家统计局 3、指标&#xff1a;地区、年份、粗离婚率 4、范围&#xff1a;31省 5、指标解释&#xff1a;粗离婚率指某地区当年离婚对数占该地区年平均人口的比重。计算公式为&#xff1a…

【Cocos TypeScript 零基础 2.1】

目录 cocos常识新建动画添加组件 cocos 下载就不讲了,多的很 cocos 界面设置中文 新建一个2D项目 SIKI_学院_点击跳转 常识 竖屏 宽720 高1280 如果背景图确定是竖屏也可以根据背景图片大小来确定项目宽高 鼠标功能 左键 选中 滚轮 放大缩小 右键 移动视角位置 场景 双击…

UE蓝图战利品掉落动画

战利品掉落动画&#xff0c;其实就是添加个冲量 add impulse 什么是冲量&#xff1f; 冲量 &#xff08;impulse&#xff09;是作用在物体上的力 在 时间上的累积效果