工作中通常 有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需要自行解决)
版权声明:本文为kaomianjin原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。