DevLearningTools

MODULE 13 · LESSON 14

<cfpdf>

cfpdf for manipulating a PDF that already exists: merging, watermarking, protecting, and extracting content, plus a real migration gotcha, digital signing actions Lucee doesn't implement at all.

New lessons are added one at a time as the course gets built out — a graded quiz for each lesson is still on the way.

cfhtmltopdf and cfdocument generate a new PDF from HTML/CFML. cfpdf does the opposite job: operating on a PDF that already exists, merging several into one, adding a watermark, password-protecting it, or pulling text and images back out.

Learning Objectives

After completing this lesson, you'll be able to:

  • Merge multiple PDFs into one with cfpdf.
  • Add a watermark and password-protect a PDF.
  • Recognize a real migration gotcha: actions Lucee's cfpdf doesn't implement at all.

How cfpdf Fits In

Existing PDF(s)

cfpdf action="..."

Merged / Watermarked / Protected Output

Some of cfpdf's 23+ Actions

actionDoes
mergeCombines multiple PDFs into one
deletePagesRemoves specific pages
addWatermark / removeWatermarkOverlays or removes a watermark
protectEncrypts and password-protects the document
thumbnailGenerates an image preview of a page
extractText / extractImagePulls text or embedded images out of the PDF
getInfo / setInfoReads or writes document metadata
addHeader / addFooterAdds page numbering or text to every page
read / writeLoads a PDF into a variable, or saves one to a file
NOTE

The full Adobe reference documents over 20 actions in total, including sign, unsign, validateSignature, archive, and sanitize, worth checking the reference directly for anything beyond this core set.

A Real Example: Merging PDFs

Tag Syntax
<cfpdf action="merge" source="cover.pdf,report.pdf,appendix.pdf" destination="final.pdf" overwrite="yes">
NOTE

keepBookmark (default false) preserves each source document's bookmarks in the merged output. merge also accepts a directory (merge every PDF in a folder instead of listing them individually) and order/ascending to control what sequence they're combined in.

A Real Example: Adding a Watermark

Tag Syntax
<cfpdf
    action="addwatermark"
    source="report.pdf"
    destination="report-draft.pdf"
    overwrite="yes"
    text="DRAFT"
    rotation="45"
    opacity="3"
    foreground="no">
NOTE

opacity is on a 0–10 scale, not 0–100. foreground="no" (the default) places the watermark behind the existing content rather than on top of it.

A Real Example: Password-Protecting the Output

Tag Syntax
<cfpdf action="protect" source="report.pdf" destination="report-protected.pdf" overwrite="yes" newOwnerPassword="ownerSecret" newUserPassword="viewerSecret">
NOTE

protect's password attributes are newOwnerPassword and newUserPassword, not ownerpassword/userpassword, those names belong to cfhtmltopdf and cfdocument instead.

A Real Migration Gotcha: Lucee's Narrower Action List

Lucee's cfpdf documents merge, read, write, protect, removePassword, deletePages, thumbnail, extractText, extractImage, extractBookmarks, addWatermark, removeWatermark, addHeader, addFooter, getInfo, and setInfo. It does not document sign, unsign, validateSignature, readSignatureFields, archive, addAttachments, addStamp, processddx, sanitize, transform, optimize, or import.

NOTE

Digital signing (sign/unsign/validateSignature) is the most consequential gap for a real migration, code that signs or validates a signed PDF on Adobe ColdFusion has no direct equivalent on Lucee's cfpdf.

Common Beginner Mistakes

Using ownerpassword/userpassword with cfpdf's protect action

protect's actual attributes are newOwnerPassword and newUserPassword, ownerpassword/userpassword are cfhtmltopdf's and cfdocument's naming instead, an easy mix-up across the PDF tags.

Assuming every Adobe cfpdf action exists on Lucee

It doesn't, digital signing (sign/unsign/validateSignature) in particular has no equivalent on Lucee's cfpdf. Check the actual supported action list before porting code that relies on one of the gaps.

Setting opacity as if it were a 0–100 percentage

It's a 0–10 scale, a value like 75 is not what it looks like.

Merging PDFs without setting keepbookmark, then expecting bookmarks to survive

It defaults to false, set it explicitly when each source document's bookmarks matter in the merged result.

Forgetting overwrite when writing to a destination that already exists

Without it, running the same operation again against an existing file can fail rather than replace it.

Best Practices

  • Check Lucee's actual supported action list before porting Adobe cfpdf-based signing, sanitizing, or archiving code.
  • Use getInfo before deciding how to process an unfamiliar or user-uploaded PDF.
  • Use explicit page ranges (like "1,6-9,56-89") rather than assuming a default range applies.
  • Set keepbookmark explicitly on a merge when the source documents' bookmarks need to survive.

Interview Questions

What's the difference between what cfdocument and cfpdf are each used for?

cfdocument generates a new PDF from CFML/HTML content. cfpdf manipulates a PDF that already exists, merging, watermarking, protecting, or extracting content from it.

What's a real, concrete gap in Lucee's cfpdf compared to Adobe's?

Digital signing and signature validation (sign, unsign, validateSignature, readSignatureFields) aren't documented on Lucee's cfpdf at all, code relying on those actions has no direct equivalent there.

What scale is cfpdf's opacity attribute on for addWatermark?

0 to 10, not a 0–100 percentage.

Summary

In this lesson, you merged multiple PDFs, added a watermark, and password-protected a document with cfpdf, and covered a real migration gotcha: Lucee's cfpdf doesn't implement digital signing or several other actions that Adobe's does.

What's Next?

The next lesson covers cfchart, generating charts and graphs directly from a query.