Using ColdFusion to Generate a Custom Word Document

An oldie but a goodie, ColdFusion can be used to generate Word documents. Here is a quick example of writing to and opening a Word document.

Create Word Template

Create a Word template by adding “placeholders” in the document. This is done by wrapping a keyword with % (percent) signs as such: %firstname%. Put in as many as you want and add any necessary formatting in Word. Your replacement text will pick up the formatting. Save the file as an RTF (.rtf). For simplicity sake, put it in the same directory as the CF file used to generate it. Here an RTF file called homeworkpass.rtf is used.

Collect the Data

This example uses form fields to fill the document. Data from a database could be used just as easily. It’s a pretty standard form, nothing special.

<form action="index.cfm" method="post">
    <fieldset>
    <legend>Homework Pass Info</legend>
    <p><label for="expirydate">Expiration Date:</label><br />
    <input type="text" id="expirydate" name="expirydate" value="#DateFormat(DateAdd('d',10,Now()),'mm/dd/yy')#" /></p>

    <p><label for="points">Points:</label><br />
    <input type="text" id="points" name="points" value="100" /></p>

    <p><label for="studentname">Student Name:</label><br />
    <input type="text" id="studentname" name="studentname" /></p>

    <p><label for="subject">Subject:</label><br />
    <input type="text" id="subject" name="subject" /></p>

    <p><label for="datereceived">Date Received:</label><br />
    <input type="text" id="datereceived" name="datereceived" value="#DateFormat(Now(),'mm/dd/yy')#" /></p>
    </fieldset>

    <fieldset>
    <legend>Version of ColdFusion:</legend>
    <p><label><input type="radio" id="cfversion" name="cfversion" value="pre8" />CFMX or earlier</label><br />
    <label><input type="radio" id="cfversion" name="cfversion" value="post8" />CF8 or later</label></p>
    </fieldset>

    <p><input type="submit" name="submit" value="Generate Word" /></p>    
    </form>

Replace Text with ColdFusion

After a little error checking, the file is opened and the placeholders are swapped out with the form field values using the Replace() function in the homeworkpass.rtf.

<cfset error = "" />

<cfif isDefined("form.submit")>

	<cfloop collection="#form#" item="i">
		<cfif NOT Len(form[i]) OR  (NOT isDefined("form.cfversion"))>
			<cfset error = "All fields must have a value" />
		</cfif>
	</cfloop>
	
	<cfif NOT Len(error)>
    
    	<cfset pathToRTF =  GetDirectoryFromPath(GetCurrentTemplatePath()) & "homeworkpass.rtf" />        
    	
        <cflock name="homeworkpass" type="exclusive" timeout="30">
        
			<cfif form.cfversion EQ "pre8">
            <!--- CFMX7 or earlier --->
                <cffile action="read" file="#pathToRTF#" variable="rtf">
             <cfelse>
            <!--- CF8 or later --->
                <cfset rtf = FileRead(pathToRTF) />
            </cfif>
        
            <cfset rtf = Replace(rtf,"%expirydate%",form.expirydate) />
            <cfset rtf = Replace(rtf,"%points%",form.points) />
            <cfset rtf = Replace(rtf,"%studentname%",form.studentname) />
            <cfset rtf = Replace(rtf,"%subject%",form.subject) />
            <cfset rtf = Replace(rtf,"%datereceived%",form.datereceived) />
            
        </cflock>
    
        <cfheader name="content-disposition" value="filename=HomeworkPass.doc" />
   	 	
    	<cfcontent type="application/msword"><cfoutput>#rtf#</cfoutput>
    	<cfabort>
	
	</cfif>
	
</cfif>

There is a section here to allow for ColdFusion version specification. For ColdFusion 8 the FileRead() function can be used. All other versions of CF will need to use cffile.

<cfif form.cfversion EQ "pre8">
    	<!--- CFMX7 or earlier --->
    		<cffile action="read" file="#pathToRTF#" variable="rtf">
   		 <cfelse>
    	<!--- CF8 or later --->
    		<cfset rtf = FileRead(pathToRTF) />
    	</cfif>

Offering a choice for ColdFusion will not be necessary in production; it’s here for illustrative purposes only. At this time all versions of Word can open .doc files.

Output the Word File

To output the Word file use cfcontent and stop processing the rest of the page.

<cfcontent type="application/msword"><cfoutput>#rtf#</cfoutput>
    	<cfabort>

Download Files (zip)

To create multiple Word documents in a batch-like process see the Using ColdFusion to Generate Multiple Word Documents (Batch Creation) post.

Posted in ColdFusion, Web development. Tags: , . Permalink. Both comments and trackbacks are closed.

33 Comments

  1. Joe
    October 18, 2010 at 1:44 pm | Permalink

    Mohammed,

    I would seriously consider using cfreport's label feature instead and make the format="rtf".

  2. Joe
    October 18, 2010 at 1:40 pm | Permalink

    dsam,

    http://forums.techarena.in/office-update-service/1283466.htm

    Looks like there's not necessarily a solution as you have it because of security patches. So use <cfcontent type="application/rtf"> instead.

  3. Joe
    October 18, 2010 at 1:26 pm | Permalink

    Carlos,
    I would suggest that you create the document in Word that has the headers/footers, page breaks, etc. and use variables in it like ~CompanyName~, ~FirstName~, ~LastName~, etc. Save it as an rtf.
    Then copy the file to your server. Have Coldfusion read the file and do the replacements (replace()). Then serve the file back to the user via the cfcontent method that Jen describes above. Make sure you use the "all" parameter of the replace statement so that all variables are changed on every page (not just the first instance of the variable).