@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
Markdown
# @npoci/pdfform
Modern PDF form renderer with HTML overlay fields. View, fill, validate, and map PDF forms directly in the browser.
[](https://www.npmjs.com/package/@npoci/pdfform)
[](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/).