Currently, I am exploring the use of Thymeleaf and Flying Saucer for generating PDFs from templates. However, I have encountered an issue with applying CSS to my Thymeleaf template. Despite reviewing various questions & answers here, here, and here, none of the proposed solutions seem to solve my problem.
This is how my resources folder directory appears:
https://i.sstatic.net/8LOwi.png
I am utilizing the default directories that Spring searches for. The head tag in my template.html
looks like this:
<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>
If I embed my CSS directly into template.html
, the resulting PDF file displays proper styling (indicating no issues with the PDF generation process). However, when attempting to link to the CSS file as demonstrated above, the generated PDF lacks proper styling (implying that the CSS is not being applied).
Moreover, I am able to access my CSS file at
http://localhost:8080/css/style.css
, so there seems to be no problem with Spring serving static content.
For clarity, here is how I generate the PDF document:
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 using 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);
// Generate the PDF using 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);
}
}
I opted for WebContext
over Context
due to encountering the following error with 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
My question remains: What am I overlooking here that results in my style.css
failing to apply to template.html
?