Thursday, November 14, 2013

Creating a PDF dynamically from an XPage - Part 2

In my first post on the subject of creating PDF's dynamically from an Xpage, I went over the research that needs to be done prior to starting.   In this post I will first give an overflow of the workflow and then go into two specific problems I encountered while trying to get a working proof of concept.

Like I said in my last post, this process is fairly complicated.  I drew up this chart to show the workflow process.   To see a better workflow chart (not drawn in windows paint) see this one from Stephan Wissel.

Step 1:  User presses button, the code behind the button simply sets a sessionScope variable and the calls an xAgent Xpage.

Step 2:   The xAgent code first gets the XML from the backend data by calling a method of an utility class I wrote.  The method uses the generateXML() method of the 'Document' class.   The method will also gather XML from the line items documents as well, and merge them into a single XML document (I haven't wrote this part yet).

Step 3:  The xAgent calls a Java class which uses Apache FOB to transform XML into PDF.   It passes it the XML String and a URI to the location of the XSL stylesheet.

Step 4:  The transformation happens on the server and then presents the user with a dialog box to open or save the PDF.

Problem #1:   Can't get a Writer while an OutputStream is already in use Exception.  

This Exception is caused whenever you have any type of error in the SSJS of your xAgent.    In my case, I was modifying code written by Paul Calhoun.   I missed that there was an package statement that hadn't been changed.   I went ahead and put a Stack Overflow before figuring out what happened.   On my SO question, Tim Tripcony gave me an excellent answer on why that exception was happening and how to avoid it.   Even if you have no interest in creating PDF's you will be smarter for having read it.

Even after figuring this out, I did several things that caused the same exception.   In this context I would translate the exception to mean "Something is wrong with the code in your xAgent"  The best thing to do here it undo what you just did and figure out why the server is choking on your code.  Consider this a generic exception that can be caused by any number of issues.

Problem #2:  Getting a "WrappedRuntimeException" when trying to pass the XML to the Transformer

This problem really confused me until I turned to Stack Overflow and got a great answer from who else but Stephan Wissel.  Looking back, I should have seen this as it was obvious after the fact.  The Transformer class was expecting a URI String that points to the XML to transform.   I was passing it the actual String XML.   This was what caused the exception.  I had to modify the Transformer class slightly to convert the String XML to a StreamSource object that it was expecting.  (If I was using the same Transformer class for views, I would have changed it prior to passing it, I still should probably do this.)

Next Post

In the next post, I will explain how to created the XSL stylesheet, and my challenges with that.  I will also tell how XPath fits into all this.


  1. Hi, have you already looked at the project POI 4 XPages from openNTF ? Cheers.

    1. Isn't that only for exports to Excel? I do have a new requirement to export to Excel so I may be using it as well. Thanks for the feedback.

  2. POI4XPages supports Export to Excel, CSV, Word and for Word the Option to export as PDF. In the most PDF Case its the best to have a Word Document and then fill the values.

  3. If you have any question about POI4XPages let my know

    1. Thanks Christian! I just might take you up on that.