Here's my current workflow:
The problem occurs when I try to resolve relative URLs like images and the like. Since my document lives in memory, it doesn't know how to resolve images or stylesheets at all. How can I set the document for it to an in-memory String object while still passing it a directory to load resources from?
String velocityOutput = VelocityEngineUtils.mergeTemplateIntoString(...);
ByteArrayOutputStream output = new ByteArrayOutputStream(...);
ITextRenderer renderer = new ITextRenderer();
renderer.setDocumentFromString(velocityOutput);
renderer.layout();
renderer.createPDF(output);
I need to do everything in-memory as I'm simply generating the report to be emailed to clients. How can I make an <img src="..."/>
resolve a relative URL in my HTML template when generated to a PDF?
I ended up simply loading my document into a Java Document
instance and then sending it to Flying Saucer with the resource directory in one call:
Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder()
.parse(new ByteArrayInputStream(templateOutput.getBytes("UTF-8")));
ITextRenderer renderer = new ITextRenderer();
renderer.setDocument(document, templateResourceDirectory);
renderer.layout();
OutputStream result = new ByteArrayOutputStream();
renderer.createPDF(result);
One thing to be especially careful of is the fact that Flying Saucer needs file-based URIs to be prefixed with file://
, and that it requires a slash at the end of the file path in order to work properly:
/var/www/cache # FAIL
file:///var/www/cache # ALSO FAIL
file:///var/www/cache/ # WIN