Export table as a PDF file in ADF

You have learned how to export table as Excel and XML files, now you will learn how to export table as a PDF file using the Apache FOP. Apache FOP (Formatting Objects Processor) is a print formatter driven by XSL formatting objects (XSL-FO) and an output independent formatter. Output formats currently supported include PDF, PS, PCL, AFP, XML, Print, AWT, PNG, RTF and TXT.

Download the sample application: ADFPDFApp.zip.

First of all, we need to transform the data of employees to XML.
To achieve it, look at this blog post: Export table as XML file in ADF.

With some changes, we will be able to export table as a PDF file.
Go to ViewController Project Properties and add Apache FOP libs.

export-table-as-a-pdf-file-in-adf1

export-table-as-a-pdf-file-in-adf2

Create a PDF Template (XML file) under Web Content/stylesheets folder and name it as employeesfo.xsl.
Copy the following code inside employeesfo.xsl file.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.1" exclude-result-prefixes="fo" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
  <xsl:output method="xml" version="1.0" omit-xml-declaration="no" indent="yes"/>
  <!--=========================-->
  <!--root element: Employees-->
  <!--=========================-->
  <xsl:template match="Employees">
    <fo:root>
      <fo:layout-master-set>
        <fo:simple-page-master master-name="simpleA4" page-height="29.7cm" page-width="21cm" margin-top="2cm" margin-bottom="2cm" margin-left="2cm" margin-right="2cm">
          <fo:region-body/>
        </fo:simple-page-master>
      </fo:layout-master-set>
      <fo:page-sequence master-reference="simpleA4">
        <fo:flow flow-name="xsl-region-body">
          <fo:block font-size="16pt" font-weight="bold" space-after="5mm">Employees</fo:block>
          <fo:block font-size="10pt">
            <fo:table table-layout="fixed" width="100%" border-collapse="separate">
              <fo:table-column column-width="4cm"/>
              <fo:table-column column-width="4cm"/>
              <fo:table-column column-width="4cm"/>
              <fo:table-column column-width="4cm"/>
              <fo:table-header text-align="center" background-color="silver" font-weight="bold">
                <fo:table-row>
                  <fo:table-cell padding="1mm" border-style="solid">
                    <fo:block>ID</fo:block>
                  </fo:table-cell>
                  <fo:table-cell padding="1mm" border-style="solid">
                    <fo:block>First Name</fo:block>
                  </fo:table-cell>
                  <fo:table-cell padding="1mm" border-style="solid">
                    <fo:block>Last Name</fo:block>
                  </fo:table-cell>
                  <fo:table-cell padding="1mm" border-style="solid">
                    <fo:block>Job Id</fo:block>
                  </fo:table-cell>
                </fo:table-row>
              </fo:table-header>
              <fo:table-body>
                <xsl:apply-templates select="Employee"/>
              </fo:table-body>
            </fo:table>
          </fo:block>
        </fo:flow>
      </fo:page-sequence>
    </fo:root>
  </xsl:template>
  <!--=========================-->
  <!--child element: Employee-->
  <!--=========================-->
  <xsl:template match="Employee">
    <fo:table-row>
      <fo:table-cell>
        <fo:block>
          <xsl:value-of select="EmployeeId"/>
        </fo:block>
      </fo:table-cell>
      <fo:table-cell>
        <fo:block>
          <xsl:value-of select="FirstName"/>
        </fo:block>
      </fo:table-cell>
      <fo:table-cell>
        <fo:block>
          <xsl:value-of select="LastName"/>
        </fo:block>
      </fo:table-cell>
      <fo:table-cell>
        <fo:block>
          <xsl:value-of select="JobId"/>
        </fo:block>
      </fo:table-cell>
    </fo:table-row>
  </xsl:template>
</xsl:stylesheet>

export-table-as-a-pdf-file-in-adf3

Add two methods inside EmployeesBean class to get the PDF template and generate the PDF file.
Open the EmployeesBean class and add the following code:

private static String TEMPLATE_PDF_EMPLOYEES = "stylesheets/employeesfo.xsl";

private static FopFactory fopFactory = FopFactory.newInstance();

private static TransformerFactory tFactory = TransformerFactory.newInstance();

private InputStream getTemplate(String template) {
  FacesContext facesContext = FacesContext.getCurrentInstance();
  return facesContext.getExternalContext().getResourceAsStream(template);
}

private void convertDOM2PDF(Node xml, InputStream template, OutputStream out) {
  try {
    // configure foUserAgent as desired
    FOUserAgent foUserAgent = fopFactory.newFOUserAgent();

    try {
      // Construct fop with desired output format and output stream
      Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, out);

      // Setup Identity Transformer
      TransformerFactory factory = TransformerFactory.newInstance();
      Transformer transformer = factory.newTransformer(new StreamSource(template));

      // Setup input for XSLT transformation
      Source src = new DOMSource(xml);

      // Resulting SAX events (the generated FO) must be piped through to FOP
      Result res = new SAXResult(fop.getDefaultHandler());

      // Start XSLT transformation and FOP processing
      transformer.transform(src, res);
    } finally {
      out.close();
    }

  } catch (Exception e) {
    e.printStackTrace(System.err);
  }
}

export-table-as-a-pdf-file-in-adf4

Rename the exportSelectedRowsToXML method to exportSelectedRowsToPDF.
Remove try-catch block from exportSelectedRowsToPDF method and add the following code:

try {
  convertDOM2PDF(rs.writeXML(0, XMLInterface.XML_OPT_ALL_ROWS), getTemplate(TEMPLATE_PDF_EMPLOYEES), outputStream);
} catch (Exception e) {
  e.printStackTrace();
}

export-table-as-a-pdf-file-in-adf5

Rename the exportAllRowsToXML method to exportAllRowsToPDF.
Remove try-catch block from exportAllRowsToPDF method and add the following code:

try {
  convertDOM2PDF(vo.writeXML(0, XMLInterface.XML_OPT_ALL_ROWS), getTemplate(TEMPLATE_PDF_EMPLOYEES), outputStream);
} catch (Exception e) {
  e.printStackTrace();
}

export-table-as-a-pdf-file-in-adf6

The empView.jsf file contains an employees table and two buttons to export rows as PDF file.
Go to source tab and change the properties of af:fileDownloadActionListener tags.

export-table-as-a-pdf-file-in-adf7

Now, when you run the application, you can export all rows as a PDF File.

export-table-as-a-pdf-file-in-adf8

You can export only the selected rows as a PDF File too.

export-table-as-a-pdf-file-in-adf9

Waslley Souza

Author: Waslley Souza

Consultor Oracle com foco em tecnologias Oracle Fusion Middleware e SOA. Certificado Oracle WebCenter Portal, Oracle ADF e Java.

3 thoughts on “Export table as a PDF file in ADF”

    1. Hi Eric!
      Open the EmployeesBean class and change MimeConstants.MIME_PDF to MimeConstants.MIME_RTF.
      Open the empView.jsf page and change the contentType property to application/rtf and filename property to .rtf
      You don’t need to change the template file.

Leave a Reply

Your email address will not be published. Required fields are marked *