Click here to Skip to main content
Click here to Skip to main content

Creating PDF with nFOP

By , 11 Jan 2006
 

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

<?xml version="1.0" encoding="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 namespaces 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:

    // Load the FO style sheet.
    XslCompiledTransform xslt = new XslCompiledTransform();
    xslt.Load("bookFo.xsl");

    // Execute the transform and output the results to a file.
    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

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Jerome Bellanger
Software Developer (Senior) Freelance
France France
Member
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionError assemblymemberMember 953878123 Oct '12 - 3:32 
Hi all, i had a problem, i try to put the nfop in my .net 4 project but i always get this error:
impossibile risolvere l'assembly "C:\Users\lpezzali\Desktop\Genius Fatture\generatePDF\bin\Debug\generatePDF.dll" a cui si fa riferimento perché dipende da "System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", non incluso nel framework di destinazione corrente ".NETFramework,Version=v4.0,Profile=Client". Rimuovere i riferimenti agli assembly non presenti nel framework di destinazione o definire una nuova destinazione per il progetto.
 
I tried to put the conversion in a separate project that create a dll, target of the project is famework 2.0
 
Any idea?
 
Thanks in advance.
SuggestionEditors for FOPmemberMember 827588227 Nov '11 - 0:49 
hi,
 
I would like to mention that one of disadvantages of FOP is that you have to learn XSL-FO and you spend quite a lot of time testing your XSL:FO file until you get the perfect output. However in the mean time that are some XSL:FO editors that can help you overcome these small problems
 
here you have some links:
 
http://www.java4less.com/fopdesigner/fodesigner.php
http://www.ecrion.com/
GeneralMy vote of 5membervinayak.bhadage19 Apr '11 - 22:52 
Good job done... thank you Smile | :)
QuestionDriver.setRenderer(8); not workingmemberpricksaw24 May '10 - 13:43 
Hello Users,
 
I have tried nFOP and it works nice for PDF generation. However, I wanted to use it to generate RTFs. Anyone knows how to do this. ApacheFOP uses JFOR for RTF conversion. Do I need to import this library too? If so, how do I do it?
 
I have tried:
 
driver.setRenderer(8);
 
Doesn't generate an RTF file. During runtime, the process hangs up.
 
Help would be greatly appreciated.
 
Thanks,
Uday
GeneralSecured PDF Generationmembervinvino200122 Apr '10 - 21:32 
Hi,
 
I want to create PDF with security options, such as "Print" is not allowed, "Content Copying" is not allowed.
 
How I have to add these properties when creating the PDF using NFOP?
 
Regards,
Vinoth
GeneralRe: Secured PDF GenerationmemberWiseLearner11 Feb '13 - 8:04 
I need to add a password to this pdf. ANy ideas??
 
Thanks!
WiseLearner

GeneralRe: Secured PDF Generationmembervinvino200111 Feb '13 - 17:48 
Hi,
 
I am not sure about in FOP, however, you can do this with FO.Net
 
Regards.
QuestionDriver present in which library? ISO8859_1 error?memberpricksaw9 Feb '10 - 13:24 
Hello, World!
 
This a very great project to use FOP in C#. Well, I am facing run time error. Appreciate little help.
 
The below code compiles and works perfect.I have installed j# redistributable 2.0 and also jre.
 
FileInputStream streamFO = new FileInputStream(foFile);
InputSource src = new InputSource(streamFO);
FileOutputStream streamOut = new FileOutputStream(pdfFile);
//Driver driver = new Driver(src, streamOut);
//driver.setRenderer(Driver.RENDER_PDF);
//driver.run();
streamOut.close();
 
However, when I uncomment the Driver part, the result is same. The PDF file is not being written. When I open the file it is empty(error: "There was an error opening this document. The file is damaged and could not be repaired.") and never been written.
 
I suspect I haven't installed some of the libraries.
 
I have added the reference to vjslib.dll and also Fop.net.dll(renamed it to Apache.net.dll).
 
When I do 'Go to Definition..' for Driver it is leads me to some class. I believe I have added the dll in the right way. But, the problem is during run-time, the PDF is not being written.
 
Thanks,
Appreciate all the help,
Uday.
AnswerRe: Driver present in which library? ISO8859_1 error?memberpricksaw9 Feb '10 - 18:22 
However, after several trial and error I have realized the problem is occurring due the nFop integration in my project. My project is a Windows NT service. It generates thread each time an event is launched and the thread the generatePDF functionality. Compiles perfect! when i run the service and launch ONE event, I see the pdf appeared at the destination folder. When I tried to open it, it says it been used by other program. OK! so, now I stop the service and open the file. It says it is damaged!
 
