J'essaie de générer un pdf contenant des caractères chinois UTF-8 via la soucoupe volante et la feuille de thym. Mais le pdf généré ignore tous les caractères chinois (les caractères latins sont acceptés). Voici la configuration de Thymeleaf
@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;
}
}
Comme vous pouvez le voir, j'ai défini le codage des caractères à UTF-8 pour le résolveur de modèles et le résolveur de vues.
Et l'utilitaire PDF pour générer des 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;
}
}
Ici, j'ai ajouté la police chinoise au résolveur.
Et voici l'en-tête html du modèle
<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/bootstrap@5.1.3/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/bootstrap@5.1.3/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>
J'ai donc essayé de déclarer que le jeu de caractères est UTF-8 et que la famille de polices est PingFang SC Regular. Mais sans surprise, cela ne fonctionne pas.
Voici la dépendance maven que j'ai ajoutée à mon projet springboot
<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>
Le corps html que je veux rendre
<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>
Quelqu'un peut-il comprendre pourquoi le caractère UTF-8 n'apparaît pas dans le pdf généré ? Toute idée serait appréciée.