开发者

使用SpringBoot集成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>
        </dependen编程cy>
    
        <!-- 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:http://www.devze.com 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) {
            T编程客栈emplateEngine 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",
                  http://www.devze.com  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导出的资料请关注编程客栈(www.devze.com)其它相关文章!

    0

    上一篇:

    下一篇:

    精彩评论

    暂无评论...
    验证码 换一张
    取 消

    最新开发

    开发排行榜