BoxLang 🚀 A New JVM Dynamic Language Learn More...

BoxLang PDF Module

v1.6.0+3 BoxLang Modules

⚡︎ BoxLang+ Module: BoxLang PDF Module

|:------------------------------------------------------:  |
| ⚡︎ B o x L a n g ⚡︎
| Dynamic : Modular : Productive
|:------------------------------------------------------:  |
Copyright Since 2023 by Ortus Solutions, Corp
www.boxlang.io | www.ortussolutions.com

Overview

This module provides comprehensive PDF manipulation and generation functionality for BoxLang, including:

  • PDF Document Generation - Create PDF documents from HTML content
  • PDF Form Manipulation - Populate and extract data from PDF forms
  • PDF Document Processing - Advanced PDF operations like merging, splitting, watermarking
  • CFML Compatibility - Full compatibility with CFML PDF tags

Installation

{% hint style="danger" %} This module is only available to +/++ subscribers only but can be installed in conjunction with the bx-plus Module with a limited trial. {% endhint %}

# For Operating Systems using our Quick Installer
install-bx-module bx-pdf

# Using CommandBox to install for web servers
box install bx-pdf

Components

This module contributes the following components to the BoxLang runtime:

Document Generation Components

  • document - Main component for creating PDF documents from HTML
  • documentitem - Specifies headers, footers, and page breaks
  • documentsection - Divides documents into sections with unique properties

PDF Manipulation Components

  • pdf - Advanced PDF operations (merge, split, watermark, etc.)
  • pdfparam - Parameters for PDF operations like attachments

PDF Form Components

  • pdfform - Manipulate PDF forms (populate/read form fields)
  • pdfformparam - Specify individual form field values

Document Component

The document component creates PDF documents from HTML content with extensive customization options.

Attributes

Attribute Type Default Description
format String"pdf"Document format (PDF only)
filename String-Output file path
variable String-Variable name to store PDF binary
encryption String"none"Encryption level: "128-bit", "40-bit", "none"
orientation String"portrait"Page orientation: "portrait", "landscape"
pageType String"A4"Page size (A4, LETTER, LEGAL, etc.)
pageWidth Numeric-Custom page width in inches
pageHeight Numeric-Custom page height in inches
marginTop Numeric-Top margin
marginBottom Numeric-Bottom margin
marginLeft Numeric-Left margin
marginRight Numeric-Right margin
scale Numeric100Scaling percentage (≤100)
backgroundVisible BooleantrueShow background elements
bookmark BooleantrueGenerate bookmarks
htmlBookmark BooleanfalseConvert HTML anchors to bookmarks
fontEmbed BooleantrueEmbed fonts in document
fontDirectory String-Custom font directory
localUrl BooleanfalseGenerate with local URLs
openpassword String-Password to open document
ownerPassword String-Owner password for restrictions
pdfa BooleanfalseGenerate PDF/A compliant document
saveAsName String-Browser save filename
overwrite BooleanfalseOverwrite existing files
src String-URL or path to HTML content
srcfile String-Absolute path to HTML file
mimeType String"text/html"Source content MIME type
unit String"inches"Measurement unit: "in", "cm"

Unsupported Attributes

The following attributes are not currently implemented and will throw an error if used:

  • permissions - Granular permissibility is not yet supported
  • permissionspassword - Granular permissibility is not yet supported
  • userPassword - Granular permissibility is not yet supported
  • authPassword - Authentication password not supported
  • authUser - Authentication user not supported
  • userAgent - HTTP user agent identifier not supported
  • proxyHost - Proxy server configuration not supported
  • proxyPassword - Proxy authentication not supported
  • proxyPort - Proxy port configuration not supported
  • proxyUser - Proxy user authentication not supported
  • tagged - ACF OpenOffice integration not supported
  • formfields - Form field attributes not implemented in standard module
  • formsType - Form type specification not implemented in standard module

DocumentItem Component

Specifies headers, footers, and page breaks within PDF documents.

Attributes

Attribute Type Required Description
type StringYesItem type: "header", "footer", "pagebreak"
evalAtPrint BooleanNo⚠️ Deprecated - content always evaluated

