UTF-8字符未在HTML模板中通过飞碟和胸腺产生的PDF中显示
我正在尝试通过飞碟和百里香eaf产生PDF包含中国UTF-8字符。但是生成的PDF只是忽略了所有汉字(拉丁文很好)。 这是百里叶配置
@Configuration
public class ThymeleafConfig {
@Bean
public ClassLoaderTemplateResolver fileTemplateResolver(){
ClassLoaderTemplateResolver fileTemplateResolver = new ClassLoaderTemplateResolver();
fileTemplateResolver.setPrefix("templates/");
fileTemplateResolver.setTemplateMode("HTML");
fileTemplateResolver.setSuffix(".html");
fileTemplateResolver.setCharacterEncoding("UTF-8");
fileTemplateResolver.setOrder(1);
return fileTemplateResolver;
}
@Bean
public SpringTemplateEngine templateEngine(){
SpringTemplateEngine springTemplateEngine = new SpringTemplateEngine();
springTemplateEngine.setEnableSpringELCompiler(true);
springTemplateEngine.setTemplateResolver(fileTemplateResolver());
return springTemplateEngine;
}
@Bean
public ThymeleafViewResolver thymeleafViewResolver() {
ThymeleafViewResolver resolver = new ThymeleafViewResolver();
resolver.setTemplateEngine(templateEngine());
resolver.setCharacterEncoding("UTF-8");
return resolver;
}
}
如您所见,
,我将字符编码设置为模板解析器和视图解析器的UTF-8。以及用于生成PDF的PDF up,
public class PDFUtil {
@Autowired
private TemplateEngine templateEngine;
public String createPdf(String templatename, String fileName, String modelName, Object model) throws IOException, DocumentException {
String fileNameUrl = "";
Context ctx = new Context();
ctx.setVariable(modelName, model);
String processedHtml = templateEngine.process(templatename, ctx);
FileOutputStream outputStream = null;
try {
final File outputFile = File.createTempFile(fileName, ".pdf");
outputStream = new FileOutputStream(outputFile);
ITextRenderer renderer = new ITextRenderer();
ITextFontResolver resolver = renderer.getFontResolver();
final ClassPathResource fonts = new ClassPathResource("fonts/PingFangSCRegular.ttf");
String test = fonts.getFilename();
resolver.addFont(fonts.getPath(), BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
renderer.setDocumentFromString(processedHtml);
renderer.layout();
renderer.createPDF(outputStream, false);
renderer.finishPDF();
FileSystemResource resource = new FileSystemResource(outputFile);
fileNameUrl = resource.getURL().toString();
}
finally {
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) { }
}
}
return fileNameUrl;
}
}
在这里,我添加了中国字体。
这是模板html头
<head th:fragment="html_head">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Title</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://unpkg.com/jsbarcode@latest/dist/JsBarcode.all.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/fontawesome.min.css" />
<style type="text/css">
@font-face {
font-family: 'PingFang SC Regular';
src: url('/fonts/PingFangSCRegular.ttf');
-fs-pdf-font-embed: embed;
-fs-pdf-font-encoding: Identity-H;
}
</style>
</head>
,所以我试图宣布charset是UTF-8,字体家族是Pingfang SC常规的。但是毫不奇怪,这行不通。
这是我添加到Springboot项目的Maven依赖性
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.xhtmlrenderer</groupId>
<artifactId>flying-saucer-pdf</artifactId>
<version>9.1.22</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.13.3</version>
</dependency>
<dependency>
<groupId>com.itextpdf.tool</groupId>
<artifactId>xmlworker</artifactId>
<version>5.5.13.3</version>
</dependency>
我想要渲染的HTML身体
<body>
<div th:fragment="header(model)">
<div class="row">
<div class="col-4">
<img id="barcode" alt="111"/>
</div>
<div class="col-4">
<h3>啊啊啊啊啊啊aaa[[${model.title}]]</h3>
<p id="print-time">[[${model.printTime}]]</p>
</div>
</div>
</div>
</body>
任何人都可以弄清楚为什么UTF-8字符在生成的PDF中不显示?任何想法都会很感激。
I'm trying to generate a pdf contains Chinese UTF-8 characters via flying saucer and thymeleaf. But the generated pdf just ignore all the Chinese characters (latin is fine). Here is the Thymeleaf configuration
@Configuration
public class ThymeleafConfig {
@Bean
public ClassLoaderTemplateResolver fileTemplateResolver(){
ClassLoaderTemplateResolver fileTemplateResolver = new ClassLoaderTemplateResolver();
fileTemplateResolver.setPrefix("templates/");
fileTemplateResolver.setTemplateMode("HTML");
fileTemplateResolver.setSuffix(".html");
fileTemplateResolver.setCharacterEncoding("UTF-8");
fileTemplateResolver.setOrder(1);
return fileTemplateResolver;
}
@Bean
public SpringTemplateEngine templateEngine(){
SpringTemplateEngine springTemplateEngine = new SpringTemplateEngine();
springTemplateEngine.setEnableSpringELCompiler(true);
springTemplateEngine.setTemplateResolver(fileTemplateResolver());
return springTemplateEngine;
}
@Bean
public ThymeleafViewResolver thymeleafViewResolver() {
ThymeleafViewResolver resolver = new ThymeleafViewResolver();
resolver.setTemplateEngine(templateEngine());
resolver.setCharacterEncoding("UTF-8");
return resolver;
}
}
As you can see, I've set the character encoding to UTF-8 for both template resolver and view resolver.
And the PDF Util for generating pdfs
public class PDFUtil {
@Autowired
private TemplateEngine templateEngine;
public String createPdf(String templatename, String fileName, String modelName, Object model) throws IOException, DocumentException {
String fileNameUrl = "";
Context ctx = new Context();
ctx.setVariable(modelName, model);
String processedHtml = templateEngine.process(templatename, ctx);
FileOutputStream outputStream = null;
try {
final File outputFile = File.createTempFile(fileName, ".pdf");
outputStream = new FileOutputStream(outputFile);
ITextRenderer renderer = new ITextRenderer();
ITextFontResolver resolver = renderer.getFontResolver();
final ClassPathResource fonts = new ClassPathResource("fonts/PingFangSCRegular.ttf");
String test = fonts.getFilename();
resolver.addFont(fonts.getPath(), BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
renderer.setDocumentFromString(processedHtml);
renderer.layout();
renderer.createPDF(outputStream, false);
renderer.finishPDF();
FileSystemResource resource = new FileSystemResource(outputFile);
fileNameUrl = resource.getURL().toString();
}
finally {
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) { }
}
}
return fileNameUrl;
}
}
Here I've added the Chinese font to the resolver.
And this is the template html head
<head th:fragment="html_head">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Title</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://unpkg.com/jsbarcode@latest/dist/JsBarcode.all.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/fontawesome.min.css" />
<style type="text/css">
@font-face {
font-family: 'PingFang SC Regular';
src: url('/fonts/PingFangSCRegular.ttf');
-fs-pdf-font-embed: embed;
-fs-pdf-font-encoding: Identity-H;
}
</style>
</head>
So I tried to declare that the charset is UTF-8 and the font family is PingFang SC Regular. But no surprise that does not work.
Here is the maven dependency I've added to my springboot project
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.xhtmlrenderer</groupId>
<artifactId>flying-saucer-pdf</artifactId>
<version>9.1.22</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.13.3</version>
</dependency>
<dependency>
<groupId>com.itextpdf.tool</groupId>
<artifactId>xmlworker</artifactId>
<version>5.5.13.3</version>
</dependency>
The html body I want to render
<body>
<div th:fragment="header(model)">
<div class="row">
<div class="col-4">
<img id="barcode" alt="111"/>
</div>
<div class="col-4">
<h3>啊啊啊啊啊啊aaa[[${model.title}]]</h3>
<p id="print-time">[[${model.printTime}]]</p>
</div>
</div>
</div>
</body>
Can anyone figure out why the UTF-8 character does not show in the generated pdf? Any idea would be appreciate.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在模板中,您可以声明字体面,但不会将其应用于页面内容。
您只需要声明应该使用字体:
另外,您无需在模板中使用
@font-face
,因为您已将字体添加到渲染器中(使用resolver.addfont
)。以下HTML应该很好:
In your template, you declare the font-face, but you don't apply it to the content of the page.
You just have to declare that the font should be used:
Also, you don't need to use
@font-face
in the template, as you have added the font to the renderer (usingresolver.addFont
).The following HTML should work fine: