UTF-8字符未在HTML模板中通过飞碟和胸腺产生的PDF中显示

发布于 2025-02-11 17:03:05 字数 6068 浏览 2 评论 0原文

我正在尝试通过飞碟和百里香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>

And the rendered result
enter image description here

Can anyone figure out why the UTF-8 character does not show in the generated pdf? Any idea would be appreciate.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

写给空气的情书 2025-02-18 17:03:05

在模板中,您可以声明字体面,但不会将其应用于页面内容。

您只需要声明应该使用字体:

body {font-family: 'PingFang SC Regular';}

另外,您无需在模板中使用@font-face,因为您已将字体添加到渲染器中(使用resolver.addfont)。

以下HTML应该很好:

<html>
    <head>
        <style>
            body {font-family: 'PingFang SC Regular';}
        </style>
    </head>
    <body>
        <h3>啊啊啊啊啊啊</h3>
    </body>
</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:

body {font-family: 'PingFang SC Regular';}

Also, you don't need to use @font-face in the template, as you have added the font to the renderer (using resolver.addFont).

The following HTML should work fine:

<html>
    <head>
        <style>
            body {font-family: 'PingFang SC Regular';}
        </style>
    </head>
    <body>
        <h3>啊啊啊啊啊啊</h3>
    </body>
</html>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文