Java html转pdf 且解决中文不显示问题

记录一下利用freemarker 将html转换pdf的教程

pom.xml引入包

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<!-- https://mvnrepository.com/artifact/com.itextpdf/itextpdf -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.11</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.itextpdf.tool/xmlworker -->
<dependency>
<groupId>com.itextpdf.tool</groupId>
<artifactId>xmlworker</artifactId>
<version>5.5.11</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.xhtmlrenderer/flying-saucer-pdf -->
<dependency>
<groupId>org.xhtmlrenderer</groupId>
<artifactId>flying-saucer-pdf</artifactId>
<version>9.1.5</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.xhtmlrenderer/flying-saucer-pdf-itext5 -->
<dependency>
<groupId>org.xhtmlrenderer</groupId>
<artifactId>flying-saucer-pdf-itext5</artifactId>
<version>9.1.5</version>
</dependency>


<!-- 解决中文字体问题 -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.freemarker/freemarker -->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.19</version>
</dependency>

点击并拖拽以移动

解决中文不显示问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package com.express.excms.enroll.config;

import com.itextpdf.text.Font;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.tool.xml.XMLWorkerFontProvider;

/**
* Created by IntelliJ IDEA.
* User: 贝先 [ Cason mo ]
* Date: 2021/11/12
* Time: 14:46
*/
public class AsianFontProvider extends XMLWorkerFontProvider {
@Override
public Font getFont(String fontname, String encoding, float size, final int style) {
try {
BaseFont bfChinese =BaseFont.createFont( "STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);
return new Font(bfChinese, size, style);
} catch (Exception e) {
e.printStackTrace();
}
return super.getFont(fontname, encoding, size, style);
}
}

点击并拖拽以移动

html转pdf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
package com.express.excms.enroll.utils;

import com.express.excms.enroll.config.AsianFontProvider;
import com.itextpdf.text.Document;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.tool.xml.XMLWorkerHelper;
import lombok.extern.slf4j.Slf4j;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.nio.charset.StandardCharsets;

/**
* Created by IntelliJ IDEA.
* User: 贝先 [ Cason mo ]
* Date: 2021/10/18
* Time: 10:54
*/
@Slf4j
public class PDFUtils {
/**
* ByteArrayOutputStream pdf文件流
* @param htmlContent 通过freemarker生成的html
* @return
* @throws Exception
*/
public static ByteArrayOutputStream htmlToPdf(String htmlContent) throws Exception {
ByteArrayOutputStream output = new ByteArrayOutputStream();
Document document = new Document();
PdfWriter pdfWriter = PdfWriter.getInstance(document, output);
document.open();
XMLWorkerHelper.getInstance().parseXHtml(pdfWriter,document,new ByteArrayInputStream(htmlContent.getBytes(StandardCharsets.UTF_8)),null, StandardCharsets.UTF_8,new AsianFontProvider());
document.close();
return output;
}

/**
* 写入到文件
* @param htmlContent 通过freemarker生成的html
* @param filePath 要写入的pdf文件地址
* @throws Exception
*/
public static void htmlToPdf(String htmlContent,String filePath) throws Exception {
Document document = new Document();
PdfWriter pdfWriter = PdfWriter.getInstance(document, new FileOutputStream(filePath));
document.open();
XMLWorkerHelper.getInstance().parseXHtml(pdfWriter,document,new ByteArrayInputStream(htmlContent.getBytes(StandardCharsets.UTF_8)),null, StandardCharsets.UTF_8,new AsianFontProvider());
document.close();
}
}

点击并拖拽以移动

freemarker 解析并获取生成的html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
        @Autowired
private Configuration configuration;


......省略



Configuration cfg = (Configuration) configuration.clone();
cfg.clearTemplateCache();
Template t = new Template(templateInDB.getName(), new StringReader(未渲染的html), configuration);
String html = FreeMarkerTemplateUtils.processTemplateIntoString(t, 要渲染的数据);
try {
ByteArrayOutputStream byteArrayOutputStream = PDFUtils.htmlToPdf(html);
//获取pdf的base64
byte[] bytes = byteArrayOutputStream.toByteArray();

} catch (Exception e) {
e.printStackTrace();
return ResponseResult.defaultFailed(e.getMessage());
}

点击并拖拽以移动

效果图

img点击并拖拽以移动编辑


Java html转pdf 且解决中文不显示问题
https://cason.work/2023/04/10/Java-html转pdf-且解决中文不显示问题/
作者
Cason Mo
发布于
2023年4月10日
许可协议