SpringBoot Thymeleaf iText7 生成 PDF(2023/08/29)

这篇具有很好参考价值的文章主要介绍了SpringBoot Thymeleaf iText7 生成 PDF(2023/08/29)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

SpringBoot Thymeleaf iText7 生成 PDF(2023/08/29)

1. 前言

近期在项目种遇到了实时生成复杂 PDF 的需求,经过一番调研和测试,最终选择了采用 Thymeleaf 和 iText7 来实现需求,本文将详细介绍实现过程。

2. 技术思路

  1. 通过 Thymeleaf 渲染生成需要的页面内容;
  2. 通过 iText7 html2pdf 库将 Thymeleaf 渲染的结果转换成 PDF;
  3. 将 PDF 内容写入到接口输出流中返回给前端浏览器展示;

3. 实现过程

  1. Maven 引入依赖;

    <!-- Thymeleaf -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
    
    <!-- iText html2pdf -->
    <dependency>
        <groupId>com.itextpdf</groupId>
        <artifactId>html2pdf</artifactId>
        <version>5.0.0</version>
    </dependency>
    
    <!-- lombok -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>
    
    <!-- 获取资源文件 -->
    <dependency>
        <groupId>cn.hutool</groupId>
        <artifactId>hutool-all</artifactId>
        <version>5.8.21</version>
    </dependency>
    
  2. 编写 Thymeleaf 模板 resources/templates/demo.html

    <!DOCTYPE html>
    <html lang="zh">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>PDF Demo</title>
    
        <style>
            body {
                padding-top: 50px;
                padding-left: 60px;
                padding-right: 60px;
                font-family: 'KaiTi', serif;
            }
    
            .title {
                color: red;
                text-align: center;
                margin-bottom: 50px;
            }
    
            table {
                width: 100%;
                border: 1px solid black;
                border-spacing: 0;
            }
    
            th {
                border: 1px solid black;
                background-color: rgb(128, 128, 128);
            }
    
            td {
                border: 1px solid black;
            }
        </style>
    </head>
    
    <body>
    <h1 class="title" th:text="${title}"></h1>
    
    <table>
        <thead>
        <tr>
            <th>序号</th>
            <th>姓名</th>
            <th>年龄</th>
            <th>性别</th>
        </tr>
        </thead>
        <tbody th:each="student, studentStat : ${students}">
        <tr>
            <td th:text="${studentStat.count}"></td>
            <td th:text="${student.name}"></td>
            <td th:text="${student.age}"></td>
            <td th:text="${student.sex}"></td>
        </tr>
        </tbody>
    </table>
    
    </body>
    </html>
    
  3. 添加中文字体资源 resources/fonts/simkai.ttf

  4. 编写 PDF 页码事件处理 handler/PageEventHandler

    package com.xiaoqqya.itextpdf.handler;
    
    import com.itextpdf.kernel.events.Event;
    import com.itextpdf.kernel.events.IEventHandler;
    import com.itextpdf.kernel.events.PdfDocumentEvent;
    import com.itextpdf.kernel.geom.Rectangle;
    import com.itextpdf.kernel.pdf.PdfDocument;
    import com.itextpdf.kernel.pdf.PdfPage;
    import com.itextpdf.kernel.pdf.canvas.PdfCanvas;
    import com.itextpdf.layout.Canvas;
    import com.itextpdf.layout.element.Paragraph;
    import com.itextpdf.layout.properties.TextAlignment;
    
    /**
     * 页码事件处理.
     *
     * @author <a href="mailto:xiaoQQya@126.com">xiaoQQya</a>
     * @since 2023/08/29
     */
    public class PageEventHandler implements IEventHandler {
    
        @Override
        public void handleEvent(Event event) {
            PdfDocumentEvent documentEvent = (PdfDocumentEvent) event;
            PdfDocument document = documentEvent.getDocument();
            PdfPage page = documentEvent.getPage();
            Rectangle pageSize = page.getPageSize();
    
            PdfCanvas pdfCanvas = new PdfCanvas(page.getLastContentStream(), page.getResources(), document);
            Canvas canvas = new Canvas(pdfCanvas, pageSize);
            float x = (pageSize.getLeft() + pageSize.getRight()) / 2;
            float y = pageSize.getBottom() + 15;
            Paragraph paragraph = new Paragraph("-- " + document.getPageNumber(page) + " --")
                    .setFontSize(10);
            canvas.showTextAligned(paragraph, x, y, TextAlignment.CENTER);
            canvas.close();
        }
    }
    
  5. 编写 Student 实体类 model/domain/Student

    package com.xiaoqqya.itextpdf.model.domain;
    
    import lombok.AllArgsConstructor;
    import lombok.Builder;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    /**
     * 学生.
     *
     * @author <a href="mailto:xiaoQQya@126.com">xiaoQQya</a>
     * @since 2023/08/29
     */
    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    public class Student {
    
        /**
         * 姓名
         */
        private String name;
    
        /**
         * 、
         * 年龄
         */
        private Integer age;
    
        /**
         * 性别
         */
        private String sex;
    }
    
  6. 编写 Service service/PdfService 生成 PDF;

    package com.xiaoqqya.itextpdf.service.impl;
    
    import cn.hutool.core.io.resource.ResourceUtil;
    import com.itextpdf.html2pdf.ConverterProperties;
    import com.itextpdf.html2pdf.HtmlConverter;
    import com.itextpdf.html2pdf.resolver.font.DefaultFontProvider;
    import com.itextpdf.io.font.FontProgramFactory;
    import com.itextpdf.kernel.events.PdfDocumentEvent;
    import com.itextpdf.kernel.geom.PageSize;
    import com.itextpdf.kernel.pdf.PdfDocument;
    import com.itextpdf.kernel.pdf.PdfWriter;
    import com.itextpdf.layout.font.FontProvider;
    import com.xiaoqqya.itextpdf.exception.CustomException;
    import com.xiaoqqya.itextpdf.handler.PageEventHandler;
    import com.xiaoqqya.itextpdf.model.domain.Student;
    import com.xiaoqqya.itextpdf.service.PdfService;
    import org.springframework.stereotype.Service;
    import org.thymeleaf.TemplateEngine;
    import org.thymeleaf.context.Context;
    
    import javax.annotation.Resource;
    import java.io.IOException;
    import java.io.OutputStream;
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * PDF Service.
     *
     * @author <a href="mailto:xiaoQQya@126.com">xiaoQQya</a>
     * @since 2023/08/29
     */
    @Service
    public class PdfServiceImpl implements PdfService {
    
        @Resource
        private TemplateEngine templateEngine;
    
        /**
         * 生成 PDF.
         *
         * @param outputStream 输出流
         */
        @Override
        public void generatePdf(OutputStream outputStream) {
            // 模拟数据
            List<Student> students = new ArrayList<>();
            students.add(Student.builder().name("小红").age(18).sex("女").build());
            students.add(Student.builder().name("小强").age(21).sex("男").build());
            students.add(Student.builder().name("熊大").age(19).sex("男").build());
    
            // 生成 Thymeleaf 上下文
            Context context = new Context();
            context.setVariable("title", "PDF Demo");
            context.setVariable("students", students);
            String demo = templateEngine.process("demo", context);
    
            // 生成 PDF, 并添加页码
            try (PdfWriter pdfWriter = new PdfWriter(outputStream); PdfDocument pdfDocument = new PdfDocument(pdfWriter)) {
                pdfDocument.setDefaultPageSize(PageSize.A4);
                pdfDocument.addEventHandler(PdfDocumentEvent.INSERT_PAGE, new PageEventHandler());
    
                ConverterProperties converterProperties = new ConverterProperties();
                FontProvider fontProvider = new DefaultFontProvider(true, true, false);
                fontProvider.addFont(FontProgramFactory.createFont(ResourceUtil.readBytes("fonts/simkai.ttf")));
                converterProperties.setFontProvider(fontProvider);
                HtmlConverter.convertToPdf(demo, pdfDocument, converterProperties);
            } catch (IOException e) {
                throw new CustomException(e.getMessage());
            }
        }
    }
    
  7. 编写 Controller controller/PdfController 返回给前端浏览器展示;

    package com.xiaoqqya.itextpdf.controller;
    
    import com.xiaoqqya.itextpdf.service.PdfService;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import javax.annotation.Resource;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    /**
     * PDF Controller.
     *
     * @author <a href="mailto:xiaoQQya@126.com">xiaoQQya</a>
     * @since 2023/08/29
     */
    @RestController
    @RequestMapping(value = "/pdf")
    public class PdfController {
    
        @Resource
        private PdfService pdfService;
    
        /**
         * 生成 PDF.
         */
        @GetMapping
        public void generatePdf(HttpServletResponse response) throws IOException {
            pdfService.generatePdf(response.getOutputStream());
        }
    }
    

