SpringBoot 下PDF生成使用填坑总结

Stella981
• 阅读 1780

一、PDF生成


===

由于直接使用IText生成PDF,数据填充较为繁琐,故:

选用Freemarker和IText生成pdf,引入依赖:

环境:jdk 1.8 + SpringBoot

*1.引入freemarker starter (版本跟随SpringBootparent即可)*

<dependency>

*2.html渲染转换组件(使用版本5*

<dependency>

*3.引入Itext PDF生成组件(使用版本5,最新版位* 7, itextopen sourcecolsesource之分,目前7****版本在网上少有例子)

<dependency>

引入依赖后,代码如下:

public static void pdfTpl(Map<String, Object> data,Configuration cfg,String ftlTemplateName,String fileUrl){

一阵代码撸完然后debug测试,发现中文pdf文件中含有中文的都不显示(空白)

心里有点慌,因为服务马上要上线,最终在组内大佬的帮助下解决了

解释:
1、Configuration cfg 使用了freemaker starter后,在项目启动时即会自动初始化 Configuration 对象到Spring容器中;
2、Template template = cfg.getTemplate("test.ftl","UTF-8"); 模板因cfg本身在Spring容器中,则在获取test.ftl模板是就会自动在resource/templates下寻找模板,默认:ftl 格式,可以修改
3、因为找了很多例子都是使用ITextRenderer 对象来渲染输出渲染的PDF,但ITextRenderer有一个问题是要解决中文不显示问题,必须把字体放在一个以 文件夹 路径访问的形式引入,SpringBoot打包后,经测试,无法获取打包后的FONT字体;
则,再另辟途径,又找到以Document方式,但document需要的是,没一个dom对象都必须一个个添加进去,网上很多都是new 专门的对象,比如:块 Paragraph 然后添加文字(数字)内容。
所以又搜索:是否可以往document插入html
最终找到https://www.cnblogs.com/mvilplss/p/5646675.html

package com.***.***(省略);

以上确实可以将html模板内容渲染,但是中文仍不显示,解决方案有两种:

*1.方案1* 直接引入字体文件

renderer.getFontResolver().addFont(fontsPath ,BaseFont.IDENTITY_H,  BaseFont.NOT_EMBEDDED);

*2.方案2* 引入****iTextAsian.jar

BaseFont base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);

所以,毫无疑问,选择方案2,引入iTextAsian pom****,注意版本要跟itextpdf 一致,至少大版本要一致,如 5 对 5。否则会报
**com.lowagie.text.DocumentException: Font'STSong-Light' with 'UniGB-UCS2-H' is not recognized.
**

<dependency>

但是如何把 设置字体 操作在添加每个 element 时进行呢?发现在 继承 XMLWorkerFontProvider 时有个getFont方法,则在此返回即可,则最终得出上述代码。

注意:模板标签(h5)容易报错,一旦模板出现问题,可优先排查标签嵌套问题,例:table标签不能嵌套div标签


二、PDF转换为图片


pdf****转图片有两种方式:icepdf和pdfbox

上面两种方式都实现过,都存在中文不显示或者乱码问题,但是由于icepdf最多只能支持转换10页pdf,所以果断选择pdfbox。

1.引入依赖

<!--pdf转图片-->

引入以上依赖,编写代码运行(原始有问题的代码没有上传git,缺失了),报错信息如下:

在实际使用中遇到问题

1)ERROR o.a.p.contentstream.PDFStreamEngine 911 - Cannot read JBIG2 image: jbig2-imageio is not installed

以上两个问题需要使用 JAI 插件和 jbig2 插件支持,通过引入 jai-imageio-core、jai-imageio-jpeg2000、jbig2-imageio

<dependency>

引入上述依赖,本地开发环境mac下,pdf转图片正常转换,一旦到Linux环境下会出现生成pdf那样的情况:中文不显示或者乱码。报错信息如下

Using fallback LiberationSans for CID-keyed font AdobeKaitiStd-Regular

注意:其中font部分在Linux和Mac系统下显示特殊字符。

网上有说缺少字体需要导入字体文件,有说覆写FontMapperImpl

类,通过字体映射解决

详见:

http://www.luyixian.cn/news\_show\_301650.aspx

SpringBoot 下PDF生成使用填坑总结

https://blog.csdn.net/kea\_iv/article/details/103734279

SpringBoot 下PDF生成使用填坑总结

SpringBoot 下PDF生成使用填坑总结

上述方案中引入字体库公司不支持,原因:对运维同学不友好。

第二种通过映射关系解决中文不显示的尝试过,没有作用。

这也不行,那也不行,那到底怎么办。

最后延用解决生成pdf的思路,解决字体问题,结果没想到成了。代码如下:

public static List<byte[]> pdf2Png(InputStream inputStream) {

使用上述代码,不用引入字体文件,完全可以解决中文显示的问题,但是后来在测试同学的细致测试下发现,如果将生成pdfpdf文件转图片连起来还是会有中文显示乱码的问题

复现方式:生成pdf文件后下载,然后上传(上传的时候,pdf转图片存储),预览图片,发现图片中的中文显示乱码。

虽然中文显示乱码但是完全可以满足用户的需求,但是本着细致负责的态度,仍着力去解决这个问题:终于问题解决了

解决方案:引入外部字体文件(好像是又回到了引入字体文件的那种解决方式,但是两者有区别,一个是解决,一个是更好的优化提升用户体验)

找到组内其他用windows的研发同学,拷贝“SIMSUN.TTC”字体文件到linux服务器,安装。千万要注意:一定要刷新缓存,因为这个问题搞了好久,虽然运维同学刷新过字体库,但是一次不生效,切记,尽量刷新多次。

到此,中文不显示的问题完美解决。

本文分享自微信公众号 - 川聊架构(gh_44ec4115d261)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Easter79 Easter79
2年前
swap空间的增减方法
(1)增大swap空间去激活swap交换区:swapoff v /dev/vg00/lvswap扩展交换lv:lvextend L 10G /dev/vg00/lvswap重新生成swap交换区:mkswap /dev/vg00/lvswap激活新生成的交换区:swapon v /dev/vg00/lvswap
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Wesley13 Wesley13
2年前
Java iText+FreeMarker生成PDF(HTML转PDF)
1.背景在某些业务场景中,需要提供相关的电子凭证,比如网银/支付宝中转账的电子回单,签约的电子合同等。方便用户查看,下载,打印。目前常用的解决方案是,把相关数据信息,生成对应的pdf文件返回给用户。!(https://static.oschina.net/uploads/space/2017/0507/202942_6jpZ_14059
Wesley13 Wesley13
2年前
P2P技术揭秘.P2P网络技术原理与典型系统开发
Modular.Java(2009.06)\.Craig.Walls.文字版.pdf:http://www.t00y.com/file/59501950(https://www.oschina.net/action/GoToLink?urlhttp%3A%2F%2Fwww.t00y.com%2Ffile%2F59501950)\More.E
Easter79 Easter79
2年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
2年前
Java_iText_PDF—生成PDF工具
Maven:<!iText(用于生成PDF)<dependency<groupIdcom.itextpdf</groupId<artifactIditextpdf</artifactId<versio
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这