fastify-xpdf
fillForm
Fill PDF form fields (text, checkbox, radio, dropdown) using pdf-lib and optionally flatten the result.
fillForm
Fill PDF form fields using pdf-lib. Accepts a PDF buffer with embedded form fields and a key-value map of field names to values. Supports text, checkbox, radio, and dropdown fields. Optionally flattens the form (removes editability) after filling.
Signature
fastify.xPDF.fillForm(
pdfBuffer: Buffer,
fieldValues: Record<string, string | boolean>,
options?: FormOptions,
): Promise<PdfResult>
interface FormOptions {
flatten?: boolean // flatten after filling (default: true)
filename?: string
saveToStorage?: boolean
folder?: string
}
interface PdfResult {
buffer: Buffer
filename: string
size: number
storageKey?: string
url?: string
}
Params
| Name | Type | Required | Description |
|---|---|---|---|
pdfBuffer | Buffer | Yes | Source PDF containing form fields (must start with %PDF header) |
fieldValues | object | Yes | { fieldName: value } — strings for text/dropdown/radio, booleans for checkboxes |
options.flatten | boolean | No | Flatten form after filling — makes fields non-editable (default: true) |
options.filename | string | No | Output filename |
options.saveToStorage | boolean | No | Upload result to xStorage |
options.folder | string | No | Storage folder override |
Returns
PdfResult: { buffer, filename, size, storageKey?, url? }.
Throws
| Error | When |
|---|---|
[xPDF] Invalid PDF buffer | pdfBuffer doesn't start with %PDF |
[xPDF] fieldValues must be an object | fieldValues is not a plain object |
Examples
Fill an employment application form
fastify.post("/applications/:id/form", async (request, reply) => {
const application = await fastify.prisma.application.findUnique({
where: { id: request.params.id },
include: { applicant: true },
});
const templateBuffer = await fetchTemplateBuffer("employment-application.pdf");
const { buffer, filename } = await fastify.xPDF.fillForm(
templateBuffer,
{
firstName: application.applicant.firstName,
lastName: application.applicant.lastName,
email: application.applicant.email,
position: application.position,
startDate: application.startDate,
fullTime: application.employmentType === "full-time",
agreeToTerms: true,
},
{ flatten: true, filename: `application-${application.id}.pdf` },
);
return reply
.header("Content-Type", "application/pdf")
.header("Content-Disposition", `attachment; filename="${filename}"`)
.send(buffer);
});
Fill without flattening (keep form editable)
// Generate a pre-filled but still-editable draft for review
const { buffer } = await fastify.xPDF.fillForm(
templateBuffer,
{ companyName: "Acme Corp", contractDate: "2025-03-01" },
{ flatten: false },
);
See Also
- listFormFields — Inspect field names and types before filling
- mergePDFs — Combine filled forms with cover pages
AI Context
package: "@xenterprises/fastify-xpdf"
method: fastify.xPDF.fillForm(pdfBuffer, fieldValues, options?)
use-when: Fill PDF form fields using pdf-lib — optionally flatten the form to prevent further editing
params: pdfBuffer (Buffer), fieldValues ({ fieldName: value }), options ({ flatten: boolean })
returns: { buffer, size }
