Skip to main content

Apache FOP Tutorial for PDF Generation

What is meant by Apache FOP?

Apache is providing open source JAVA application for PDF(or any other format) file generation from XML data.Simply to can give data in XML,it gives output in PDF or any format.But it is primary for PDF output.

Official explanation,
OP (Formatting Objects Processor) is the world's first print formatter driven by XSL formatting objects (XSL-FO) and the world's first output independent formatter. It is a Java application that reads a formatting object (FO) tree and renders the resulting pages to a specified output. Output formats currently supported include PDF, PCL, PS, SVG, XML (area tree representation), Print, AWT, MIF and TXT

How wcan configure apache fop with our project?

I am going to explain how to generate PDF using Apache FOP.
I will explain it in steps

Step 1:
You will require 3 jar for configurations.Here fop jar depend on both avalon api and avalon impl.
              1.    apache fop 1.1
              2.    avalon-framework-api 4.3.1
              3.    avalon-framework-impl 4.3.1

Step 2:
Create FOP factory instance. It can be reusable.

 
FopFactory fopFactory = FopFactory.newInstance();


Step 3:
By default FOP searches system FONT files.But  if you want to add external font .then you have to create XML file containing path of you fonts TTF file.
This is demo XML file. (fontcfg.xml) place it in CLASSPATH of your project.


<fop version="1.0">
  <renderers>
    <renderer mime="application/pdf">
       <fonts>  
           <font kerning="no" embed-url="C:\mypath\myfont.ttf" encoding-mode="auto"   embedding-mode="full">
               <font-triplet name="MYFONT" style="normal" weight="normal"/>
           </font>    
       </fonts>
   </renderer>
  </renderers>
</fop>



Then now configure it with fop factory.


 
StreamSource configSrc = new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream(fontcfg.xml));DefaultConfigurationBuilder cfgBuilder = new DefaultConfigurationBuilder();
Configuration cfg = cfgBuilder.build(configSrc.getInputStream());
fopFactory.setUserConfig(cfg); 
 

Step 5:
we have to OutputStream to store file in disk.Remember after using output streame please close it carefully.We have taken OutputStream in buffer to increase performance.


 
OutputStream out = new BufferedOutputStream(new FileOutputStream(new File("C:/Temp/mypdffile.pdf")));

Step 6:
 We have created all basic configurations.Now we have create data that will displayed on PDF.In case of FOP it will accept data in XML format.So we to give it XML file.
This is Demo XML file containing name to display (name.xml).


 <name>Oomph Fortuity</name> 
 

If have complex data ,then you can use java JAXB API to create XML files.

Step 7:
We have XML file which have data in it.Now give make-up to it when it will displayed on PDF.We have to create XSL file that will give look to our PDF.It is like a styling file for XML
This is demo file (name2fo.xsl)

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:fo="http://www.w3.org/1999/XSL/Format">
  <xsl:output method="xml" indent="yes"/>
  <xsl:template match="/">
    <fo:root>
      <fo:layout-master-set>
        <fo:simple-page-master master-name="A4-portrait"
              page-height="29.7cm" page-width="21.0cm" margin="2cm">
          <fo:region-body/>
        </fo:simple-page-master>
      </fo:layout-master-set>
      <fo:page-sequence master-reference="A4-portrait">
        <fo:flow flow-name="xsl-region-body">
          <fo:block>
            Hello, <xsl:value-of select="name"/>!
          </fo:block>
        </fo:flow>
      </fo:page-sequence>
    </fo:root>
  </xsl:template>
</xsl:stylesheet>



You can get all information regarding it syntax and its basic knowledge.

http://www.w3schools.com/xslfo/

Remember, name.xml and name2fo.xml should be place in CLASSPATH.

Step 8:
Now configure fop factory to generate PDF file.


 
Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, out);
Or 
FOUserAgent foUserAgent = fopFactory.newFOUserAgent(); 
Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF,foUserAgent, out);
 

Here,we can also create foUserAgent,you can change default behaviour of document generation.Multiple optional methods available in this object.

Step 9:
Create JAXP transformer to transform XSL document.JAXP is for XML processing.
This template is reusable.It is like a cache so that it will process XSL file only once and can reused multiple times.


 
TransformerFactory factory = TransformerFactory.newInstance(); 
 
Templates template = factory.newTemplates(new StreamSource(new File("name2fo.xsl"))));
 

Step 10:
Create Sourecs Stream of XML data.

Source src = new StreamSource(new File("name.xml"));

Step 11:
Apache is using SAX event based API.Hence FO file is send to FOP in the form of SAX events must be piper otherwise it will have nagative impact in performance.


Result res = new SAXResult(fop.getDefaultHandler());

Step 12 :
Startinng JAXP ,trast XSLT transformation and consequesncili it starts sending output to FOP,FOP starts its processsing in Baground.When transform() method return,finished,FO had finished its PDF generation.


transformer.transform(src, res);

That's it ! we have almost done all of setting in this tutorial and generated simple PDF.

Simple Scenario here is that 
1.      XML        --- >  XSL-FO    :it is done by JAXP-complient XSLT processor
2       XSL-FO  --- >  PDF           :it is done bt FOP 

I have maintained tutorial as simple as possible by avoiding complex technical terms if you have not earlier aware. If you have any complaint or suggestion please mail me at oomph.fortuity@gmail.com

References:
http://xmlgraphics.apache.org/fop/1.1/









Popular posts from this blog

Share data between Iframe and its Parent using JQuery

There could be requirement that you have to pass variables values to Iframe from parent or in other scenario you have to pass values from Iframe to its parent.I am going to show simple example of above situation with the help of JQuery.
           Support we have parent HTML page having iframe included like below

<html> <body> <input id="parentValue" type="text" value="I am from Parent !" /> <iframe src="domainurl/relativepath" id="iframe"></iframe> <script> $(document).ready(function() { //code to take value from child iframe var childValue = $("#iframe").contents().find("#childValue").val(); alert(childValue); }); </script> </body> </html> 
        and we have frame code like below
<html> <body> <input id="childValue" type="text" value="I …

Spring Default Limit for Collection and Array is 256

If you are working in Web Application Development then you may stuck or already had ,then you will get mad of getting this error


java.lang.ArrayIndexOutOfBoundsException:Arrayindexoutofrange256
How this error emanates in Spring?

i will explain you with example.Suppose you are adding Values in List in JSP using JSTL tag or other.
This list is in Form(HTML).When you POST this form,In behind Stage,Spring does binding of Object and List if present.

But wait...
In Spring,Default limit for array and collection growing is 256.

Why this limit is Set?

seldom you have to send List size greater than this limit.
Spring has set this limit to avoid notable OutOfMemoryErrors in case of large indexes.

So,than What if i want to set Collection greater than this size?

I had told earlier,spring does binding behind.If we tell spring to increase it's size or set collection size behalf of spring.
You you can do it.

We have initBinder,  in Spring  it is called when spring does the binding mechanism
e.g @Mod…