Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flying saucer, Thymeleaf and Spring

I have a Spring application and need to build support for PDF generation. I'm thinking of using Flying-saucer together with Thymeleaf to render the PDF. However, I cannot find that much information about using Flying-saucer together with Thymeleaf. Have anyone else used those to technologies together?

like image 300
per_jansson Avatar asked Apr 19 '14 17:04

per_jansson


People also ask

Is Thymeleaf fully integrated with Spring?

It provides full integration with Spring Framework. It applies a set of transformations to template files in order to display data or text produced by the application. It is appropriate for serving XHTML/HTML5 in web applications. The goal of Thymeleaf is to provide a stylish and well-formed way of creating templates.

Is Thymeleaf supported by Spring MVC?

Thymeleaf offers a set of Spring integrations that allow you to use it as a fully-featured substitute for JSP in Spring MVC applications.

Is Thymeleaf part of Spring Boot?

You can use Thymeleaf templates to create a web application in Spring Boot. You will have to follow the below steps to create a web application in Spring Boot by using Thymeleaf. In the above example, the request URI is /index, and the control is redirected into the index. html file.


1 Answers

I'm using Flyingsaucer-R8 with Thymeleaf 2.0.14 without problems (and I'm sure current version of Thymeleaf works as well).

I have separate TemplateEngine with classpath template resolver configured for this purpose. Using it to produce XHTML as String. Flyingsaucer creates PDF document from result then. Check example below.

Code below is example - NOT PRODUCTION ready code use it with NO WARRANTY. For sake of clarity there's no try-catch handling and no resources caching (creating PDF is quite expensive operation). Consider that.

Code

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

import org.springframework.core.io.ClassPathResource;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;
import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver;
import org.xhtmlrenderer.pdf.ITextFontResolver;
import org.xhtmlrenderer.pdf.ITextRenderer;

import com.lowagie.text.DocumentException;
import com.lowagie.text.pdf.BaseFont;
import com.sun.xml.internal.messaging.saaj.util.ByteOutputStream;

public class FlyingSoucerTestService {

  public void test() throws DocumentException, IOException {
    ClassLoaderTemplateResolver templateResolver = new ClassLoaderTemplateResolver();
    templateResolver.setPrefix("META-INF/pdfTemplates/");
    templateResolver.setSuffix(".html");
    templateResolver.setTemplateMode("XHTML");
    templateResolver.setCharacterEncoding("UTF-8");

    TemplateEngine templateEngine = new TemplateEngine();
    templateEngine.setTemplateResolver(templateResolver);

    Context ctx = new Context();
    ctx.setVariable("message", "I don't want to live on this planet anymore");
    String htmlContent = templateEngine.process("messageTpl", ctx);

    ByteOutputStream os = new ByteOutputStream();
    ITextRenderer renderer = new ITextRenderer();
    ITextFontResolver fontResolver = renderer.getFontResolver();

    ClassPathResource regular = new ClassPathResource("/META-INF/fonts/LiberationSerif-Regular.ttf");
    fontResolver.addFont(regular.getURL().toString(), BaseFont.IDENTITY_H, true);

    renderer.setDocumentFromString(htmlContent);
    renderer.layout();
    renderer.createPDF(os);

    byte[] pdfAsBytes = os.getBytes();
    os.close();

    FileOutputStream fos = new FileOutputStream(new File("/tmp/message.pdf"));
    fos.write(pdfAsBytes);
    fos.close();
  }
}

Template

<?xml version="1.0" encoding="utf-8"?>

<!DOCTYPE html SYSTEM "http://www.thymeleaf.org/dtd/xhtml1-strict-thymeleaf-spring3-4.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <style>
            div.border {
                border: solid;
                border-width: 1px 1px 0px 1px;  
                padding: 5px 20px 5px 20px;
            }
        </style>        
    </head>
<body style="font-family: Liberation Serif;">

<div class="border">
    <h1 th:text="${message}">message</h1>
</div>

</body>
</html>
like image 62
michal.kreuzman Avatar answered Oct 10 '22 03:10

michal.kreuzman