当前位置:   article > 正文

Spring Boot集成itext实现html生成PDF功能

Spring Boot集成itext实现html生成PDF功能

1.itext介绍

iText是著名的开放源码的站点sourceforge一个项目,是用于生成PDF文档的一个java类库。通过iText不仅可以生成PDF或rtf的文档,而且可以将XML、Html文件转化为PDF文件

iText 的特点

以下是 iText 库的显着特点 −

  • Interactive − iText 为你提供类(API)来生成交互式 PDF 文档。使用这些,你可以创建地图和书籍。

  • Adding bookmarks, page numbers, etc − 使用 iText,你可以添加书签、页码和水印

  • Split & Merge − 使用 iText,你可以将现有的 PDF 拆分为多个 PDF,还可以向其中添加/连接其他页面。

  • Fill Forms − 使用 iText,你可以在 PDF 文档中填写交互式表单。

  • Save as Image − 使用 iText,你可以将 PDF 保存为图像文件,例如 PNG 或 JPEG。

  • Canvas − iText 库为您提供了一个 Canvas 类,你可以使用它在 PDF 文档上绘制各种几何形状,如圆形、线条等。

  • Create PDFs − 使用 iText,你可以从 Java 程序创建新的 PDF 文件。你也可以包含图像和字体。

2.代码工程

实验目标:将thymeleaf 的views生成成PDF

pom.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5. <parent>
  6. <artifactId>springboot-demo</artifactId>
  7. <groupId>com.et</groupId>
  8. <version>1.0-SNAPSHOT</version>
  9. </parent>
  10. <modelVersion>4.0.0</modelVersion>
  11. <artifactId>itextpdf</artifactId>
  12. <properties>
  13. <maven.compiler.source>8</maven.compiler.source>
  14. <maven.compiler.target>8</maven.compiler.target>
  15. </properties>
  16. <dependencies>
  17. <dependency>
  18. <groupId>org.springframework.boot</groupId>
  19. <artifactId>spring-boot-starter-web</artifactId>
  20. </dependency>
  21. <dependency>
  22. <groupId>org.springframework.boot</groupId>
  23. <artifactId>spring-boot-autoconfigure</artifactId>
  24. </dependency>
  25. <dependency>
  26. <groupId>org.springframework.boot</groupId>
  27. <artifactId>spring-boot-starter-test</artifactId>
  28. <scope>test</scope>
  29. </dependency>
  30. <dependency>
  31. <groupId>org.springframework.boot</groupId>
  32. <artifactId>spring-boot-starter-thymeleaf</artifactId>
  33. </dependency>
  34. <dependency>
  35. <groupId>com.itextpdf</groupId>
  36. <artifactId>html2pdf</artifactId>
  37. <version>3.0.1</version>
  38. </dependency>
  39. <dependency>
  40. <groupId>com.itextpdf</groupId>
  41. <artifactId>kernel</artifactId>
  42. <version>7.1.12</version>
  43. </dependency>
  44. <dependency>
  45. <groupId>org.projectlombok</groupId>
  46. <artifactId>lombok</artifactId>
  47. </dependency>
  48. </dependencies>
  49. </project>

application.yaml

  1. server:
  2. port: 8088
  3. spring:
  4. thymeleaf:
  5. cache: false

DemoApplication

  1. package com.et.itextpdf;
  2. import org.springframework.boot.SpringApplication;
  3. import org.springframework.boot.autoconfigure.SpringBootApplication;
  4. import org.springframework.boot.web.servlet.ServletComponentScan;
  5. @ServletComponentScan
  6. @SpringBootApplication
  7. public class DemoApplication {
  8. public static void main(String[] args) {
  9. SpringApplication.run(DemoApplication.class, args);
  10. }
  11. }

controller