When two events are launched simultaneously, it shoots we a exception error. Does ISO8859_1 mean something?
 
Please help. Below is the code I have been working. fsw_Created is the function launched when the event occurs. Am I messing up with the threads?
 
private void fsw_Created(object sender, System.IO.FileSystemEventArgs e)
        {
            Thread t = new Thread(new ParameterizedThreadStart(Sendfile));
            t.Start(info);
        }
 
        public void Sendfile(object _info)
        {
            String[] info = (String[])_info;            
            GeneratePDF(@"C:\Report.fo", "C:\Report.pdf");
            
        }
 
        private static 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();
        }
 
Thanks,
Uday.
GeneralRe: Driver present in which library? ISO8859_1 error?memberpricksaw11 Feb '10 - 16:34 
I am sorry, I have traced the problem myself. After many exception handling and debugging, I have realized that the FO file had encoding="ISO8859_1" instead of encoding="UTF-8"!!!! D'Oh! | :doh: Laugh | :laugh:
 
<?xml version="1.0" encoding="iso-8859-1"?>
 
changed to...
 
<?xml version="1.0" encoding="utf-8"?>
 
Hope this little tip would help in future.
 
Uday.
GeneralI am getting error like thismemberShaik Haneef14 Sep '09 - 20:41 
Could not load file or assembly 'vjslib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
GeneralRe: I am getting error like thismemberKotty19856 Nov '09 - 4:51 
Solution:
install the Microsoft Visual J# Version 2.0 Redistributable Package from https://www.microsoft.com/downloads/details.aspx?familyid=F72C74B3-ED0E-4AF8-AE63-2F0E42501BE1&displaylang=en[^]
then it works.
GeneralIssue parsing out encoded htmlmembercoolaid0925 Aug '09 - 8:51 
I'm at a point where I'm using NFOP to take an XML file, parse it using an XSL file, and save a PDF. However, because the XML is well formed, the html within it looks like this:
 
&lt;p&gt;Some text here &lt;strong&gt;bolded text&lt;/strong&gt;
 
So in the PDF, this gets converted to:
 
<p>Some text here <strong>bolded text</strong>
 
The people who need to look at the PDFs don't know html and won't want to see this extra code.
 
I've tried using Saxon to parse through this particular bit of code, but errors display. I've learned via Google that Saxon and NFOP require the inclusion of their respective libraries (ApacheFop.Net.dll and IKVM.GNU.Classpath) but these libraries have an overlap in the form of org.xml.sax.
 
Does anyone use any particular parser to convert encoded xml as specified above into the appropriate characters - just for one or two nodes?
Questionimagesmembercoolaid0920 Aug '09 - 9:34 
I'm trying to include the following image reference:
 
<fo:block>
<fo:external-graphic src="url(catcode_logo.jpg)"
width="99px" height="109px"/>
</fo:block>
 
I've also tried:
 
<fo:block>
<fo:external-graphic src="file:catcode_logo.jpg"
width="99px" height="109px"/>
</fo:block>
 
The image is at the same level as the other files, but it's not being included in the PDF. Are external graphics not supported by NFOP?
AnswerRe: imagesmemberpricksaw1 Mar '10 - 11:08 
your tag should look like
 
 <fo:external-graphic src="url(C:\\catcode_logo.jpg)" width="99px" height="109px"/>
 
Include the entire path.
QuestionFop license?memberpereszczako8 Jun '09 - 22:39 
Does anybody know what type of license Fop has?
I have found one post on the Apache mailing list that gives me some doubts if I can use this library in commercial applications.
The questions are as follows:
 
Thequestion is if the person who did that port did it correctly without
violating the Apache license.
He produces a source and binary distribution. The binary only contains a
DLL. No license included. The source however contains a copy of the
source code from FOP, Xerces and Avalon Framework.
 
Now, the following can be said:
- The Apache Software license is not included in his distributions.
- He took a copy of the source before we applied the long license
headers in FOP.
- The notice "This product includes software developed..." is missing
AFAICS.
- The name "nfop" might not be in line with the FOP license???
- It's not obvious where he potentially changed Apache code.

QuestionBarcode fonts embedded using the userconfig.xml filememberdjblues30 Apr '09 - 8:46 
Hi, is it possible to embed for example EAN-13 ttf font in the code.
Using the userconfig.xml file and ean-13.ttf and ean-13.xml file...
 
Can someone help me out here.
GeneralIssue with FOPmembersonu941 Dec '08 - 22:09 
Hi,
 
This code is working fine in my local, but when i placed this code in my QA server it is giving this error.
 
Please help me in this regard.
================================================
Microsoft (R) Visual Basic Compiler version 8.0.50727.1433
for Microsoft (R) .NET Framework version 2.0.50727.1433
Copyright (c) Microsoft Corporation. All rights reserved.
 
