当前位置: 首页 > news >正文

使用 Spring Boot 集成 Thymeleaf 和 Flying Saucer 实现 PDF 导出

在 Spring Boot 项目中,生成 PDF 报表或发票是常见需求。本文将介绍如何使用 Spring Boot 集成 Thymeleaf 模板引擎和 Flying Saucer 实现 PDF 导出,并提供详细的代码实现和常见问题解决方案。


目录

      • 一、项目依赖
      • 二、创建 Thymeleaf 模板
      • 三、创建 PDF 生成工具类
      • 四、在 Spring Boot 中使用 PDF 生成功能
      • 五、常见错误及解决方案
        • 1. 中文字符乱码
        • 2. 图片加载失败
        • 3. 样式不生效
        • 4. 模板路径识别错误
        • 5. 依赖冲突
        • 6. 内存不足
      • 总结

一、项目依赖

要实现 PDF 导出功能,首先需要在项目中添加以下依赖:

<dependencies><!-- Thymeleaf模板引擎 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><!-- Flying Saucer for PDF generation --><dependency><groupId>org.xhtmlrenderer</groupId><artifactId>flying-saucer-pdf</artifactId><version>9.1.22</version></dependency><!-- iTextPDF (com.lowagie 版本,用于兼容 Flying Saucer) --><dependency><groupId>com.lowagie</groupId><artifactId>itext</artifactId><version>2.1.7</version></dependency>
</dependencies>

注意:Flying Saucer 使用的是旧版 iText 库 com.lowagie,而不是新版 com.itextpdf,确保使用正确版本以避免依赖冲突。


二、创建 Thymeleaf 模板

新建一个 HTML 模板用于生成发票内容,例如在 resources/templates/pdf/invoice.html 文件中编写如下 HTML:

