Todd has posted 4 posts at DZone. View Full User Profile

ColdFusion + Java = Easy, Rapid & Powerful

02.05.2008
| 8988 views |
  • submit to reddit

Many ColdFusion developers know that the underlying power of ColdFusion is Java. I've personally never written a line of Java, but I have taken advantage of this power by integrating some Java projects into my ColdFusion code. One example of such integration is my PPTUtils project. PPTUtils utilizes HSLF which is a sub-project of the larger and widely recognized Apache POI project. Here's a quick definition of HSLF from the project page:

HSLF is the POI Project's pure Java implementation of the Powerpoint '97(-2007) file format. It does not support the new PowerPoint 2007 .pptx file format, which is not OLE2 based.

HSLF provides a way to read powerpoint presentations, and extract text from it. It also provides some (currently limited) edit capabilities.

So at it's core HSLF allows users to interact with PowerPoint files. Pretty cool, but it gets cooler.

Integrating Java with ColdFusion is quite simple. If you have access you can simply drop your JAR files into the ColdFusion Classpath and restart ColdFusion. You can also use a Java Class Loader (my favorite was built by Mark Mandel) to dynamically load your Java libraries.

Using the HSLF Java library in my project was simple. I dropped the latest build of Apache POI into my project and created a simple ColdFusion Component (CFC) which loads the classes and provides a super simple API for reading PowerPoint files (including detailed formatting/layout) and extracting plain text or metadata. Compared to the sample implementations in Java I like to think that the ColdFusion code for converting/reading a PowerPoint file is now much simpler. Here is some sample code showing how easy it is to create results like this using ColdFusion.

<!--- get the path to the ppt --->
<cfset pptFile = expandPath("verity.ppt") />
<!--- create the pptutils object --->
<cfset pptutils = createObject("component", "pptutils.com.pptutils").init() />
<!--- get the ppt in html format --->
<cfset ppt = pptutils.readPowerPoint(pathToPPT=pptFile) />
<html>
<head>
</head>
<body>
<!---
<cfdump var="#ppt#">
<cfabort>
--->

<cfset imgStruct = structNew() />

<cfoutput>
<cfloop from="1" to="#arrayLen(ppt)#" index="i">
<cfset slide = ppt[i] />
<cfset imgName = "" />

<cfif len(slide.slideBackgroundImage.imgData) and listFindNoCase(getWriteableImageFormats(), slide.slideBackgroundImage.imgType)>
<cfset imgAsBase64 = toBase64(slide.slideBackgroundImage.imgData) />
<cfset findImgArr = structFindValue(imgStruct, imgAsBase64) />

<cfif not arrayLen(findImgArr)>
<cfset imgName = "bg_" & structCount(imgStruct) + 1 & "." & slide.slideBackgroundImage.imgType />
<cfset structInsert(imgStruct, imgName, imgAsBase64)>
<cfset bgImg = imageNew(slide.slideBackgroundImage.imgData) />
<cfset ImageScaleToFit(bgImg, slide.slideWidth, slide.slideHeight) />
<cfset imgDest = expandPath(imgName) />
<cfimage action="write" source="#bgImg#" destination="#imgDest#" overwrite="true" />
<cfelse>
<cfset imgName = findImgArr[1].key />
</cfif>
</cfif>

<div style="position:relative; height:#slide.slideHeight#px;width:#slide.slideWidth#px;background: url(#imgName#) no-repeat;"><!--- this div represents a slide --->
<!--- textboxes --->
<cfloop from="1" to="#arrayLen(slide.textBoxes)#" index="j">
<cfset tBox = slide.textBoxes[j] />
<div style="position:absolute; left:#tBox.x#px; top:#tBox.y#px; height:#tBox.height#px; width:#tBox.width#px;">
<cfloop from="1" to="#arrayLen(tBox.textSpans)#" index="k">
<cfset tSpan = tBox.textSpans[k] />
<div style="color:rgb(#tSpan.fontColor#); font-family:#tSpan.fontFamily#; font-size:#tSpan.fontSize#; font-weight:#tSpan.fontWeight#; text-align:#tSpan.textAlign#; text-decoration:#tSpan.textDecoration#;">
#repeatString(repeatString(" ", 3), tSpan.indentLevel)#<!--- <cfif len(tSpan.bulletChar)>#chr(tSpan.bulletChar)#</cfif> --->
#tSpan.text#
</div>
</cfloop>
</div>
</cfloop>
<!--- images --->
<cfloop from="1" to="#arrayLen(slide.images)#" index="k">
<cfset img = slide.images[k] />
<cfif listFindNoCase(getReadableImageFormats(), img.imgType)>
<cfset i = imageNew(img.imgdata) />
<cfset imageResize(i,img.width, img.height )>
<div style="position:absolute; left:#img.x#px; top:#img.y#px;">
<cfimage action="writeToBrowser" source="#i#">
</div>
</cfif>
</cfloop>
</div><!--- end slide --->
</cfloop>
</cfoutput>

</body>
</html>

So remember I said that it gets even cooler? The latest major release of ColdFusion (version 8) introduced a simple set of tags to make creating dynamic SWF based presentations super simple. The tag set (<cfpresentation>, <cfpresenter> and <cfpresentationslide>) lets you simply wrap the generated HTML and get a stunning SWF presentation (which can be written to disk or generated on the fly).

For links to all of my demos shown above (plus a few more) see my demo page. The PPTUtils project can be downloaded from RIAForge.

Published at DZone with permission of its author, Todd Sharp.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)