4. 测试

浏览器访问 http://localhost:8080/pdf 查看效果。

参考文章:文章来源地址https://www.toymoban.com/news/detail-688510.html

  • 使用itext7将HTML转为pdf · Issue #12 · ydq/blog (github.com);

到了这里,关于SpringBoot Thymeleaf iText7 生成 PDF(2023/08/29)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 记录使用iText7查找PDF内容关键字坐标,加盖电子签名、印章

    项目以前签字都是由C端那边进行合成操作,最近项目要求把那块功能,由后端进行实现,其中包含坐标、、任意位置进行签字操作,坐标是最容易实现的,曾经也写过类似的功能在(添加图片印章到PDF)直接复用就可以了 为了实现位置签字,在网上查找了挺多

    2024年02月07日
    浏览(34)
  • SpringBoot Thymeleaf企业级真实应用:使用Flying Saucer结合iText5将HTML界面数据转换为PDF输出(四) 表格中断问题

    接上一篇 SpringBoot Thymeleaf企业级真实应用:使用Flying Saucer结合iText5将HTML界面数据转换为PDF输出(三) 给pdf加水印、页眉页脚、页眉logo 设置表格的css样式

    2024年02月12日
    浏览(36)
  • 【Java】使用iText生成PDF文件

    iText介绍 iText是著名的开放源码的站点sourceforge一个项目,是用于生成PDF文档的一个java类库。通过iText不仅可以生成PDF或rtf的文档,而且可以将XML、Html文件转化为PDF文件。 项目要使用iText,必须引入jar包。才能使用,maven依赖如下: 输出中文,还要引入下面itext-asian.jar包:  

    2024年02月10日
    浏览(26)
  • Java XPath 使用(2023/08/29)

    众所周知,Java 语言适合应用于 Web 开发领域,不擅长用来编写爬虫。但在 Web 开发过程中有时又存在爬取数据的需求,此时采用其它语言编写独立爬虫模块的话存在维护不方便的问题,所以此处笔者选择了使用 Java + XPath 实现简单的爬虫功能,如果爬虫需求较多且复杂还是推

    2024年02月10日
    浏览(29)
  • 【Java】itext 实现 html根据模板生成pdf 中文不显示/图片不显示问题解决

    工作中需要使用生成pdf记录,选取使用的是itext 生成 pdf方式。分享下实现方式及遇到的问题。 这里随便找个html课程表作为示例,添加了几张图片为了展示图片转pdf功能。 一:引入jar包 二:导入ftl文件 这块使用的是html语法,将文件后缀名改为ftl即可,在需要参数的地方通过

    2024年02月05日
    浏览(32)
  • Itext生成pdf文件,html转pdf时中文一直显示不出来

    尝试好多种方式,最后可能是跟字体有关系 字体设置为C:/Windows/Fonts/simhei.ttf  黑体,同时html页面上样式要添加 pdf生成方式参考项目:E:myfilesprojectgithubdemo-html2pdf 字体问题参考文章:https://blog.51cto.com/u_15127651/4527950 最后完美解决字体问题!!

    2024年02月20日
    浏览(32)
  • 行业追踪,2023-08-29

    凡所有相,皆是虚妄。若见诸相非相,即见如来。 k 线图是最好的老师,每天持续发布板块的rps排名,追踪板块,板块来开仓,板块去清仓,丢弃自以为是的想法,板块去留让市场来告诉你 跟踪板块总结: 成交额超过 100 亿 排名靠前,macd柱由绿转红 成交量要大于均线 有必

    2024年02月10日
    浏览(22)
  • 2023-08-29力扣每日一题

    链接: 823. 带因子的二叉树 题意: 用给的数字建二叉树,要求父节点是子节点的乘积 解: 乐了 1500ms+30MB //注释版120ms+18MB 实际代码: 限制: 1 = arr.length = 1000 2 = arr[i] = 109 arr 中的所有值 互不相同

    2024年02月11日
    浏览(19)
  • 2023-08-29 LeetCode(带因子的二叉树)

    点击跳转到题目位置 给出一个含有不重复整数元素的数组 arr ,每个整数 arr[i] 均大于 1。 用这些整数来构建二叉树,每个整数可以使用任意次数。其中:每个非叶结点的值应等于它的两个子结点的值的乘积。 满足条件的二叉树一共有多少个?答案可能很大,返回 对 109 + 7

    2024年02月10日
    浏览(72)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包