DocumentSection Component

Divides PDF documents into sections with unique headers, footers, and page numbering.

Attributes

Attribute Type Description
name StringSection name (used for bookmarks)
marginTop NumericSection top margin
marginBottom NumericSection bottom margin
marginLeft NumericSection left margin
marginRight NumericSection right margin
src StringURL or relative path to content
srcfile StringAbsolute path to content file
mimeType StringContent MIME type

Unsupported Attributes

The following attributes are not currently implemented and will throw an error if used:

  • userAgent - HTTP user agent identifier for URL fetching
  • authPassword - Authentication password for URL content
  • authUser - Authentication username for URL content

PDFForm Component

Manipulates PDF forms created in Adobe Acrobat and Adobe LiveCycle Designer. Supports both populating form fields and extracting form data.

Actions

  • populate - Fill form fields with data
  • read - Extract form field data to structures or files

Attributes

Attribute Type Required Description
action StringYes"populate" or "read"
source AnyYesSource PDF form (file path, byte array, or variable)
destination StringNoOutput file path (populate action)
result StringNoVariable name for extracted data (read action)
overwrite BooleanNoOverwrite existing files (default: false)
overwriteData BooleanNoOverwrite existing form data (default: false)
fdfdata StringNoFDF file path for import/export
XMLdata StringNo⏳ XML data (planned feature)

Examples

Populating Form Fields

<bx:pdfform action="populate" 
            source="/forms/employee-form.pdf" 
            destination="/completed/employee-123.pdf"
            overwrite="true">
    
    <bx:pdfformparam name="employeeId" value="EMP-123" />
    <bx:pdfformparam name="firstName" value="John" />
    <bx:pdfformparam name="lastName" value="Smith" />
    <bx:pdfformparam name="department" value="Engineering" />
    <bx:pdfformparam name="salary" value="$85,000" />
    <bx:pdfformparam name="startDate" value="2024-01-15" />
    
</bx:pdfform>

Reading Form Data

<bx:pdfform action="read" 
            source="/submitted/employee-form-filled.pdf" 
            result="employeeData" />

<!-- Access extracted data -->
<bx:output>
    Employee: #employeeData.firstName# #employeeData.lastName#<br>
    ID: #employeeData.employeeId#<br>
    Department: #employeeData.department#
</bx:output>

<bx:dump var="#employeeData#" />

FDF Data Operations

<!-- Export form data to FDF -->
<bx:pdfform action="read"
            source="/filled-forms/survey.pdf"
            fdfdata="/exported-data/survey-data.fdf" />

<!-- Import FDF data to populate form -->
<bx:pdfform action="populate"
            source="/templates/survey-template.pdf"
            destination="/completed/survey-filled.pdf"
            fdfdata="/data/survey-responses.fdf" />

PDFFormParam Component

Specifies individual form field values when populating PDF forms. Must be nested within a pdfform component.

Attributes

Attribute Type Required Description
name StringYesForm field name
value StringYesValue to assign to the field
index IntegerNoField index for LiveCycle forms (default: 1)

Usage Notes

  • Acrobat Forms: Cannot have multiple fields with the same name, so index is not applicable
  • LiveCycle Forms: Support multiple fields with the same name, use index to distinguish them
  • Case Sensitivity: Field values are case-sensitive
  • Data Types: Component handles various field types (text, checkbox, radio, dropdown, etc.)

Example

<bx:pdfform action="populate" source="registration-form.pdf" destination="completed-form.pdf">
    
    <!-- Text fields -->
    <bx:pdfformparam name="fullName" value="Jane Doe" />
    <bx:pdfformparam name="email" value="[email protected]" />
    
    <!-- Checkbox (requires specific values like "Yes"/"No" or "On"/"Off") -->
    <bx:pdfformparam name="agreeToTerms" value="Yes" />
    
    <!-- Dropdown selection -->
    <bx:pdfformparam name="country" value="United States" />
    
    <!-- Radio button -->
    <bx:pdfformparam name="gender" value="Female" />
    
    <!-- Date field -->
    <bx:pdfformparam name="birthDate" value="1985-03-15" />
    
    <!-- Numeric field -->
    <bx:pdfformparam name="yearsExperience" value="8" />
    
