Spring Boot集成itext实现html生成PDF功能
liuian 2024-12-04 13:46 66 浏览
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
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>springboot-demo</artifactId>
<groupId>com.et</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>itextpdf</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>html2pdf</artifactId>
<version>3.0.1</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>kernel</artifactId>
<version>7.1.12</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
</project>application.yaml
server:
port: 8088
spring:
thymeleaf:
cache: falseDemoApplication
package com.et.itextpdf;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
@ServletComponentScan
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}controller
converterProperties.setBaseUri 很重要。 否则,像 /main.css 这样的静态资源将无法找到
package com.et.itextpdf.controller;
import com.et.itextpdf.pojo.Order;
import com.et.itextpdf.util.OrderHelper;
import com.itextpdf.html2pdf.ConverterProperties;
import com.itextpdf.html2pdf.HtmlConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.WebContext;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
@Controller
@RequestMapping("/orders")
public class PDFController {
@Autowired
ServletContext servletContext;
private final TemplateEngine templateEngine;
public PDFController(TemplateEngine templateEngine) {
this.templateEngine = templateEngine;
}
@RequestMapping(path = "/")
public String getOrderPage(Model model) {
Order order = OrderHelper.getOrder();
model.addAttribute("orderEntry", order);
return "order";
}
@RequestMapping(path = "/pdf")
public ResponseEntity<?> getPDF(HttpServletRequest request, HttpServletResponse response) throws IOException {
/* Do Business Logic*/
Order order = OrderHelper.getOrder();
/* Create HTML using Thymeleaf template Engine */
WebContext context = new WebContext(request, response, servletContext);
context.setVariable("orderEntry", order);
String orderHtml = templateEngine.process("order", context);
/* Setup Source and target I/O streams */
ByteArrayOutputStream target = new ByteArrayOutputStream();
ConverterProperties converterProperties = new ConverterProperties();
converterProperties.setBaseUri("http://localhost:8088");
/* Call convert method */
HtmlConverter.convertToPdf(orderHtml, target, converterProperties);
/* extract output as bytes */
byte[] bytes = target.toByteArray();
/* Send the response as downloadable PDF */
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=order.pdf")
.contentType(MediaType.APPLICATION_PDF)
.body(bytes);
}
}view
Spring MVC 带有模板引擎,可以提供动态的 HTML 内容。 我们可以通过以下方法轻松将这些回复转换为 PDF 格式。 在本例中,我导入了 spring-boot-starter-web 和 spring-boot-starter-thymeleaf 来为我的 spring boot 项目提供 MVC 和 thymeleaf 支持。 您可以使用自己选择的模板引擎。 看看下面这个thymeleaf模板内容。 主要展示订单详细信息。 另外,通过 OrderHelper 的辅助方法来生成一些虚拟订单内容。
<!doctype html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"
name="viewport">
<meta content="ie=edge" http-equiv="X-UA-Compatible">
<title>Spring Boot - Thymeleaf</title>
<link th:href="@{/main.css}" rel="stylesheet"/>
</head>
<body class="flex items-center justify-center h-screen">
<div class="rounded-lg border shadow-lg p-10 w-3/5">
<div class="flex flex-row justify-between pb-4">
<div>
<h2 class="text-xl font-bold">Order #<span class="text-green-600" th:text="${orderEntry.orderId}"></span>
</h2>
</div>
<div>
<div class="text-xl font-bold" th:text="${orderEntry.date}"></div>
</div>
</div>
<div class="flex flex-col pb-8">
<div class="pb-2">
<h2 class="text-xl font-bold">Delivery Address</h2>
</div>
<div th:text="${orderEntry.account.address.street}"></div>
<div th:text="${orderEntry.account.address.city}"></div>
<div th:text="${orderEntry.account.address.state}"></div>
<div th:text="${orderEntry.account.address.zipCode}"></div>
</div>
<table class="table-fixed w-full text-right border rounded">
<thead class="bg-gray-100">
<tr>
<th class="text-left pl-4">Product</th>
<th>Qty</th>
<th>Price</th>
<th class="pr-4">Total</th>
</tr>
</thead>
<tbody>
<tr th:each="item : ${orderEntry.items}">
<td class="pl-4 text-left" th:text="${item.name}"></td>
<td th:text="${item.quantity}"></td>
<td th:text="${item.price}"></td>
<td class="pr-4" th:text="${item.price * item.quantity}"></td>
</tr>
</tbody>
</table>
<div class="flex flex-row-reverse p-5">
<h2 class="font-medium bg-gray-200 p-2 rounded">
Grand Total: <span class="text-green-600" th:text="${orderEntry.payment.amount}"></span>
</h2>
</div>
<h2 class="text-xl font-bold">Payment Details</h2>
<table class="table-fixed text-left w-2/6 border">
<tr>
<th class="text-green-600">Card Number</th>
<td th:text="${orderEntry.payment.cardNumber}"></td>
</tr>
<tr>
<th class="text-green-600">CVV</th>
<td th:text="${orderEntry.payment.cvv}"></td>
</tr>
<tr>
<th class="text-green-600">Expires (MM/YYYY)</th>
<td th:text="${orderEntry.payment.month +'/'+ orderEntry.payment.year}"></td>
</tr>
</table>
</div>
</body>
</html>POJO
package com.et.itextpdf.pojo;
import lombok.Data;
@Data
public class Account {
private String name;
private String phoneNumber;
private String email;
private Address address;
}package com.et.itextpdf.pojo;
import lombok.Data;
@Data
public class Address {
private String street;
private String city;
private String state;
private String zipCode;
}package com.et.itextpdf.pojo;
import lombok.Data;
import java.math.BigDecimal;
@Data
public class Item {
private String sku;
private String name;
private Integer quantity;
private BigDecimal price;
}package com.et.itextpdf.pojo;
import lombok.Data;
import java.util.List;
@Data
public class Order {
private Integer orderId;
private String date;
private Account account;
private Payment payment;
private List<Item> items;
}package com.et.itextpdf.pojo;
import lombok.Data;
import java.math.BigDecimal;
@Data
public class Payment {
private BigDecimal amount;
private String cardNumber;
private String cvv;
private String month;
private String year;
}以上只是一些关键代码,所有代码请参见下面代码仓库
代码仓库
- https://github.com/Harries/springboot-demo
3.测试
- 启动spring boot应用
- 访问http://127.0.0.1:8088/orders/
- 访问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
相关推荐
-
- 驱动网卡(怎么从新驱动网卡)
-
网卡一般是指为电脑主机提供有线无线网络功能的适配器。而网卡驱动指的就是电脑连接识别这些网卡型号的桥梁。网卡只有打上了网卡驱动才能正常使用。并不是说所有的网卡一插到电脑上面就能进行数据传输了,他都需要里面芯片组的驱动文件才能支持他进行数据传输...
-
2026-01-30 00:37 liuian
- win10更新助手装系统(微软win10更新助手)
-
1、点击首页“系统升级”的按钮,给出弹框,告诉用户需要上传IMEI码才能使用升级服务。同时给出同意和取消按钮。华为手机助手2、点击同意,则进入到“系统升级”功能华为手机助手华为手机助手3、在检测界面,...
- windows11专业版密钥最新(windows11专业版激活码永久)
-
Windows11专业版的正版密钥,我们是对windows的激活所必备的工具。该密钥我们可以通过微软商城或者通过计算机的硬件供应商去购买获得。获得了windows11专业版的正版密钥后,我...
-
- 手机删过的软件恢复(手机删除过的软件怎么恢复)
-
操作步骤:1、首先,我们需要先打开手机。然后在许多图标中找到带有[文件管理]文本的图标,然后单击“文件管理”进入页面。2、进入页面后,我们将在顶部看到一行文本:手机,最新信息,文档,视频,图片,音乐,收藏,最后是我们正在寻找的[更多],单击...
-
2026-01-29 23:55 liuian
- 一键ghost手动备份系统步骤(一键ghost 备份)
-
步骤1、首先把装有一键GHOST装系统的U盘插在电脑上,然后打开电脑马上按F2或DEL键入BIOS界面,然后就选择BOOT打USDHDD模式选择好,然后按F10键保存,电脑就会马上重启。 步骤...
- 怎么创建局域网(怎么创建局域网打游戏)
-
1、购买路由器一台。进入路由器把dhcp功能打开 2、购买一台交换机。从路由器lan端口拉出一条网线查到交换机的任意一个端口上。 3、两台以上电脑。从交换机任意端口拉出网线插到电脑上(电脑设置...
- 精灵驱动器官方下载(精灵驱动手机版下载)
-
是的。驱动精灵是一款集驱动管理和硬件检测于一体的、专业级的驱动管理和维护工具。驱动精灵为用户提供驱动备份、恢复、安装、删除、在线更新等实用功能。1、全新驱动精灵2012引擎,大幅提升硬件和驱动辨识能力...
- 一键还原系统步骤(一键还原系统有哪些)
-
1、首先需要下载安装一下Windows一键还原程序,在安装程序窗口中,点击“下一步”,弹出“用户许可协议”窗口,选择“我同意该许可协议的条款”,并点击“下一步”。 2、在弹出的“准备安装”窗口中,可...
- 电脑加速器哪个好(电脑加速器哪款好)
-
我认为pp加速器最好用,飞速土豆太懒,急速酷六根本不工作。pp加速器什么网页都加速,太任劳任怨了!以上是个人观点,具体性能请自己试。ps:我家电脑性能很好。迅游加速盒子是可以加速电脑的。因为有过之...
- 任何u盘都可以做启动盘吗(u盘必须做成启动盘才能装系统吗)
-
是的,需要注意,U盘的大小要在4G以上,最好是8G以上,因为启动盘里面需要装系统,内存小的话,不能用来安装系统。内存卡或者U盘或者移动硬盘都可以用来做启动盘安装系统。普通的U盘就可以,不过最好U盘...
- u盘怎么恢复文件(u盘文件恢复的方法)
-
开360安全卫士,点击上面的“功能大全”。点击文件恢复然后点击“数据”下的“文件恢复”功能。选择驱动接着选择需要恢复的驱动,选择接入的U盘。点击开始扫描选好就点击中间的“开始扫描”,开始扫描U盘数据。...
- 系统虚拟内存太低怎么办(系统虚拟内存占用过高什么原因)
-
1.检查系统虚拟内存使用情况,如果发现有大量的空闲内存,可以尝试释放一些不必要的进程,以释放内存空间。2.如果系统虚拟内存使用率较高,可以尝试增加系统虚拟内存的大小,以便更多的应用程序可以使用更多...
-
- 剪贴板权限设置方法(剪贴板访问权限)
-
1、首先打开iphone手机,触碰并按住单词或图像直到显示选择选项。2、其次,然后选取“拷贝”或“剪贴板”。3、勾选需要的“权限”,最后选择开启,即可完成苹果剪贴板权限设置。仅参考1.打开苹果手机设置按钮,点击【通用】。2.点击【键盘】,再...
-
2026-01-29 21:37 liuian
- 平板系统重装大师(平板重装win系统)
-
如果你的平板开不了机,但可以连接上电脑,那就能好办,楼主下载安装个平板刷机王到你的个人电脑上,然后连接你的平板,平板刷机王会自动识别你的平板,平板刷机王上有你平板的我刷机包,楼主点击下载一个,下载完成...
- 联想官网售后服务网点(联想官网售后服务热线)
-
联想3c服务中心是联想旗下的官方售后,是基于互联网O2O模式开发的全新服务平台。可以为终端用户提供多品牌手机、电脑以及其他3C类产品的维修、保养和保险服务。根据客户需求层次,联想服务针对个人及家庭客户...
- 一周热门
- 最近发表
- 标签列表
-
- python判断字典是否为空 (50)
- crontab每周一执行 (48)
- aes和des区别 (43)
- bash脚本和shell脚本的区别 (35)
- canvas库 (33)
- dataframe筛选满足条件的行 (35)
- gitlab日志 (33)
- lua xpcall (36)
- blob转json (33)
- python判断是否在列表中 (34)
- python html转pdf (36)
- 安装指定版本npm (37)
- idea搜索jar包内容 (33)
- css鼠标悬停出现隐藏的文字 (34)
- linux nacos启动命令 (33)
- gitlab 日志 (36)
- adb pull (37)
- python判断元素在不在列表里 (34)
- python 字典删除元素 (34)
- vscode切换git分支 (35)
- python bytes转16进制 (35)
- grep前后几行 (34)
- hashmap转list (35)
- c++ 字符串查找 (35)
- mysql刷新权限 (34)
