image not displaying in PDF template using Spring Boot, flying saucer and Thymeleaf

Viewed 8789

I create a file pdf from html template using Spring Boot, flying saucer, thymeleaf. But image is not displaying in my file.

Project structure:

Project structure

code html:

<div class="col-xs-6 invoice-col-2">
   <img src="../static/images/mastercard.png" alt="mastercard"></img>
</div>

When I change img tag to:

<img src="../static/images/mastercard.png" alt="mastercard" th:src="@{static/images/mastercard.png}"></img>

When I create PDF file, I get an error:

org.thymeleaf.exceptions.TemplateProcessingException: Link base "static/images/mastercard.png" cannot be context relative (/) or page relative unless you implement the org.thymeleaf.context.IWebContext interface (context is of class: org.thymeleaf.context.Context)

4 Answers

In order to embed an image in a PDF generated by Flying Saucer,

1) Convert the image to a base64 encoded string.

Path path = Paths.get("src/main/resources/static/images/mastercard.png");
String base64Image = convertToBase64(path);

Function to convert image stored in a path like shown above, to a base64 encoded string

private String convertToBase64(Path path) {
    byte[] imageAsBytes = new byte[0];
    try {
      Resource resource = new UrlResource(path.toUri());
      InputStream inputStream = resource.getInputStream();
      imageAsBytes = IOUtils.toByteArray(inputStream);

    } catch (IOException e) {
      System.out.println("\n File read Exception");
    }

    return Base64.getEncoder().encodeToString(imageAsBytes);
  }

2) Set the base64 encoded image in the thymeleaf context

    Context context = new Context();
    String image = "data:image/png;base64, " + base64Image;
    context.setVariable("image",  image);

    String html = templateEngine.process("template", context);

3) In HTML, set the value of image as shown below:

<img th:src="${image}" style="width: 200px; height=100px"/>

4) Finally, render the HTML template to PDF

  ITextRenderer renderer = new ITextRenderer();
  renderer.setDocumentFromString(html); // html -> String created in Step 2
  renderer.layout();
  final ByteArrayOutputStream baos = new ByteArrayOutputStream();
  renderer.createPDF(baos)

Now you have the byteArrayOutputStream of the generated PDF, with which you can choose to store them to a file server or serve it to a client in a format of your choice.

Use standard html src atribute and relative path from root of the project.

You can put your image in the root of the project and use it like this:

<img src="mastercard.png" />

If you want to resource folders you can set it like this:

<img src="src/main/resources/static/images/mastercard.png" />
Related