</bx:pdfform>

PDF Component

Performs advanced PDF operations like merging, splitting, watermarking, and form manipulation.

Supported Actions

Action Description
addAttachments Add file attachments to PDF
addHeader Add headers to pages
addFooter Add footers to pages
addWatermark Add watermark to pages
deletePages Remove specific pages
export Export form data (FDF/XFDF)
extractText Extract text content
extractimage Extract embedded images
getInfo Get PDF metadata
import Import form data
merge Combine multiple PDFs
protect Add password protection
removePassword Remove password protection
removeWatermark Remove watermarks
removeHeaderFooter Remove headers/footers
thumbnail Generate page thumbnails
transform Transform/manipulate pages
unsign Remove digital signatures
validatesignature Validate signatures
write Save PDF to file

Key Attributes

Attribute Type Description
action StringOperation to perform (see actions above)
source AnySource PDF(s) - file path, binary data, or variable
destination StringOutput file path
pages StringPage selection: "1-5", "1,3,5", "*"
overwrite BooleanOverwrite existing files
password StringPassword for encrypted PDFs

Examples

Merging PDFs

<bx:pdf action="merge" 
        destination="/combined/merged-document.pdf" 
        overwrite="true">
    
    <bx:pdfparam source="/docs/doc1.pdf" />
    <bx:pdfparam source="/docs/doc2.pdf" />
    <bx:pdfparam source="/docs/doc3.pdf" />
    
</bx:pdf>

Adding Watermarks

<bx:pdf action="addWatermark"
        source="/documents/report.pdf"
        destination="/documents/watermarked-report.pdf"
        image="/images/confidential.png"
        opacity="0.3"
        position="center"
        rotation="45">
</bx:pdf>

Extracting Text

<bx:pdf action="extractText"
        source="/documents/report.pdf"
        destination="/extracted/report.txt"
        pages="1-10">
</bx:pdf>

Password Protection

<bx:pdf action="protect"
        source="/documents/sensitive.pdf"
        destination="/documents/protected.pdf"
        newOwnerPassword="admin123"
        newUserPassword="user123"
        permissions="print,copy">
</bx:pdf>

PDFParam Component

Specifies parameters for PDF operations, particularly for merge and attachment operations.

Attributes

Attribute Type Description
source StringSource file path
filename StringAttachment filename
encoding StringFile encoding (default: UTF-8)
mimeType StringFile MIME type
description StringAttachment description
password StringPassword for encrypted files

Example

<bx:pdf action="addAttachments" 
        source="/base/document.pdf" 
        destination="/enhanced/document.pdf">
    
    <bx:pdfparam source="/files/spreadsheet.xlsx"
                 filename="data.xlsx" 
                 mimeType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
                 description="Supporting data analysis" />
    
    <bx:pdfparam source="/images/chart.png"
                 filename="sales-chart.png"
                 mimeType="image/png" 
                 description="Q4 Sales Performance Chart" />
    
</bx:pdf>

Advanced Examples

Complete Document Generation

<bx:set testImage = "https://ortus-public.s3.amazonaws.com/logos/ortus-medium.jpg"/>
<bx:document format="pdf" 
             filename="/reports/annual-report.pdf"
             pageType="A4"
             orientation="portrait"
             encryption="128-bit"
             openpassword="company2024"
             fontEmbed="true">
    
    <!-- Global Header -->
    <bx:documentitem type="header">
        <div style="text-align: center; border-bottom: 2px solid #333; padding: 10px;">
            <h2>Annual Business Report 2024</h2>
        </div>
    </bx:documentitem>
    
    <!-- Global Footer -->
    <bx:documentitem type="footer">
        <div style="text-align: center; font-size: 10px;">
            Page #bxdocument.currentpagenumber# of #bxdocument.totalpages#
        </div>
    </bx:documentitem>
    
    <!-- Executive Summary Section -->
    <bx:documentsection name="Executive Summary">
        <h1>Executive Summary</h1>
        <p>This report provides an overview of our performance...</p>
    </bx:documentsection>
    
    <!-- Charts Section -->
    <bx:documentsection name="Performance Charts" src="#testImage#" />
    
