Oracle Technologies Primer

July 22, 2011

Creating A PDF Document within a BPEL Process

Quite recently I had this requirement in one of my project to create a PDF snapshot from a BPEL Process. The PDF document was required to be archived and contain a brief detail of key business indicators for the order and also whether the was processed manually or automatically.

The business requirement thus set it was now evident that we needed to define a schema to extract the key order indicators and use it in an Embedded Java activity inside a BPEL process to call a custom piece of Java code that create a PDF document.

Defining the schema

Here is snapshot of the schema I choose to create to describe the Order Indicators for a Sales Order Instance.


The Order message is intercepted in the bpel process to determine whether it is to be processed manually or automatically.

A first Look at the PDF

Creating an instance and letting the Order process manually I was able to derive a PDF capturing the order summary at an archived location. The below screenshot shows how the document looked like.


Creating the Process

The first step in the process would be to instantiate a salesOrderIndicator variable based on the above schema and extract information from the Sales Order payload inside the BPEL process.

I created a custom Java class to print a PDF document using the iText api for Java.

The library can be obtained from sourceforge here

Create a Java project in JDeveloper and name it OrderApprovalDocument. Add the Itextpdf-5.1.1.jar to the project classpath.


The OrderApprovalDocument class will create an instance of PdfWriter, take in value from the BPEL JAVA Embedded activity and create the pdf document in a tabular format.

package com.beatech.salesapp;

import com.itextpdf.text.BadElementException;
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.Image;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.Barcode;
import com.itextpdf.text.pdf.BarcodeEAN;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;

import java.awt.Color;


import java.util.Date;
import java.util.Iterator;
import java.util.Map;

