Creating PDF and FlashPaper output with the cfdocument tag



The cfdocument tag converts everything between its start and end tags into PDF or FlashPaper output format and returns it to the browser or saves it to a file. As a result you can easily convert HTML to printable output, as the following example shows:

<cfdocument format="FlashPaper"> 
<p>This is a document rendered by the cfdocument tag.</p> 
</cfdocument>

The cfdocument tag supports all HTML and CFML tags, with the following exceptions:

  • cfchart

  • Tags that generate content displayed in Flash Player.

  • Interactive tags, such as form, cfform, and cfapplet

  • JavaScript that dynamically modifies elements or element positions

Additionally, the HTML wrapped by the cfdocument tag must be well-formed, with end tags for every start tag and proper nesting of block-level elements.

Note: ColdFusion does not return HTML and CFML outside the <cfdocument></cfdocument> pair.

Creating basic reports from HTML and CFML

You can convert HTML-based reports into PDF or FlashPaper output by wrapping the HTML in the cfdocument start and end tags, and specifying cfdocument attributes, as appropriate, to customize the following items:

  • Page size

  • Page orientation

  • Margins

  • Encryption (PDF only)

  • User password and owner password (PDF only)

  • Permissions (PDF only)

For complete information on these options, see the cfdocument tag discussion in the CFML Reference.

Note: Embedding fonts in the report can help ensure consistent display across multiple browsers and platforms. For more information on the considerations related to embedding fonts, see Creating a simple report.

The following example displays a list of employees, using a cfoutput tag to loop through the query:

<cfdocument format="flashpaper"> 
<h1>Employee List</h1> 
<!--- Inline query used for example purposes only. ---> 
<cfquery name="EmpList" datasource="cfdocexamples"> 
    SELECT FirstName, LastName, Salary, Contract 
    FROM Employee 
</cfquery> 
<cfoutput query="EmpList"> 
#EmpList.FirstName#, #EmpList.LastName#, #LSCurrencyFormat(EmpList.Salary)#, 
    #EmpList.Contract#<br> 
</cfoutput> 
</cfdocument>

Creating sections, headers, and footers

You can use the cfdocument and cfdocumentsection tags to fine-tune your printable output, as follows:

  • cfdocumentitem: Creates page breaks, headers, or footers.

  • cfdocumentsection: Divides output into sections, optionally specifying custom margins. Within a section, use the cfdocumentitem tag to specify unique headers and footers for each section. Each document section starts on a new page.

The cfdocumentitem tag

You use one or more cfdocumentitem tags to specify headers and footers or to create a page break. You can use cfdocumentitem tags with or without the cfdocumentsection tag, as follows:

  • With cfdocumentsection: The cfdocumentitem attribute applies only to the section, and overrides previously specified headers and footers.

  • Without cfdocumentsection: The cfdocumentitem attribute applies to the entire document, as follows:

    • If the tag is at the top of the document, it applies to the entire document.

    • If the tag is in the middle of the document, it applies to the rest of the document.

    • If the tag is at the end of the document, it has no affect.

You can use the cfdocumentitem tag to create a running header for an entire document, as the following example shows:

<cfdocument format="PDF"> 
<!--- Running header ---> 
<cfdocumentitem type="header"> 
    <font size="-3"><i>Directory Report</i></font> 
</cfdocumentitem> 
<h3>cfdirectory Example</h3> 
<!--- Use cfdirectory to display directories by name and size ---> 
<cfdirectory 
    directory="#GetDirectoryFromPath(GetTemplatePath())#" 
    name="myDirectory" recurse="yes" 
    sort="directory ASC, name ASC, size DESC"> 
<!---- Output the contents of the cfdirectory as a cftable -----> 
<cftable query="myDirectory" 
    htmltable colheaders> 
    <cfcol header="DIRECTORY:" text="#directory#"> 
    <cfcol header="NAME:" text="#Name#"> 
    <cfcol header="SIZE:" text="#Size#"> 
</cftable> 
</cfdocument>

The cfdocumentsection tag

When using cfdocumentsection, all text in the document must be enclosed within cfdocumentsection tags. ColdFusion ignores HTML and CFML outside cfdocumentsection tags. The margin attributes override margins specified in previous sections or in the parent cfdocument tag. If you specify margin attributes, the unit attribute of the parent cfdocument tag control the units; the default for the unit attribute is inches.