converterProperties.setBaseUri 很重要。否则,像 /main.css 这样的静态资源将无法找到

  1. package com.et.itextpdf.controller;
  2. import com.et.itextpdf.pojo.Order;
  3. import com.et.itextpdf.util.OrderHelper;
  4. import com.itextpdf.html2pdf.ConverterProperties;
  5. import com.itextpdf.html2pdf.HtmlConverter;
  6. import org.springframework.beans.factory.annotation.Autowired;
  7. import org.springframework.http.HttpHeaders;
  8. import org.springframework.http.MediaType;
  9. import org.springframework.http.ResponseEntity;
  10. import org.springframework.stereotype.Controller;
  11. import org.springframework.ui.Model;
  12. import org.springframework.web.bind.annotation.RequestMapping;
  13. import org.thymeleaf.TemplateEngine;
  14. import org.thymeleaf.context.WebContext;
  15. import javax.servlet.ServletContext;
  16. import javax.servlet.http.HttpServletRequest;
  17. import javax.servlet.http.HttpServletResponse;
  18. import java.io.ByteArrayOutputStream;
  19. import java.io.IOException;
  20. @Controller
  21. @RequestMapping("/orders")
  22. public class PDFController {
  23. @Autowired
  24. ServletContext servletContext;
  25. private final TemplateEngine templateEngine;
  26. public PDFController(TemplateEngine templateEngine) {
  27. this.templateEngine = templateEngine;
  28. }
  29. @RequestMapping(path = "/")
  30. public String getOrderPage(Model model) {
  31. Order order = OrderHelper.getOrder();
  32. model.addAttribute("orderEntry", order);
  33. return "order";
  34. }
  35. @RequestMapping(path = "/pdf")
  36. public ResponseEntity<?> getPDF(HttpServletRequest request, HttpServletResponse response) throws IOException {
  37. /* Do Business Logic*/
  38. Order order = OrderHelper.getOrder();
  39. /* Create HTML using Thymeleaf template Engine */
  40. WebContext context = new WebContext(request, response, servletContext);
  41. context.setVariable("orderEntry", order);
  42. String orderHtml = templateEngine.process("order", context);
  43. /* Setup Source and target I/O streams */
  44. ByteArrayOutputStream target = new ByteArrayOutputStream();
  45. ConverterProperties converterProperties = new ConverterProperties();
  46. converterProperties.setBaseUri("http://localhost:8088");
  47. /* Call convert method */
  48. HtmlConverter.convertToPdf(orderHtml, target, converterProperties);
  49. /* extract output as bytes */
  50. byte[] bytes = target.toByteArray();
  51. /* Send the response as downloadable PDF */
  52. return ResponseEntity.ok()
  53. .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=order.pdf")
  54. .contentType(MediaType.APPLICATION_PDF)
  55. .body(bytes);
  56. }
  57. }

view

