- Java使用Itext5与html模板生成pdf
- 前言
- 一、引入依赖
- 二、相关使用说明
- 1.工具类
- 2.模板配置
- 3.模板的抽象类(定义了相关方法)
- 4.模板实体类,用于封装数据供html使用
- 5.html模板
- 6.导出接口
- 效果
- 总结
前言
本文内容是通过使用Itext5+html模板生成pdf文件,模板文件支持自定义。一、引入依赖
二、相关使用说明 1.工具类com.itextpdf itextpdf 5.5.13.2 com.itextpdf itext-asian 5.2.0 com.itextpdf.tool xmlworker 5.5.13.2 org.xhtmlrenderer flying-saucer-pdf-itext5 9.1.22 org.springframework.boot spring-boot-starter-thymeleaf ognl ognl 3.1.15
package com.example.demo.utils;
import com.itextpdf.text.pdf.BaseFont;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.xhtmlrenderer.pdf.ITextFontResolver;
import org.xhtmlrenderer.pdf.ITextRenderer;
import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.time.LocalDateTime;
@Slf4j
public class HtmlUtil {
private HtmlUtil() {
}
// 字体路径,放在资源目录下
private static final String FONT_PATH = "/etc/ftcloud/public/font/simsun.ttc";
public static void htmlToPdf(String html, HttpServletResponse response, String fileName) {
try {
//如果没换名称就以当前时间当做文件名
String name = StringUtils.isBlank(fileName) ? LocalDateTime.now() + ".pdf" : fileName;
OutputStream out = response.getOutputStream();
response.setCharacterEncoding("utf-8");
response.setHeader("content-type", "application/octet-stream");
fileName = URLEncoder.encode(name, "UTF-8");
response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
ITextRenderer renderer = new ITextRenderer();
renderer.setDocumentFromString(html);
// 解决中文支持
ITextFontResolver fontResolver = renderer.getFontResolver();
fontResolver.addFont(FONT_PATH, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
renderer.layout();
renderer.createPDF(out);
out.flush();
out.close();
} catch (Exception e) {
log.error("-------HTML转pdf失败--------:{}", e);
}
}
}
2.模板配置
package com.example.demo.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver;
@Configuration
public class TemplateEngineConfig {
// 注入TemplateEngine模版引擎
@Bean
public TemplateEngine templateEngine(){
ClassLoaderTemplateResolver resolver = new ClassLoaderTemplateResolver();
// 设置模版前缀,相当于需要在资源文件夹中创建一个html2pdfTemplate文件夹,所有的模版都放在这个文件夹中
resolver.setPrefix("/pdfTemplate/");
// 设置模版后缀
resolver.setSuffix(".html");
resolver.setCharacterEncoding("UTF-8");
// 设置模版模型为HTML
resolver.setTemplateMode("HTML");
TemplateEngine engine = new TemplateEngine();
engine.setTemplateResolver(resolver);
return engine;
}
}
3.模板的抽象类(定义了相关方法)
package com.example.demo.template;
import com.example.demo.utils.HtmlUtil;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;
public abstract class AbstractTemplate {
// 使用thymeleaf模版引擎
private TemplateEngine engine;
// 模版名称
private String templateName;
private AbstractTemplate() {
}
public AbstractTemplate(TemplateEngine engine, String templateName) {
this.engine = engine;
this.templateName = templateName;
}
protected String templateName() {
return this.templateName;
}
private Map variables() {
Map variables = new HashMap<>();
// 对应html模版中的template变量,取值的时候就按照“${template.字段名}”格式,可自行修改
variables.put("template", this);
return variables;
}
public String process() {
Context ctx = new Context();
// 设置model
ctx.setVariables(variables());
// 根据model解析成html字符串
return engine.process(templateName(), ctx);
}
public void parse2Pdf(HttpServletResponse response, String fileName) {
String html = process();
// 通过html转换成pdf
HtmlUtil.htmlToPdf(html, response, fileName);
}
}
4.模板实体类,用于封装数据供html使用
package com.example.demo.vo;
import com.example.demo.template.AbstractTemplate;
import lombok.Data;
import org.thymeleaf.TemplateEngine;
import java.util.List;
@Data
public class Model extends AbstractTemplate {
public Model(TemplateEngine engine, String templateName) {
super(engine, templateName);
}
private String name;
private List personList;
}
5.html模板
报告模版
报告模版
template.name
姓名
性别
年龄
电话
身份证
创建时间
6.导出接口
@GetMapping("/api/getHtmlPdf")
public void getHtmlPdf(String time, HttpServletResponse response) {
//第二个参数表示要使用的html模板名称(不用加.html后缀)
Model model = new Model(engine, "person");
model.setName("名称");
List personList = personService.list(Wrappers.lambdaQuery(Person.class).le(Person::getId, 100));
model.setPersonList(personList);
//生成pdf,指定目标文件路径
model.parse2Pdf(response, "pdf导出测试.pdf");
}
效果
启动项目,在浏览器中输入导出pdf的url可直接进行下载:
导出的效果如下图所示:
使用时注意需要引文中文字体,否则带有中文的内容无法展示,字体下载链接(访问码:7tt2)。