Within a section, use the cfdocumentitem tag to specify unique headers and footers for each section and a page break before each section, as the following example shows:

<cfquery datasource="cfdocexamples" name="empSalary"> 
SELECT Emp_ID, firstname, lastname, e.dept_id, salary, d.dept_name  
FROM employee e, departmt d 
WHERE e.dept_id = d.dept_id 
ORDER BY d.dept_name 
</cfquery> 
 
<cfdocument format="PDF"> 
    <cfoutput query="empSalary" group="dept_id"> 
        <cfdocumentsection> 
            <cfdocumentitem type="header"> 
                <font size="-3"><i>Salary Report</i></font> 
            </cfdocumentitem> 
            <cfdocumentitem type="footer"> 
            <font size="-3">Page #cfdocument.currentpagenumber#</font> 
            </cfdocumentitem>         
            <h2>#dept_name#</h2> 
            <table width="95%" border="2" cellspacing="2" cellpadding="2" > 
            <tr> 
                <th>Employee</th> 
                <th>Salary</th> 
            </tr> 
        <cfset deptTotal = 0 > 
        <!--- inner cfoutput ---> 
        <cfoutput> 
            <tr> 
                <td><font size="-1"> 
                #empSalary.lastname#, #empSalary.firstname#</font> 
                </td> 
                <td align="right"><font size="-1"> 
                #DollarFormat(empSalary.salary)#</font> 
                </td> 
            </tr> 
        <cfset deptTotal = deptTotal + empSalary.salary>             
        </cfoutput> 
            <tr> 
                <td align="right"><font size="-1">Total</font></td> 
                <td align="right"><font size="-1">#DollarFormat(deptTotal)#</font></td> 
            </tr> 
            <cfset deptTotal = 0> 
            </table> 
        </cfdocumentsection> 
    </cfoutput> 
</cfdocument> 

Using the cfdocument scope

When you use the cfdocument tag, ColdFusion creates a scope named cfdocument. This scope contains the following variables:

currentpagenumber
Displays the current page number.

totalpagecount
Displays the total page count.

currentsectionpagenumber
Displays the current section number.

totalsectionpagecount
Displays the total number of sections.

Note: You can use the cfdocument scope variables in expressions within the cfdocumentitem tag only.

You typically use these variables in a header or footer to display the current page number and total number or pages, as the following example shows:

<cfdocumentitem type= "footer> #cfdocument.currentpagenumber# of 
    #cfdocument.totalpagecount#</cfdocumentitem>

Creating bookmarks in PDF files

You can use the cfdocumentbookmark attribute to create bookmarks for each section within a PDF document, as the following example shows:

<cfdocument format="PDF" bookmark="yes"> 
    <cfdocumentitem type="header"> 
    <font size="-1" align="center"><i>Building Better Applications</i></font> 
    </cfdocumentitem> 
    <cfdocumentitem type="footer"> 
    <font size="-1"><i>Page <cfoutput>#cfdocument.currentpagenumber# of 
        #cfdocument.totalpagecount#</cfoutput></i></font> 
    </cfdocumentitem> 
    <cfdocumentsection name="Introduction"> 
        <h3>Introduction</h3> 
        <p>The introduction goes here.</p> 
    </cfdocumentsection> 
    <cfdocumentsection name="Chapter 1"> 
        <h3>Chapter 1: Getting Started</h3> 
        <p>Chapter 1 goes here.</p> 
    </cfdocumentsection> 
    <cfdocumentsection name="Chapter 2"> 
        <h3>Chapter 2: Building Applications</h3> 
        <p>Chapter 2 goes here.</p> 
    </cfdocumentsection> 
    <cfdocumentsection name="Conclusion"> 
        <h3>Conclusion</h3> 
        <p>The conclusion goes here.</p> 
    </cfdocumentsection> 
</cfdocument>

The bookmarks appear in the bookmarks panel of the PDF document.

Using cfhttp to display web pages

You can use the cfhttp tag in combination with the cfdocument tag to display entire web pages in PDF or FlashPaper output format, as the following example shows:

<!--- You can pass a URL in the URL string ---> 
<cfparam name="url.target_url" default="http://www.boston.com"> 
<cfoutput> 
<cfhttp url="#url.target_url#" resolveurl="yes"> 
 
