根据ftl模板转换pdf下载
今天使用ftl模板填充数据,并用itextpdf将填充好的html转换为pdf供前端下载,遇到一个非常恶心的问题,弄了一天,记录一下。
就是中文在html中能正常显示但转为pdf后无法显示。网上各种教程加各种AI都没有给我一个正确的答案,最终我试了一天总算写了一个demo。
首先我的itextpdf是5.5.13.3版本的
网上说解决中文不显示需要添加字体依赖(但是我没有成功)
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
然后还可以使用本地字体依赖文件,在windows下的fonts中找,于是我添加了simhei.ttf字体文件
AI等给了一堆方式将html转pdf但是小心他根本没有引入对应的字体
最终我写了一个静态方法
public static byte[] convertHtmlToPdf(String htmlContent) throws DocumentException, IOException { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); Document document = new Document(); PdfWriter writer = PdfWriter.getInstance(document, outputStream); document.open(); String fontPath = "/fonts/simhei.ttf"; // 解决PDF中文不显示 XMLWorkerFontProvider provider = new XMLWorkerFontProvider(XMLWorkerFontProvider.DONTLOOKFORFONTS); provider.register(fontPath);//注册字体 // 解析HTML并应用字体 XMLWorkerHelper.getInstance().parseXHtml( writer, document, new ByteArrayInputStream(htmlContent.getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8, provider ); document.close(); return outputStream.toByteArray(); }
还有一个顶级的坑:你的ftl模板必须指定字体,否则itextpdf还是不能识别中文
<!DOCTYPE html>
<html>
<head>
<title>${title}</title>
<style>
body {
font-family: "SimHei", "WenQuanYi Micro Hei", "Heiti TC", sans-serif;
}
table { width: 100%; border-collapse: collapse; }
th, td { border: 1px solid #ddd; padding: 8px; }
th { background-color: #f2f2f2; }
</style>
</head>
<body>
<h1>${title}</h1>
<table>
<tr>
<th>ID</th>
<th>姓名</th>
<th>邮箱</th>
</tr>
<#list users.users as user>
<tr>
<td>${user.id}</td>
<td>${user.name}</td>
<td>${user.email}</td>
</tr>
</#list>
</table>
<p>生成时间: ${.now?string("yyyy-MM-dd HH:mm:ss")}</p>
</body>
</html>
标黄的都是解决中文不显示的关键!!!
最后附上字体文件 simhei.ttf 放在resources下(已压缩):下载文件
还有添加字体还需要一个依赖
<dependency>
<groupId>com.itextpdf.tool</groupId>
<artifactId>xmlworker</artifactId>
<version>5.5.13.3</version>
</dependency>

浙公网安备 33010602011771号