SpringBoot将html页面转化为pdf文件
废话不多说,先看效果图。
本示例重要功能点: 访问 url 直接下载 pdf 文件,前后端分离的项目可能通过这种方式下载 pdf 文件; 将 html 页面(含中文、图片)转换成 pdf 文件
技术栈: Flying Saucer thymeleaf 1、创建 Spring Boot 项目
进入 http://start.spring.io 创建 Spring Boot 项目,Spring Boot 版本为 2.7.0,选择如下依赖: Starter:spring-boot-starter-web spring-boot-starter-thymeleaf lombok 2、修改 pom.xml 文件,添加将 html 页面转换成 pdf 文件需要的依赖: org.xhtmlrenderer flying-saucer-pdf 9.1.22 commons-io commons-io 2.11.0 ognl ognl 3.1.29 com.github.jtidy jtidy 1.0.2 3、创建演示数据需要的实体类 —— Student.javaimport lombok.Builder; import lombok.Data; @Data @Builder public class Student { private Integer id; private String name; private String gender; private Integer age; }4、创建具体的业务处理类 —— PdfService.javaimport com.lowagie.text.DocumentException; import com.lowagie.text.pdf.BaseFont; import com.wangc.downloadpdf.entity.Student; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.thymeleaf.TemplateEngine; import org.thymeleaf.context.Context; import org.w3c.tidy.Tidy; import org.xhtmlrenderer.pdf.ITextRenderer; import javax.annotation.Resource; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.UnsupportedEncodingException; import java.nio.charset.StandardCharsets; import java.util.List; @Slf4j @Service public class PdfService { @Resource private TemplateEngine templateEngine; public ByteArrayInputStream exportPdf(String template, List students) throws Exception { Context context = new Context(); context.setVariable("students", students); String content = convertToXhtml(templateEngine.process(template, context)); ByteArrayInputStream byteArrayInputStream = null; try { ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); ITextRenderer renderer = new ITextRenderer(); renderer.getFontResolver().addFont("c:/Windows/Fonts/simsun.ttc", BaseFont.IDENTITY_H, BaseFont.EMBEDDED); renderer.setDocumentFromString(content); renderer.layout(); renderer.createPDF(byteArrayOutputStream, false); renderer.finishPDF(); byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray()); } catch (DocumentException e) { log.error(e.getMessage(), e); } return byteArrayInputStream; } private String convertToXhtml(String htmlContent) throws UnsupportedEncodingException { Tidy tidy = new Tidy(); tidy.setInputEncoding("UTF-8"); tidy.setOutputEncoding("UTF-8"); tidy.setXHTML(true); ByteArrayInputStream inputStream = new ByteArrayInputStream(htmlContent.getBytes(StandardCharsets.UTF_8)); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); tidy.parseDOM(inputStream, outputStream); return outputStream.toString("UTF-8"); } }5、创建控制器 —— PdfController.javaimport com.wangc.downloadpdf.entity.Student; import com.wangc.downloadpdf.service.PdfService; import org.apache.commons.io.IOUtils; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.servlet.ModelAndView; import javax.annotation.Resource; import javax.servlet.http.HttpServletResponse; import java.io.ByteArrayInputStream; import java.util.List; import java.util.stream.Collectors; import java.util.stream.IntStream; @Controller public class PdfController { @Resource private PdfService pdfService; @GetMapping("/downloadPdf") public void downloadPdf(HttpServletResponse response) throws Exception { List students = createTestData(); ByteArrayInputStream byteArrayInputStream = pdfService.exportPdf("students", students); response.setContentType("application/octet-stream"); response.setHeader("Content-Disposition", "attachment; filename=receipt.pdf"); IOUtils.copy(byteArrayInputStream, response.getOutputStream()); } // 效果预览 @GetMapping("/view") public ModelAndView view() throws Exception { List students = createTestData(); ModelAndView mv = new ModelAndView(); mv.setViewName("students"); mv.addObject("students", students); return mv; } // 测试数据 private List createTestData() { final List students = IntStream.range(1, 10) .mapToObj(v -> Student.builder() .id(v) .name("学生" + v) .age(16) .gender(v % 2 == 0 ? "男" : "女") .build()) .collect(Collectors.toList()); return students; } }6、创建 html 模板 —— students.html Students View 7、启动项目
访问 http://localhost:9090/view 查看 html 页面效果。访问 http://localhost:9090/downloadPdf 下载 pdf 文件。