Skip to content
Liios edited this page Nov 4, 2022 · 6 revisions

Base URI for withHtmlContent method

The easiest way to get the baseUri argument for the withHtmlContent method is to create an empty or dummy (content not important) file in the folder you wish to use as base directory.

The following example assumes the following files are present at the base of the resources folder which is typically src/main/resources when using Maven.

  • /pdf/ - base directory for our generator related resources
  • /pdf/base-uri.htm - dummy file to resolve uri, may be empty, however a useful comment is suggested
  • /pdf/images/
  • /pdf/images/image.jpg - Sample image, we will include this image using a relative path
public class Demo {
    // Typically our html is created using a template engine
    // We can use relative URLs such as "./images/image.jpg"
    private static final String HTML = "<html><body><img alt=\"Demo\" src=\"./images/image.jpg\"/></body></html>";

    public byte[] createPDF() throws IOException {
        // This shows how to get the URL of a resource (which must exist)
        String resBaseUri = Demo.class.getResource("/pdf/base-uri.htm").toString();

        // Alternatively, this shows how to get the URL of a normal file
        // In this case, we reuse the source project in our home directory
        // IMPORTANT: The following two lines are not needed if using a resource folder as base directory (see above instead)
        String home = System.getProperty("user.home");
        String fileBaseUri = Paths.get(home + "/demo-project/src/main/resources/pdf/base-uri.htm").toUri().toString();

        try (ByteArrayOutputStream os = new ByteArrayOutputStream()) {
            PdfRendererBuilder builder = new PdfRendererBuilder();

            // We use the URL to the empty resource as the baseUri argument
            // Could also change to fileBaseUri to use normal file
            builder.withHtmlContent(HTML, resBaseUri);
            builder.toStream(os);
            builder.run();

            return os.toByteArray();
        }
    }
}

Tip derived from #631

Image link

If you require a plain image link, you can make the surrounding a tag inline-block and turn off text decorations. Also remove any whitespace between the a tag and img tag.

<a href="https://github.com" style="display:inline-block; text-decoration: none;"><img src="some-image.jpg" alt="Something" /></a>

Tip derived from #495

Modifying unsupported HTML at runtime

If your tool generates unsupported markup, you may be able to change it at runtime to something supported by this library. To do this register a DOM mutator. Here is one that converts font tag color attributes (<font color="#ff00ff">) to CSS:

        FSDOMMutator domChanger = (doc) -> {
            // doc is a mutable org.w3c.dom.Document.
            NodeList fontTags = doc.getElementsByTagName("font");

            for (int i = 0; i < fontTags.getLength(); i++) {
                Element fontTag = (Element) fontTags.item(i);

                if (fontTag.hasAttribute("color")) {
                    String color = fontTag.getAttribute("color");

                    if (!fontTag.hasAttribute("style")) {
                        fontTag.setAttribute("style", "color: " + color + ';');
                    } else {
                        String oldStyle = fontTag.getAttribute("style");
                        String newStyle = oldStyle + "; color: " + color + ';';

                        fontTag.setAttribute("style", newStyle);
                    }
                }
            }
        };

You register dom mutators with the builder:

builder.addDOMMutator(domChanger);

Tip related to #736

I am running out of memory, what should I do?

Mitigate Java heap space errors or OutOfMemoryException by supplying a PDDocument with custom memory settings.

final PdfRendererBuilder pdfRendererBuilder = new PdfRendererBuilder();
// Limits virtual memory usage to 16 MB, the rest will go to temp files.
final int MAX_MEMORY_BYTES = 16 * 1024 * 1024;
final PDDocument document = new PDDocument(MemoryUsageSetting.setupMixed(MAX_MEMORY_BYTES));
pdfRendererBuilder.usePDDocument(document);