CSS var() 函数在 Thymeleaf 模板转 PDF 中不起作用

问题描述 投票:0回答:1

我目前正在尝试创建 PDF 格式的报告,并正在尝试使用 Thymeleaf 创建 HTML 模板,然后尝试使用 Flyingsaucer 将其转换为 PDF。它工作得相当好,除了由于某种原因,我可以声明我喜欢的所有 CSS 变量,在使用 CSS

var()
函数时,样式表实际上不会使用存储在变量中的颜色。举个小例子:

pom.xml

<dependency>
  <groupId>org.thymeleaf</groupId>
  <artifactId>thymeleaf</artifactId>
  <version>3.1.1.RELEASE</version>
</dependency>
<dependency>
  <groupId>org.xhtmlrenderer</groupId>
  <artifactId>flying-saucer-pdf</artifactId>
  <version>9.1.22</version>
</dependency>

模板.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8" />
    <link th:href="@{/css/report.css}" rel="stylesheet" />
</head>
<body>
    <div class="document-titles">
        <h1 class="document-title">Baking report</h1><br />
        <h2 class="document-date">September 2023</h2><br />
        <h3 class="document-project-name">Project name: cake</h3>
    </div>

    <h1>Test h1</h1>
    <h1>Test h1b (should be on next page (and it is!))</h1>
    <ul>
        <li>A</li>
        <li>B</li>
    </ul>
    <ol>
        <li>Cake</li>
        <li>Pie</li>
    </ol>
    <table>
        <tr>
            <th>Name</th>
            <th>Amount</th>
            <th>Price</th>
        </tr>
        <tr>
            <td>Eggs</td>
            <td>4</td>
            <td>€4</td>
        </tr>
        <tr>
            <td>Flour</td>
            <td>300 gr</td>
            <td>€1</td>
        </tr>
    </table>
</body>
</html>

报告.css

:root {
    /* Colors */
    --blue: #00a8dc;
    --grey: #9badbf;
    --text-black: #212529;
    --white: #fff;
}

@page {
    size: a4;
    orientation: portrait;
}

@page:first {
    margin: 0;
    background-image: url("../images/report-cover.jpg");
    background-size: cover;
}

h1 {
    page-break-before: always;
    color: var(--blue); /* THIS IS COMPLETELY IGNORED; H1 REMAINS DEFAULT BLACK */
}

h1.document-title, h2.document-date, h3.document-project-name {
    page-break-before: avoid;
    margin: 0;
    padding: 0;
}

PdfProofOfConcept.java

package com.acme.reports;

import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;
import org.thymeleaf.context.IExpressionContext;
import org.thymeleaf.linkbuilder.StandardLinkBuilder;
import org.thymeleaf.templatemode.TemplateMode;
import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver;
import org.xhtmlrenderer.pdf.ITextRenderer;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Map;

public class PdfProofOfConcept {

    // https://www.baeldung.com/thymeleaf-generate-pdf
    public static void main(String... args) throws IOException {
        String template = parseThymeleafTemplate();
        generatePdfFromHtml(template);
    }

    private static void generatePdfFromHtml(String html) throws IOException {
        String outputFolder = System.getProperty("user.home") + File.separator + "thymeleaf_report.pdf";
        OutputStream outputStream = new FileOutputStream(outputFolder);

        ITextRenderer renderer = new ITextRenderer();
        renderer.setDocumentFromString(html);
        renderer.layout();
        renderer.createPDF(outputStream);

        outputStream.close();
    }

    private static String parseThymeleafTemplate() {
        ClassLoaderTemplateResolver htmlTemplateResolver = new ClassLoaderTemplateResolver();
        htmlTemplateResolver.setSuffix(".html");
        htmlTemplateResolver.setTemplateMode(TemplateMode.HTML);

        TemplateEngine templateEngine = new TemplateEngine();
        templateEngine.setTemplateResolver(htmlTemplateResolver);
        templateEngine.setLinkBuilder(new CustomLinkBuilder());

        Context context = new Context();
        context.setVariable("secretIngredient", "Chocolate chips");

        return templateEngine.process("templates/report/thymeleaf_report", context);
    }

}

// Needed for using relative links in an offline setting (e.g. without a webserver)
// https://stackoverflow.com/a/74511450
class CustomLinkBuilder extends StandardLinkBuilder {
    @Override
    protected String computeContextPath(IExpressionContext context, String base, Map<String, Object> parameters) {
        return "./src/main/resources/static";
    }
}

正如代码的最后一段所示,我遇到了一个问题,在 HTML 中加载样式表不起作用,因为 Thymeleaf 期望它从

HttpServletRequest
提供服务,而在我的情况下没有运行网络服务器,因此引用了资源和使用(例如样式表、javascript 和图像)需要构建自定义链接,因为它不是由网络服务器提供的。 (因此是
CustomLinkBuilder
。)我想 css
var()
函数可能会发生类似的事情,通常必要的 CSS 预处理发生在浏览器或服务器上。我是否正确?如果是,我如何构建自己的预处理器? (至少对于
var()
函数。)或者是否有其他解释解释为什么原生 CSS 函数不能与 Thymeleaf 一起使用?

java css thymeleaf
1个回答
0
投票

PDF 转换设置:检查用于将 Thymeleaf 模板转换为 PDF 的工具或库的设置和选项。某些 PDF 转换库可能具有与 CSS 处理相关的特定配置选项。确保 CSS 处理已启用并正确配置。

后备值:如果 PDF 渲染引擎不支持 CSS 变量,您可能需要直接在 CSS 规则中为使用变量的属性提供后备值。这样,即使不支持该变量,PDF 仍将以指定的样式呈现。

/* Fallback value in case the variable is not supported */
element {
  property: var(--my-variable, #ff0000);
}
© www.soinside.com 2019 - 2024. All rights reserved.