Search code examples
coldfusiondocument

Download CFM page as Word Doc


I'm trying to render the output of a .cfm into a Word doc using cfinclude like so:

<cfheader name="content-disposition" value="attachment; filename=""MyDocument.doc""" />
<cfcontent type="application/msword" reset="true">
<cfinclude template="PageToDownload.cfm">

Since cfinclude outputs the .cfm as html, this should theoretically work. However, doing this downloads a document that errors in Word with "A text/xml declaration may occur only at the very beginning of input." I inspected the downloaded document with Notepad++ and saw this at the top:


<?xml version="1.0" encoding="UTF-8"?>
<!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>
...

If I remove the empty line, the ?xml, and the !DOCTYPE (basically cut off everything up to <html), this document opens in Word. Is it possible to strip off the xml and DOCTYPE tags and start at <html using cfinclude? Or, is there another approach I should take?


Solution

  • Using your technique, what you can do is put the contents of PageToDownload.cfm into a variable using <cfsavecontent>. Once the contents are in said variable, you could strip out everything prior to the opening <html> tag and then <cfoutput> that variable after your <cfheader> and <cfcontent> statements.

    Your code could look something like this.

    <!--- Save contents of file to download into fileContents variable --->
    <cfsavecontent variable="fileContent">
        <cfinclude template="PageToDownload.cfm">
    </cfsavecontent>
    
    <!--- Strip out contents prior to the opening <html> tag --->
    <cfset pos = findNoCase("<html", fileContent)>
    <cfset fileContent = mid(fileContent, pos, 1000000)>
    
    <!--- Output fileContent after the header statements --->
    <cfheader name="content-disposition" value="attachment; filename=""MyDocument.doc""" />
    <cfcontent type="application/msword" reset="true">
    <cfoutput>#fileContent#</cfoutput>