<cfdocument format="FlashPaper"> 
<cfdocumentitem type="header"> 
    <cfoutput>#url.target_url#</cfoutput> 
</cfdocumentitem> 
<cfdocumentitem type="footer"> 
    <cfoutput>#cfdocument.currentpagenumber# / #cfdocument.totalpagecount#</cfoutput> 
</cfdocumentitem> 
<!--- Display the page ---> 
#cfhttp.filecontent# 
</cfdocument> 
</cfoutput>

Using advanced PDF options

The cfdocument tag supports the Acrobat security options, as the following table shows:

Security option

Description

Encryption

Use the encryption attribute to specify whether PDF output is encrypted. Specify one of the following:

  • 128-bit

  • 40-bit

  • none

User password

Use the userpassword attribute to specify a password that users must enter to view the document.

Owner password

Use the ownerpassword attribute to specify a password that users must enter to view and optionally modify the document.

Additionally, the cfdocument tag supports the following Acrobat security permissions through the permissions attribute. Specify one or more of the following values; separate multiple permissions with a comma:

Permission

Description

Printing

Specify the AllowPrinting attribute to enable viewers to print the document.

Modification

Specify the AllowModifyContents attribute to let viewers modify the document, assuming they have the required software.

Copy

Specify the AllowCopy attribute to let viewers select and copy text from the document.

Annotation

Specify AllowModifyAnnotations to let viewers add comments to the document. If users add annotations, they must save the PDF after making changes.

Screen readers

Specify AllowScreenReaders to enable access to the document through a screen reader.

Fill in

Specify AllowFillIn to enable users to use form fields.

Assembly

Specify AllowAssembly to enable users to create bookmarks and thumbnails, as well as insert, delete, and rotate pages.

Degraded printing

Specify AllowDegradedPrinting to enable lower-resolution printing. This format prints each page as a bitmap, so printing can be slower.

Note: The defaults for these options vary, based on encryption level. These options apply to PDF only. For more information, see the cfdocument discussion in the CFML Reference.

The following example creates a PDF document that allows copying only:

<cfdocument format="PDF" encryption="40-bit" 
    ownerpassword="us3rpa$$w0rd" userpassword="us3rpa$$w0rd" 
    permissions="AllowCopy" > 
<h1>Employee List</h1> 
<cfquery name="EmpList" datasource="cfdocexamples"> 
    SELECT FirstName, LastName, Salary 
    FROM Employee 
</cfquery> 
<cfoutput query="EmpList"> 
    #EmpList.FirstName#, #EmpList.LastName#, #LSCurrencyFormat(EmpList.Salary)#<br> 
</cfoutput> 
</cfdocument>

Saving printable reports in files

You can use the cfdocument filename attribute to save the generated PDF or SWF content to a file, as the following example shows:

<!--- The compasstravel database is part of the Getting Started 
    tutorial application, found under the cfdocs directory. ---> 
<cfquery datasource="compasstravel" name="compasstrips"> 
SELECT tripName, tripDescription, tripLocation, price 
FROM trips 
ORDER BY price 
</cfquery> 
<cfdocument format="pdf" 
        filename="#GetDirectoryFromPath(GetTemplatePath())#/compasstrips.pdf" 
        overwrite="yes"> 
    <cfdocumentsection>  
        <h1 align="center">Compass Travel</h1> 
        <h2 align="center">Destination Guide</h2> 
        <p align="center"><img src="cfdocs/getting_started/photos/somewhere.jpg"></p> 
    </cfdocumentsection>  
    <cfdocumentsection>  
        <cfdocumentitem type="header"> 
            <font size="-3"> <i>Compass Travel Trip Descriptions</i></font> 
        </cfdocumentitem>  
        <cfdocumentitem type="footer">  
            <font size="-3">  
                <cfoutput>Page #cfdocument.currentpagenumber#</cfoutput> 
            </font>  
        </cfdocumentitem>  
        <cfoutput query="compasstrips">  
            <hr> 
            <h2>#tripName#</h2> 
            <p><b>#tripLocation#</b></p> 
            <p>Price: #DollarFormat(price)#</p> 
            <p>#tripDescription#</p> 
        </cfoutput>  
    </cfdocumentsection>  
</cfdocument>