Skip to content

Instantly share code, notes, and snippets.

@learncfinaweek
Created November 20, 2012 21:32
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save learncfinaweek/4121316 to your computer and use it in GitHub Desktop.
Save learncfinaweek/4121316 to your computer and use it in GitHub Desktop.
Document Handling - cfdocument

cfdocument will take your combination of CFML and HTML and convert it to a PDF. At its simplest, you can stick some text between the opening and closing tags of cfdocument (there is currently no built-in cfdocument script equivalent) and it will render a PDF to the screen. Here is some sample code:

Creating a Simple PDF

<cfdocument format="PDF">
   <cfoutput>
   Bacon ipsum dolor sit amet sirloin fatback #dateformat(now(), "short")#
   </cfoutput>
</cfdocument>

What HTML is Supported?

It would be optimal if anything you produce in a browser will look exactly the same in the cfdocument generated PDF. However, cfdocument currently only supports HTML 4.01, XML 1.0, DOM Level 1 and 2, and CSS1 and CSS2. To be fair, the current support level will cover 90% of most HTML generation you attempt to do. There are 76 supported CSS styles; see http://help.adobe.com/en_US/ColdFusion/10.0/CFMLRef/WSc3ff6d0ea77859461172e0811cbec22c24-7c21.html for the entire list. Also note that if you have a Word file that you save HTML, the resulting PDF will not look anything like the Word document.

Setting Page Attributes

cfdocument has attributes that allow you to set margins, page size, page orientation, and passwords.

<!--- These attributes will create a password protected legal sized PDF with the following characteristics
Bottom Margin: 2.0 inches
Top Margin: 1 inch
Left Margin: 1/2 inch
Right Margin: 1 1/2 inch
User Password: secret123
Encrypted: 128-bit encryption
--->
<cfdocument format="PDF" pagetype="legal" marginbottom="2.0" margintop="1.0" marginleft="0.5" marginright="1.5" userpassword="secret123" encryption="128-bit">
   <cfoutput>
   Bacon ipsum dolor sit amet sirloin fatback #dateformat(now(), "short")#
   </cfoutput>
</cfdocument>

Headers, Footers & Page Breaks using cfdocumentitem

cfdocumentitem can be used to create PDF headers, footers, and page breaks. If you are not using cfdocumentsection (covered next), then where you place the cfdocumentitem in your HTML will make a difference as to how it affects the entire document.

<cfdocument format="PDF">
	<cfoutput>
		<cfdocumentitem type="header">
		    <h1 style="text-align:center;">BIG FANCY HEADER</h1>
		</cfdocumentitem>
		Bacon ipsum dolor sit amet sirloin fatback #dateformat(now(), "short")#
		<cfdocumentitem type="pagebreak"/>
		Bacon ipsum dolor sit amet sirloin fatback #dateformat(now(), "short")#
		<cfdocumentitem type="footer">
		    <h1 style="text-align:center;">Page #cfdocument.currentPageNumber# of #cfdocument.totalPageCount#</h1>
		</cfdocumentitem>
	</cfoutput>
</cfdocument>

cfdocumentsection

Sometimes you may want to create a PDF that does not have the same header and footer for every single page (like a title page), or you may have few pages that need different margins. To deal with this, you can use cfdocumentsection, which puts your HTML content into separate blocks, each of which can have their own settings for margins, headers, and footers defined in a cfdocumentitem nested in that cfdocumentsection.

<cfdocument format="PDF">
	<cfoutput>
		<!--- Section 1 --->
		<cfdocumentsection name="bookmark1">
		    <cfdocumentitem type="header">
		    <h1 style="text-align:center;">BIG FANCY HEADER</h1>
		    </cfdocumentitem>
		    Bacon ipsum dolor sit amet sirloin fatback #dateformat(now(), "short")#
		    <cfdocumentitem type="footer">
		    <h1 style="text-align:center;">Page #cfdocument.currentPageNumber# of #cfdocument.totalPageCount#</h1>
		    </cfdocumentitem>
		</cfdocumentsection>
	&lt;!--- Section 2 ---&gt;
	&lt;cfdocumentsection name="bookmark2"&gt;
	    &lt;cfdocumentitem type="header"&gt;
	    &lt;h1 style="text-align:center;"&gt;2nd page header&lt;/h1&gt;
	    &lt;/cfdocumentitem&gt;
	    Bacon ipsum dolor sit amet sirloin fatback #dateformat(now(), "short")#
	    &lt;cfdocumentitem type="footer"&gt;
	    &lt;h1 style="text-align:center;"&gt;Page #cfdocument.currentPageNumber# of #cfdocument.totalPageCount#&lt;/h1&gt;
	    &lt;/cfdocumentitem&gt;
	&lt;/cfdocumentsection&gt;
&lt;/cfoutput&gt;

</cfdocument>

Tips for Working with cfdocument

If you find that your application must use a lot of cfdocument, here are some tips for improving performance and rendering.

Avoid using relative file paths:

<!--- Don't use these below --->
<link rel="stylesheet" type="text/css" src="../assets/mainStyle.css">
<img src="../images/mypic.png">

<!--- INSTEAD use expand path to provide the full path to the file ---> <link rel="stylesheet" type="text/css" src="#expandPath('../assets/')#mainStyle.css"> <img src="#expandPath('../images/')#mypic.png">

Set the localURL attribute to yes. When you set this attribute of cfdocument to true, it tells ColdFusion to retrieve image files directly from the server rather by attempting to use HTTP.

@JamoCA
Copy link

JamoCA commented Sep 8, 2016

Please consider adding a "Alternative PDF Generator" section. I've been communicating with other developers that are using third-party Java, C and command line solutions because of rendering issues with CFDocument. It appears that the version of IceBrowser/iText that is used is from 2008. (New licensing fees are probably cost preventing Adobe from upgrading.)
https://twitter.com/gamesover/status/752530433481568256

Instead of spending hours attempting to tweak HTML to get it to look close to what I want, I started experimenting with WKHTMLTOPDF, an open source (LGPLv3) command line tools to render HTML into PDF and various image formats using the Qt WebKit rendering engine. I've found that it's able to quickly produce high quality PDFs with consistent results using ColdFusion 8, 9, 10, 11 & 2016. (I can even generate PDFs offline without using any CFThreads... no Enterprise license required.) It supports all markup that is renderable by WebKit. This means better support for CSS3 (ie, rounded corners) and support for javascript delay, SVG (high quality logos) & webfonts (FontAwesome icons)! You can add headers & footers that are evaluated on-the-fly. I have some related blog posts here:
https://gamesover2600.tumblr.com/search/wkhtmltopdf

What other CF alternatives are being used by other ColdFusion developers... and what CFDocument problems did it solve?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment