1.最近项目中使用到了这个功能,所以就来记录一下,并且记录下使用过程中遇到的坑
2.首先需要引入依赖
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.23</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.10</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
<dependency>
<groupId>com.itextpdf.tool</groupId>
<artifactId>xmlworker</artifactId>
<version>5.5.11</version>
</dependency>
<dependency>
<groupId>org.xhtmlrenderer</groupId>
<artifactId>flying-saucer-pdf-itext5</artifactId>
<version>9.0.6</version>
</dependency>
3.我这里是自己简单搭了一个springboot的项目来进行示例讲解,所以首先是controller层的代码:
package com.example.demo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping("/download")
public class download {
@Autowired
private PdfTemplateRenderImpl pdfTemplateRender;
@RequestMapping("/d1")
public ResponseEntity<byte[]> downloadTemplatex() throws Exception {
HttpHeaders headers = new HttpHeaders();
String filename = new String("ssk.pdf".getBytes("utf-8"), "iso-8859-1");
headers.setContentDispositionFormData("attachment", filename);
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
//xxxxService.queryXXXById(); 查询数据填充到html模板中,使用map存放
Map<String,Object> dataMap=new HashMap<>();
dataMap.put("name","张三丰");
dataMap.put("age","18岁");
dataMap.put("address","浙江省杭州市滨江区");
dataMap.put("study","本科");
dataMap.put("marry","未婚");
byte[] bytes= pdfTemplateRender.render(dataMap,"person.html");
ResponseEntity<byte[]> responseEntity = new ResponseEntity<>(bytes, headers, HttpStatus.CREATED);
return responseEntity;
}
}
4.然后是pdfTemplate
package com.example.demo;
import javax.annotation.PostConstruct;
import java.io.IOException;
import java.util.Map;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import org.springframework.stereotype.Service;
@Service
public class PdfTemplateRenderImpl {
private Configuration configuration;
@PostConstruct
private void init() throws IOException {
configuration = new Configuration(Configuration.VERSION_2_3_23);
//download是存放html文件的目录,对该目录下的html文件进行加载
configuration.setClassLoaderForTemplateLoading(this.getClass().getClassLoader(), "/download");
configuration.setDefaultEncoding("UTF-8");
}
public byte[] render(Map<String, Object> data, String templateFileName) throws Exception {
String htmlContent = freeMarkerVar(data, templateFileName);
return PdfUtil.htmlToPdf(htmlContent);
}
private String freeMarkerVar(Map<String, Object> data, String templateFileName) throws Exception {
try {
Template template = configuration.getTemplate(templateFileName);
Writer writer = new StringWriter();
template.process(data, writer);
return writer.toString();
} catch (IOException | TemplateException e) {
throw new Exception("系统异常", e);
}
}
}
5.然后是PdfUtil相关代码
/**
* Alipay.com Inc.
* Copyright (c) 2004-2021 All Rights Reserved.
*/
package com.example.demo;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import com.itextpdf.text.pdf.BaseFont;
import org.xhtmlrenderer.pdf.ITextFontResolver;
import org.xhtmlrenderer.pdf.ITextRenderer;
/**
* @author hanansheng
* @version $Id: PdfUtil.java, v 0.1 2021年03月03日 下午4:56 hanansheng Exp $
*/
public class PdfUtil {
/**
* 将html 转化为 pdf
*
* @param htmlContent html utf-8编码
* @return pdf文件字节流
*/
public static byte[] htmlToPdf(String htmlContent) throws Exception {
try {
ITextRenderer renderer = new ITextRenderer();
//解决中文不显示问题
ITextFontResolver fontResolver = renderer.getFontResolver();
fontResolver.addFont(PdfUtil.class.getClass().getResource("/test1/simhei.ttf").getPath(), BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
renderer.setDocumentFromString(htmlContent);
renderer.layout();
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
renderer.createPDF(outputStream);
return outputStream.toByteArray();
} catch (FileNotFoundException e) {
throw new Exception("系统异常", e);
} catch (Exception e) {
throw new Exception("系统异常", e);
}
}
}
6.然后是我的html文件;注意这里html文件是解析为freemarker然后进行解析的
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>个人情况</title>
<style>
body {
font-family: SimHei;
}
.main{
width: 960px;margin: 0 auto;
color: rgba(0,0,0,0.85);
position: relative;
padding-top: 16px;
padding-bottom: 25px;
}
.title {
line-height: 40px;font-size: 28px;font-weight: bold;text-align: center;position: relative;
}
.table{
width: 100%;
border: 1px solid #696969;
border-collapse: collapse;
font-size: 12px;
}
.table td {
height: 32px;
border: 1px solid #ccc;
text-align: center;
}
.table td:last-child{ width: 750px; text-align: left;padding-left: 16px; box-sizing: border-box;}
</style>
</head>
<body>
<div class="main">
<h1 class="title">
<img src="https://xxxxxxxxx" style="width: 218px;height:30px;position: absolute;left:0;top: 0"/> 心系天下</h1>
<table class="table">
<tr style="border-bottom: 1px solid #696969">
<td rowspan="6" style="max-width: 40px; background-color: #e0e0e0;color: #000">个<br/>人<br/>情<br/>况</td><td>姓名</td><td>${name!"/"}</td>
</tr>
<tr>
<td>年龄</td> <td>${age!"/"}</td>
</tr>
<tr>
<td>家庭住址</td><td>${address!"/"}</td>
</tr>
<tr>
<td>学历</td><td>${study!"/"}</td>
</tr>
<tr>
<td>婚姻情况</td><td>${marry!"/"}</td>
</tr>
</table>
<image src="https:xxxxxxxxxxxxxxxxxxx"
style="width: 75px;position: absolute;bottom: 0; right: -20px"/>
</div>
</body>
</html>
7.然后导出来的pdf如下图所示:

容易出现的一些坑:
1.中文不显示问题,这个问题在pdfUtil类中我已经解决了,需要在html页面中设置字体,然后pdfUtil加载一个字体集xx.ttf文件
2.图片加载不出来问题,图片路径尽量使用http:xxxx连接,另外要使用img标签,不要使用image标签
3.在html中尽量不要使用css3的语法,否则下载出来的pdf可能对css3的样式会失效
4.html页面取值的时候,如果后台传过来是空,那么直接会报错,可以在页面进行一个控制,如果为空就显示斜杠/ ,如下图所示:

5.生成的pdf有白色边框的问题,有问题的形式如下:

这样有白色边框是有问题的,解决方法就是在html(ftl)文件中添加样式
@page:left{
margin: 0cm;
}
@page:right{
margin: 0cm;
}
添加后完美解决边框问题,修改后展示如下:完美解决

演示的demo已经打包上传,需要的可以自行下载,地址:XItextRender将html文件转为pdf下载deno(解决中文不显示和图片等问题)javademo-Java文档类资源-CSDN下载
本文记录了使用Java的ITextRenderer库将HTML转换为PDF的过程,包括在SpringBoot项目中实现该功能的步骤。内容涉及控制器、PDF模板、PDFUtil工具类的编写,以及HTML文件的注意事项。在实践中遇到的坑包括中文不显示、图片加载失败、CSS3样式失效、空值报错和PDF边框问题,并提供了相应的解决方案。文章最后分享了包含完整示例的代码下载链接。
将html转为pdf下载及遇到的一些坑&spm=1001.2101.3001.5002&articleId=121451301&d=1&t=3&u=35d31219d07d4bdaa62745dc748b3f8d)
1816

被折叠的 条评论
为什么被折叠?



