Some thoughts on Sage CRM, FOP, PDF and Reports

2 minute read time.
Sage CRM uses Apache FOP (Formatting Objects Processor) to generate its reports in PDF format.

See http://xmlgraphics.apache.org/fop/

FOP is an example of a print formatter that uses XSL formatting objects (XSL-FO) and is in theory not tied to outputting in a particular format, although its usage in Sage CRM is designed around creating PDF files.

When Sage CRM is installed it gets installed with it in the

C:\Program Files\FOP

folder.

The interaction with FOP for the reports creation is controlled within the Administration area under

Administration -> E-mail and Documents -> Documents & Reports Configuration



We can see that FOP is called via a batch file (FOP.bat) and this in turn calls the Java application that reads a formatting object (FO) tree and renders the resulting pages to PDF.

We can see where the "Adobe Converter Parameter String" field in the screen shot above reads

-q %1 %2

The -q means quiet mode. The %1 is the input file and the %2 is the output file.

The input file is created in the folder
C:\Program Files\Sage\CRM\[installname]\WWWRoot\Temp\Temporary Report Files

initially as a tmp file and then as an XML file.

The output file is then created in

C:\Program Files\Sage\CRM\[installname]\WWWRoot\Temp\Temporary Adobe Files

Once the file has been converted the temp XML file is removed.

In theory you may be able to use FOP directly yourself within an ASP page.

A simple way of use FOP to generate PDF files is to use the inbuilt Sage CRM actions. For example if you have a need to create a Report like a Summary Report button on a custom new entity then you could add a button to the ASP page. Like this:



//Example to show how to build a button that calls a custom report from a screen.
//intReportAction is either 1410 to display the report options or 1411 to directly run the report
//var intReportAction = 1410;
var intReportAction = 1411;
//Allowed values for strDestination are "Screen", "Adobe", "CSV", "Excel"
var strDestination = "Adobe";
var strSummaryReportButton = CRM.Button("Print to Excel", "executesummaryreport.gif", CRM.URL(intReportAction)+" &Key41=31 &FlgNewWindow=True &Destination="+strDestination+" &PageSize=210x297 &Orientation=Landscape", "", "", "EWARE_HELP")

myBlock.AddButton(strSummaryReportButton);



The Action code 1411 means that the report is generated as a PDF file. You will have to take care and identify the primary key value for the report. This report ID is the value in the parameter key41.

Although the above button definition is for the ASP COM API, the same basic principle can be used for the .NET API.
  • Danny

    I don't at the moment. I will try and see what I can find out.

  • Do you have any examples of code to accomplish that?

  • The button example above prints the report to PDF because the Destination=Adobe in the url is a flag passed into the eWare dll along with the system action 1411. This causes the report to be run serverside to generate the PDF file.

    Your button example that calls an ASP page will just call the page as normal. You would have to call the page and with the ASP code identify that the output was to generate to PDF, and then send the HTML of the page to POP or another html to pdf conversion program on the server. Once the pdf file is created on the server the ASP page could redirect to it and load that with in the browser.

  • I have a custom summary screen that I would like to be able to print as PDF. I added the following code to my summary screen to add the print button. However it does not open up a pdf with my screen to print. This code is opening up a new window with the contents I want to print in it. How can I make it so it opens the content as a pdf to print?

    var strDestination = "Adobe";

    var strSummaryReportButton = CRM.Button("Print", "print.gif", CRM.URL("CustomSummary.asp")+"&cust_customentityid="+Id+"&FlgNewWindow=True&Destination="+strDestination+"&PageSize=210x297&Orientation=Landscape", "", "", "EWARE_HELP")

    AddButton(strSummaryReportButton);