JAVA 生成PDF (thymeleaf,html,itext,pdf)

工作中通常 有java 生成 PDF 的需求,本篇博客为java开发者提供参考方案

主要通过 html + thymeleaf(或其他模板引擎都可) + itextpdf 的方式 生成pdf

HTML 只能是纯html + css,能够支持svg标签,不支持js

前置条件 : 会写html(不会就让前端给) + 能够使用thymeleaf(或者使用其他模板,比较简单)+pdf中文支持插件 simsun.ttf 

POM 依赖

      <!-- https://mvnrepository.com/artifact/com.itextpdf/html2pdf -->
      <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>html2pdf</artifactId>
            <version>4.0.4</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>ognl</groupId>
            <artifactId>ognl</artifactId>
            <version>${ognl.version}</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.jsoup/jsoup -->
        <dependency>
            <groupId>org.jsoup</groupId>
            <artifactId>jsoup</artifactId>
            <version>1.15.1</version>
        </dependency>

pdf生成流程 : 读取 thymeleaf+html 的模板  -> thymeleaf 解析html模板为String - > html2pdf 转换html为pdf

代码实现

package com.jianan.qns.ams.batch.utils;

import com.jianan.tms.common.exception.ServiceException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;

import java.io.*;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * jzc
 */
@Slf4j
public class ThymeleafUtil {

    public static TemplateEngine templateEngine = new TemplateEngine();

    /**
     * 获取一份html 字符串
     * 其他模板生成html(jsp, FreeMarker..) 或者 html不需要额外处理,可以自行实现
     * @param absolutePath  resources下html的相对路径 eg: /template/index.html
     * @param params        html模板中需要的参数 具体请见 spring thymeleaf 文档
     * Map<String, Object> params = new HashMap();
     * params.put("batchNo","PC202212083894");
     * <td colspan="6" th:text="${batchNo}">PC202212083894</td>
     *                       
     * @return
     */
    public static String getHtmlString(String absolutePath, Map<String, Object> params) {
        try {
            InputStream fileInputSteam = ThymeleafUtil.class.getResourceAsStream(absolutePath);
            log.info("开始是读取html文件");
            Context context = new Context();
            context.setVariables(params);
            return templateEngine.process(getFileString(fileInputSteam), context);
        } catch (Exception e) {
            log.error("html文件生成失败:cause--->" + e.getMessage());
            throw new RuntimeException("html模板读取失败");
        }
    }

    public static String getFileString(InputStream fileInputSteam) {

        try {
            return IOUtils.toString(fileInputSteam, "UTF-8");
        } catch (IOException e) {
            log.error("读取stream 字符失败 {}",e);
            throw new ServiceException("读取stream 字符失败");
        }
    }

}
/**
 * jzc
 */
@Slf4j
public class ITextHtmlPdfUtil {

    /**
     * 分析报告的html
     */
    public static final String ANALYSE_HTML = "/template/index.html";

    /**
     * 中文支持插件在resource下的位置
     */
    public static final String FONT = "/template/simsun.ttf";

    /**
     * PDF扩展名
     */
    public static final String PDF_EXTENSION = ".pdf";

    public static final String ANALYSE_REPORT = "前缀";

    /**
     * pdf html 的路径
     */
    public static final String TEMPLATE_PATH = "/template";

    public static byte[] createPdf(String htmlString) throws IOException {

        PageSize pageSize = new PageSize(1200, 2000);

        return createPdf(TEMPLATE_PATH, htmlString, pageSize);
    }

    // html 转 pdf 并返回字节数组
    public static byte[] createPdf(String resourceTemplateUri, String html, PageSize pageSize) throws IOException {
        //设置pdf的尺寸
        ByteArrayOutputStream outputStream = null;
        InputStream fontInputStream = null;
        try {
            outputStream = new ByteArrayOutputStream();
            PdfWriter writer = new PdfWriter(outputStream);
            PdfDocument pdf = new PdfDocument(writer);
            pdf.setTagged();
            pdf.setDefaultPageSize(pageSize);

            ConverterProperties properties = new ConverterProperties();
            //pdf宽高
            properties.setBaseUri(resourceTemplateUri);
            MediaDeviceDescription mediaDeviceDescription = new MediaDeviceDescription(MediaType.SCREEN);
            mediaDeviceDescription.setWidth(pageSize.getWidth());
            properties.setMediaDeviceDescription(mediaDeviceDescription);
            //中文支持
            FontProvider fontProvider = new DefaultFontProvider();
            fontInputStream = ITextHtmlPdfUtil.class.getResourceAsStream(FONT);
            FontProgram fontProgram = FontProgramFactory.createFont(IOUtils.toByteArray(fontInputStream));

            fontProvider.addFont(fontProgram);
            properties.setFontProvider(fontProvider);

            InputStream inputStreamRoute = new ByteArrayInputStream(html.getBytes());
            HtmlConverter.convertToPdf(inputStreamRoute, pdf, properties);

            return outputStream.toByteArray();
        } finally {
            IOUtils.closeQuietly(outputStream);
            IOUtils.closeQuietly(fontInputStream);
        }
    }
}
    public static void main(String[] args) throws IOException {
        Map<String, Object> params = new HashMap();
        params.put("batchNo", "PC202212083894");

        String html = ThymeleafUtil.getHtmlString("/template/index.html", params);

        byte[] bytes = createPdf(html);
       
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("/Users/xxx/Desktop/123.pdf"));
        bos.write(bytes);
        bos.close();
        log.info("生成pdf 结束");
    }

效果图

simsun.ttf 插件:  中文支持插件下载  (我自己的链接,失效了请百度下载,只支持linux服务器,windows需要自行解决)

  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值