Introduction
nFOP is an elegant solution to generate PDF on the fly. It is originally a Java open source product that has been migrated to .NET.
The purpose of this article is to show the use of nFOP to generate a PDF file from XML data. We won't describe the FO format here. Many excellent articles exist on the Web about FO which is a W3C standard. Unfortunately it doesn't seem to be much known by the .NET community so far.
First, you have to download nFOP from here.
Using the Code
Here is the data in input - my favourite French books:
Books.xml
="1.0" ="utf-8"
<Books>
<Book>
<Title>Madame Bovary</Title>
<Author>Gustave Flaubert</Author>
<Price>10</Price>
</Book>
<Book>
<Title>Bel Ami</Title>
<Author>Maupassant</Author>
<Price>18</Price>
</Book>
<Book>
<Title>La Curée</Title>
<Author>Emile Zola</Author>
<Price>12</Price>
</Book>
<Book>
<Title>Les Chouans</Title>
<Author>Honoré de Balzac</Author>
<Price>15</Price>
</Book>
</Books>
Here is now the XSL transformation that I will apply to this XML. I create a table in FO language, with three columns. The rows will be generated by the XSL transformation, one for each book.
BookFo.xsl
<fo:table-body>
<fo:table-row>
<fo:table-cell>
<fo:block>Title</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block>Author</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block>Price</fo:block>
</fo:table-cell>
</fo:table-row>
<xsl:for-each select="Books/Book">
<fo:table-row>
<fo:table-cell>
<fo:block>
<xsl:value-of select=".//Title" />
</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block>
<xsl:value-of select=".//Author" />
</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block>
<xsl:value-of select=".//Price" />
</fo:block>
</fo:table-cell>
</fo:table-row>
</xsl:for-each>
</fo:table-body>
</fo:table>
In Visual Studio, reference the nFop assembly ApacheFop.Net.dll and the J# assembly vjslib.dll.
You will need to add the following namespace
s to your class:
using System.Xml;
using System.Xml.Xsl;
using System.Xml.XPath;
using org.apache.fop;
using org.apache.fop.apps;
using org.apache.fop.tools;
using org.xml.sax;
using java.io;
We call the classic XML/XSL transformation to produce the FO file:
XslCompiledTransform xslt = new XslCompiledTransform();
xslt.Load("bookFo.xsl");
xslt.Transform("books.xml", "books.fo");
At last, here comes the most interesting part, the use of NFOP to generate the PDF file.
Here is the method that does the job:
private void GeneratePDF(string foFile, string pdfFile)
{
FileInputStream streamFO = new FileInputStream(foFile);
InputSource src = new InputSource(streamFO);
FileOutputStream streamOut = new FileOutputStream(pdfFile);
Driver driver = new Driver(src, streamOut);
driver.setRenderer(1);
driver.run();
streamOut.close();
}
Conclusion
nFOP is an easy solution to implement and it is free. Because the PDF structure is described in an XML file, it is easy to configure its disposition, which clients always ask for.
To learn more about FOP, visit the Apache site and download the Java version. It contains plenty of samples of FO files and good documentation.
History
- 11th January, 2006: Initial post