public class OrderApprovalDocument {
public OrderApprovalDocument() {

private static Font catFont =new Font(Font.FontFamily.HELVETICA, 11, Font.BOLD);
private static Font redFont =new Font(Font.FontFamily.TIMES_ROMAN, 9, Font.NORMAL, BaseColor.RED);
private static Font subFont =new Font(Font.FontFamily.HELVETICA, 6, Font.BOLD);
private static Font smallBold =new Font(Font.FontFamily.HELVETICA, 8, Font.BOLD);

public void createPDFSummary( Map varMap, String approvalStatus)

String fileName = "c:/Arrun/OrderApprovalSnapshot_"+(String)varMap.get("PURCHASE ID")+".pdf";

try {
Document document = new Document();
PdfWriter writer =PdfWriter.getInstance(document, new FileOutputStream(fileName));;
addContent(document,writer,varMap, approvalStatus);
} catch (Exception e) {

// iText allows to add metadata to the PDF which can be viewed in your Adobe Reader under File -> Properties

private static void addDocumentMetaData(Document document) {
document.addTitle("Order Approval Summary");
document.addSubject("Sales Order Summary Document");
document.addKeywords("Sales Orchestraction Project,Order Approval Summary");
document.addAuthor("Sales Orchestraction Project");
document.addCreator("Sales Orchestraction Project");

private static void addDocumentTitle(Document document, Map contentMap) throws DocumentException {
Paragraph preface = new Paragraph();
// Adding one empty line
addEmptyLine(preface, 1);
// Adding a Document header
preface.add(new Paragraph("APPROVAL FLOW FOR ORDER : " + (String)contentMap.get("PURCHASE ID"), catFont));
addEmptyLine(preface, 1);
// A Small body: Report generated by  _Name, _Date
preface.add(new Paragraph("Report Generated by Order Approval Flow,  " +new Date(), redFont));
addEmptyLine(preface, 2);


private static void addContent(Document document, PdfWriter writer, Map contentMap, String approvalStatus) throws DocumentException {
// Add a table
createTable(document, writer,contentMap, approvalStatus);

private static void createTable(Document document, PdfWriter writer, Map varMap, String approvalStatus) throws BadElementException, DocumentException {
PdfPTable table = new PdfPTable(3);

PdfPCell c1 = new PdfPCell(new Phrase("ORDER APPROVAL SUMMARY", new Font(smallBold)));
c1.setBorderColor(new BaseColor(Color.RED));
c1.setBorder( Rectangle.BOX);
PdfContentByte cb = writer.getDirectContent();
BarcodeEAN codeEAN = new BarcodeEAN();

String s= "000000000000"+(String)varMap.get("PURCHASE ID"); // twelve zeros prepended

Image imageEAN = codeEAN.createImageWithBarcode(cb, null, null);
c1 = new PdfPCell(imageEAN,false);

c1 = new PdfPCell(new Phrase("ORDER ID",new Font(smallBold)));
c1.setBorderColor(new BaseColor(Color.RED));
c1.setBorder( Rectangle.BOX);

c1 = new PdfPCell(new Phrase((String)varMap.get("PURCHASE ID"),new Font(smallBold)));
c1.setBorderColor(new BaseColor(Color.RED));
c1.setBorder( Rectangle.BOX);

c1 = new PdfPCell(new Phrase("KEY INDICATORS",new Font(smallBold)));
c1.setBorderColor(new BaseColor(Color.RED));
c1.setBorder( Rectangle.BOX);
Iterator entries = varMap.entrySet().iterator();
while (entries.hasNext()) {
Map.Entry entry = (Map.Entry);
c1 = new PdfPCell(new Phrase( (String)entry.getKey(),new Font(subFont)));
c1.setBorderColor(new BaseColor(Color.RED));
c1.setBorder( Rectangle.BOX);

c1 = new PdfPCell(new Phrase((String)entry.getValue(),new Font(subFont)));
c1.setBorderColor(new BaseColor(Color.RED));
c1.setBorder( Rectangle.BOX);
c1.setBackgroundColor(new BaseColor(255,181,188));


c1 = new PdfPCell(new Phrase("APPROVAL STATUS",new Font(subFont)));
c1.setBorderColor(new BaseColor(Color.RED));
c1.setBorder( Rectangle.BOX);
c1 = new PdfPCell(new Phrase(approvalStatus,new Font(subFont)));
c1.setBorderColor(new BaseColor(Color.RED));
c1.setBorder( Rectangle.BOX);
c1.setBackgroundColor(new BaseColor(227,7,7));

private static void addEmptyLine(Paragraph paragraph, int number) {
for (int i = 0; i < number; i++) {
paragraph.add(new Paragraph(" "));


Feel free to add your own custom style to the pdf. You can even add your corporate logo into the snapshot. :-)

Secondly use the Embedded Java Activity from the BPEL process to call this custom class and pass a Map containing the key indicators for the sales order instance.

You can even pass the entire XML from the embedded java activity and unmarshall the XML in the custom class. Its a matter of choice.


Here is the java code for the embedded activity

System.out.println("<<<=====================Entering JAVA Embedding===============================>>>");
Map variableMap = new HashMap();
// Setting the Map
variableMap.put("FULFILMENT ID",((XMLElement)getVariableData("salesOrderIndicator","/ns12:SALOrderIndicator/ns12:fulfillmentID")).getFirstChild().getNodeValue());

variableMap.put("ORDER GUID",((XMLElement)getVariableData("salesOrderIndicator","/ns12:SALOrderIndicator/ns12:orderGUID")).getFirstChild().getNodeValue());

variableMap.put("PURCHASE ID",((XMLElement)getVariableData("salesOrderIndicator","/ns12:SALOrderIndicator/ns12:purchaseID")).getFirstChild().getNodeValue());

variableMap.put("ORDER AMOUNT",((XMLElement)getVariableData("salesOrderIndicator","/ns12:SALOrderIndicator/ns12:orderAmount")).getFirstChild().getNodeValue());

variableMap.put("DISCOUNT AMOUNT",((XMLElement)getVariableData("salesOrderIndicator","/ns12:SALOrderIndicator/ns12:discountAmount")).getFirstChild().getNodeValue());

variableMap.put("TAX AMOUNT",((XMLElement)getVariableData("salesOrderIndicator","/ns12:SALOrderIndicator/ns12:taxAmount")).getFirstChild().getNodeValue());

variableMap.put("PROMISED SHIP TIME",((XMLElement)getVariableData("salesOrderIndicator","/ns12:SALOrderIndicator/ns12:promisedShipDateTime")).getFirstChild().getNodeValue());

variableMap.put("BOOKING TIME",((XMLElement)getVariableData("salesOrderIndicator","/ns12:SALOrderIndicator/ns12:bookingDateTime")).getFirstChild().getNodeValue());

if(((XMLElement)getVariableData("ruleProcessingResponse","payload","/ns20:callFunctionStatefulDecision/ns20:resultList/ns21:OrderClass/ns21:isManualOrder")).getFirstChild().getNodeValue()  == "true")
// Calling the Custom Class with the Map and approval status
OrderApprovalDocument createDoc = new OrderApprovalDocument();
catch (Exception e)
System.out.println("<<<=====================Leaving JAVA Embedding===============================>>>");

Open the .bpel file inside the composite and import the required classes for the Java Embedding activity using the <bpelx:exec/> extension.


Create a JAR from the custom java class project as OrderApprovalDocument.jar and add it to the classpath of the composite project.


Also copy the OrderApprovalDocument.jar into the SCA-INF\lib directory of the project inside the composite application.

Deploy the onto the soa server of the SOA Suite 11g runtime domain and test the process with a simple order message.

You can see the generated PDF in the directory mentioned in the custom java class. The pdf file is appended with the instance order number.



  1. […] my previous post I had described how we can create a custom Java Class to save custom business indicators in a […]

    Pingback by Archiving Audit Diagrams as Images in Oracle SOA Suite BPM Processes « Oracle Technologies Premier — July 26, 2011 @ 4:10 pm

  2. the Java embedding approach is very interesting and I was not aware of that thanks.

    As an alternative I would like to show you the XSLFO approach, you can create a XSLFO template and call the Apache FOP servlet with HTTP there is a description here:

    Comment by Jon — October 30, 2011 @ 8:09 pm

    • Hi Jon, I was not aware of the XSLFO approach and it looks very interesting. However the documentation available to use it to generate a PDF from a BPEL process is not exhaustive. Is there a way that PDF’s can be formatted?

      Comment by Arun Pareek — October 31, 2011 @ 2:27 am

  3. I used an alternative approach for achieving the same.
    I wrote the same java code using iText Pdf jars and exposed that java code as a web service which was deployed on the same weblogic server.
    Hence, now, all services can use the same external java as a Partner link in their BPEL.

    The same can be done using Apache XSL-FO too.


    Comment by punix — January 2, 2012 @ 6:56 pm

  4. Hi,i want to say something.
    1. First, explore any standard Java 2 PDF generator APIs / Softwares. Apache may have one. In my earlier project, I used Open Source iText APIs, to create really very Complex PDF documents totally from Java. It has complex Fonts, colors, Tables, Graphichs, add images, header, footers etc etc including barcodes also in pdf itself. (From Apache)
    2. So first develop a simple HelloWorld sample using one of above APIs and use the data in this to generate the PDFs, Once you explore and do all this, you are all set.
    Now coming to your requirement:
    1. Create a XSD Schema, that takes input data elements that should go into PDF file. Create a Response XSD schema also, that may send back details of files created etc etc.
    2. Create a WebService with one service, one port and couple of operations. Example create one operation like generatePdf(). Use above schema elements. Create the WebService. NOW in the actual generated Service class, for this Operation use your hello world sample code to create the PDFs. The most important thing is the location to Store the PDF File. you can store it in Database table or in File System. If it is FileSystem, make sure you can control the location using some properties file. Because it can be on Windows or Unix. So this should be dynamic.
    3. First Run the WebService client and pass the data and make sure that the pdf file is created in the location you specified.
    Now comes the actual BPEL process where you use all the above. Create a BPEL process that calls this webservice and passes in the input payload. WebService generats the pdf file (if No Errors) in a specific laotion. Now have a FILE Adapater component read this file and send the response down to further process. I hope you got the point.
    The important thing is generation of PDF file from Java which any BPEL or Oracle cannot do by default. You should do this using some java apis. Once file is there, you can pretty much do anything uisng BPEL or WebService.

    Comment by bobbell2 (@bobbell222) — November 4, 2014 @ 7:43 am

RSS feed for comments on this post. TrackBack URI

Post your comments and suggestions here

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

The Silver is the New Black Theme. Blog at

Adam Deane

Business Process and Workflow

Oracle Technologies Primer

Technical posts on OSB/WLS/AIA, Oracle SOA Suite, BPM and Fusion Middleware

SOA Community Blog

by Jürgen Kress

Technical posts on OSB/WLS/AIA, Oracle SOA Suite, BPM and Fusion Middleware

Rubicon Red

Technical posts on OSB/WLS/AIA, Oracle SOA Suite, BPM and Fusion Middleware

J@n van Zoggel

mumblings of a middleware minion

Oracle .. Java .. OpenSource .. SOA

Just another weblog

Nitin's Oracle Fusion Middleware and SOA World

SOA FMW BPM BPEL OSB Governance J2EE and all the Geeky stuff


Musings on Integration with Oracle Fusion Middleware


Get every new post delivered to your Inbox.

Join 927 other followers

%d bloggers like this: