pdfRendererLast updated on
Last updated on
Fill PDF forms with AcroForm field support
Fill PDF forms by populating AcroForm fields with form data. Built on pdf-lib, supporting text fields, checkboxes, dropdowns, and radio buttons with automatic field serialization.
Example
import { open } from '@open-form/core'
import { pdfRenderer } from '@open-form/renderer-pdf'
const form = open.form({
name: 'w9',
fields: {
name: { type: 'text', label: 'Name' },
businessName: { type: 'text', label: 'Business Name' },
taxClassification: { type: 'enum', enum: ['individual', 'llc', 'corporation'] },
address: { type: 'text', label: 'Address' },
ssn: { type: 'text', label: 'SSN' }
},
layers: {
pdf: {
kind: 'file',
mimeType: 'application/pdf',
path: '/templates/w9-form.pdf',
bindings: {
// Map PDF field names to form field expressions
'topmostSubform[0].Page1[0].f1_1[0]': 'name',
'topmostSubform[0].Page1[0].f1_2[0]': 'businessName',
'topmostSubform[0].Page1[0].c1_1[0]': 'taxClassification:individual',
'topmostSubform[0].Page1[0].c1_1[1]': 'taxClassification:llc',
'topmostSubform[0].Page1[0].f1_5[0]': 'address'
}
}
},
defaultLayer: 'pdf'
})
// Fill the form with data
const filled = form.fill({
fields: {
name: 'John Smith',
businessName: 'Smith Consulting',
taxClassification: 'llc',
address: '123 Main St, New York, NY 10001'
}
})
// Render the filled form
const output = await filled.render({
renderer: pdfRenderer()
})
// output is Uint8Array - write to file
fs.writeFileSync('w9-filled.pdf', output)Import
From the umbrella package:
import { pdfRenderer } from '@open-form/renderers'Or from the individual package:
import { pdfRenderer } from '@open-form/renderer-pdf'API
pdfRenderer()
Factory function that creates a configured PDF renderer instance.
function pdfRenderer(options?: PdfRendererOptions): OpenFormRenderer<
RendererLayer & { type: 'pdf'; content: Uint8Array },
Uint8Array
>Parameters
PdfRendererOptions
PdfSignatureOptions
Returns
Returns an OpenFormRenderer object with:
renderPdf()
Low-level function for direct PDF rendering without the full renderer interface.
async function renderPdf(options: RenderPdfOptions): Promise<Uint8Array>RenderPdfOptions
Returns
Returns a Promise<Uint8Array> containing the filled PDF document.
inspectAcroFormFields()
Utility function to inspect AcroForm fields in a PDF template.
async function inspectAcroFormFields(
template: Uint8Array,
options?: InspectOptions
): Promise<PdfFieldInfo[]>Parameters
InspectOptions
PdfFieldInfo
Inspecting PDF Fields
Use inspectAcroFormFields() to discover field names in a PDF template:
import { inspectAcroFormFields } from '@open-form/renderer-pdf'
import fs from 'fs'
const template = fs.readFileSync('form.pdf')
const fields = await inspectAcroFormFields(template)
console.log(fields)
// [
// { name: 'f1_1', type: 'text', required: true },
// { name: 'c1_1', type: 'checkbox', value: false },
// { name: 'dropdown1', type: 'dropdown', value: ['Option A'] }
// ]Binding Syntax
PDF bindings map AcroForm field names to form field names with special syntax for complex cases:
Simple Binding
bindings: {
'pdfFieldName': 'formFieldName'
}Enum Checkboxes
For PDF checkboxes that represent enum values, use :value syntax:
bindings: {
'checkbox_individual': 'taxType:individual', // Check if taxType === 'individual'
'checkbox_llc': 'taxType:llc', // Check if taxType === 'llc'
'checkbox_corp': 'taxType:corporation' // Check if taxType === 'corporation'
}Split Fields
For fields split across multiple PDF inputs (like SSN), use :partNumber syntax:
bindings: {
'ssn_part1': 'ssn:1', // First part: "123" from "123-45-6789"
'ssn_part2': 'ssn:2', // Second part: "45"
'ssn_part3': 'ssn:3' // Third part: "6789"
}Combined Fields
Combine multiple form fields into one PDF field:
bindings: {
'cityStateZip': 'city,state,zipCode' // "San Francisco, CA, 94105"
}Nested Paths
Access nested data using dot notation:
bindings: {
'buyer_name': 'parties.buyer.fullName'
}Automatic Serialization
Field values are automatically serialized based on their schema types:
// Money fields formatted as "$50,000.00"
// Date fields formatted as "April 1, 2024"
// Phone fields formatted as "(555) 123-4567"Related
- Renderers - Renderer interface overview
- Serialization - Value formatting