<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><title>发票</title><style>body { font-family: Arial, sans-serif; margin: 20px; }h1 { text-align: center; }table { width: 100%; border-collapse: collapse; margin-top: 20px; }th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }th { background-color: #f2f2f2; }.total { font-weight: bold; }.footer { margin-top: 30px; text-align: center; font-size: 12px; color: #888; }</style>
</head>
<body>
<h1>发票</h1>
<p>发票编号:<span th:text="${invoiceNumber}"></span></p>
<p>开具日期:<span th:text="${invoiceDate}"></span></p>
<p>买家姓名:<span th:text="${buyerName}"></span></p><h2>商品详情</h2>
<table><thead><tr><th>商品名称</th><th>描述</th><th>数量</th><th>单价</th><th>小计</th></tr></thead><tbody><tr th:each="item : ${goodsItems}"><td th:text="${item.goodsName}"></td><td th:text="${item.goodsDesc}"></td><td th:text="${item.quantity}"></td><td th:text="${item.unitPrice}"></td><td th:text="${item.totalPrice}"></td></tr></tbody>
</table><p class="total">总金额:<span th:text="${finalAmount}"></span></p>
<div class="footer">感谢您的购买!</div>
</body>
</html>

三、创建 PDF 生成工具类

接下来,创建 PdfUtil 工具类,通过 Thymeleaf 渲染 HTML 并使用 Flying Saucer 将 HTML 转为 PDF:

package com.xyh.transaction.utils;import com.xyh.transaction.entity.dto.goods.GoodsInvoice;
import com.xyh.transaction.exception.BusinessException;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;
import org.xhtmlrenderer.pdf.ITextRenderer;import java.io.ByteArrayOutputStream;
import java.util.List;public class PdfUtil {public static byte[] generateInvoicePdf(String buyerName, String invoiceNumber,List<GoodsInvoice> goodsItems, String finalAmount) {TemplateEngine templateEngine = new TemplateEngine();// 使用 Thymeleaf 渲染 HTMLContext context = new Context();context.setVariable("buyerName", buyerName);context.setVariable("invoiceNumber", invoiceNumber);context.setVariable("goodsItems", goodsItems);context.setVariable("finalAmount", finalAmount);String htmlContent = templateEngine.process("pdf/invoice.html", context);// 将 HTML 转换为 PDFtry (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {ITextRenderer renderer = new ITextRenderer();renderer.getFontResolver().addFont("/path/to/your/font/simhei.ttf", true); // 防止中文乱码renderer.setDocumentFromString(htmlContent);renderer.layout();renderer.createPDF(outputStream);return outputStream.toByteArray();} catch (Exception e) {e.printStackTrace();throw new BusinessException("发票PDF 生成失败");}}
}

四、在 Spring Boot 中使用 PDF 生成功能

在 Spring Boot 控制器中调用 PdfUtil.generateInvoicePdf,将生成的 PDF 返回给用户或作为附件发送邮件:

@RestController
@RequestMapping("/invoice")
public class InvoiceController {@GetMapping("/generate")public ResponseEntity<byte[]> generateInvoice() {byte[] pdfBytes = PdfUtil.generateInvoicePdf("张三", "INV-12345",goodsItems, "1000.00");HttpHeaders headers = new HttpHeaders();headers.setContentType(MediaType.APPLICATION_PDF);headers.setContentDispositionFormData("attachment", "invoice.pdf");return new ResponseEntity<>(pdfBytes, headers, HttpStatus.OK);}
}

五、常见错误及解决方案

1. 中文字符乱码
  • 问题:生成的 PDF 中,中文字符可能出现乱码。
  • 解决方案:确保 addFont 引用支持中文的字体文件(如 simhei.ttf)。
2. 图片加载失败
  • 问题:HTML 中的图片在 PDF 中无法正常显示。

  • 解决方案:将图片路径设置为绝对路径或通过 setBaseURL 指定资源根路径:

    renderer.getSharedContext().setBaseURL("file:/path/to/resources/");
    
3. 样式不生效
  • 问题:Flying Saucer 不支持高级 CSS。
  • 解决方案:使用基本的 table 布局和简单 CSS,不依赖 flex、CSS 变量等。
4. 模板路径识别错误
  • 问题:模板引擎找不到指定 HTML 文件。
  • 解决方案:检查文件路径和模板配置,确保模板放置在 resources/templates/pdf 目录下。
5. 依赖冲突
  • 问题:Flying Saucer 使用旧版 iText,与其他依赖产生冲突。
  • 解决方案:独立模块管理依赖,使用 maven-shade-plugin 处理冲突类。
6. 内存不足
  • 问题:生成大型 PDF 时出现内存溢出。
  • 解决方案:增加 JVM 内存配置,或简化 HTML 结构降低内存占用。

总结

使用 Spring Boot 集成 Thymeleaf 和 Flying Saucer 实现 PDF 导出是生成发票、报告等文档的高效方式。通过以上实现步骤和常见问题解决方案,希望可以帮助您顺利在项目中集成此功能。

相关文章:

使用 Spring Boot 集成 Thymeleaf 和 Flying Saucer 实现 PDF 导出

在 Spring Boot 项目中&#xff0c;生成 PDF 报表或发票是常见需求。本文将介绍如何使用 Spring Boot 集成 Thymeleaf 模板引擎和 Flying Saucer 实现 PDF 导出&#xff0c;并提供详细的代码实现和常见问题解决方案。 目录 一、项目依赖二、创建 Thymeleaf 模板三、创建 PDF 生…...

web——upload1——攻防世界

第一次做木马题目&#xff0c;有点懵逼&#xff0c;浮现一下做题思路 可以上传一个文件&#xff0c;通过学习学习到了一句话木马 一句话木马&#xff1a; 利用文件上传漏洞&#xff0c;往目标网站中上传一句话木马&#xff0c;然后你就可以在本地通过中国菜刀chopper.exe即可…...

nginx 搭建网站

1.查看防火墙状态systemctl status firewalld 2.getenforce 3.安装nginx yum install nginx -y 4.网站信息 echo "welcome to yinchuankejixuanyuan" > /usr/share/nginx/html/index.html 5.查看命令状态 nginx -t 6.重启 systemctl restart nginx...

Java基础-Java中的常用类(上)

(创作不易&#xff0c;感谢有你&#xff0c;你的支持&#xff0c;就是我前行的最大动力&#xff0c;如果看完对你有帮助&#xff0c;请留下您的足迹&#xff09; 目录 String类 创建字符串 字符串长度 连接字符串 创建格式化字符串 String 方法 System类 常用方法 方…...

气压仪器智能打气泵方案芯片SIC8833

智能打气泵方案最开始是机械式的开发&#xff0c;后来慢慢地演变成由一个气缸、压力传感器和主控芯片的开发的PCBA方案&#xff0c;它具备小体积、智能数显、预设胎压、动态测量、精准压力检测以及过充过放等功能。 其方案设计原理是利用主控芯片和压力传感器的组合设计&#x…...

软件测试(系统测试)的定位和专业:完善产品;专业;非助手;自动化

软件测试&#xff08;系统测试&#xff09;的定位 在研发流程的后端&#xff0c;测试并非无中生有的创举&#xff0c;而是从既有基础&#xff08;即“1”&#xff09;出发&#xff0c;致力于推动产品向更高层次&#xff08;即从“1”到“100”&#xff09;的跃升与完善。在这一…...

2024 CSS保姆级教程四

CSS中的动画 CSS动画&#xff08;CSS Animations&#xff09;是为层叠样式表建议的允许可扩展标记语言&#xff08;XML&#xff09;元素使用CSS的动画的模块​ 即指元素从一种样式逐渐过渡为另一种样式的过程​ 常见的动画效果有很多&#xff0c;如平移、旋转、缩放等等&#…...

PostgreSQL技术内幕17:PG分区表

文章目录 0.简介1.概念介绍2.分区表技术产生的背景3.分区类型及使用方式4.实现原理4.1 分区表创建4.2 分区表查询4.3 分区表写入4.4 分区表删除 0.简介 本文主要介绍PG中分区表的概念&#xff0c;产生分区表技术的原因&#xff0c;使用方式和其内部实现原理&#xff0c;旨在能…...

群控系统服务端开发模式-应用开发-上传工厂开发

现在的文件、图片等上传基本都在使用oss存储。而现在常用的oss存储有阿里云、腾讯云、七牛云、华为云等&#xff0c;但是用的最多的还是前三种。而我主要封装的是本地存储、阿里云存储、腾讯云存储、七牛云存储。废话不多说&#xff0c;直接上传设计图及说明&#xff0c;就一目…...

【Docker系列】指定系统平台拉取 openjdk:8 镜像

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...

语音识别:docker部署FunASR以及springboot集成funasr

内容摘选自: https://github.com/modelscope/FunASR/blob/main/runtime/docs/SDK_advanced_guide_offline_zh.md FunASR FunASR是一个基础语音识别工具包&#xff0c;提供多种功能&#xff0c;包括语音识别&#xff08;ASR&#xff09;、语音端点检测&#xff08;VAD&#xf…...

Rust项目结构

文章目录 一、module模块1.文件内的module 二、模块化项目结构1.关于module2.各个模块之间互相引用 三、推荐项目结构1.实例 参考 一、module模块 1.文件内的module 关键字&#xff1a;mod 引入模块中的方法 usemod名字&#xff1a;方法名usemod名字.*写全路径 二、模块化项…...

计算并联电阻的阻值

计算并联电阻的阻值 C语言代码C代码Java代码Python代码 &#x1f490;The Begin&#x1f490;点点关注&#xff0c;收藏不迷路&#x1f490; 对于阻值为r1和r2的电阻&#xff0c;其并联电阻阻值公式计算如下&#xff1a; R1/(1/r11/r2) 输入 两个电阻阻抗大小&#xff0c;浮…...

MySQL符号类型(详细)

在 MySQL 中&#xff0c;符号可以分为几种主要类型&#xff0c;以下是所有符号类型的小写分类&#xff1a; 1. 占位符 ?&#xff1a;用于准备语句中的占位符&#xff0c;表示将来要替换的值。 2. 分隔符 ;&#xff1a;表示 sql 语句的结束。 ,&#xff1a;用于分隔列、值或…...

Angular引用控件类

说明&#xff1a; angular 在一个控件类里面&#xff0c;引入另外一个控件类&#xff0c;这样做的好处&#xff0c;就是代码分离&#xff0c;当你一个页面存在多少类似于独立的界面时&#xff0c;可以使用这种方式&#xff0c;分离代码 更好维护程序 效果图&#xff1a; step…...

stm32 踩坑笔记

串口问题&#xff1a; 问题&#xff1a;会改变接收缓冲的下一个字节 串口的初始化如下&#xff0c;位长度选择了9位。因为要奇偶校验&#xff0c;要选择9位。但是接收有用数据只用到1个字节。 问题原因&#xff1a; 所以串口接收时会把下一个数据更改...

文件上传和文件包含

声明: 本文章只是适用于网络安全教学,请自觉遵守网络安全法,严禁用于非法途径,若读者做出来任何危害网络安全的行为,后果自负,均与本人无关. 文件上传&#xff1a; 大部分的网站和应用系统都有上传的功能&#xff0c;如用户头像上传&#xff0c;图片上传&#xff0c;文档上传…...

[Unity Demo]从零开始制作空洞骑士Hollow Knight第十八集补充:制作空洞骑士独有的EventSystem和InputModule

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、制作空洞骑士独有的EventSystem和InputModule总结 前言 hello大家好久没见&#xff0c;之所以隔了这么久才更新并不是因为我又放弃了这个项目&#xff0c;而…...

yelp数据集上试验SVD,SVDPP,PMF,NMF 推荐算法

SVD、SVD、PMF 和 NMF 是几种常见的推荐算法&#xff0c;它们主要用于协同过滤和矩阵分解方法来生成个性化推荐。下面是对每种算法的简要介绍&#xff1a; 1. SVD&#xff08;Singular Value Decomposition&#xff09; 用途&#xff1a;SVD 是一种矩阵分解技术&#xff0c;通…...

计算机视觉常用数据集Cityscapes的介绍、下载、转为YOLO格式进行训练

我在寻找Cityscapes数据集的时候花了一番功夫&#xff0c;因为官网下载需要用公司或学校邮箱邮箱注册账号&#xff0c;等待审核通过后才能进行下载数据集。并且一开始我也并不了解Cityscapes的格式和内容是什么样的&#xff0c;现在我弄明白后写下这篇文章&#xff0c;用于记录…...

使用VSCode开发Django指南

使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架&#xff0c;专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用&#xff0c;其中包含三个使用通用基本模板的页面。在此…...

Debian系统简介

目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版&#xff…...

基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容

基于 ​UniApp + WebSocket​实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配​微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...

测试markdown--肇兴

day1&#xff1a; 1、去程&#xff1a;7:04 --11:32高铁 高铁右转上售票大厅2楼&#xff0c;穿过候车厅下一楼&#xff0c;上大巴车 &#xffe5;10/人 **2、到达&#xff1a;**12点多到达寨子&#xff0c;买门票&#xff0c;美团/抖音&#xff1a;&#xffe5;78人 3、中饭&a…...

oracle与MySQL数据库之间数据同步的技术要点

Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异&#xff0c;它们的数据同步要求既要保持数据的准确性和一致性&#xff0c;又要处理好性能问题。以下是一些主要的技术要点&#xff1a; 数据结构差异 数据类型差异&#xff…...

论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)

笔记整理&#xff1a;刘治强&#xff0c;浙江大学硕士生&#xff0c;研究方向为知识图谱表示学习&#xff0c;大语言模型 论文链接&#xff1a;http://arxiv.org/abs/2407.16127 发表会议&#xff1a;ISWC 2024 1. 动机 传统的知识图谱补全&#xff08;KGC&#xff09;模型通过…...

Redis的发布订阅模式与专业的 MQ(如 Kafka, RabbitMQ)相比,优缺点是什么?适用于哪些场景?

Redis 的发布订阅&#xff08;Pub/Sub&#xff09;模式与专业的 MQ&#xff08;Message Queue&#xff09;如 Kafka、RabbitMQ 进行比较&#xff0c;核心的权衡点在于&#xff1a;简单与速度 vs. 可靠与功能。 下面我们详细展开对比。 Redis Pub/Sub 的核心特点 它是一个发后…...

安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖

在Vuzix M400 AR智能眼镜的助力下&#xff0c;卢森堡罗伯特舒曼医院&#xff08;the Robert Schuman Hospitals, HRS&#xff09;凭借在无菌制剂生产流程中引入增强现实技术&#xff08;AR&#xff09;创新项目&#xff0c;荣获了2024年6月7日由卢森堡医院药剂师协会&#xff0…...

mac 安装homebrew (nvm 及git)

mac 安装nvm 及git 万恶之源 mac 安装这些东西离不开Xcode。及homebrew 一、先说安装git步骤 通用&#xff1a; 方法一&#xff1a;使用 Homebrew 安装 Git&#xff08;推荐&#xff09; 步骤如下&#xff1a;打开终端&#xff08;Terminal.app&#xff09; 1.安装 Homebrew…...

C++课设:简易日历程序(支持传统节假日 + 二十四节气 + 个人纪念日管理)

名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏介绍:《编程项目实战》 目录 一、为什么要开发一个日历程序?1. 深入理解时间算法2. 练习面向对象设计3. 学习数据结构应用二、核心算法深度解析…...