我正在评估Thymeleaf和Flying Saucer从模板生成PDF,我有一个问题,应用css到我的Thymeleaf模板。我已经阅读了相关的问题和答案here,here和here;但是没有一个建议的解决方案解决了我的问题。
这是我的资源文件夹的样子:
所以我使用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
?
6条答案
按热度按时间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
,这是没有意义的.为了使用静态资源,我必须传递它的绝对路径.我开始用途:
它工作得很好,但如果有多个主机名或服务器在代理上运行,那么这将是一个硬编码的解决方案。最好知道用户请求的真实的的基本URL是什么。所以我们不能真正摆脱HttpSevletRequest。
下面是我的代码:
1.配置资源处理程序:
1.从HttpServletRequest中获取基url,你可以将其注入到方法中或在你的服务类中自动连接,或者从RequestContextHolder中获取。我在我的Service类中写了这个:
1.这是我在课堂上使用模板引擎的地方:
1.在我的模板中,我使用绝对的css url如下:
fv2wmkja2#
语法看起来很好,所以问题不在于语法。
此外,如果没有
IWebContext
接口,则无法使用@{...}
语法,因此出现此异常。snvhrwxg3#
我也有类似的问题-我的css没有应用到我的模板页面。
我的问题是,CSS文件是在CSSSASS格式
当我把它转换成普通的css格式时
成功了
jw5wzhpr4#
我通过改变href中的路径结构解决了这个问题。我和你有相同的目录结构(html文件在模板文档中,css文件在静态文档中)。
它可以帮助你将css应用到你的html页面。
xriantvc5#
我发现了一个懒人的方法来处理这个问题。它很有效,方法很简单。“inserted”片段只是一个简单HTML文档主体中的CSS样式标签。我把它放在目标文件的HEAD中,就在我放LINK REL标签的地方:
iecba09b6#
对于那些为此而挣扎的人,如果你正在使用Spring Security依赖项,请确保像这样向你的文件夹给予请求:
然后把你的CSS文件放在static/css文件夹下。
然后将CSS链接添加到HTML文件中,如下所示:
希望这对某人有帮助!