pdf在线预览_SpringBoot + FreeMarker + FlyingSaucer 实现PDF在线预览、打印、下载

关键技术点:

1. Freemarker模板引擎
模板语法
2. FlyingSaucer根据模板生成pdf
兼容中文(及中文换行问题)
兼容CSS(绝对、相对定位)
兼容图片
多页输出
(示例代码没有dao、service层,生产环境中自行添加,本示例完整,不坑人)

实现步骤

SpringBoot项目搭建

项目结构截图

f1374990b34163d25dbd37559586ba65.png

Maven依赖配置

768adf4d080ea7bf690c387d28efee79.png

PDF工具类编写

PdfUtils.java,方法上有完整注释,思路是利用模板引擎动态处理模板参数,先生成html字符串放在StringWriter中,再用HTML字符串生成Document,再利用FlyingSaucer的ITextRenderer处理Document,最后输出pdf。

0358ca201e6f788743da5678851c82ec.png

dbfd57f080ee169295b9266f2a001133.png

25bd4ee4b883b68b56e283c992550f15.png

d715d7db7ad0ece399235bd619d888dc.png

中文字符坑点:

 填坑:

generateAll方法中

d2d489fbd8c4431dcea144fda4783226.png

①需要拷贝宋体字体文件到resource目录下(字体位置在“c:/Windows/Fonts/simsun.ttc”),方便集成和迁移

e8035176a80362d4c18e1a3937442e2c.png

②在页面中设置body的样式,必须写成英文,同时大小写敏感,

b459b443205e2ba87350c3051f3555f9.png

6e6fb43257293efbb64f89c89750d317.png

另外:也有不少文章直接根据操作系统类型取宋体字体文件路径的全路径,如下,显得代码臃肿:

497098602d8d8feee37b22fb23da7bb4.png

注意: generateAll方法中已经实现了一个模板接收多个参数对象,输出多页到一个pdf文件中,读者可根据自己需要改造

FreeMarker模板编写

跟编写普通html页面一样,定义2个页面,一个主页面index.ftl,一个pdf模板页面pdfPage.ftl

 文件结构:

fe385f65c68a9b15c66a82fd6994f345.png

index.ftl,很简单,一个标题,两个按钮,一个预览功能,一个下载功能,同时预接收一个${title}参数

注:freemarker的语法和原理,读者自行科普

d7446d692be207a7aac177e25ff9ba1a.png

pdfPage.ftl 

757a6f968796e65b689812e93dfc82b4.png

2628cf4c6e3add47884bd74a29ae14e9.png

坑点(用户经常有页面尺寸需求,比如纸张类型): 1. 页面尺寸(A3,A4)设置和脚标设置页面尺寸填坑: 在节点中加入CSS3页面page属性,以毫米为单位设置size,即最终输出pdf每页的大小A3: 297mm * 420mm (纵向)A4: 210mm * 297mm (纵向)A3: 420mm * 297mm (横向)A4: 297mm * 210mm (横向)这些都可以写成${XXX}占位符形式,通过后端代码传入脚标填坑: 见下图

b26cb3983fd95db2cd70a6087ddc2bd3.png

2. CSS路径和图片路径填坑css路径:  引用css文件必须用http://全路径,如上图,可以把css文件单独放到一台服务器上,通过域名或者ip+端口访问.填坑图片路径:  css中引用的图片一样要使用http://全路径,如下图:

17f7a343b0ca3be0b52c59237e81a1e7.png

Controller代码编写

写两个Controller,PublicController.java 和 PdfController.java
PublicController.java用来访问主页面, PdfController.java用来接受预览和下载请求
PublicController.java

b320a834ad3172399e5218d7ecb88cb3.png

PdfController.java

20ef2b5fd6ad59f4f0ea5441ceac1a3a.png

0f957f26fde0354ed2fd663823d261cf.png

配置application.yml

0b447cb646361fb5a0e347890399f10e.png

运行演示

运行项目,访问http://localhost:8999/

c9bc6afc63e416562e7f0d54a746ca63.png

点击预览效果如下(有个小坑,就是input控件中的汉字有问题,反正我实际生产中pdf模板不用input控件),其实这个页面已集成了下载和打印功能,这是Chrome自带的pdf预览。

90d69bfc827667f0266b97a4ddd76c74.png

再点击下载,效果如下:

37ddfa7bab7a1bfdc8c7a370f935ea74.png

显示已下载,从pdf软件打开该pdf文件效果如下:

0e278dca8e0093813e87881dd7d1d044.png

大功告成!

坑点总结

1. 中文字体
2. Css路径
3. 图片路径
4. 页面尺寸(纸张大小)

建议

该示例只是为了演示如何利用freemarker模板引擎生成pdf预览、下载,其中数据都为静态数据,在实际项目中调整数据来源可完美达到预期效果,目前支持比较好的是Chrome内核浏览器,为达到更好的浏览器支持,可以用PDF.js来完成兼容。

PdfUtils.java只是对模板操作做了简单封装,可以根据自己的需要进行二次封装,generateAll方法中已经实现了一个模板接收多个参数对象,输出多页到一个pdf文件中,读者可根据自己需要改造(比如把多个不同的模板输出到一个pdf文件中)。

03c119e110c095b7eca5e28d575273c1.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值