前言

最近项目要实现java导出PDF,要导出的文件都有自己的模板样式。所以我们的思路是:先整出html模板,然后将数据填充进去,生成最终的html 文件流,拿到之后,转为PDF文件导出。

因为考虑的Itext是要收费的,所以我们使用了openhtmltopdf,它是基于LGPL 协议的。可以用在商业项目中。

openhtmltopdf

  1. Git 地址

点我

  1. 快速开始

点我

一个例子

我这个例子是 我已经将HTML对象转换为String字符串了,我是将字符串转换为PDF导出的。

  1. maven依赖 ```xml 1.0.8
com.openhtmltopdf openhtmltopdf-core ${openhtml.version}
  1. <dependency>
  2. <!-- Required for PDF output. -->
  3. <groupId>com.openhtmltopdf</groupId>
  4. <artifactId>openhtmltopdf-pdfbox</artifactId>
  5. <version>${openhtml.version}</version>
  6. </dependency>
  7. <dependency>
  8. <!-- Required for image output only. -->
  9. <groupId>com.openhtmltopdf</groupId>
  10. <artifactId>openhtmltopdf-java2d</artifactId>
  11. <version>${openhtml.version}</version>
  12. </dependency>
  13. <dependency>
  14. <!-- Optional, leave out if you do not need right-to-left or bi-directional text support. -->
  15. <groupId>com.openhtmltopdf</groupId>
  16. <artifactId>openhtmltopdf-rtl-support</artifactId>
  17. <version>${openhtml.version}</version>
  18. </dependency>
  19. <dependency>
  20. <!-- Optional, leave out if you do not need logging via slf4j. -->
  21. <groupId>com.openhtmltopdf</groupId>
  22. <artifactId>openhtmltopdf-slf4j</artifactId>
  23. <version>${openhtml.version}</version>
  24. </dependency>
  25. <dependency>
  26. <!-- Optional, leave out if you do not need SVG support. -->
  27. <groupId>com.openhtmltopdf</groupId>
  28. <artifactId>openhtmltopdf-svg-support</artifactId>
  29. <version>${openhtml.version}</version>
  30. </dependency>
  1. 2. code
  2. ```java
  3. package com.example.demo.controller;
  4. import org.springframework.core.io.ResourceLoader;
  5. import cn.hutool.core.util.ReUtil;
  6. import com.openhtmltopdf.pdfboxout.PdfRendererBuilder;
  7. import org.springframework.beans.factory.annotation.Autowired;
  8. import org.springframework.web.bind.annotation.GetMapping;
  9. import org.springframework.web.bind.annotation.RestController;
  10. import java.io.File;
  11. import java.io.FileOutputStream;
  12. import java.io.IOException;
  13. @RestController
  14. public class TestPDF {
  15. @Autowired
  16. ResourceLoader resourceLoader;
  17. @GetMapping("/123")
  18. public void createPDF() throws IOException {
  19. create();
  20. }
  21. private void create() throws IOException {
  22. String html = "";
  23. // 因为html中有特殊字符&nbsp;,我的做法是将其去除
  24. String newHTML = ReUtil.replaceAll(html, "&nbsp;", "");
  25. //导出PDF存放的位置,也可以是一个流
  26. FileOutputStream os = new FileOutputStream("E:\\desktop\\11.pdf");
  27. PdfRendererBuilder builder = new PdfRendererBuilder();
  28. builder.useFastMode();
  29. builder.testMode(true);
  30. //填充html字符串
  31. builder.withHtmlContent(newHTML,"");
  32. builder.toStream(os);
  33. //设置字体,这个字体需要跟你html 中的字体要一致的
  34. builder.useFont(new File("/simsun.ttc"),"SimSun");
  35. builder.run();
  36. }
  37. }
  1. 测试结果

会在桌面给你生成一个PDF文件,速度还挺快的

  1. 输出横版PDF
    1. # 需要在你的html文件中设置
    2. @page {
    3. size: A4 landscape;
    4. }

单元格数据自动换行

需要在css中设置

  1. table td{
  2. overflow-wrap: break-word;
  3. word-wrap:break-word;
  4. }

如果你还需要换行后,所有一行的单元格向上对齐,还需要加上下面的属性:

  1. style="vertical-align: top;"

导出PDF支持中文,或者中文繁体

  1. 首先需要在引入字体库

    1. private static void addFont(PdfRendererBuilder builder) throws IOException {
    2. InputStream streamForSimsun = HTMLUtils.class.getClassLoader().getResourceAsStream("template/simsun.ttc");
    3. File targetFileForSimsun = new File("simsun.ttc");
    4. FileUtils.copyInputStreamToFile(streamForSimsun, targetFileForSimsun);
    5. builder.useFont(targetFileForSimsun, "simsun");
    6. streamForSimsun.close();
    7. }
  2. 在HTML中,设置字体

    1. style="font-family: arial, simsun"

官网给的参考:https://github.com/danfickle/openhtmltopdf/issues/129