Java iText Convert XML to PDF Example Tutorial - Part 1

In some of the tutorials earlier we discussed how to convert HTML to PDF using iText and Flying Saucer. In this post, we will discuss how to convert an XML to PDF document using iText and Flying Saucer. We are going to explain two different transformation on the XML. We are going to apply a CSS based transformation and an XSLT based transformation on the XML to produce the PDF. I will run through this XML to PDF conversion in Java with a basic example and this series will be sub-divided into multiple parts depending on the extent to which we will cover this. Let us first discuss how to transform XML to PDF using these libraries. We will apply an XSLT transformation on the XML so that we can get a HTML out of our XML and then use Flying Saucer to convert the HTML into a PDF. The solution is a complete working example and you can always share your expertise with us to make this better or easier..(if you find one).

The XML we will be using for this tutorial is provided below;
<?xml version="1.0"?>
<ConvertXMLtoPDF>  
  <TestData>
        <Title>Ebook of XML</Title>
        <Price>300</Price>
  </TestData>
  <TestData>
        <Title>Ebook of XSLT</Title>
        <Price>200</Price>
  </TestData>
  <TestData>
        <Title>Ebook of Java</Title>
        <Price>400</Price>
  </TestData>
</ConvertXMLtoPDF>
The XSLT style sheet that we have defined to convert this XML for presenting inside a PDF document is provided below;
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method='html' version='1.0' encoding='UTF-8' indent='yes'/>
<xsl:template match="/">
  <html>
  <body>
  <h2>Generate PDF from XML and XSLT StyleSheet Using iText, Flying Saucer and Java XSLT Transformer</h2>
    <table border="1">
      <tr bgcolor="#9acd32">
        <th align="left">Title</th>
        <th align="left">Price</th>
      </tr>
      <xsl:for-each select="ConvertXMLtoPDF/TestData">
      <tr>
        <td><xsl:value-of select="Title"/></td>
        <td><xsl:value-of select="Price"/></td>
      </tr>
      </xsl:for-each>
    </table>    
  </body>
  </html>
</xsl:template>
</xsl:stylesheet>
As far as I came to know, there is no direct way to send this XML and XSLT and get a PDF for iText. So, we will first transform the XML to a HTML using the stylesheet given earlier and then use the interim output to produce a PDF. Follow the step-by-step guide provided below to first convert an XML to HTML using Java's native libraries; [ we will be using javax.xml.transform and javax.xml.transform.stream classes to do this ]
        /* Create a TransformerFactory object */           
        TransformerFactory tFactory = TransformerFactory.newInstance();
        /* Get the incoming XSLT file */
        Transformer transformer = tFactory.newTransformer(new StreamSource("sample.xsl"));
        /* Get the XML file and apply the XSLT transformation to convert to HTML */
        transformer.transform(new StreamSource("sample.xml"),new StreamResult(new FileOutputStream("sample.html")));
Now, we have got a HTML file and we know how to convert this HTML file to a PDF document. The code to do this is provided below;
        String File_To_Convert = "sample.html";
        String url = new File(File_To_Convert).toURI().toURL().toString();
        System.out.println(""+url);
        String HTML_TO_PDF = "ConvertedFile.pdf";
        OutputStream os = new FileOutputStream(HTML_TO_PDF);       
        ITextRenderer renderer = new ITextRenderer();
        renderer.setDocument(url);      
        renderer.layout();
        renderer.createPDF(os);        
        os.close();
And that is all you have to do if you have a XML and XSLT and want to get a PDF out of it in iText. You can always get rid of the interim HTML file which we are creating in this process if you feel that it will involve more IO operation. The HTML can be obtained in the memory and converted into a PDF using iText. This short tutorial would have given you an idea on how to get started with converting an XML to PDF in Java iText. The complete code with import declarations and exception handlers is provided below;
import java.io.*;
import com.lowagie.text.DocumentException;
import org.xhtmlrenderer.pdf.ITextRenderer;
import javax.xml.transform.*;
import javax.xml.transform.stream.*;
public class XMLtoPDF {    
    public static void main(String[] args) 
            throws IOException, DocumentException, TransformerException,TransformerConfigurationException,FileNotFoundException {                  
        TransformerFactory tFactory = TransformerFactory.newInstance();
        Transformer transformer = tFactory.newTransformer(new StreamSource("sample.xsl"));
        transformer.transform(new StreamSource("sample.xml"),new StreamResult(new FileOutputStream("sample.html")));
        String File_To_Convert = "sample.html";
        String url = new File(File_To_Convert).toURI().toURL().toString();
        System.out.println(""+url);
        String HTML_TO_PDF = "ConvertedFile.pdf";
        OutputStream os = new FileOutputStream(HTML_TO_PDF);       
        ITextRenderer renderer = new ITextRenderer();
        renderer.setDocument(url);      
        renderer.layout();
        renderer.createPDF(os);        
        os.close();
    }
}
When you run this example code,make sure you have the required JAR files as documented in HTML to PDF tutorial. You will have to get an output PDF file out of the XML, as shown below;

XML to PDF Conversion using Java

If you observe the output, the color we have specified in XSLT is missing. If you look at the HTML however, you can find the color. Do you know how to restore the color into the PDF that got lost during the conversion? Let us know how to do this.

3 comments:

  1. Change the stylesheet and the background color will appear correctly.
    tr style="background-color:#9acd32;"

    ReplyDelete
  2. The tag xsl:stylesheet MUST be this:



    or it WON'T work.
    It only needs to be changed the version from 1.0 to 1.1.

    ReplyDelete