开发者

基于SpringBoot实现HTML转PDF功能的常用方式

开发者 https://www.devze.com 2025-10-13 10:19 出处:网络 作者: 智_永无止境
目录01 引言02 框架选型2.1 io.woo.htmltopdf2.2 openhtmltopdf2.3 Flying Saucer03 Springboot集成thymeleaf3.1 Maven依赖3.2 页面3.3 数据渲染3.4 渲染效果04 Html转PDF4.1 io.woo.htmltopdf4.2 openhtmltopdf4.3
目录
  • 01 引言
  • 02 框架选型
    • 2.1 io.woo.htmltopdf
    • 2.2 openhtmltopdf
    • 2.3 Flying Saucer
  • 03 Springboot集成thymeleaf
    • 3.1 Maven依赖
    • 3.2 页面
    • 3.3 数据渲染
    • 3.4 渲染效果
  • 04 Html转PDF
    • 4.1 io.woo.htmltopdf
    • 4.2 openhtmltopdf
    • 4.3 Flying Saucer
  • 05 小结

    01 引言

    你是否因为HtmlPDF发愁?又是否因为中文乱码而心烦意乱?又是否因为格式导致PDF排版错乱而苦恼?…

    在企业里,我们经常会遇到下载PDF报告的场景,前端展示还好,可以使用pdf.js类似的框架处理,但是很多时候,需要服务端自己渲染数据然后,上传或者邮件发送。好好的页面,转成PDF直接错乱了,只能一点点的调试,才能完成。过程费时费力。

    这不,前两天正好遇到HtmlPDF的需求,调整了许久的样式才完成PDF的完美转化。

    02 框架选型

    Html转化成PDF的框架有很多,小编也试了好几种,将觉得好用的分享给大家。

    2.1 io.woo.htmltopdf

    Maven

    <dependency>
    	<groupId>io.woo</groupId>
    javascript	<artifactId>htmltopdf</artjavascriptifactId>
    	<version>1.0.4</version>
    </dependency>
    <!-- Thanks for using https://jar-download.com -->
    

    官网地址:https://jar-download.com

    基于SpringBoot实现HTML转PDF功能的常用方式

    github地址:https://github.com/wooio/htmltopdf-Java

    基于SpringBoot实现HTML转PDF功能的常用方式

    2.2 openhtmltopdf

    Maven

    <dependency>
        <groupId>com.openhtmltopdf</groupId>
        <artifactId>openhtmltopdf-core</artifactId>
        <version>1.0.10</version>
    </dependency>
    <dependency>
        <groupId>com.openhtmltopdf</groupId>
        <artifactId>openhtmltopdf-pdfbox</artifactId>
        <version>1.0.10</version>
    </dependency>
    

    基于SpringBoot实现HTML转PDF功能的常用方式

    GitHub地址:https:python//github.com/danfickle/openhtmltopdf

    2.3 Flying Saucer

    Maven

    <dependency>
        <groupId>org.Xhtmlrenderer</groupId>
        <artifactId>flying-saucer-pdf</artifactId>
        <version>10.0.0</version>
    </dependency>
    

    基于SpringBoot实现HTML转PDF功能的常用方式

    GitHub地址:https://github.com/flyingsaucerproject/flyingsaucer

    03 Springboot集成thymeleaf

    3.1 Maven依赖

    这里暂时忽略Hwww.devze.comtmlPDF的依赖,后面按需引入。

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- 模板引擎 -->
    <dependeoZYRYncy>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
    
    <!-- html 2 pdf 工具 -->
    

    3.2 页面

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8" />
        <title>评估报告</title>
    </head>
    <body>
    <div class="total-container">
        <div class="container" th:each="item:${list}">
            <input type="hidden" th:value="${item.licenseCode}" name="licenseCode" />
            <div class="img-container">
                <img th:src="${item.image1}" />
                <img th:src="${item.image2}" />
            </div>
            <div class="title" th:text="${item.vehicleName}"></div>
            <div>
                <ul>
                    <li>
                        <label>品牌:</label>
                        <span th:text="${item.brandName}"></span>
                    </li>
                    <li>
                        <label>车系:</label>
                        <span th:text="${item.seriesName}"></span>
                    </li>
                    <li>
                        <label>年款:</label>
                        <span th:text="${item.modelYear}"></span>
                    </li>
                    <li>
                        <label>上牌年月:</label>
                        <span th:text="${item.licenseYear}"></span>
                    </li>
                    <li>
                        <label>里程(公里):</label>
                        <span th:text="${item.displayMileage}"></span>
                    </li>
                    <li>
                        <label>成交日期:</label>
                        <span th:text="${item.dealDate}"></span>
                    </li>
                    <li>
                        <label>成交价(元):</label>
                        <span th:text="${item.dealPrice}"></span>
                    </li>
                </ul>
            </div>
        </div>
    </div>
    </body>
    </html>
    

    这里描述了车辆的信息

    3.3 数据渲染

    @RequestMapping("index")
    public String index(Model model) {
        List<Map<String, Object>> list = new ArrayList<>();
        for (int i = 0; i < 3; i++) {
            Map<String, Object> item = new HashMap<>();
            item.put("image1", "http://img.example.com/a.jpg");
            item.put("image2", "http://img.example.com/b.jp");
            item.put("vehicleName", "路虎Defender[卫士](进口)2023款Defender130 48V[卫士 130 48V] 3.0T手自-体P400 HSE");
            item.put("brandName", "路虎");
            item.put("seriesName", "Defender[卫士]");
            item.put("modelYear", "2023款");
            item.put("licenseYear", SDF.format(new Date()));
            item.put("displayMileage", DF.format(new BigDecimal("9657")));
            item.put("dealDate", SDF.format(new Date()));
            item.put("dealPrice", DF.format(new BigDecimal("1000000")));
    
            list.add(item);
        }
        model.addAttribute("list", list);
        return "index";
    }
    

    3.4 渲染效果

    基于SpringBoot实现HTML转PDF功能的常用方式

    左右没有留白。

    04 Html转PDF

    上面已经完成Html的渲染和展示。我们只需要拿到Html并通过工具,转化成PDF即可。

    HtmlPDF不需要通过浏览器渲染,需要服务端直接渲染并拿到渲染之后的Html。渲染的代码块:

    Map<String, Object> map = new HashMap<>();
    map.put("list", list);
    
    Context context = new Context(Locale.getDefault(), map);
    String html = templateEngine.process("index", context);
    System.out.println(html);
    

    4.1 io.woo.htmltopdf

    核心方法:

    InputStream convert = HtmlToPdf.create()
                    .object(HtmlToPdfObject.
                            forHtml(htmlContent)
                            .defaultEncoding("utf-8"))
                    .convert();
    
    IOUtils.copyLarge(convert, response.getOutputStream());
    

    效果

    基于SpringBoot实现HTML转PDF功能的常用方式

    我们会发现转成PDF之后,左右会自动留白。现在的问题是,图片需要调整一下,调整到左右留白差不多,这个是难点。

    应该怎么去调整呢?

    因为生成的PDF默认都是基于A4的尺寸:21cm*29.7cm。所以我们直接将宽度设置为21cm

    .container{
        width: 21cm;
        /*设置边框方便查看*/
        box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
    }
    

    转成PDF之后右边距还是有较大的空隙的:

    基于SpringBoot实现HTML转PDF功能的常用方式

    我们继续加大宽度,最终结果:宽度设置23cm比较合适。此时,就可在页面上愉快的调整图片或者其他与元素了。

    4.2 openhtmltopdf

    核心方法

    PdfRendererBuilder builder = new PdfRendererBuilder();
    builder.withHtmlContent(htmlContent, null);
    builder.toStream(response.getOutputStream());
    
    // 配置字体支持中文
    builder.useFont(new File("C:\\Windows\\Fonts\\simhei.ttf"), "SimHei");
    
    builder.run();
    

    基于SpringBoot实现HTML转PDF功能的常用方式

    注意事项

    需要设置支持中的字体,且页面的font-family需要明确指出

    font-family: "SimHei";
    

    页面元素必须要有闭合标签,否则报错

    基于SpringBoot实现HTML转PDF功能的常用方式

    调整

    调整依然是难点。经过测试,该框架的的PDFA4纸的大小基本一致。而内容则是去除留白的长度。

    经过测量:PDF长度794px,两边留白56px,所以页面长度:794-56-56 = 682px

    调正页面长度:

    .container{
        font-family: "SimHei";
        width: 682px;
        box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
    }
    

    效果非常完美:

    基于SpringBoot实现HTML转PDF功能的常用方式

    4.3 Flying Saucer

    核心方法

    ITextRenderer renderer = new ITextRenderer();
    renderer.getFontResolver().addFont("C:\\Windows\\Fonts\\simh	ei.ttf", BaseFont.IDENTITY_H,BaseFont.NOT_EMBEDDED);
    renderer.setDocumentFromString(htmlContent);
    renderer.layout();
    renderer.createPDF(response.getOutputStream());
    

    这里同样要设置支持中文,和openhtmltopdf配置类似。

    调整方式同4.2openhtmltopdf本身就是基于Flying Saucer,所以这里就不在演示,两个同宗同源。

    05 小结

    每一款软件都是其特定标准,调整的顺序也不一样。无论如何,解决问题的思路是一致的。相比较io.woo.htmltopdf可能更加方便,本身就支持中文,而其他两个则需要单独配置才能支持中文。你们更喜欢哪一种呢?

    以上就是基于SpringBoot实现HTML转PDF功能的常用方式的详细内容,更多关于SpringBoot实现HTML转PDF的资料请关注编程客栈(www.devze.com)其它相关文章!

    0

    精彩评论

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

    关注公众号