How do you create a PDF from XML in Java?

At the moment, I'm creating an XML file in Java and displaying it in a JSP page by transforming it with XSL/XSLT. Now I need to take that XML file and display the same information in a PDF. Is there a way I can do this by using some kind of XSL file? I've seen the iText Java-PDF library, but I can't find any way to use it with XML and a stylesheet. Any assistance would be much appreciated. Thanks in advance!

asked Oct 17, 2008 at 15:09 Philip Morton Philip Morton 132k 38 38 gold badges 89 89 silver badges 97 97 bronze badges Now there is iText® XMLWorker, default implementation is HTML/CSS to pdf Commented May 28, 2011 at 8:23

It is better to consider using Apache-FOP framework. I've added an answer down below, using apache-fop.

Commented Dec 8, 2016 at 21:52

11 Answers 11

A - Explanation

You should use Apache FOP framework to generate pdf output. Simply you provide data in xml format and render the page with an xsl-fo file and specify the parameters like margin, page layout in this xsl-fo file.

I'll provide a simple demo, I use maven build tool to gather the needed jar files. Please notify that at the end of the page, there is an svg graphics embedded in pdf. I also want to demonstrate that you can embed svg graphics inside pdf.

B - Sample XML input data

    User Bill Data Thursday December 9 2016 00:04:29  John Doe 34239 123AD329248 17.84  Michael Doe 54823 942KFDSCW322 34.50  Jane Brown 66742 ABDD324KKD8 69.36   

C - The XSL-FO Template

                    Bill Id: , Date:    XXX COMPANY      Page of       MONTHLY BILL REPORT        Full Name  Postal Code  National ID  Payment                                    

D - Project Directory Structure

enter image description here

E - Pom file

 4.0.0 com.levent.fopdemo apache-fop-demo jar 1.0-SNAPSHOT apache-fop-demo http://maven.apache.org 2.1    org.apache.xmlgraphics fop $  Apache Fop Demo  org.apache.maven.plugins maven-compiler-plugin 3.5.1 1.8 1.8      

F - Demo Code: PdfGenerationDemo.java

package com.levent.fopdemo; import java.io.File; import java.io.IOException; import java.io.OutputStream; import javax.xml.transform.Result; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.sax.SAXResult; import javax.xml.transform.stream.StreamSource; import org.apache.fop.apps.FOPException; import org.apache.fop.apps.FOUserAgent; import org.apache.fop.apps.Fop; import org.apache.fop.apps.FopFactory; import org.apache.fop.apps.MimeConstants; public class PdfGenerationDemo < public static final String RESOURCES_DIR; public static final String OUTPUT_DIR; static < RESOURCES_DIR = "src//main//resources//"; OUTPUT_DIR = "src//main//resources//output//"; >public static void main( String[] args ) < try < convertToPDF(); >catch (FOPException | IOException | TransformerException e) < e.printStackTrace(); >> public static void convertToPDF() throws IOException, FOPException, TransformerException < // the XSL FO file File xsltFile = new File(RESOURCES_DIR + "//template.xsl"); // the XML file which provides the input StreamSource xmlSource = new StreamSource(new File(RESOURCES_DIR + "//data.xml")); // create an instance of fop factory FopFactory fopFactory = FopFactory.newInstance(new File(".").toURI()); // a user agent is needed for transformation FOUserAgent foUserAgent = fopFactory.newFOUserAgent(); // Setup output OutputStream out; out = new java.io.FileOutputStream(OUTPUT_DIR + "//output.pdf"); try < // Construct fop with desired output format Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, out); // Setup XSLT TransformerFactory factory = TransformerFactory.newInstance(); Transformer transformer = factory.newTransformer(new StreamSource(xsltFile)); // Resulting SAX events (the generated FO) must be piped through to // FOP Result res = new SAXResult(fop.getDefaultHandler()); // Start XSLT transformation and FOP processing // That's where the XML is first transformed to XSL-FO and then // PDF is created transformer.transform(xmlSource, res); >finally < out.close(); >> >