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>










