Export ViewObject data to PDF file using Apache PDFBox

Sharing is Caring

Hello All
Hope you all are doing well ūüôā

This post is about exporting view object data in a pdf file directly from af:table , export to excel is built in feature of ADF but exporting data in PDF requires little bit of extra effort
So here for this requirement I am using ApachePDFBox library , previously I have posted about using this API to create PDF file from text data
I know many of you will not visit that link ūüėČ So a quick overview

What is Apache PDFBox

The Apache PDFBox library is an open source Java tool for working with PDF documents. This project allows creation of new PDF documents, manipulation of existing documents and the ability to extract content from documents. Apache PDFBox also includes several command line utilities.

Let’s implement this

    • Create a Fusion Web Application and prepare model using Departments table of HR Schema

 

 

    • Add PDFBox jar to view controller project

 

 

    • Drop Departments view object as table on page and add two buttons to Export All Rows and Export Selected Row

 

 

  • Now see the managed bean code that exports viewObject data to PDF file , Idea is to add viewObject data in a multi dimensional array and then iterate over array to draw a table in pdf Go through the comments to understand code part

Packages and Helper method-

 

import java.io.IOException;

import javax.faces.event.ActionEvent;

import oracle.adf.model.BindingContext;
import oracle.adf.model.binding.DCIteratorBinding;

import oracle.binding.BindingContainer;

import oracle.jbo.Row;
import oracle.jbo.RowSetIterator;
import oracle.jbo.ViewObject;

import org.apache.pdfbox.exceptions.COSVisitorException;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.edit.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDType1Font;

 

 /**
     * Generic Method to call operation binding**/
    public BindingContainer getBindingsCont() {
        return BindingContext.getCurrent().getCurrentBindingsEntry();
    }

 

Method to Export All Rows of ViewObject to PDF-

 

    /**Method to export all rows of viewObject to PDF
     * @param actionEvent
     * @throws IOException
     */
    public void exportAllRowsToPdfAction(ActionEvent actionEvent) throws IOException {
        //Create new PDF Document
        PDDocument document = new PDDocument();
        PDPage page = new PDPage();
        document.addPage(page);
        PDPageContentStream contentStream = new PDPageContentStream(document, page);

//Get the iterator of af:table on page
DCIteratorBinding iter = (DCIteratorBinding) getBindingsCont().get(‚ÄúDepartmentsVO1Iterator‚ÄĚ);
//No of total rows+ 1 for array sizing
int totRows = ((int) iter.getEstimatedRowCount()) + 1;
//Here 4 is the number of columns
String[][] content = new String[totRows][4];

int column = 4;
//Set header text in first row of table in PDF
content[0][0] = ‚ÄúDepartment Id‚ÄĚ;
content[0][1] = ‚ÄúDepartment Name‚ÄĚ;
content[0][2] = ‚ÄúManager Id‚ÄĚ;
content[0][3] = ‚ÄúLocation Id‚ÄĚ;

//Get viewObject from iterator and Iterate over it to add all data in array
ViewObject vo = iter.getViewObject();
RowSetIterator rsi = vo.createRowSetIterator(null);
int i = 1;
while (rsi.hasNext()) {
Row nextRow = rsi.next();

for (int j = 0; j < column; j++) {
System.out.println(i + ‚Äú‚ÄĚ + j);
if (j == 0 && nextRow.getAttribute(‚ÄúDepartmentId‚ÄĚ) != null) {
content[i][j] = nextRow.getAttribute(‚ÄúDepartmentId‚ÄĚ).toString();
}
if (j == 1 && nextRow.getAttribute(‚ÄúDepartmentName‚ÄĚ) != null) {
content[i][j] = nextRow.getAttribute(‚ÄúDepartmentName‚ÄĚ).toString();
}
if (j == 2 && nextRow.getAttribute(‚ÄúManagerId‚ÄĚ) != null) {
content[i][j] = nextRow.getAttribute(‚ÄúManagerId‚ÄĚ).toString();
}
if (j == 3 && nextRow.getAttribute(‚ÄúLocationId‚ÄĚ) != null) {
content[i][j] = nextRow.getAttribute(‚ÄúLocationId‚ÄĚ).toString();
}
}
i++;
}
rsi.closeRowSetIterator();
//Write data to PDF
writeToPdf(contentStream, content);

contentStream.close();
try {
//Save generated pdf document in a drive
document.save(‚ÄúD:\Departments.pdf‚ÄĚ);
} catch (COSVisitorException e) {
}
}

 

