-->

WKHTMLTOPDF and Coldfusion

2019-07-15 02:19发布

问题:

Is it possible to use coldfusion URL variables with WKHTMLTOPDF plugin? I am trying it as follows but only receiving a blank PDF. I'm assuming it's failing because of the URL variables.

 <cfexecute name="C:\Program Files (x86)\wkhtmltopdf\bin\wkhtmltopdf.exe" 
    arguments="c:\inetpub\wwwroot\serviceticket\reports\dropoff_receipt.cfm?ticket_id=#url.ticketID#&signature_id=#check_signature.id# C:\google.pdf"
    timeout="10" /> 

Update 1:

Changed the source to a URL, same error though.

    <cfexecute name="C:\Program Files (x86)\wkhtmltopdf\bin\wkhtmltopdf.exe" 
    arguments="'../../serviceticket/reports/dropoff_receipt.cfm?ticket_id=#url.ticketID#&signature_id=#check_signature.id# C:\google.pdf"
    timeout="10" /> 

Update 2:

After adding the full URL, here is a screenshot of the PDF that is now made. It's obviously not blank but the path of the URL in the error message is way different than the URL I am specifying.??

-Brian

回答1:

I wrote a CF9+ wrapper for WKHTMLTOPDF. It generates the command line arguments and puts them in the correct order. You can also provide separate header, body & footer URLs.

http://gamesover2600.tumblr.com/post/125851537339/generating-pdfs-using-coldfusion-wkhtmltopdf

I recommend saving ColdFusion-generated HTML as a temporary static file to an actual webserver. This is so that WKHTMLTOPDF doesn't have to deal w/any CF-related session/security obstacles and can correctly determine all related MIME types (something you can't do if you use file:// parameters.) You can delete the temp files after PDF generation or save them for later review/regeneration.

For page breaks, use CSS page-break-inside, page-break-after and page-break-before.

<CF_WKHTMLTOPDF
  AddDefaultHeader = "0"
  PageURL = "http://#CGI.Server_Name#/test_page.htm"
  filename = "c:\test_page.pdf"
  orientation = "portrait"
  DisableSmartShrinking="yes"
  dpi="96"
  PageSize="letter"
  margintop = "0"
  marginleft = "0"
  marginright = "0"
  marginbottom = "0">

<CFDUMP VAR="#WKHMLTOPDF_Result#">


回答2:

To expand upon the some of the items in the comments:

  1. Be sure to test any command line programs from the command line first, before plugging it into CFExecute. That allows you to identify any special syntax needed (such as quoting paths containing spaces, etcetera) and identify any potential permissions issues. The latter is not the issue here, but it is a common gotcha with CFExecute, since the CF service tends to run under a lower permission account by default.

  2. Always use one of the available error variables. Otherwise, you may not be aware of any errors that occur. (No idea why some recent versions of the CF documentation make no mention those variables...)

    • errorVariable - Variable name. Populate this variable name with any error messages
    • errorFile - Absolute File path. Output any text the program writes to StdErr to this file. Typically, this translates to mean error messages.

    NB: Just be aware that some programs, also write status messages to the StdErr stream, not just errors. So a non-empty error variable or file does not always indicate a problem. WKHTMLToPDF just so happens to be one of those programs, so keep that in mind.

  3. Regarding URL variables, those will be evaluated and converted into strings before they ever reach the program. Similar to database queries, the program will only see the generated string, after any CF variables have been evaluated. As long as that argument string is valid for the called program, your code should work fine.

  4. Finally, in order for the CFML code contained in that .cfm file to be evaluated by the CF server, you must call it as a URL, ie http://servername/scriptname.cfm , and not as a local file. Obviously, verify the target URL is reachable in a browser first.

Putting it all together, this simple test case worked fine under CF11.

CFExecute

 <cfset url.ticketID = 123>
 <cfset check_signature.id = 456>

 <!--- Note: Arguments containing spaces may need to be enclosed in quotes --->
 <cfexecute name="C:\Program Files\wkhtmltopdf\bin\wkhtmltopdf.exe" 
    arguments="http://localhost:8500/wkhtmlTestPage.cfm?ticket_id=#url.ticketID#&signature_id=#check_signature.id# C:\temp\wkhtmlTest.pdf"
    errorVariable="errorMessage"
    timeout="10"
    /> 

    <cfdump var="#errorMessage#" label="errorVariable">

wkhtmlTestPage.cfm

<cfparam name="URL.ticket_id" default="default ticket_id">
<cfparam name="URL.signature_id" default="default signature_id">

<cfdump var="#URL#">