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

SpringBoot集成:5分钟实现HTML转PDF功能

01 引言

你是否因为HtmlPDF发愁?又是否因为中文乱码而心烦意乱?又是否因为格式导致PDF排版错乱而苦恼?…

在企业里,我们经常会遇到下载PDF报告的场景,前端展示还好,可以使用pdf.js类似的框架处理,但是很多时候,需要服务端自己渲染数据然后,上传或者邮件发送。好好的页面,转成PDF直接错乱了,只能一点点的调试,才能完成。过程费时费力。

这不,前两天正好遇到HtmlPDF的需求,调整了许久的样式才完成PDF的完美转化。

02 框架选型

Html转化成PDF的框架有很多,小编也试了好几种,将觉得好用的分享给大家。

2.1 io.woo.htmltopdf

Maven

<dependency><groupId>io.woo</groupId><artifactId>htmltopdf</artifactId><version>1.0.4</version>
</dependency>
<!-- Thanks for using https://jar-download.com -->

官网地址:https://jar-download.com

GitHub地址:https://github.com/wooio/htmltopdf-java

2.2 openhtmltopdf

Maven

<dependency><groupId>com.openhtmltopdf</groupId><artifactId>openhtmltopdf-core</artifactId><version>1.0.10</version>
</dependency>
<dependency><groupId>com.openhtmltopdf</groupId><artifactId>openhtmltopdf-pdfbox</artifactId><version>1.0.10</version>
</dependency>

GitHub地址:https://github.com/danfickle/openhtmltopdf

2.3 Flying Saucer

Maven

<dependency><groupId>org.xhtmlrenderer</groupId><artifactId>flying-saucer-pdf</artifactId><version>10.0.0</version>
</dependency>

GitHub地址:https://github.com/flyingsaucerproject/flyingsaucer

03 Springboot集成thymeleaf

3.1 Maven依赖

这里暂时忽略HtmlPDF的依赖,后面按需引入。

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 模板引擎 -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency><!-- html 2 pdf 工具 -->

3.2 页面

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8" /><title>评估报告</title>
</head>
<body>
<div class="total-container"><div class="container" th:each="item:${list}"><input type="hidden" th:value="${item.licenseCode}" name="licenseCode" /><div class="img-container"><img th:src="${item.image1}" /><img th:src="${item.image2}" /></div><div class="title" th:text="${item.vehicleName}"></div><div><ul><li><label>品牌:</label><span th:text="${item.brandName}"></span></li><li><label>车系:</label><span th:text="${item.seriesName}"></span></li><li><label>年款:</label><span th:text="${item.modelYear}"></span></li><li><label>上牌年月:</label><span th:text="${item.licenseYear}"></span></li><li><label>里程(公里):</label><span th:text="${item.displayMileage}"></span></li><li><label>成交日期:</label><span th:text="${item.dealDate}"></span></li><li style="border-bottom: none;"><label>成交价(元):</label><span th:text="${item.dealPrice}"></span></li></ul></div></div>
</div>
</body>
</html>

这里描述了车辆的信息

3.3 数据渲染

@RequestMapping("index")
public String index(Model model) {List<Map<String, Object>> list = new ArrayList<>();for (int i = 0; i < 3; i++) {Map<String, Object> item = new HashMap<>();item.put("image1", "http://img.example.com/a.jpg");item.put("image2", "http://img.example.com/b.jp");item.put("vehicleName", "路虎Defender[卫士](进口)2023款Defender130 48V[卫士 130 48V] 3.0T手自-体P400 HSE");item.put("brandName", "路虎");item.put("seriesName", "Defender[卫士]");item.put("modelYear", "2023款");item.put("licenseYear", SDF.format(new Date()));item.put("displayMileage", DF.format(new BigDecimal("9657")));item.put("dealDate", SDF.format(new Date()));item.put("dealPrice", DF.format(new BigDecimal("1000000")));list.add(item);}model.addAttribute("list", list);return "index";
}

3.4 渲染效果

左右没有留白。

04 Html转PDF

上面已经完成Html的渲染和展示。我们只需要拿到Html并通过工具,转化成PDF即可。

HtmlPDF不需要通过浏览器渲染,需要服务端直接渲染并拿到渲染之后的Html。渲染的代码块:

Map<String, Object> map = new HashMap<>();
map.put("list", list);Context context = new Context(Locale.getDefault(), map);
String html = templateEngine.process("index", context);
System.out.println(html);

4.1 io.woo.htmltopdf

核心方法:

