Is there any way to make only one xslt transformation and render the output to pdf, png, svg files?
StreamSource contentSource = new StreamSource(xmlContentStream);
StreamSource transformSource = new StreamSource(xslFoMarkupStream);
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
Transformer xslfoTransformer = getTransformer(transformSource);
Fop fop = fopFactory.newFop("application/pdf", foUserAgent, outStream);
Result res = new SAXResult(fop.getDefaultHandler());
// Start XSLT transformation and FOP processing
xslfoTransformer.transform(contentSource, res);
xmlContentStream.close();
xslMarkupStream.close();
return outStream;
In the case above to generate PDF and then PNG I will have to create a new Fop instance with different mime type and then again call xslfoTransformer.transform().
That means that I will have the transformation twice, but I wonder if there is a way to run the transformation once and then render the output to different formats? (Custom Renderer?)
Or maybe there are any suggestions to speed up the rendering as I still need to do it several times - once for PDF, PNG, SVG.
I also tried to generate PDF via FOP and then convert it to image via Apache PdfBox. That works slightly faster, but looks silly.
Thank_you.
You can save one step. Your code does 2 steps above: take some arbitrary XML, transform that into XSL:FO using XSLT and then render the output into whatever format you want. You could do the transformation XML to XSL:FO (probably the slower part) once and use that result as input to 2 FO instances. Something like this:
public void fopReport(OutputStream pdfOut, OutputStream jpgOut, Source xmlSource, Source xsltSource) throws Exception {
// Create the FO content
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer(xsltSource);
ByteArrayOutputStream foBytesStream = new ByteArrayOutputStream();
StreamResult foByteStreamResult = new StreamResult(foBytesStream);
transformer.transform(xmlSource, foByteStreamResult);
byte[] foBytes = foBytesStream.toByteArray();
// Render twice
FopFactory fopFactory = FopFactory.newInstance();
FOUserAgent uaPDF = fopFactory.newFOUserAgent();
FOUserAgent uaJpg = fopFactory.newFOUserAgent();
Fop fopPDF = fopFactory.newFop(MimeConstants.MIME_PDF, uaPDF, pdfOut);
Fop fopJpg = fopFactory.newFop(MimeConstants.MIME_JPEG, uaJpg, jpgOut);
//PDF
Source src = new StreamSource(new ByteArrayInputStream(foBytes));
Transformer resultTransformer = factory.newTransformer();
resultTransformer.transform(src, new SAXResult(fopPDF.getDefaultHandler()));
//JPF
src = new StreamSource(new ByteArrayInputStream(foBytes));
resultTransformer = factory.newTransformer();
resultTransformer.transform(src, new SAXResult(fopJpg.getDefaultHandler()));
}
Hope that helps