使用SpringBoot集成Thymeleaf和Flying Saucer实现PDF导出
一、项目依赖
要实现 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 渲染 HTML Context 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 转换为 PDF try (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 导出是生成发票、报告等文档的高效方式。通过以上实现步骤和常见问题解决方案,希望可以帮助您顺利在项目中集成此功能。
以上就是使用SpringBoot集成Thymeleaf和Flying Saucer实现PDF导出的详细内容,更多关于SpringBoot实现PDF导出的资料请关注脚本之家其它相关文章!
最新评论