C:\inetpub\wwwroot\CBIQuestionnaire\PDF\Default.aspx.vb(11) : warning BC40056: Namespace or type specified in the Imports 'org.apache.fop.apps' doesn't contain any public member or cannot be found. Make sure the namespace or the type is defined and contains at least one public member. Make sure the imported element name doesn't use any aliases.
 
Imports org.apache.fop.apps
~~~~~~~~~~~~~~~~~~~
C:\inetpub\wwwroot\CBIQuestionnaire\PDF\Default.aspx.vb(13) : warning BC40056: Namespace or type specified in the Imports 'org.xml.sax' doesn't contain any public member or cannot be found. Make sure the namespace or the type is defined and contains at least one public member. Make sure the imported element name doesn't use any aliases.
 
Imports org.xml.sax
~~~~~~~~~~~
C:\inetpub\wwwroot\Ire\PDF\Default.aspx.vb(17) : error BC30182: Type expected.
 
Dim obj_DA As New DataAccess
~~~~~~~~~~
C:\inetpub\wwwroot\Ire\PDF\Default.aspx.vb(399) : error BC30002: Type 'java.io.FileInputStream' is not defined.
 
Dim streamFO As New java.io.FileInputStream(FoFile)
~~~~~~~~~~~~~~~~~~~~~~~
C:\inetpub\wwwroot\Ire\PDF\Default.aspx.vb(400) : error BC30002: Type 'InputSource' is not defined.
 
Dim src As New InputSource(streamFO)
~~~~~~~~~~~
C:\inetpub\wwwroot\Ire\PDF\Default.aspx.vb(401) : error BC30002: Type 'java.io.FileOutputStream' is not defined.
 
Dim streamOut As New java.io.FileOutputStream(PDFFile)
~~~~~~~~~~~~~~~~~~~~~~~~
C:\inetpub\wwwroot\Ire\PDF\Default.aspx.vb(402) : error BC30002: Type 'Driver' is not defined.
 
Dim driver As New Driver(src, streamOut)
Generalreference-orientation does not workmemberMember 212122031 Mar '08 - 9:14 
hello,
 
reference-orientation is not supported in the nfop, is there any way i can do to make it work?
 
thanks,
grace
QuestionLatin2 character setsussGabor10 Dec '07 - 23:41 
Hi,
 
How can I make documents with non Latin1 (WinAnsi) (for example Latin2) character sets?
I made a little app to make font and userconfig xml files. What's next?
QuestionBuildmemberlokesh_sg7 Nov '07 - 0:23 
Hi,
 
In Visual Sudio 2005, I am not able to build the nFop assembly i.e 'ApacheFop.Net.dll'
 
The following build error occurs:-
 
Error 1 /target must be 'exe' or 'winexe' if /main is specified ApacheFop.Net
 
please let me know how one can successfully build the ApacheFop.Net assembly.
 
Regards,
Lokesh
QuestionHyphenationmemberDaniele Fusi28 Mar '07 - 23:34 
Thanks for the article, it really helps FO-newbies like me starting... I have a question about hyphenation: how can I use it in NFOP? The binaries I download from sourceforge just include a couple of DLL's, and if I try to generate PDF from a block like:
 
<fo:block hyphenate="true" language="en">...long text...</fo:block>
 
I get multiple warnings from the processor like:
...
Using org.apache.xerces.parsers.SAXParser as SAX2 Parser
building formatting object tree
setting up fonts
[1]
Couldn't find hyphenation pattern en
Error building hyphenation tree for language en
...

GeneralJava does not workmemberMember #385632223 Feb '07 - 5:42 
Hello,
 
I added Appache.Net.dll in the project reference and added namespaces of org.xml.sax, org.apache.fop, org.apache.fop.apps, org.apache.fop.tools and java.io. When I build the project, it said that namespace 'java' could not be found. I don't what is wrong. If you know what happened, please let me know. Thank you a lot!
 
Jin
GeneralRe: Java does not workmemberWingnut121327 Feb '07 - 8:02 
You need to install the J# .net framework.
QuestionLarge FO files take very long time to processmemberDadou00220 Nov '06 - 19:45 
Thank you for a very useful piece of code! One question; I am using this to generate PDF reports from large fo files (>50MB), however the process takes a very long time (>10 minutes). Do you know any tricks to speed up this process? For example it takes about 2 minutes to set up fonts before even beginning to render the first page...
 
Any assistance would be greatly appreciated!
 
Darren

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130516.1 | Last Updated 11 Jan 2006
Article Copyright 2006 by Jerome Bellanger
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid