@encryptioner/html-to-pdf-generator
v1.0.3
Published
Modern multi-page PDF generator from HTML content with smart pagination and styling support
Downloads
515
Maintainers
Readme
HTML to PDF Generator
A modern, framework-agnostic library for converting HTML content to professional multi-page PDFs with smart pagination and rich features.
📦 NPM Package: https://www.npmjs.com/package/@encryptioner/html-to-pdf-generator
📚 Documentation
Complete documentation is available in the documentation folder:
- 📖 Full Documentation Index - Complete guide and API reference
- 🚀 Quick Start Guide - Get started in 5 minutes
- ⚙️ Installation Guide - Detailed installation instructions
- 🎨 API Reference - All options and configurations
Framework Guides
Feature Documentation
- Multi-Page Generation
- Image Handling
- Table Support
- Page Breaks
- Color Management
- Watermarks
- Headers & Footers
- Metadata
- Security & Encryption
- PDF Preview
- Batch Generation
✨ Features
Core Features
- ✅ Multi-page support with smart pagination
- ✅ Framework adapters for React, Vue, Svelte, and vanilla JS
- ✅ OKLCH color support with automatic Tailwind CSS compatibility
- ✅ Image optimization with SVG conversion and DPI control
- ✅ Table pagination with automatic header repetition
- ✅ Smart page breaks with orphan prevention
- ✅ HTML string support for generating PDFs from HTML markup
- ✅ TypeScript support with full type definitions
- ✅ Progress tracking with real-time callbacks
Advanced Features
- ✅ Watermarks - Add text or image watermarks with opacity control
- ✅ Headers/Footers - Dynamic templates with variables ({{pageNumber}}, {{totalPages}}, {{date}}, {{title}})
- ✅ PDF Metadata - Set title, author, subject, keywords, and creation date
- ✅ PDF Security - Password protection and permission controls (printing, copying, modifying)
- ✅ PDF Preview - Real-time PDF preview with live updates and debouncing
- ✅ Batch generation - Combine multiple HTML sections into one PDF
- ✅ Media type emulation - Apply @media print styles automatically
- ✅ External CSS - Automatic loading and processing of stylesheets
- ✅ Background images - Proper handling of CSS background images
- ✅ Custom CSS injection - Add custom styles before rendering
📦 Installation
npm install @encryptioner/html-to-pdf-generatorpnpm add @encryptioner/html-to-pdf-generatoryarn add @encryptioner/html-to-pdf-generator🚀 Quick Start
Vanilla JavaScript/TypeScript
import { generatePDF } from '@encryptioner/html-to-pdf-generator';
const element = document.getElementById('my-content');
await generatePDF(element, 'my-document.pdf', {
format: 'a4',
orientation: 'portrait',
margins: [10, 10, 10, 10], // [top, right, bottom, left] in mm
showPageNumbers: true,
watermark: {
text: 'CONFIDENTIAL',
opacity: 0.1,
position: 'diagonal'
}
});From HTML String
import { generatePDFFromHTML } from '@encryptioner/html-to-pdf-generator';
const html = `
<!DOCTYPE html>
<html>
<head>
<style>
body { font-family: Arial, sans-serif; }
.header { color: #333; font-size: 24px; }
</style>
</head>
<body>
<h1 class="header">My Document</h1>
<p>This is a paragraph with some content.</p>
</body>
</html>
`;
await generatePDFFromHTML(html, 'document.pdf', {
format: 'a4',
metadata: {
title: 'My Document',
author: 'John Doe'
}
});React
import { usePDFGenerator } from '@encryptioner/html-to-pdf-generator/react';
function MyComponent() {
const { targetRef, generatePDF, isGenerating, progress } = usePDFGenerator({
filename: 'my-document.pdf',
format: 'a4',
showPageNumbers: true,
});
return (
<div>
<div ref={targetRef}>
<h1>Content to convert to PDF</h1>
<p>This will be in your PDF document</p>
</div>
<button onClick={generatePDF} disabled={isGenerating}>
{isGenerating ? `Generating... ${progress}%` : 'Download PDF'}
</button>
</div>
);
}Vue 3
<script setup>
import { usePDFGenerator } from '@encryptioner/html-to-pdf-generator/vue';
const { targetRef, generatePDF, isGenerating, progress } = usePDFGenerator({
filename: 'my-document.pdf',
format: 'a4',
showPageNumbers: true,
});
</script>
<template>
<div>
<div ref="targetRef">
<h1>Content to convert to PDF</h1>
<p>This will be in your PDF document</p>
</div>
<button @click="generatePDF" :disabled="isGenerating">
{{ isGenerating ? `Generating... ${progress}%` : 'Download PDF' }}
</button>
</div>
</template>Svelte
<script>
import { createPDFGenerator } from '@encryptioner/html-to-pdf-generator/svelte';
let targetElement;
const { generatePDF, isGenerating, progress } = createPDFGenerator({
filename: 'my-document.pdf',
format: 'a4',
showPageNumbers: true,
});
const handleDownload = () => {
if (targetElement) {
generatePDF(targetElement);
}
};
</script>
<div bind:this={targetElement}>
<h1>Content to convert to PDF</h1>
<p>This will be in your PDF document</p>
</div>
<button on:click={handleDownload} disabled={$isGenerating}>
{$isGenerating ? `Generating... ${$progress}%` : 'Download PDF'}
</button>🔧 Advanced Usage
Watermarks
await generatePDF(element, 'document.pdf', {
watermark: {
text: 'CONFIDENTIAL',
opacity: 0.1,
position: 'diagonal', // 'center' | 'diagonal' | 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right'
fontSize: 48,
color: '#999999',
rotation: 45
}
});Headers & Footers
await generatePDF(element, 'document.pdf', {
metadata: {
title: 'Annual Report 2024'
},
headerTemplate: {
template: '<div style="text-align: center;">{{title}} - {{date}}</div>',
height: 15,
css: 'font-size: 11px; border-bottom: 1px solid #ccc;'
},
footerTemplate: {
template: '<div style="text-align: center;">Page {{pageNumber}} of {{totalPages}}</div>',
height: 12
}
});Available template variables:
{{pageNumber}}- Current page number{{totalPages}}- Total number of pages{{date}}- Current date{{title}}- Document title from metadata
PDF Security
Password protect your PDFs and control permissions:
await generatePDF(element, 'secure.pdf', {
securityOptions: {
enabled: true,
userPassword: 'secret123', // Password to open PDF
ownerPassword: 'admin456', // Password to change permissions
permissions: {
printing: 'highResolution', // 'none' | 'lowResolution' | 'highResolution'
modifying: false, // Disable modifications
copying: false, // Disable text copying
annotating: false, // Disable annotations
fillingForms: false // Disable form filling
}
}
});Note: jsPDF uses RC4 40-bit encryption, which provides basic protection but is not suitable for highly sensitive documents. For stronger encryption, consider server-side solutions.
Full security documentation: documentation/advanced/security.md
PDF Preview
Display a real-time preview of your PDF with automatic updates as content changes:
import { PDFGenerator } from '@encryptioner/html-to-pdf-generator';
const generator = new PDFGenerator({
format: 'a4',
previewOptions: {
containerId: 'pdf-preview', // ID of container element (required)
liveUpdate: true, // Auto-update when content changes
debounce: 500, // Wait 500ms after changes before updating
scale: 1, // Lower scale for faster preview
quality: 0.7 // Lower quality for faster preview
}
});
// Start preview
const contentElement = document.getElementById('content');
await generator.startPreview(contentElement);
// Preview automatically updates as content changes
// Manually update if needed: await generator.updatePreview();
// Stop preview and download final high-quality PDF
generator.stopPreview();
await generator.generatePDF(contentElement, 'final.pdf');HTML Structure:
<div id="content">
<!-- Your content to preview -->
</div>
<div id="pdf-preview" style="width: 100%; height: 600px; border: 1px solid #ccc;"></div>Full preview documentation: documentation/advanced/preview.md
Batch Generation
import { generateBatchPDF } from '@encryptioner/html-to-pdf-generator';
const items = [
{
content: document.getElementById('section-1'),
pageCount: 2,
title: 'Introduction',
newPage: true // Start on a new page
},
{
content: document.getElementById('section-2'),
pageCount: 3,
title: 'Content',
newPage: true
}
];
const result = await generateBatchPDF(items, 'combined.pdf', {
showPageNumbers: true
});
console.log(`Generated ${result.totalPages} pages`);Using the PDFGenerator Class
import { PDFGenerator } from '@encryptioner/html-to-pdf-generator';
const generator = new PDFGenerator({
format: 'a4',
orientation: 'portrait',
margins: [15, 15, 15, 15],
showPageNumbers: true,
pageNumberPosition: 'footer',
compress: true,
onProgress: (progress) => {
console.log(`Generating PDF: ${progress}%`);
},
onComplete: (blob) => {
console.log(`PDF generated! Size: ${blob.size} bytes`);
},
onError: (error) => {
console.error('PDF generation failed:', error);
},
});
// Generate PDF
await generator.generatePDF(element, 'document.pdf');
// Or get blob without downloading
const blob = await generator.generateBlob(element);🖥️ MCP Server (Model Context Protocol)
The package includes an MCP server for server-side PDF generation, enabling Claude Desktop and other MCP clients to generate PDFs.
Quick Setup for Claude Desktop
Build the package:
pnpm install && pnpm run buildAdd to Claude Desktop config (
~/Library/Application Support/Claude/claude_desktop_config.jsonon macOS):{ "mcpServers": { "html-to-pdf": { "command": "node", "args": ["/absolute/path/to/html-to-pdf-generator/mcp/dist/index.js"] } } }Restart Claude Desktop and use PDF generation in your conversations:
You: Generate a PDF invoice with these items and save to /tmp/invoice.pdf Claude: [Uses generate_pdf tool to create PDF]
MCP Tools Available
generate_pdf- Generate PDF from HTML with full feature supportgenerate_batch_pdf- Combine multiple HTML sections into one PDFgenerate_pdf_from_url- Convert web pages to PDF (CORS-aware)
📖 Full MCP Documentation: See mcp/README.md for complete setup, API reference, and examples.
📖 API Options
PDFGeneratorOptions
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| format | 'a4' \| 'letter' \| 'a3' \| 'legal' | 'a4' | Paper format |
| orientation | 'portrait' \| 'landscape' | 'portrait' | Page orientation |
| margins | [number, number, number, number] | [10, 10, 10, 10] | Margins [top, right, bottom, left] in mm |
| compress | boolean | true | Enable PDF compression |
| scale | number | 2 | HTML2Canvas scale factor (1-4) |
| imageQuality | number | 0.85 | JPEG quality (0-1) |
| showPageNumbers | boolean | false | Show page numbers |
| pageNumberPosition | 'header' \| 'footer' | 'footer' | Page number position |
| customCSS | string | '' | Custom CSS to inject |
| watermark | WatermarkOptions | undefined | Watermark configuration |
| headerTemplate | HeaderFooterTemplate | undefined | Header template |
| footerTemplate | HeaderFooterTemplate | undefined | Footer template |
| metadata | PDFMetadata | undefined | PDF metadata |
| securityOptions | PDFSecurityOptions | undefined | Security & encryption settings |
| emulateMediaType | 'screen' \| 'print' | 'screen' | Media type to emulate |
| onProgress | (progress: number) => void | - | Progress callback (0-100) |
| onComplete | (blob: Blob) => void | - | Completion callback |
| onError | (error: Error) => void | - | Error callback |
Full API documentation: documentation/api/options.md
🔍 Browser Compatibility
- ✅ Chrome/Edge 90+
- ✅ Firefox 88+
- ✅ Safari 14+
- ✅ Modern mobile browsers
Note: Requires browser support for html2canvas and jsPDF.
🤝 Contributing
We welcome contributions! Please see our Contributing Guide for details.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
📝 License
MIT License - see LICENSE.md for details.
🐛 Issues & Support
- Issues: GitHub Issues
- Email: [email protected]
🙏 Acknowledgments
Built with:
- jsPDF - PDF generation
- html2canvas-pro - HTML to canvas rendering
- pdf-lib - PDF merging
📊 Package Stats
- Bundle Size: ~400KB (minified)
- Dependencies: 3 core dependencies
- TypeScript: Full type definitions included
- Tree-shakeable: ESM and CJS builds
- Framework Support: React, Vue, Svelte, Vanilla JS
- Server-Side: Node.js with Puppeteer
Ready to get started? → Quick Start Guide