Spring MVC 带有模板引擎,可以提供动态的 HTML 内容。我们可以通过以下方法轻松将这些回复转换为 PDF 格式。在本例中,我导入了 spring-boot-starter-web 和 spring-boot-starter-thymeleaf 来为我的 spring boot 项目提供 MVC 和 thymeleaf 支持。您可以使用自己选择的模板引擎。看看下面这个thymeleaf模板内容。主要展示订单详细信息。另外,通过 OrderHelper 的辅助方法来生成一些虚拟订单内容。

  1. <!doctype html>
  2. <html lang="en" xmlns:th="http://www.thymeleaf.org">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"
  6. name="viewport">
  7. <meta content="ie=edge" http-equiv="X-UA-Compatible">
  8. <title>Spring Boot - Thymeleaf</title>
  9. <link th:href="@{/main.css}" rel="stylesheet"/>
  10. </head>
  11. <body class="flex items-center justify-center h-screen">
  12. <div class="rounded-lg border shadow-lg p-10 w-3/5">
  13. <div class="flex flex-row justify-between pb-4">
  14. <div>
  15. <h2 class="text-xl font-bold">Order #<span class="text-green-600" th:text="${orderEntry.orderId}"></span>
  16. </h2>
  17. </div>
  18. <div>
  19. <div class="text-xl font-bold" th:text="${orderEntry.date}"></div>
  20. </div>
  21. </div>
  22. <div class="flex flex-col pb-8">
  23. <div class="pb-2">
  24. <h2 class="text-xl font-bold">Delivery Address</h2>
  25. </div>
  26. <div th:text="${orderEntry.account.address.street}"></div>
  27. <div th:text="${orderEntry.account.address.city}"></div>
  28. <div th:text="${orderEntry.account.address.state}"></div>
  29. <div th:text="${orderEntry.account.address.zipCode}"></div>
  30. </div>
  31. <table class="table-fixed w-full text-right border rounded">
  32. <thead class="bg-gray-100">
  33. <tr>
  34. <th class="text-left pl-4">Product</th>
  35. <th>Qty</th>
  36. <th>Price</th>
  37. <th class="pr-4">Total</th>
  38. </tr>
  39. </thead>
  40. <tbody>
  41. <tr th:each="item : ${orderEntry.items}">
  42. <td class="pl-4 text-left" th:text="${item.name}"></td>
  43. <td th:text="${item.quantity}"></td>
  44. <td th:text="${item.price}"></td>
  45. <td class="pr-4" th:text="${item.price * item.quantity}"></td>
  46. </tr>
  47. </tbody>
  48. </table>
  49. <div class="flex flex-row-reverse p-5">
  50. <h2 class="font-medium bg-gray-200 p-2 rounded">
  51. Grand Total: <span class="text-green-600" th:text="${orderEntry.payment.amount}"></span>
  52. </h2>
  53. </div>
  54. <h2 class="text-xl font-bold">Payment Details</h2>
  55. <table class="table-fixed text-left w-2/6 border">
  56. <tr>
  57. <th class="text-green-600">Card Number</th>
  58. <td th:text="${orderEntry.payment.cardNumber}"></td>
  59. </tr>
  60. <tr>
  61. <th class="text-green-600">CVV</th>
  62. <td th:text="${orderEntry.payment.cvv}"></td>
  63. </tr>
  64. <tr>
  65. <th class="text-green-600">Expires (MM/YYYY)</th>
  66. <td th:text="${orderEntry.payment.month +'/'+ orderEntry.payment.year}"></td>
  67. </tr>
  68. </table>
  69. </div>
  70. </body>
  71. </html>

POJO

  1. package com.et.itextpdf.pojo;
  2. import lombok.Data;
  3. @Data
  4. public class Account {
  5. private String name;
  6. private String phoneNumber;
  7. private String email;
  8. private Address address;
  9. }
  1. package com.et.itextpdf.pojo;
  2. import lombok.Data;
  3. @Data
  4. public class Address {
  5. private String street;
  6. private String city;
  7. private String state;
  8. private String zipCode;
  9. }
  1. package com.et.itextpdf.pojo;
  2. import lombok.Data;
  3. import java.math.BigDecimal;
  4. @Data
  5. public class Item {
  6. private String sku;
  7. private String name;
  8. private Integer quantity;
  9. private BigDecimal price;
  10. }
  1. package com.et.itextpdf.pojo;
  2. import lombok.Data;
  3. import java.util.List;
  4. @Data
  5. public class Order {
  6. private Integer orderId;
  7. private String date;
  8. private Account account;
  9. private Payment payment;
  10. private List<Item> items;
  11. }
  1. package com.et.itextpdf.pojo;
  2. import lombok.Data;
  3. import java.math.BigDecimal;
  4. @Data
  5. public class Payment {
  6. private BigDecimal amount;
  7. private String cardNumber;
  8. private String cvv;
  9. private String month;
  10. private String year;
  11. }

以上只是一些关键代码,所有代码请参见下面代码仓库

代码仓库

  • https://github.com/Harries/springboot-demo

3.测试

  • 启动spring boot应用

  • 访问http://127.0.0.1:8088/orders/,返回结果如下:

97936304275725be522bf6771310b4fe.png

  • 访问http://127.0.0.1:8088/orders/pdf,生成pdf并下载

4.引用

  • https://springhow.com/spring-boot-pdf-generation/

  • https://kb.itextpdf.com/itext/ebooks

  • http://www.liuhaihua.cn/archives/710362.html

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/340039
推荐阅读
相关标签
  

闽ICP备14008679号