Method to Export Selected Row of ViewObject to PDF-

 

    /**Method to export selected row to PDF
     * @param actionEvent
     * @throws IOException
     */
    public void exportCurRowToPdfAction(ActionEvent actionEvent) throws IOException {
        //Create new PDF Document
        PDDocument document = new PDDocument();
        PDPage page = new PDPage();
        document.addPage(page);
        PDPageContentStream contentStream = new PDPageContentStream(document, page);

//Get the iterator of af:table on page
DCIteratorBinding iter = (DCIteratorBinding) getBindingsCont().get(‚ÄúDepartmentsVO1Iterator‚ÄĚ);
//Define the array for two rows only
String[][] data = new String[2][4];

//Set header text in first row of table in PDF
data[0][0] = ‚ÄúDepartment Id‚ÄĚ;
data[0][1] = ‚ÄúDepartment Name‚ÄĚ;
data[0][2] = ‚ÄúManager Id‚ÄĚ;
data[0][3] = ‚ÄúLocation Id‚ÄĚ;

//Get current row of Iterator and insert data in array
Row row = iter.getCurrentRow();

if (row.getAttribute(‚ÄúDepartmentId‚ÄĚ) != null) {
data[1][0] = row.getAttribute(‚ÄúDepartmentId‚ÄĚ).toString();
}
if (row.getAttribute(‚ÄúDepartmentName‚ÄĚ) != null) {
data[1][1] = row.getAttribute(‚ÄúDepartmentName‚ÄĚ).toString();
}
if (row.getAttribute(‚ÄúManagerId‚ÄĚ) != null) {
data[1][2] = row.getAttribute(‚ÄúManagerId‚ÄĚ).toString();
}
if (row.getAttribute(‚ÄúLocationId‚ÄĚ) != null) {
data[1][3] = row.getAttribute(‚ÄúLocationId‚ÄĚ).toString();
}
//Write data to PDF
writeToPdf(contentStream, data);

contentStream.close();
try {
//Save generated pdf document in a drive
document.save(‚ÄúD:\Departments.pdf‚ÄĚ);
} catch (COSVisitorException e) {
}
}

 

Method to draw table in PDF ‚Äď

 

    /**Method to draw table on pdf using array of data
     * @param page
     * @param contentStream
     * @param y
     * @param margin
     * @param content
     * @throws IOException
     */
    public static void writeToPdf(PDPageContentStream contentStream, String[][] data) throws IOException {
        final int rows = data.length;
        final int cols = data[0].length;

//Height for each row
final float rowHeight = 20f;
//Width of table drawn
final float tableWidth = 550;

//Total table height
final float tableHeight = rowHeight * rows;
//Width of each column
final float colWidth = tableWidth / (float) cols;
final float cellMargin = 5f;
//Margin from left
float margin = 20;
//Margin from top (Increase value to decrease margin)
float y = 750;
//draw the rows
float anoy = y;

for (int i = 0; i <= rows; i++) {
contentStream.drawLine(margin, anoy, margin + tableWidth, anoy);
anoy -= rowHeight;
}

//Draw the columns
float anox = margin;
for (int i = 0; i <= cols; i++) {
contentStream.drawLine(anox, y, anox, y ‚Äď tableHeight);
anox += colWidth;
}

//Setting for font and size
contentStream.setFont(PDType1Font.COURIER_BOLD, 10);

float textx = margin + cellMargin;
float texty = y ‚Äď 15;
for (int i = 0; i < data.length; i++) {
for (int j = 0; j < data[i].length; j++) {
if (data[i][j] != null) {
String text = data[i][j];

contentStream.beginText();
contentStream.moveTextPositionByAmount(textx, texty);
contentStream.drawString(text);
contentStream.endText();
textx += colWidth;
}
}
texty -= rowHeight;
textx = margin + cellMargin;
}
}

All Done ūüôā Now run and check application

Sample ADF Application (Jdeveloper 12.1.3)- Download
Cheers ūüôā Happy Learning

Related Posts

An Oracle ACE, Blogger, Reviewer, Technical Lead working on Oracle ADF

0 thoughts on “Export ViewObject data to PDF file using Apache PDFBox”

  1. This is terribly inefficient. It will take a very long time to create detailed pdf which includes multiple view objects with and without master-child relationships. Instead of this, I strongly recommend using Oracle Bi Desktop Publisher libraries instead of pdfbox, creating java class to convert view objects to xml, and pass that xml to the Publisher libraries. Then all you need to do is draw .rtf template in word and pass it as input to Publisher as well. I can provide example if you want.

  2. This is for a single viewObject , If you need to create detailed report then you can use any report tool like jasper and call that in application using integration libraries or the way you suggested above ūüôā

Leave a Reply

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