使用SpringBoot集成Thymeleaf和Flying?Saucer實(shí)現(xiàn)PDF導(dǎo)出
一、項(xiàng)目依賴(lài)
要實(shí)現(xiàn) PDF 導(dǎo)出功能,首先需要在項(xiàng)目中添加以下依賴(lài):
<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 庫(kù) com.lowagie,而不是新版 com.itextpdf,確保使用正確版本以避免依賴(lài)沖突。
二、創(chuàng)建 Thymeleaf 模板
新建一個(gè) HTML 模板用于生成發(fā)票內(nèi)容,例如在 resources/templates/pdf/invoice.html 文件中編寫(xiě)如下 HTML:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>發(fā)票</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>發(fā)票</h1>
<p>發(fā)票編號(hào):<span th:text="${invoiceNumber}"></span></p>
<p>開(kāi)具日期:<span th:text="${invoiceDate}"></span></p>
<p>買(mǎi)家姓名:<span th:text="${buyerName}"></span></p>
<h2>商品詳情</h2>
<table>
<thead>
<tr>
<th>商品名稱(chēng)</th>
<th>描述</th>
<th>數(shù)量</th>
<th>單價(jià)</th>
<th>小計(jì)</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">感謝您的購(gòu)買(mǎi)!</div>
</body>
</html>
三、創(chuàng)建 PDF 生成工具類(lèi)
接下來(lái),創(chuàng)建 PdfUtil 工具類(lèi),通過(guò) Thymeleaf 渲染 HTML 并使用 Flying Saucer 將 HTML 轉(zhuǎn)為 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 轉(zhuǎn)換為 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("發(fā)票P(pán)DF 生成失敗");
}
}
}
四、在 Spring Boot 中使用 PDF 生成功能
在 Spring Boot 控制器中調(diào)用 PdfUtil.generateInvoicePdf,將生成的 PDF 返回給用戶(hù)或作為附件發(fā)送郵件:
@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);
}
}
五、常見(jiàn)錯(cuò)誤及解決方案
1. 中文字符亂碼
- 問(wèn)題:生成的 PDF 中,中文字符可能出現(xiàn)亂碼。
- 解決方案:確保
addFont引用支持中文的字體文件(如simhei.ttf)。
2. 圖片加載失敗
問(wèn)題:HTML 中的圖片在 PDF 中無(wú)法正常顯示。
解決方案:將圖片路徑設(shè)置為絕對(duì)路徑或通過(guò)
setBaseURL指定資源根路徑:
renderer.getSharedContext().setBaseURL("file:/path/to/resources/");
3. 樣式不生效
- 問(wèn)題:Flying Saucer 不支持高級(jí) CSS。
- 解決方案:使用基本的
table布局和簡(jiǎn)單 CSS,不依賴(lài) flex、CSS 變量等。
4. 模板路徑識(shí)別錯(cuò)誤
- 問(wèn)題:模板引擎找不到指定 HTML 文件。
- 解決方案:檢查文件路徑和模板配置,確保模板放置在
resources/templates/pdf目錄下。
5. 依賴(lài)沖突
- 問(wèn)題:Flying Saucer 使用舊版 iText,與其他依賴(lài)產(chǎn)生沖突。
- 解決方案:獨(dú)立模塊管理依賴(lài),使用
maven-shade-plugin處理沖突類(lèi)。
6. 內(nèi)存不足
- 問(wèn)題:生成大型 PDF 時(shí)出現(xiàn)內(nèi)存溢出。
- 解決方案:增加 JVM 內(nèi)存配置,或簡(jiǎn)化 HTML 結(jié)構(gòu)降低內(nèi)存占用。
總結(jié)
使用 Spring Boot 集成 Thymeleaf 和 Flying Saucer 實(shí)現(xiàn) PDF 導(dǎo)出是生成發(fā)票、報(bào)告等文檔的高效方式。通過(guò)以上實(shí)現(xiàn)步驟和常見(jiàn)問(wèn)題解決方案,希望可以幫助您順利在項(xiàng)目中集成此功能。
以上就是使用SpringBoot集成Thymeleaf和Flying Saucer實(shí)現(xiàn)PDF導(dǎo)出的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot實(shí)現(xiàn)PDF導(dǎo)出的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
關(guān)于Java中使用jdbc連接數(shù)據(jù)庫(kù)中文出現(xiàn)亂碼的問(wèn)題
這篇文章主要介紹了關(guān)于Java中使用jdbc連接數(shù)據(jù)庫(kù)中文出現(xiàn)亂碼的問(wèn)題,默認(rèn)的編碼和數(shù)據(jù)庫(kù)表中的數(shù)據(jù)使用的編碼是不一致的,如果是中文,那么在數(shù)據(jù)庫(kù)中執(zhí)行時(shí)已經(jīng)是亂碼了,需要的朋友可以參考下2023-04-04
JSP頁(yè)面pageEncoding和contentType屬性
有關(guān)于JSP頁(yè)面中pageEncoding和contentType屬性。2013-04-04
MybatisPlus關(guān)聯(lián)查詢(xún)的完美實(shí)現(xiàn)方案
我們?cè)陧?xiàng)目開(kāi)發(fā)的時(shí)候,難免會(huì)遇到連表查詢(xún)的操作,所以下面這篇文章主要給大家介紹了關(guān)于MybatisPlus關(guān)聯(lián)查詢(xún)的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2021-12-12
Java中與數(shù)字相關(guān)的常用類(lèi)的用法詳解
在我們的代碼中,經(jīng)常會(huì)遇到一些數(shù)字&數(shù)學(xué)問(wèn)題、隨機(jī)數(shù)問(wèn)題、日期問(wèn)題和系統(tǒng)設(shè)置問(wèn)題等,為了解決這些問(wèn)題,Java給我們提供了多個(gè)處理相關(guān)問(wèn)題的類(lèi),比如Number類(lèi)、Math類(lèi)、Random類(lèi)等等,本篇文章我們先從Number數(shù)字類(lèi)和Math數(shù)學(xué)類(lèi)學(xué)起2023-05-05
SpringBoot使用JavaMailSender實(shí)現(xiàn)發(fā)送郵件
JavaMailSender是Spring Framework中的一個(gè)接口,用于發(fā)送電子郵件,本文主要為大家詳細(xì)介紹了SpringBoot如何使用JavaMailSender實(shí)現(xiàn)發(fā)送郵件,需要的可以參考下2023-12-12
Java?Spring?boot?配置JDK和MAVEN開(kāi)發(fā)環(huán)境的過(guò)程
本文詳細(xì)介紹了如何配置JDK和Maven環(huán)境,包括JDK的安裝與環(huán)境變量設(shè)置,Maven的下載、配置環(huán)境變量和設(shè)置阿里云倉(cāng)庫(kù),最后簡(jiǎn)述了在IntelliJ?IDEA中配置JDK和Maven的步驟,本教程適合Java開(kāi)發(fā)新手進(jìn)行開(kāi)發(fā)環(huán)境的搭建,確保順利進(jìn)行Java項(xiàng)目的開(kāi)發(fā)2024-11-11

