cfhtmltopdf converts HTML, CSS, and JavaScript into a PDF using PDFG, a WebKit-based rendering engine that runs as a separate service. It's ColdFusion's modern generation option, HTML5 and CSS3 aware, but it's specific to Adobe ColdFusion, Lucee has no equivalent tag by this name.
Learning Objectives
After completing this lesson, you'll be able to:
- Generate a PDF from inline HTML or an external URL with cfhtmltopdf.
- Configure page setup and security attributes.
- Recognize a real limitation, HTML form fields aren't preserved, and why the tag doesn't exist on Lucee.
How cfhtmltopdf Actually Renders a Page
HTML/CSS/JS Source
PDFG WebKit Engine (Separate Jetty Service)
Rendered Like a Browser Would
PDF Output
A Basic Example
<cfhtmltopdf destination="report.pdf" overwrite="yes">
<h1>Invoice Report</h1>
<p>Generated dynamically via ColdFusion.</p>
</cfhtmltopdf>cfhtmltopdf's Attributes
| Attribute | Meaning |
|---|---|
| source | A URL or file path to convert, instead of the tag body |
| destination | Output file path; omit it to display the PDF directly in the browser |
| name | A variable to hold the generated PDF instead of writing it to a file |
| pageType | letter (default), legal, A4, A5, B4, B5, B4-JIS, B5-JIS, or custom |
| pageWidth / pageHeight | Custom dimensions, only used when pageType="custom" |
| orientation | portrait (default) or landscape |
| unit | in (default) or cm |
| marginTop / marginBottom / marginLeft / marginRight | Page margins |
| encryption | AES_128, RC4_40, RC4_128, RC4_128M, or none (default) |
| userPassword / ownerPassword | Passwords for viewing vs modifying the PDF |
| permissions | AllowPrinting, AllowCopy, AllowModifyContents, and others |
| overwrite | Whether to replace an existing file at destination (default no) |
| conformance | PDF/A-1a, PDF/A-1b, PDF/A-2a/b/u, or PDF/A-3a/b/u for long-term archival compliance |
A Real Example: Converting an External URL With Custom Dimensions
<cfhtmltopdf
destination="usage_example.pdf"
overwrite="yes"
source="https://example.com/"
unit="in"
pageheight="8"
pagewidth="4"
pagetype="custom">A Real Example: A Password-Protected PDF
<cfhtmltopdf
destination="confidential.pdf"
source="https://example.com/report"
pagetype="A4"
ownerpassword="ownerSecret"
userpassword="viewerSecret"
encryption="RC4_128"
permissions="AllowPrinting,AllowCopy">ownerpassword controls who can modify the document, userpassword controls who can open it at all. Combining encryption with permissions is how the actual restrictions (printing, copying) get enforced, not just the passwords alone.
A Real Limitation: HTML Form Fields
Form fields present in the source HTML are not preserved in the resulting PDF, they don't become interactive PDF form fields. cfhtmltopdf renders the page's visual output, it doesn't translate HTML forms into PDF/AcroForm fields.
A Real Deployment Detail: Platform Support
The WebKit rendering engine itself only runs natively on Windows and Linux. On a Mac, ColdFusion has to connect to a remote PDF Service Manager running on a supported platform, there's no local rendering path on macOS.
Why This Tag Doesn't Exist on Lucee
cfhtmltopdf is specific to Adobe ColdFusion's PDFG WebKit-based service. Lucee has no equivalent tag by this name, on Lucee, HTML-to-PDF conversion goes through cfdocument instead, using its own Flying Saucer (or classic) rendering engine, covered in the next lesson.
Common Beginner Mistakes
Expecting HTML form fields to survive conversion
They don't, cfhtmltopdf renders visual output, it doesn't produce interactive PDF form fields from an HTML form.
Forgetting overwrite="yes" when regenerating to the same destination repeatedly
It defaults to no, a repeated run without it fails rather than silently replacing the existing file.
Writing cfhtmltopdf-based code and expecting it to run unchanged on Lucee
The tag simply doesn't exist there. The equivalent capability on Lucee is cfdocument with its Flying Saucer engine, not a direct port.
Best Practices
- Use conformance (a PDF/A variant) when the output needs to meet long-term archival requirements.
- Set encryption and permissions together, passwords alone don't restrict printing or copying without them.
- Test against the real target HTML/CSS, WebKit's rendering can differ from what a modern browser shows for the same markup.
- Reach for cfdocument instead when the same generation code needs to run on both Adobe ColdFusion and Lucee.
Interview Questions
What engine does cfhtmltopdf actually use to render the PDF?
PDFG, a WebKit-based engine that runs as a separate service (a Jetty-based PDF Service Manager), not the main ColdFusion request thread itself.
Why wouldn't an HTML form submitted through cfhtmltopdf become a fillable PDF form?
Form fields aren't preserved in the conversion, cfhtmltopdf produces the page's visual rendering, not interactive PDF/AcroForm fields.
Why would cfhtmltopdf-based code fail entirely on Lucee?
The tag is Adobe ColdFusion-specific, Lucee has no equivalent by that name. The comparable capability there is cfdocument with the Flying Saucer engine.
Summary
In this lesson, you generated a PDF from inline HTML and an external URL with cfhtmltopdf, configured page setup and security attributes, covered the real limitation with HTML form fields, and why the tag is specific to Adobe ColdFusion.
What's Next?
The next lesson covers cfdocument, the cross-engine tag that generates PDFs on both Adobe ColdFusion and Lucee.