UNPKG

@npoci/pdfform

Version:

Modern PDF form renderer with HTML overlay fields - view, fill, and map PDF forms in the browser

220 lines (168 loc) 5.84 kB
# @npoci/pdfform Modern PDF form renderer with HTML overlay fields. View, fill, validate, and map PDF forms directly in the browser. [![npm version](https://img.shields.io/npm/v/@npoci/pdfform.svg)](https://www.npmjs.com/package/@npoci/pdfform) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) ## Features - 🎯 **HTML Overlay Fields** - Real HTML inputs positioned over PDF forms - 📝 **Form Filling** - Fill and export PDF forms programmatically - 🔍 **Field Mapping** - Visual field mapper to create user-friendly field definitions - ✅ **Validation** - Built-in validation with custom patterns and error messages - 🎨 **Customizable** - Override field renderers and styles - 📦 **Framework Agnostic** - Works with React, Vue, Angular, or vanilla JS - 🔒 **Type Safe** - Full TypeScript support ## Installation ```bash npm install @npoci/pdfform ``` ## Quick Start ### Basic PDF Form Renderer ```javascript import { PDFFormRenderer } from '@npoci/pdfform' const renderer = new PDFFormRenderer({ container: document.getElementById('pdf-container'), pdfUrl: 'path/to/form.pdf' }) // Listen for field changes renderer.on('fieldChange', (field, validationState) => { console.log(`${field.name}: ${field.value}`, validationState) }) // Render the PDF await renderer.render() // Get form values const values = renderer.getFieldValues() // { email: 'user@example.com', name: 'John Doe' } // Get validation states const states = renderer.getFieldStates() // { email: { valid: true }, name: { valid: false, error: 'Required' } } ``` ### Field Definitions Make PDF fields user-friendly with custom definitions: ```javascript const renderer = new PDFFormRenderer({ container: document.getElementById('pdf-container'), pdfUrl: 'form.pdf', fieldDefinitions: [ { key: 'field_12_a', // Original PDF field name name: 'email', // User-friendly name for getFieldValues() title: 'Email Address', placeholder: 'Enter your email', required: true, pattern: '^[^@]+@[^@]+\\.[^@]+$', errorMessage: 'Please enter a valid email' } ] }) ``` ### Custom Field Renderers Override how specific fields are rendered: ```javascript const renderer = new PDFFormRenderer({ container: document.getElementById('pdf-container'), pdfUrl: 'form.pdf', fieldOverrides: { 'signature_field': { createField(field, bounds, setValue) { const canvas = document.createElement('canvas') canvas.width = bounds.width canvas.height = bounds.height // Add your signature drawing logic return canvas }, getValue(element) { return element.toDataURL() }, setValue(element, value) { // Load signature from data URL } } } }) ``` ### Fill and Download PDFs ```javascript import { PDFFiller } from '@npoci/pdfform' const filler = new PDFFiller() const values = renderer.getRawFieldValues() // Fill the PDF const filledPdfBytes = await filler.fillFromUrl('form.pdf', values) // Download const blob = new Blob([filledPdfBytes], { type: 'application/pdf' }) const url = URL.createObjectURL(blob) const link = document.createElement('a') link.href = url link.download = 'filled-form.pdf' link.click() ``` ## Field Mapper Create field definitions visually with the built-in mapper: ```javascript import { PDFFieldMapper } from '@npoci/pdfform' const mapper = new PDFFieldMapper({ container: document.getElementById('mapper-container'), pdfUrl: 'form.pdf' }) // Listen for field selection mapper.on('fieldSelected', ({ field, currentMapping }) => { console.log('Selected:', field.key) }) // Export field definitions const definitions = mapper.getFieldDefinitions() console.log(JSON.stringify(definitions, null, 2)) ``` ## API Reference ### PDFFormRenderer #### Options ```typescript interface PDFFormRendererOptions { container: HTMLElement pdfUrl: string fieldDefinitions?: FieldDefinition[] fieldRenderers?: Record<string, FieldRenderer> fieldOverrides?: Record<string, FieldRenderer> scale?: number page?: number highlightColor?: string // Default: '#ffffcc' highlightColorFocus?: string // Default: '#ffffaa' } ``` #### Methods - `render(): Promise<void>` - Render the PDF - `setPage(pageNumber: number): void` - Change page - `getFieldValues(): Record<string, any>` - Get form values with user-friendly names - `getRawFieldValues(): Record<string, any>` - Get values with original PDF field names - `getFieldStates(): Record<string, ValidationState>` - Get validation states - `setFieldValues(values: Record<string, any>): void` - Set multiple field values - `destroy(): void` - Clean up resources #### Events - `ready` - PDF loaded and fields discovered - `fieldChange` - Field value changed with validation - `pageChange` - Page changed - `error` - Error occurred ### PDFFieldMapper #### Options ```typescript interface PDFFieldMapperOptions { container: HTMLElement pdfUrl: string fieldDefinitions?: FieldDefinition[] } ``` #### Methods - `render(): Promise<void>` - Render the mapper - `setFieldDefinition(key: string, definition: FieldDefinition): void` - Map a field - `removeFieldDefinition(key: string): void` - Remove mapping - `getFieldDefinitions(): FieldDefinition[]` - Get all mappings - `exportDefinitions(): string` - Export as JSON - `importDefinitions(json: string): void` - Import mappings - `clearMappings(): void` - Clear all mappings ## Browser Compatibility - Chrome/Edge 88+ - Firefox 85+ - Safari 14+ ## License MIT © npoci ## Contributing Issues and PRs welcome! Please check existing issues before creating new ones. ## Acknowledgments Built on top of [PDF.js](https://mozilla.github.io/pdf.js/) and [pdf-lib](https://pdf-lib.js.org/).