Making PD4ML available in ColdFusion® Web application

v3.x

The described integration method was tested with ColdFusion MX 6.1 enterprise and development editions running under Jrun4

Copy pd4ml.jar, pd4ml_tl.jar and pd4ml.tld (pd4ml_demo.jar, pd4ml_tl_demo.jar and pd4ml.tld) to the directory WEB-INF/lib of your CF-enabled application. By default it is ${jrun4}/servers/cfusion/cfusion-ear/cfusion-war/WEB-INF/lib

Restart the CF runtime!

Creating a PD4ML-enabled .cfm page

<cfimport taglib="/WEB-INF/lib/pd4ml.tld" prefix="pd4ml"><pd4ml:transform
       screenWidth="400"
       pageFormat="A5"
       pageOrientation="landscape"
       pageInsets="15,15,15,15,points"
       enableImageSplit="false"
       inline="true"
       fileName="myreport.pdf"
       encoding="ISO8859_1"
       interpolateImages="false">
 
<pd4ml:header
       titleTemplate="$[title]"
       pageNumberTemplate="page $[page]"
       titleAlignment="left"
       pageNumberAlignment="right"
       color="##008000"
       initialPageNumber="1"
       pagesToSkip="1"
       fontSize="14"
       areaHeight="18"/>
<html>
<head>
<title>Hello, CF!</title>
<style>
       td {
             font-family: "Sans-Serif";
             font-size: 12;
       }
</style>
</head>
<body>
 
<img src="images/logos.gif" width="125" height="74">
<p>
<font face="tahoma">Hello, CF!</font>
 
<p>
<cfoutput>
Today's date is #DateFormat(Now(), "dd.mm.yyyy")#
</cfoutput>
<p>
 
<table border="0" width="300">
 
<cfloop index = "LoopCount" from = "1" to = "25">
       <cfset x = variables.LoopCount mod 2 >
 
       <tr>
       <cfoutput>
       <cfif variables.LoopCount IS "1">
             <td bgcolor="##d0d0d0">Euros</td>
             <td bgcolor="##d0d0d0">Dollars</td>
             <td bgcolor="##d0d0d0">Pounds</td>
       <cfelseif variables.x IS NOT "1">
             <td>#LoopCount * 10# &##128;</td>
             <td>#LoopCount * 10# $</td>
             <td>#LoopCount / 10 * 2# £</td>
       <cfelse>
             <td bgcolor="##e7e7e7">#LoopCount * 10# &##128;</td>
             <td bgcolor="##e7e7e7">#LoopCount + 17# $</td>
             <td bgcolor="##e7e7e7">#LoopCount / 10 * 2# £</td>
       </cfif>
       </cfoutput>
       </tr>
 
</cfloop>
 
</table>
 
</body>
</html>
</pd4ml:transform>
Comments:
  • There is no any white space character before tag. If there are any, then they appear in the resulting PDF file and corrupt it.
  • '#' characters have special meanings in ColdFusion. The character in the PD4ML header color definition is unescaped by duplication of '#'

Troubleshooting

The type for attribute authorName of tag transform could not be determined
Jrun engine needs to be restarted. Newly installed PD4ML tag library is not known to the runtime.

MS Internet Explorer 6.0 and Acrobat Reader 6.0.1 (or its newer version) show blank screen instead of resulting PDF. The problem is not existent with other browsers and Acrobat Reader's versions
Rename your .cfm page to .pdf and add the corresponding file extensions mapping to WEB-INF/web.xml. Access the page using the new name ended with .pdf (instead of .cfm).

The extension mapping code to be added:

<servlet-mapping>
    <servlet-name>CfmServlet</servlet-name>
    <url-pattern>*.pdf</url-pattern>
</servlet-mapping>

<pd4ml:page.break/> causes an error
It seems Jrun4 does not allow dots in custom JSP tag names. To fix the issue open WEB-INF/lib/pd4ml.tld in text editor, duplicate (copy-paste) page.break tag description section. In the copied section replace page.break tag name with page_break. And than replace <pd4ml:page.break/> tags in your .cfm code with <pd4ml:page_break/>

Integration of PD4ML with ColdFusion Standard edition

Unfortunately not all runtime modes of ColdFusion allow to use JSP tag libraries. In that case the only way to integrate PD4ML is to use PD4ML Java API.

The following is the integration example .cfm contributed by David REYNAUD:

<html>
<head>
<title>PD4ML under CFMX 6.x Std Edition</title>
</head>
 
<body>
<!---
BEFORE RUNNING :
Idea 1 :
put the JAR file : pd4ml_demo.jar
in the same folder as current CFM page
Idea 2 :
maybe you can put the JAR file : pd4ml_demo.jar
into the ColfdFusion's CustomTags directory
Idea 3 :
use the ColdFusion Admin to configure classpath to use the jar
--->
<cfscript>
	// The source file to convert (http:// or file:)
	inURI="file:n:/web/tests/pd4ml/test.html";
	// The pdf file to generate (full pathname)
	fileOut="n:/web/tests/pd4ml/test.pdf";

	unnitsvalue="mm"; // Millimeters
	// A4 'vertical' in mm
	format = createObject("java","java.awt.Dimension").init(210,297);
	topValue = 10; // mm
	leftValue = 10; // mm
	rightValue = 10; // mm
	bottomValue = 10; // mm
	landscapevalue="yes";

	userSpaceWidth=780; // px
	splitValue=0;
	patchValue=1;

	authorName="";

	// PD4ML Object instantiation
	pd4ml = createObject("java","org.zefer.pd4ml.PD4ML");

	// Format, orientation, insets
	if (landscapeValue) format = pd4ml.changePageOrientation(format);
		insets = createObject("java","java.awt.Insets").init(topValue,leftValue,bottomValue,rightValue);
	if (unnitsvalue EQ "mm") {
		pd4ml.setPageSizeMM(format);
		pd4ml.setPageInsetsMM(insets);
	} else {
		pd4ml.setPageSize(format);
		pd4ml.setPageInsets(insets);
	}

	if(authorName NEQ "")
		pd4ml.setAuthorName(authorname);

	if (userSpaceWidth NEQ "") 
		pd4ml.setHtmlWidth( userSpaceWidth );
		
	pd4ml.enableImgSplit( splitValue );
	pd4ml.enableRenderingPatch( patchValue );

	fos = createObject("java","java.io.FileOutputStream").init(fileOut);
	pd4ml.render(inURI,fos); // Start rendering
 
</cfscript>
<cfoutput>File '#inURI#' converted to '#fileOut#'</cfoutput>
</body>
</html>