JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 11
  • Score
    100M100P100Q63915F
  • License MIT

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

Package Exports

  • @npoci/pdfform
  • @npoci/pdfform/dist/pdfform.css

Readme

@npoci/pdfform

Modern PDF form renderer with HTML overlay fields. View, fill, validate, and map PDF forms directly in the browser.

npm version License: 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

npm install @npoci/pdfform

Quick Start

Basic PDF Form Renderer

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:

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:

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

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:

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

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

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 and pdf-lib.