Skip to content

Instantly share code, notes, and snippets.

@JamoCA
Last active December 16, 2022 04:30
Show Gist options
  • Save JamoCA/74e556e7d4f1a715a41d to your computer and use it in GitHub Desktop.
Save JamoCA/74e556e7d4f1a715a41d to your computer and use it in GitHub Desktop.
WKHTMLTOPDF ColdFusion Custom Tag - Converts multiple HTML fragments to PDF.
<CFSETTING ENABLECFOUTPUTONLY="Yes">
<!--- 4/2/2015 by SunStar Media http://www.sunstarmedia.com/ --->
<!--- more posts here: https://gamesover2600.tumblr.com/tagged/wkhtmltopdf --->
<CFPARAM NAME="Attributes.wkhtmltopdfEXEPath" DEFAULT="c:\Program Files\wkhtmltopdf\bin\wkhtmltopdf.exe">
<CFPARAM NAME="Attributes.ShowDebug" DEFAULT="no"><!--- Yes/No Shows inline results. (default = no) --->
<CFPARAM NAME="Attributes.DebugVar" DEFAULT="WKHMLTOPDF_Result" TYPE="variableName"><!--- Variable name w/PDF generation data. Optional --->
<CFPARAM NAME="Attributes.TimeOut" DEFAULT="60" TYPE="integer"><!--- CFExecute Timeout (Default = 60) --->
<CFPARAM NAME="Attributes.HeaderURL" DEFAULT=""><!--- Publicly accessible URL. Optional --->
<!--- TODO: Add HeaderSpacing --->
<CFPARAM NAME="Attributes.AddDefaultHeader" DEFAULT="no"><!--- yes/no (no = default) --->
<CFPARAM NAME="Attributes.MarginTop" DEFAULT=""> <!--- INT (inches). Add "mm" to specify millimeters --->
<CFPARAM NAME="Attributes.MarginRight" DEFAULT=""> <!--- INT (inches). Add "mm" to specify millimeters --->
<CFPARAM NAME="Attributes.MarginBottom" DEFAULT=""> <!--- INT (inches). Add "mm" to specify millimeters --->
<CFPARAM NAME="Attributes.MarginLeft" DEFAULT=""> <!--- INT (inches). Add "mm" to specify millimeters --->
<CFPARAM NAME="Attributes.Orientation" DEFAULT="portrait"> <!--- portrait (default) | landscape --->
<CFPARAM NAME="Attributes.PageSize" DEFAULT="letter"><!--- letter, legal, a4 MORE: http://doc.qt.io/qt-4.8/qprinter.html#PaperSize-enum --->
<CFPARAM NAME="Attributes.Title" DEFAULT=""><!--- Text. Optional (Default = First HTML page title) --->
<CFPARAM NAME="Attributes.EnableForms" DEFAULT="no"><!--- Yes/No. Turn HTML form fields into pdf form fields (Default = no) --->
<CFPARAM NAME="Attributes.NoImages" DEFAULT="no"><!--- Yes/No. Do not load or print images (Default = No) --->
<CFPARAM NAME="Attributes.DisableJavascript" DEFAULT="no"><!--- Yes/No. Do not allow web pages to run javascript (Default = no) --->
<cfparam name="Attributes.JavascriptDelay" DEFAULT="200" TYPE="integer"><!--- INT. Wait some milliseconds for javascript finish (default 200) --->
<CFPARAM NAME="Attributes.PageOffset" DEFAULT="0" TYPE="integer"><!--- INT. Set the starting page number (default 0) --->
<CFPARAM NAME="Attributes.DisableSmartShrinking" DEFAULT="no"><!--- Yes/No. Disable the intelligent shrinking strategy used by WebKit that makes the pixel/dpi ratio none constant --->
<CFPARAM NAME="Attributes.Zoom" DEFAULT="0" type="float"><!--- Float. Use this zoom factor (default 1) --->
<CFPARAM NAME="Attributes.FooterURL" DEFAULT=""><!--- Publicly accessible URL. Optional --->
<!--- TODO: Add FooterSpacing --->
<CFPARAM NAME="Attributes.FooterTextLeft" DEFAULT=""><!--- Text. Adds left-aligned footer text. --->
<CFPARAM NAME="Attributes.AddFooterPageNum" DEFAULT="no"><!--- Yes/No. Adds left-aligned page number in footer. (default = no) --->
<CFPARAM NAME="Attributes.FooterText" DEFAULT=""><!--- Text. Adds centered footer text --->
<CFPARAM NAME="Attributes.NoFooterLine" DEFAULT="yes"><!--- Yes/No. Do not display line above the footer (default=Yes) --->
<!--- TODO: Add FooterFontName --->
<CFPARAM NAME="Attributes.FooterFontSize" DEFAULT="12" TYPE="integer"><!--- INT. Set footer font size (default 12) --->
<CFPARAM NAME="Attributes.HeaderLine" DEFAULT="no"><!--- Yes/No. Display line below the header (default=no) --->
<!--- TODO: Add HeaderFontName --->
<CFPARAM NAME="Attributes.HeaderFontsize" DEFAULT="12" TYPE="integer"><!--- INT. Set footer font size (default 12) --->
<CFPARAM NAME="Attributes.PageURL" TYPE="URL"><!--- Publicly accessible URL. Required --->
<CFPARAM NAME="Attributes.Filename" TYPE="STRING"><!--- Physical file path & name. Required. --->
<CFSET DebugData = StructNew()>
<cfscript>
function inchToCM(i){
if (findnocase("mm", i)){
return i;
} else {
return (val(i) * 25.4) & "mm";
}
}
</cfscript>
<CFSET PDFOptions = ArrayNew(1)>
<CFIF isValid("URL", Attributes.HeaderURL)>
<CFSET ArrayAppend(PDFOptions, "--header-html #Attributes.HeaderURL#")>
<CFSET ArrayAppend(PDFOptions, "--header-spacing 0")>
<CFELSEIF YesNoFormat(Trim(Attributes.AddDefaultHeader))>
<CFSET ArrayAppend(PDFOptions, "--default-header")>
</CFIF>
<CFIF VAL(Attributes.MarginTop)>
<CFSET ArrayAppend(PDFOptions, "-T #inchToCM(Attributes.MarginTop)#")>
</CFIF>
<CFIF VAL(Attributes.MarginRight)>
<CFSET ArrayAppend(PDFOptions, "-R #inchToCM(Attributes.MarginRight)#")>
</CFIF>
<CFIF VAL(Attributes.MarginBottom)>
<CFSET ArrayAppend(PDFOptions, "-B #inchToCM(Attributes.MarginBottom)#")>
</CFIF>
<CFIF VAL(Attributes.MarginLeft)>
<CFSET ArrayAppend(PDFOptions, "-L #inchToCM(Attributes.MarginLeft)#")>
</CFIF>
<CFIF trim(Attributes.Orientation) IS "landscape">
<CFSET ArrayAppend(PDFOptions, "--orientation Landscape")>
</CFIF>
<CFSET ArrayAppend(PDFOptions, "--page-size #Attributes.pageSize#")>
<CFIF LEN(Trim(Attributes.Title))>
<CFSET ArrayAppend(PDFOptions, "--title ""#Trim(Attributes.Title)#""")>
</CFIF>
<CFIF YesNoFormat(Attributes.enableForms)>
<CFSET ArrayAppend(PDFOptions, "--enable-forms")>
</CFIF>
<CFIF YesNoFormat(Attributes.noImages)>
<CFSET ArrayAppend(PDFOptions, "--no-images")>
</CFIF>
<CFIF YesNoFormat(Attributes.disableJavascript)>
<CFSET ArrayAppend(PDFOptions, "--disable-javascript")>
</CFIF>
<CFIF isvalid("integer", Attributes.javascriptDelay) AND VAL(Attributes.javascriptDelay) NEQ 200>
<CFSET ArrayAppend(PDFOptions, "--javascript-delay #VAL(Attributes.javascriptDelay)#")>
</CFIF>
<CFIF VAL(Attributes.PageOffset)>
<CFSET ArrayAppend(PDFOptions, "--page-offset #VAL(Attributes.PageOffset)#")>
</CFIF>
<CFIF YesNoFormat(Attributes.DisableSmartShrinking)>
<CFSET ArrayAppend(PDFOptions, "--disable-smart-shrinking")>
</CFIF>
<CFIF VAL(Attributes.Zoom)>
<CFSET ArrayAppend(PDFOptions, "zoom #VAL(Attributes.Zoom)#")>
</CFIF>
<CFIF isValid("URL", Attributes.FooterURL)>
<CFSET ArrayAppend(PDFOptions, "--footer-html #Attributes.FooterURL#")>
<CFSET ArrayAppend(PDFOptions, "--footer-spacing 0")>
<CFELSE>
<CFIF LEN(Trim(Attributes.footerTextLeft))>
<CFSET ArrayAppend(PDFOptions, "--footer-left ""#Trim(Attributes.footerTextLeft)#""")>
<CFELSEIF YesNoFormat(Attributes.AddFooterPageNum)>
<CFSET ArrayAppend(PDFOptions, "--footer-left ""Page [page] of [toPage]""")>
</CFIF>
<CFIF LEN(Trim(Attributes.footerText))>
<CFSET ArrayAppend(PDFOptions, "--footer-center ""#Trim(Attributes.footerText)#""")>
</CFIF>
<CFIF YesNoFormat(Attributes.noFooterLine)>
<CFSET ArrayAppend(PDFOptions, "--no-footer-line")>
</CFIF>
<CFIF isValid("integer", Attributes.FooterFontsize) AND VAL(Attributes.FooterFontsize) NEQ 12>
<CFSET ArrayAppend(PDFOptions, "--footer-font-size #VAL(Attributes.FooterFontsize)#")>
</CFIF>
</CFIF>
<!--- If not headerURL, add optional header text options --->
<CFIF NOT isValid("URL", Attributes.HeaderURL) AND YesNoFormat(Trim(Attributes.AddDefaultHeader))>
<CFIF LEN(trim(Attributes.Title))>
<CFSET ArrayAppend(PDFOptions, "--header-left ""#Attributes.Title#""")>
</CFIF>
<CFIF YesNoFormat(Attributes.HeaderLine)>
<CFSET ArrayAppend(PDFOptions, "--header-line")>
</CFIF>
<CFIF YesNoFormat(Attributes.AddFooterPageNum)>
<CFSET ArrayAppend(PDFOptions, "--header-right """"")>
</CFIF>
<CFIF isValid("integer", Attributes.HeaderFontsize) AND VAL(Attributes.HeaderFontsize) NEQ 12>
<CFSET ArrayAppend(PDFOptions, "--header-font-size #VAL(Attributes.HeaderFontsize)#")>
</CFIF>
</CFIF>
<CFSET wkhtmltopdfCommandLine = trim("#trim(ArrayToList(PDFOptions,' '))# #Attributes.PageURL# #Attributes.filename#")>
<CFIF FileExists(Attributes.filename)>
<cffile action="DELETE" file="#Attributes.filename#">
</CFIF>
<CFSET DebugData["CommandLine"] = """#Attributes.wkhtmltopdfEXEPath#"" #wkhtmltopdfCommandLine#">
<CFIF YesNoFormat(Attributes.ShowDebug)>
<CFOUTPUT>
<div><textarea style="width:95%; height:100px;">"#Attributes.wkhtmltopdfEXEPath#" #wkhtmltopdfCommandLine#</textarea></div>
</CFOUTPUT>
</CFIF>
<CFSET PDFResult = "">
<CFSET PDFTimeStart = GetTickCount()>
<cfexecute name="#Attributes.wkhtmltopdfEXEPath#"
arguments="#wkhtmltopdfCommandLine#"
timeout="#Attributes.TimeOut#"
variable="PDFResult">
</CFEXECUTE>
<CFSET DebugData["GenerationTime"] = GetTickCount() - PDFTimeStart>
<CFSET DebugData["Result"] = PDFResult>
<CFIF YesNoFormat(Attributes.ShowDebug)>
<CFOUTPUT>
<div><b>Result:</b> #PDFResult#</div>
<div><b>PDF Generation Time:</b> #NumberFormat(GetTickCount() - PDFTimeStart)# ms</div>
</CFOUTPUT>
</CFIF>
<CFIF LEN(Attributes.DebugVar) AND isValid("variableName", Attributes.DebugVar)>
<CFSET Caller[Attributes.DebugVar] = DebugData>
</CFIF>
<CFSETTING ENABLECFOUTPUTONLY="No">
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment