Spring Boot Sping Boot + Thymeleaf css未应用于模板

vfhzx4xs  于 2023-04-11  发布在  Spring
关注(0)|答案(6)|浏览(207)

我正在评估Thymeleaf和Flying Saucer从模板生成PDF,我有一个问题,应用css到我的Thymeleaf模板。我已经阅读了相关的问题和答案hereherehere;但是没有一个建议的解决方案解决了我的问题。
这是我的资源文件夹的样子:

所以我使用Spring将查找的默认目录。这就是我的template.html中head标签的样子:

<head>
    <title>Spring Boot and Thymeleaf Example</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
    <link rel="stylesheet" type="text/css" href="../static/css/style.css" th:href="@{/css/style.css}"/> 
</head>

如果我在template.html中内联我的css,那么生成的pdf文件将被正确地样式化(所以我如何生成pdf不应该有问题)。然而,当我试图链接到上面显示的css文件时,生成的pdf没有样式化(所以css没有应用)。
最后,我可以在http://localhost:8080/css/style.css访问我的css文件,所以Spring提供静态内容似乎没有问题。
为了完整起见,我是这样生成PDF的:

private final SpringTemplateEngine templateEngine;
private final Log log;

@Autowired
public PdfGenerator(SpringTemplateEngine templateEngine) {
    this.templateEngine = templateEngine;
    log = LogFactory.getLog(getClass());
}

public void generate(HttpServletRequest servletRequest, HttpServletResponse servletResponse, ServletContext servletContext) {
    // Parse the pdf template with Thymeleaf
    Locale locale = getLocale(servletRequest);
    WebContext context = new WebContext(servletRequest, servletResponse, servletContext, locale);
    context.setVariable("user", buildDummyUser());
    context.setVariable("discounts", buildDummyDiscounts());
    String html = templateEngine.process("template", context);

    // Create the pdf with Flying Saucer
    try (OutputStream outputStream = new FileOutputStream("generated.pdf")) {
        ITextRenderer renderer = new ITextRenderer();
        renderer.setDocumentFromString(html);
        renderer.layout();
        renderer.createPDF(outputStream);
    } catch (IOException | DocumentException e) {
        log.error("Error while generating pdf", e);
    }
}

我使用WebContext而不是Context,因为我在使用Context时遇到以下错误:

org.thymeleaf.exceptions.TemplateProcessingException: Link base "/css/style.css" cannot be context relative (/...) unless the context used for executing the engine implements the org.thymeleaf.context.IWebContext interface

我在这里遗漏了什么,为什么我的style.css没有应用到template.html

eoigrqb6

eoigrqb61#

我也遇到了同样的问题,我也试图使用thymeleaf模板解析器来生成PDF。我对thymeleaf和spring框架做了很多研究,我尝试了WebContext,我尝试了HttpServletRequest,我尝试了一些Spring Thymeleaf集成解决方案,它也不起作用。所以我认为这不是语法错误,我最终使用了绝对路径而不是相对路径。Url for reference
这里的原因与我的假设,让我们假设我们的资源是在localhost:8080/myapp/css/style.css上提供的。请求资源的相对路径实际上取决于它所涉及的上下文。例如,一个正常的thymeleaf模型Veiw,它在客户端的浏览器上返回为html页面,因此在这种情况下,上下文将是请求主机名,端口和应用程序上下文(例如:localhost:8080/myapp)。相对路径将基于此。因此,如果相对路径是/css/style. css,则上下文+相对路径将导致localhost:8080/myapp/css/style.css
与web上下文不同,在我们的例子中,离线模板位于服务器后端,因此我假设上下文是服务器运行上下文,这将是本地服务器路径+ appcontext(例如:D:/myServer/apps/myapp),相对路径/css/style. css在这将是D:/myServer/apps/myapp/css/style.css,这是没有意义的.为了使用静态资源,我必须传递它的绝对路径.
我开始用途:

<link rel="stylesheet" type="text/css" th:href="@{http://localhost:8080/myapp/css/style.css}"/>

它工作得很好,但如果有多个主机名或服务器在代理上运行,那么这将是一个硬编码的解决方案。最好知道用户请求的真实的的基本URL是什么。所以我们不能真正摆脱HttpSevletRequest。
下面是我的代码:
1.配置资源处理程序:

@Override
public void addResourceHandlers(final ResourceHandlerRegistry registry) {
    registry.addResourceHandler("/css/**")
    .addResourceLocations("classpath:/css/")
            .setCachePeriod(31556926);
}

1.从HttpServletRequest中获取基url,你可以将其注入到方法中或在你的服务类中自动连接,或者从RequestContextHolder中获取。我在我的Service类中写了这个:

private static String getCurrentBaseUrl() {
ServletRequestAttributes sra = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
HttpServletRequest req = sra.getRequest();
return req.getScheme() + "://" + req.getServerName() + ":" + req.getServerPort() + req.getContextPath();
}

1.这是我在课堂上使用模板引擎的地方:

Context context = new Context();
    context.setVariable("variales", variables);
    context.setVariable("baseUrl", getCurrentBaseUrl());
    String content = springTemplateEngine.process("myTemplate",context);

1.在我的模板中,我使用绝对的css url如下:

<link type="stylesheet" th:src="@{|${baseUrl}/css/style.css|}" />
fv2wmkja

fv2wmkja2#

语法看起来很好,所以问题不在于语法。
此外,如果没有IWebContext接口,则无法使用@{...}语法,因此出现此异常。

snvhrwxg

snvhrwxg3#

我也有类似的问题-我的css没有应用到我的模板页面。
我的问题是,CSS文件是在CSSSASS格式

.table
   margin: 0 0 40px 0

当我把它转换成普通的css格式时

.table {
  margin: 0 0 40px 0;
  }

成功了

jw5wzhpr

jw5wzhpr4#

我通过改变href中的路径结构解决了这个问题。我和你有相同的目录结构(html文件在模板文档中,css文件在静态文档中)。

<head>
    <title>Spring Boot and Thymeleaf Example</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
    <link rel="stylesheet" type="text/css" href="/css/style.css"/> 
</head>

它可以帮助你将css应用到你的html页面。

xriantvc

xriantvc5#

我发现了一个懒人的方法来处理这个问题。它很有效,方法很简单。“inserted”片段只是一个简单HTML文档主体中的CSS样式标签。我把它放在目标文件的HEAD中,就在我放LINK REL标签的地方:

<th:block th:insert="std-reports/std-reports-css-fragment.html :: style"></th:block>
iecba09b

iecba09b6#

对于那些为此而挣扎的人,如果你正在使用Spring Security依赖项,请确保像这样向你的文件夹给予请求:

然后把你的CSS文件放在static/css文件夹下。
然后将CSS链接添加到HTML文件中,如下所示:

<link rel="stylesheet" th:href="@{/css/index.css}">

希望这对某人有帮助!

相关问题