InputStream convert = HtmlToPdf.create().object(HtmlToPdfObject.forHtml(htmlContent).defaultEncoding("utf-8")).convert();IOUtils.copyLarge(convert, response.getOutputStream());

效果

我们会发现转成PDF之后,左右会自动留白。现在的问题是,图片需要调整一下,调整到左右留白差不多,这个是难点。

应该怎么去调整呢?

因为生成的PDF默认都是基于A4的尺寸:21cm*29.7cm。所以我们直接将宽度设置为21cm

.container{width: 21cm;/*设置边框方便查看*/box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
}

转成PDF之后右边距还是有较大的空隙的:

我们继续加大宽度,最终结果:宽度设置23cm比较合适。此时,就可在页面上愉快的调整图片或者其他与元素了。

4.2 openhtmltopdf

核心方法

PdfRendererBuilder builder = new PdfRendererBuilder();
builder.withHtmlContent(htmlContent, null);
builder.toStream(response.getOutputStream());// 配置字体支持中文
builder.useFont(new File("C:\\Windows\\Fonts\\simhei.ttf"), "SimHei");builder.run();

注意事项

  • 需要设置支持中的字体,且页面的font-family需要明确指出

    font-family: "SimHei";
    
  • 页面元素必须要有闭合标签,否则报错

调整

调整依然是难点。经过测试,该框架的的PDFA4纸的大小基本一致。而内容则是去除留白的长度。

经过测量:PDF长度794px,两边留白56px,所以页面长度:794-56-56 = 682px

调正页面长度:

.container{font-family: "SimHei";width: 682px;box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
}

效果非常完美:

4.3 Flying Saucer

核心方法

ITextRenderer renderer = new ITextRenderer();
renderer.getFontResolver().addFont("C:\\Windows\\Fonts\\simh	ei.ttf", BaseFont.IDENTITY_H,BaseFont.NOT_EMBEDDED);
renderer.setDocumentFromString(htmlContent);
renderer.layout();
renderer.createPDF(response.getOutputStream());

这里同样要设置支持中文,和openhtmltopdf配置类似。

调整方式同4.2openhtmltopdf本身就是基于Flying Saucer,所以这里就不在演示,两个同宗同源。

05 小结

每一款软件都是其特定标准,调整的顺序也不一样。无论如何,解决问题的思路是一致的。相比较io.woo.htmltopdf可能更加方便,本身就支持中文,而其他两个则需要单独配置才能支持中文。你们更喜欢哪一种呢?

http://www.dtcms.com/a/471556.html

相关文章:

  • 深圳外贸网站推广公司学做网站书籍
  • 做直播网站视频教程大连网络运营
  • 凤岗做网站国家工商网查询企业信息
  • 个人项目开发(1):使用Spring Secruity实现用户登录
  • 建一个网站大约花多少钱网站建设的整个过程
  • SNMP Trap(告警上报)在 v1 与 v2 版本中节点(OID)或事件描述不一致的问题解决
  • 机器视觉的光纤检测应用
  • 东莞建外贸网站好济南定制网站建设
  • 【agent】AI 数字人构建7:Open-LLM-VTuber使用pycharm配置uv解释器及本地sherpa-onnx实现 tts
  • 网站设计的优点js网页特效
  • wordpress动静分离七牛徐州seo公司
  • 网站推广平台搭建软件设计开发
  • 唐山软件开发公司排名惠州搜索引擎优化
  • 河北通信网站建设google seo怎么优化
  • 推广网站的图片怎么做宁波知名seo关键词优化
  • 网站建设预算计算方法2022网页游戏排行榜前十名
  • 网站开发需要哪些知识和工具wordpress官方主题论坛
  • 湘潭企业网站建设做类似知乎网站
  • 宇宙中的“未知之门“:多维时空理论中的神秘通道
  • 系统难还是网站设计难做仙居手机网站开发
  • 算法精讲:广度优先搜索(BFS)——从原理到实战的完整指南
  • 做网站需要icp吗网站建设dede模板免费
  • 好用的土木建筑网站汕头高端网站建设
  • MySQL数据库面试高频问题及解析
  • 怎么用自己的电脑做网站服务器爱企业工商信息查询系统
  • 无锡游戏网站建设公司作文生成器网站
  • .概述网站建设的基本流程哪个网站可以做鸟瞰图
  • 做网站要学云南免费网站建设
  • 杨浦专业做网站互联网服务平台待备案机动车
  • 购物网站设计模版自定义手机网站建设