Generating PDFs in ColdFusion

2.2k views Asked by At

I have an application for customer and product management that has many screens/pages. I would like certain pages to be printable and exportable to PDF.

To print a document, its a simple case of providing a CSS stylesheet for @Print media which strips a lot of the regular styling. However, when generating the PDF I noticed the <cfdocument> and <cfhtmltopdf> tags both want the an entire HTML page to render (including <head> tags).

This means that it doesn't recognise the purpose of the PDF as being for print and doesn't pick up the @Print styles. Currently I'm having to make a seperate makepdf.cfm page and repeat the HTML of the page I want to export along with including ONLY the print CSS stylesheet.

This seems a bit crazy because I'll have to update the makepdf.cfm page each and everytime I change a main application screen that can be printed/exported to pdf.

Is there a better way to achieving what I'm trying to do?

2

There are 2 answers

2
snackboy On BEST ANSWER

I am not sure how your CSS is organized, but I had a similar situation where I needed to print various content off the screen. My solution was to use an AJAX call (CFAJAXPROXY) in Javascript to a CFC in order to set a CF session variable with the DIV content and then call my print page which will output the content with the cfhtmltopdf tag. My experience has been that the CSS must be included in within whichever PDF generation tag you are using.

For example:

 <div id="myContent">content on my page to print</div> 

And a button to print

 <button onclick="printContent('myContent')">Print</button> 

The onclick calls the following in the Javascript:

var printContent = function(_contentDiv){
   var _content = $('#' + _contentDiv).html();  
   var _setContent = _cfc.setContent(_content);  
   window.location.href = 'printPage.cfm';  
 } 

The "_cfc" is defined in a cfajaxproxy call.

The CF function that's going to get called looks something like the following:

<cfcomponent>  
    <cffunction access="remote" name="setContent" returntype="string">  
       <cfargument name="_content" required="yes" type="string">  
       <cfset session.content = _content>  
       <cfreturn "whateveryouwant">  
     </cffunction>  
 </cfcomponent>  

And the printPage.cfm might look like this (I use Bootstrap as my CSS):

 <cfhtmltopdf>  
     <link href="css/bootstrap.css" rel="Stylesheet" type="text/css"></link>  
     <cfoutput>#session.content#</cfoutput>  
 </cfhtmltopdf>  

This is obviously a bare bones solution, but it works. I would imagine that if you needed different CSS pages, you could set the HREF value in the link tag as a session parameter as well

0
Tim Heald On

Assuming you're using a link tag in the head you can try to use cfinclude inside style tags to include the css file. cfdocument seems to do better with inline styles.

I ended up passing a url flag pdf=0/1, then in the template simply add a cfif around whatever content you want to toggle.

I'm trying to get it to recognize FontAwesome and Google Charts at this point. Seems to help so far.