See all tutorials

Tutorials » How to generate a simple PDF file

This tutorial is a simple introduction on how Webpagebytes CMS framework can be used to generate PDF documents. Although the PDF document will be very simple the purpose is to get an understanding of the technology and the steps involved in this PDF generation. More advance tutorials about PDF files will follow.

Webpagebytes CMS can generate text based content (html, xml, json, plain text and so on) which can be static or dynamic. XLS-FO (XSL Formatting Objects) is a W3C specification that can be used to generate PDF documents by using Apache FOP print formatter (or other print formatter tools).

To generate the PDF file with Webpagebytes CMS take the following steps

Write a simple XLS-FO content

Step 1

In Webpagebytes CMS administration web interface create a site page with the following XSL-FO content

<?xml version="1.0" encoding="UTF-8"?>
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set>
<fo:simple-page-master master-name="A4" page-width="210mm" page-height="297mm" margin="10mm">
    <fo:region-body margin-top="10mm" />
    </fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="A4" initial-page-number="1">
    <fo:title> Webpagebytes CMS PDF example</fo:title>
    <fo:flow flow-name="xsl-region-body">
        <fo:block>
           First PDF with Webpagebytes CMS!           
        </fo:block>
    </fo:flow>
</fo:page-sequence>
</fo:root>

Implement a controller and use Apache FOP

Step 2

The controller will fetch the site page with XLS-FO content and with Apache FOP will generate the PDF document, which will be returned as the request response.
One of the previous tutorials ( How to fetch content to create other content ) covered the content fetch feature of the Webpagebytes CMS. The same feature is applied here too.

package com.example;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.stream.StreamSource;
import org.apache.fop.apps.Fop;
import org.apache.fop.apps.FopFactory;
import org.apache.fop.apps.MimeConstants;
import com.webpagebytes.cms.WPBContentProvider;
import com.webpagebytes.cms.WPBForward;
import com.webpagebytes.cms.WPBModel;
import com.webpagebytes.cms.WPBRequestHandler;
import com.webpagebytes.cms.exception.WPBException;

public class SimplePDFController implements WPBRequestHandler {

    WPBContentProvider contentProvider;    
    private FopFactory fopFactory;
    private TransformerFactory transformerFactory;

    @Override
    public void initialize(WPBContentProvider contentProvider) 
    {
        this.contentProvider = contentProvider;        
        transformerFactory = TransformerFactory.newInstance();
        fopFactory = FopFactory.newInstance();
    }

    @Override
    public void handleRequest(HttpServletRequest request,
            HttpServletResponse response, WPBModel model, WPBForward forward)
            throws WPBException 
    {
        String pageGuid = model.getCmsModel().get(WPBModel.URI_PARAMETERS_KEY).get("pageGuid");
               
        ByteArrayOutputStream bos = new ByteArrayOutputStream(1000);
        contentProvider.writePageContent(pageGuid, model, bos);
        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
        
        response.setContentType("application/pdf");
        
        OutputStream os = null;
        try
        {
            os = response.getOutputStream();         
            Transformer transformer = transformerFactory.newTransformer();
            Source source = new StreamSource(bis);
            Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, os);
            Result res = new SAXResult(fop.getDefaultHandler());
            transformer.transform(source, res);
        
        } catch (Exception e)
        {
            throw new WPBException("cannot generate pdf", e);
        }          
    }
}

Expose a site url to get the PDF file

Step 3

Create a site url and use the previous controller to generate the response content. There needs to be created also a customization parameter named 'pageGuid' with the site page external key that contains the XLS-FO content.

Test the PDF generation

Step 4

Open a browser and navigate to http://[your_server_and_port]/pdf to get the generated PDF file.

Fork me on GitHub