Search code examples
coldfusionwkhtmltopdf

Coldfusion creating reports with wkhtmltopdf


I am trying to get some assistance with wkhtmltopdf.

I have downloaded and installed and trying to get it to work correctly with my program.

What I have is a form that lets the user choose print, preview or excel. When the user chooses print I want pop up the html table that is created by a query depending on the associates and locations that are chosen.

Right now when the user chooses print it just shows this table in the browser.

<cfif FORM.Format IS "print">

<!---<cfdocument format="pdf" scale="75" backgroundvisible="yes" overwrite="no" fontembed="yes">--->

<link rel="stylesheet" href="css/form-table.css"/>

<!---<cfdocumentitem type="header" > 
    <cfoutput><p align= "right">Page #cfdocument.currentpagenumber# of #cfdocument.totalpagecount#</p></cfoutput> 
</cfdocumentitem> --->

<div class="RTable">
    <h3 class="RTable-h3">CHECKLIST STATS</h3>

    <cfoutput>
    <ul class="RTable-headingList">
        <li>FROM <span class="RTable-headingList-date">#dateFormat(date1, 'mm/dd/yyyy')#</span> TO <span class="RTable-headingList-date">#dateFormat(date2, 'mm/dd/yyyy')#</span></li>
        <li>LOCATIONS: <span class="RTable-headingList-locations">#locList#</span></li>
    </ul>
    </cfoutput>

    <table class="table table-hover RTable-table">

        <thead>
            <tr>
                <th>Associate Name</th>
                <th>Location</th>
                <th><small>Generated by</small>Associate</th>
                <th><small>Generated by</small>Selected Location(s)</th>
                <th><small>Associate Percentage of</small>Location Total</th>
            </tr>
        </thead>

        <tbody>
        <cfoutput query="GetEmployeeInfo">
      <tr>
          <td class="RTable-name"><cfif rnA EQ 1><strong>#assoc_name#</strong></cfif></td>
          <td class="RTable-location"><cfif rnL EQ 1>#trans_location#</cfif></td>
          <td>#checklistsByAssocLoc#</td> 
          <td>#assocChecklistsByLoc#</td> 
          <td>#DecimalFormat(totalChecklistsByAssocLocPct)# %</td> 
          <!---<td> rnA: #rnA# | rnL: #rnL# | rnTotAssoc: #rnTotAssoc# </td> --->
      </tr>
      <cfif rnTotAssoc EQ 1> 
      <tr class="RTable-row-associate-total"> 
          <td>Associate Total</td> 
          <td></td> 
          <td>#totalChecklistsByAssoc#</td> 
          <td>#totalAssocChecklistsByAllFilteredLoc#</td> 
          <td>#DecimalFormat(totalChecklistsByLocPct)# %</td>
      </tr>
      </cfif>
    </cfoutput>
    </tbody>
</table>

</div>

<!---</cfdocument>--->

I am trying to use it like cfdocument in the <cfif FORM.Format IS "print"> do I cfexecute this table some how in replace of how I have the table? I am using this as reports and dont want to save a million reports to the server. I guess I am looking for some assistance in getting off on the right foot. Any help would be greatly appreciated.

Iv tried adding this code inside the if "print":

<cfexecute name="C:\Program Files\wkhtmltopdf\bin\wkhtmltopdf.exe" 
    arguments="http://path/path/checklist/wkhtmltestpage.cfm C:\temp\wkhtmlTest.pdf"
    errorVariable="errorMessage"
    timeout="10"
    /> 

But this does not download it to show the user to print.

Also for some reason its not going to the link I am specifying its making a pdf of the login page...


Solution

  • When WKHTMLTOPDF requests the webpage, the "user" is not authenticated and the CGI.Http_User_Agent contains "wkhtmltopdf". The remote IP of the request will also be a local IP that is configured on the server. As a result, I don't directly process any CFM scripts using WKHTMLTOPDF.

    I recommend:

    • Use CFContent to capture generated static HTML.
    • Save the HTML to a public-accessible directory with a random file name.
    • Use the web path + random file name w/WKHTMLTOPDF command line.
    • After PDF is generated, delete random files.

    This process will make any issues easier to troubleshoot. I prefer creating static BAT files with the same randomized filename so that I can manually re-run on the server or even locally on my on PC to further troubleshoot and view any weird messages returned by the program. There's many other command line settings you'll want to pass (margins, orientation, pagesize, header/footer, JS delay, etc), so creating a standalone BAT file with all of the command line arguments is the best approach. (I noticed in another question that you may be using CFX_Exec. I recommend using it over CFExecute.)

    <!--- Simple WKHTMLTOPDF Generation Usage --->
    <cfset FileID = CreateUUID()>
    <cffile action="WRITE" file="#webroot#\#FileID#.htm" output="#TheHTML#">
    <cfexecute name="C:\wkhtmltopdf.exe" arguments="http://mywebsite.com/#FileID#.htm C:\temp\#FileID#.pdf" timeout="30">
    <cffile action="DELETE" file="#webroot#\#FileID#.htm">
    

    To deliver the PDF file, you can either perform a 302 redirect to the randomized PDF file and let your webserver handle the mimetype (and then delete it later) or use CFContent to deliver it using a ColdFusion thread and automatically delete it:

    <!--- Return PDF to browser inline or as downloadable attachment --->
    <!--- <cfheader name="content-disposition" value="attachment; filename=""NiceFilename.pdf"""> --->
    <cfheader name="content-disposition" value="inline; filename=""NiceFilename.pdf""">
    <cfcontent type="application/pdf" file="C:\temp\#FileID#.pdf" deletefile="Yes">