</bx:document>

PDF Processing Pipeline

<!-- Step 1: Merge quarterly reports -->
<bx:pdf action="merge" destination="/temp/combined-quarterly.pdf">
    <bx:pdfparam source="/reports/q1-2024.pdf" />
    <bx:pdfparam source="/reports/q2-2024.pdf" />
    <bx:pdfparam source="/reports/q3-2024.pdf" />
    <bx:pdfparam source="/reports/q4-2024.pdf" />
</bx:pdf>

<!-- Step 2: Add company watermark -->
<bx:pdf action="addWatermark"
        source="/temp/combined-quarterly.pdf"
        destination="/temp/watermarked-report.pdf"
        image="/assets/company-watermark.png"
        opacity="0.2"
        pages="*">
</bx:pdf>

<!-- Step 3: Add password protection -->
<bx:pdf action="protect"
        source="/temp/watermarked-report.pdf"
        destination="/final/annual-report-protected.pdf"
        newOwnerPassword="admin2024"
        newUserPassword="view2024"
        permissions="print">
</bx:pdf>

Form Processing Workflow

<!-- Process submitted form data -->
<bx:pdfform action="read" 
            source="/submissions/application-#url.id#.pdf" 
            result="applicationData" />

<!-- Validate and process data -->
<bx:if applicationData.status eq "pending">
    
    <!-- Update form with approval stamp -->
    <bx:pdfform action="populate"
                source="/submissions/application-#url.id#.pdf"
                destination="/processed/approved-application-#url.id#.pdf"
                overwriteData="true">
        
        <bx:pdfformparam name="status" value="APPROVED" />
        <bx:pdfformparam name="approvedBy" value="#session.user.name#" />
        <bx:pdfformparam name="approvalDate" value="#dateFormat(now(), 'yyyy-mm-dd')#" />
        
    </bx:pdfform>
    
</bx:if>

CFML Compatibility

This module provides full compatibility with CFML PDF tags:

  • cfdocumentbx:document
  • cfdocumentitembx:documentitem
  • cfdocumentsectionbx:documentsection
  • cfpdfbx:pdf
  • cfpdfparambx:pdfparam
  • cfpdfformbx:pdfform
  • cfpdfformparambx:pdfformparam

Migration from ColdFusion requires only prefix changes (cfbx).

Technical Requirements

  • BoxLang Runtime 1.0.0+
  • Java 21+

Support and Documentation

Changelog

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.


Unreleased

1.6.0 - 2025-11-05

Fixed

  • BLMODULES-104 Fixed index out of bounds errors when deleting large quantities of pages

Changed

  • Updated Flying Saucer Library to v10
  • Updated Java dependencies and build actions

1.5.0 - 2025-10-27

Added

  • Added PDF Component - Boxlang+ license required
  • Added PDFForm Component - Boxlang+ license required
  • Added PDFFormParam Component - Boxlang+ license required

Fixed

  • Fixed CFDocument handling of encoding on URL includes

1.4.3 - 2025-10-03

1.4.2 - 2025-04-23

1.4.1 - 2025-03-13

1.3.1 - 2025-03-01

1.3.0 - 2025-03-01

Fixed

  • Archive classifier for shadow jar was missing

Added

  • New gradle plugin for shadow jar
  • Update all internal dependencies

1.2.0 - 2025-02-18

1.1.0 - 2025-02-14

  • Updated build processes
  • Fixed logger implementaton to latest runtime conventions
  • removed multi-version on changelogs
  • Updated Java dependencies to latest versions

1.0.0 - 2025-01-22

  • First iteration of this module

<<<<<<< HEAD

=======

development

$ box install bx-pdf

No collaborators yet.
     
  • {{ getFullDate("2024-08-06T18:22:06Z") }}
  • {{ getFullDate("2025-11-05T18:40:09Z") }}
  • 2,563
  • 9,232