1. import com.itextpdf.text.Document;
    2. import com.itextpdf.text.PageSize;
    3. import com.itextpdf.text.pdf.PdfWriter;
    4. import com.itextpdf.tool.xml.XMLWorkerHelper;
    5. import freemarker.template.Configuration;
    6. import freemarker.template.Template;
    7. import javax.servlet.http.HttpServletResponse;
    8. import java.io.*;
    9. import java.net.URLEncoder;
    10. import java.nio.charset.StandardCharsets;
    11. import java.util.Map;
    12. /**
    13. * @author X-MD
    14. * @version 1.0.0
    15. * @Description 根据HTML魔板导出PDF
    16. * @createTime 2022年01月17日 16:47:00
    17. */
    18. public class PdfHtmlUtil {
    19. private static Configuration freemarkerCfg;
    20. static {
    21. //freemarker的模板目录
    22. try {
    23. freemarkerCfg = new Configuration(Configuration.VERSION_2_3_28);
    24. String templatePath = PdfHtmlUtil.class.getResource("/").getPath() + "/templates";
    25. freemarkerCfg.setDirectoryForTemplateLoading(new File(templatePath));
    26. } catch (IOException e) {
    27. e.printStackTrace();
    28. }
    29. }
    30. /**
    31. * 预览PDF
    32. *
    33. * @param response
    34. * @param data 数据
    35. * @param template templates文件下的HTML文件名称(test.html)
    36. */
    37. public static void createHtmlPdfPreview(HttpServletResponse response, String filename, Map<String, Object> data, String template) {
    38. try (
    39. ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    40. ) {
    41. createHtmlPdf(outputStream, data, template);
    42. // inline(默认)当前页面打开;attachment 下载到本地=
    43. response.setContentType("application/pdf");
    44. response.addHeader("Content-Disposition", "inline;filename=" + URLEncoder.encode(filename, "UTF-8") + ".pdf");
    45. OutputStream stream = response.getOutputStream();
    46. outputStream.writeTo(stream);
    47. outputStream.flush();
    48. } catch (Exception e) {
    49. e.printStackTrace();
    50. }
    51. }
    52. /**
    53. * 下载PDF
    54. *
    55. * @param response
    56. * @param data 数据
    57. * @param template templates文件下的HTML文件名称(test.html)
    58. */
    59. public static void createHtmlPdfDownload(HttpServletResponse response, String filename, Map<String, Object> data, String template) {
    60. try (
    61. ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    62. ) {
    63. createHtmlPdf(outputStream, data, template);
    64. response.setContentType("application/x-download");
    65. response.addHeader("Content-Disposition", "inline;filename=" + URLEncoder.encode(filename, "UTF-8") + ".pdf");
    66. OutputStream stream = response.getOutputStream();
    67. outputStream.writeTo(stream);
    68. outputStream.flush();
    69. } catch (Exception e) {
    70. e.printStackTrace();
    71. }
    72. }
    73. private static void createHtmlPdf(ByteArrayOutputStream outputStream, Map<String, Object> data, String template) {
    74. String content = freeMarkerRender(data, template);
    75. Document document = new Document(PageSize.A4);
    76. try (
    77. ByteArrayInputStream stream = new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8))
    78. ) {
    79. PdfWriter pdfWriter = PdfWriter.getInstance(document, outputStream);
    80. document.open();
    81. XMLWorkerHelper xmlWorkerHelper = XMLWorkerHelper.getInstance();
    82. xmlWorkerHelper.parseXHtml(pdfWriter, document, stream, StandardCharsets.UTF_8, new AsianFontProvider());
    83. } catch (Exception e) {
    84. e.printStackTrace();
    85. } finally {
    86. document.close();
    87. }
    88. }
    89. /**
    90. * freemarker渲染html
    91. */
    92. private static <T> String freeMarkerRender(T data, String htmlTmp) {
    93. try (
    94. Writer out = new StringWriter()
    95. ) {
    96. // 获取模板,并设置编码方式
    97. Template template = freemarkerCfg.getTemplate(htmlTmp);
    98. // 合并数据模型与模板,将合并后的数据和模板写入到流中,这里使用的字符流
    99. template.process(data, out);
    100. out.flush();
    101. return out.toString();
    102. } catch (Exception e) {
    103. e.printStackTrace();
    104. }
    105. return null;
    106. }
    107. }