Another day in the life of a ColdFusion drone

This may be of use to the handful of people in the universe who: 1. use ColdFusion; 2. have no direct access to their Coldfusion server; 3. need to manipulate PowerPoint on the server; and 4. aren’t using .NET

OK, the three of you who are still reading may continue.

So I’m trying to do this via COM and ColdFusion’s cfobject tag.

First, I waited a couple months for the people who run the server to get PowerPoint installed on the server. Then I dusted off some old code from CF Comet.

My code looked like this:

<cfobject TYPE="com" NAME="objPPT" CLASS="PowerPoint.Application" ACTION="connect">
<cfobject TYPE="com" NAME="objPPT" CLASS="PowerPoint.Application" ACTION="create">

presentationsCollection = objPPT.Presentations;

myPresentation = presentationsCollection.Open("D:xxxmaingetppt.ppt", False, False, False);

newpresentation = objPresentation.SaveAS("D:xxxmainnew.ppt",11, True);
// Close a presentation

objPresentation.Close();

// Quit PowerPoint

objPPT.Quit();

Here was my error the first time I ran the script. (Note: path and file names have been altered)
An exception occurred when executing a Com method.
The cause of this exception was that: AutomationException: 0x80004005 -
PowerPoint could not open the file. in 'Microsoft Office PowerPoint 2003'.

Updated April 2009

Thank you Todd for noticing that somehow my posting got completely botched in the copy and paste process. Here is a working example of a ColdFusion file that uses COM to open a powerpoint pre-loaded onto the server, add data, and then save the new file into a location on the server where the user can download it

Also available as a text file

<cfset VARIABLES.localpath = “D:\rootfolder\subfolder\”>

<cfset VARIABLES.remotepath = “http://someurl/”>

<cfset VARIABLES.pptext = “.ppt”>

<cfset VARIABLES.sourcefile = “testppt”>

<cfset VARIABLES.nowdate = tostring(DateFormat(Now(),’yyyymmdd’))>

<cfset VARIABLES.nowtime = tostring(TimeFormat(Now(),’hhmmss’))>

<cfset VARIABLES.newfile = trim(VARIABLES.nowdate) & trim(VARIABLES.nowtime)>

<cfset VARIABLES.basefilepath = VARIABLES.localpath & VARIABLES.sourcefile & VARIABLES.pptext>

<cfset VARIABLES.newfilepath = VARIABLES.localpath & VARIABLES.newfile & VARIABLES.pptext>

<cfset VARIABLES.newurl = VARIABLES.remotepath & VARIABLES.newfile & VARIABLES.pptext>

<cfquery name=”Query” datasource=”datasource”>

some query to populate chart

</cfquery>

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>

<html xmlns=”http://www.w3.org/1999/xhtml”>

<head>

<meta http-equiv=”Content-Type” content=”text/html; charset=iso-8859-1″ />

<title>PowerPoint Creator</title>

</head>

<body>

<cftry>

<CFOBJECT

TYPE=”com”

NAME=”objPPT”

CLASS=”PowerPoint.Application”

ACTION=”connect”>

<cfcatch>

<CFOBJECT

TYPE=”com”

NAME=”objPPT”

CLASS=”PowerPoint.Application”

ACTION=”create”>

</cfcatch>

</cftry>

<!—

kudos to

http://www.cfregex.com/cfcomet/forum/ViewThread.cfm?ThreadID=F09104FE-1802-684D-687BF5A8897E7E1F

—>

<cfset presentationsCollection = objPPT.Presentations>

<cfscript>

//open as readonly

myPresentation = presentationsCollection.Open(VARIABLES.basefilepath, True, False, False);

//The presentation object has a slides collection

if (isDebugMode()) writeOutput(“Creating collection”);

CollSlides = myPresentation.Slides;

//The first param defines the number of slides.

//The second parameter defines the slide layout

//Figured out blank by trial and error

//blank = 12

//blank with title = 11

ObjSlide = CollSlides.Add(1, 11);

// This chunk of code creates a title. I know it’s a lot just to create a title, but Powerpoint has a lot of classes.

slideShape = ObjSlide.Shapes;

newShape = slideShape.Title;

myTextFrame = newShape.TextFrame;

myTextRange = myTextFrame.TextRange;

myTextRange.Text = “This is the Title”;

// This is how to add more text to the slide.

bodyShape = SlideShape.AddTextBox(1, 200, 300, 700, 100);

bodyShapeTextFrame = bodyShape.TextFrame;

bodyShapeTextRange = bodyShapeTextFrame.TextRange;

bodyShapeTextRange.Text = “This is some additional text”;

//add table

//http://skp.mvps.org/ppttable.htm

//AddTable(NumRows, NumColumns, Left, Top, Width, Height)

//

//Somewhere I read you couldn’t stack your arguments (this.that.theother) more than two deep

//This doesn’t seem to be true.

//

//Define the most rows that can display on a page

imaxrows = 10;

//How many rows returned by query?

irowct = Query.RecordCount;

//have to account for record count of 0, or we’ll have issues

//note the nify use of integer division and mod

if (irowct GT imaxrows)

inumslides = funcnumslides(irowct, imaxrows);

function funcnumslides(i1, i2){

inumint = i1 \ i2;

inummod = i1 mod i2;

if (inummod GT 0)

return inumint + 1;

else

return inumint;

}

ObjSlide = CollSlides.Add(inumslides, 11);

bodyShape = SlideShape.AddTable(imaxrows,1,30,110,660,320);

oTable = bodyShape.Table;

oCell = oTable.Cell(1,1);

try {

otext = oCell.Shape.TextFrame.TextRange;

rsltText = Query.RecordCount;

otext.Text = rsltText;

}

catch(Any excpt)

{

WriteOutput(“#excpt.Message#”);

}

newpresentation = myPresentation.SaveAS(VARIABLES.newfilepath, 11, True);

// Close a presentation

myPresentation.Close();

//Quit PowerPoint

objPPT.Quit();

</cfscript>

<p>Your file is ready for <a href = “<cfoutput>#VARIABLES.newurl#</cfoutput>”>download</a>.
On opening you will be asked to allow macros. Click OK.</p>

</body>

</html>

Share and Enjoy:
  • Print
  • Digg
  • StumbleUpon
  • del.icio.us
  • Facebook
  • Yahoo! Buzz
  • Twitter
  • Google Bookmarks
  • LinkedIn
  • Technorati
  • Tumblr
This entry was posted in ColdFusion, Web Design and tagged , . Bookmark the permalink.

Comments are closed.