Node.js Guide
This guide covers using printwell with Node.js.
Installation
npm install printwell
Or with yarn:
yarn add printwell
Basic Usage
ES Modules (Recommended)
import { Converter } from 'printwell';
const converter = new Converter();
const result = await converter.htmlToPdf('<h1>Hello, World!</h1>');
await result.writeToFile('output.pdf');
CommonJS
const { Converter } = require('printwell');
async function main() {
const converter = new Converter();
const result = await converter.htmlToPdf('<h1>Hello, World!</h1>');
await result.writeToFile('output.pdf');
}
TypeScript
Full TypeScript support with included type definitions:
import { Converter, PdfOptions, RenderOptions, PdfResult } from 'printwell';
const converter = new Converter();
const options: PdfOptions = {
pageSize: 'A4',
margins: { top: 20, right: 15, bottom: 20, left: 15 }
};
const result: PdfResult = await converter.htmlToPdf(html, null, options);
Converting Documents
HTML String to PDF
import { Converter } from 'printwell';
const converter = new Converter();
const html = `
<!DOCTYPE html>
<html>
<head>
<style>
body { font-family: Arial; padding: 40px; }
h1 { color: #333; }
</style>
</head>
<body>
<h1>My Document</h1>
<p>This is a PDF generated from HTML.</p>
</body>
</html>
`;
const result = await converter.htmlToPdf(html);
// Get as Buffer
const buffer = result.data;
// Write to file
await result.writeToFile('output.pdf');
// Get page count
console.log(`Pages: ${result.pageCount}`);
URL to PDF
const result = await converter.urlToPdf('https://example.com');
await result.writeToFile('example.pdf');
Configuration Options
PDF Options
const result = await converter.htmlToPdf(html, null, {
// Page size: 'A3', 'A4', 'A5', 'Letter', 'Legal', 'Tabloid'
pageSize: 'A4',
// Or custom size in mm
pageWidthMm: 210,
pageHeightMm: 297,
// Orientation: 'Portrait' or 'Landscape'
orientation: 'Portrait',
// Margins in mm
margins: {
top: 20,
right: 15,
bottom: 20,
left: 15
},
// Scale factor (0.1 to 2.0)
scale: 1.0,
// Print background graphics
printBackground: true,
// Page ranges
pageRanges: '1-5,8,10-12',
// Headers and footers
headerTemplate: '<div style="font-size:10px">Header</div>',
footerTemplate: '<div style="font-size:10px">Page <span class="pageNumber"></span> of <span class="totalPages"></span></div>',
// Metadata
metadata: {
title: 'My Document',
author: 'Author Name',
subject: 'Document Subject',
keywords: 'pdf, nodejs'
}
});
Render Options
const result = await converter.htmlToPdf(html, {
// Base URL for relative resources
baseUrl: 'https://example.com/',
// Viewport
viewport: {
width: 1920,
height: 1080,
deviceScaleFactor: 2.0
},
// Resource loading
resources: {
allowRemote: true,
timeoutMs: 30000,
blockedDomains: ['ads.example.com'],
userAgent: 'Custom User Agent'
},
// Custom CSS
userStylesheets: [
'body { font-family: "Custom Font"; }'
]
});
Batch Processing
Converter Pool
For high-throughput scenarios:
import { ConverterPool } from 'printwell';
// Create pool with 4 concurrent converters
const pool = new ConverterPool(4);
// Convert multiple documents
const htmlDocs = [
'<h1>Document 1</h1>',
'<h1>Document 2</h1>',
'<h1>Document 3</h1>'
];
const results = await pool.convertBatch(htmlDocs);
for (let i = 0; i < results.length; i++) {
await results[i].writeToFile(`output_${i}.pdf`);
}
Parallel Conversion
const urls = [
'https://example.com/page1',
'https://example.com/page2',
'https://example.com/page3'
];
const results = await Promise.all(
urls.map(url => converter.urlToPdf(url))
);
PDF Post-Processing
Watermarks
import { addWatermark, addWatermarks } from 'printwell';
import { readFile, writeFile } from 'fs/promises';
const pdfData = await readFile('input.pdf');
// Text watermark
const result = addWatermark(pdfData, {
text: 'CONFIDENTIAL',
position: 'Center',
rotation: 45,
opacity: 0.3,
fontSize: 72,
color: { r: 128, g: 128, b: 128 }
});
await writeFile('watermarked.pdf', result);
// Multiple watermarks
const multiResult = addWatermarks(pdfData, [
{ text: 'DRAFT', position: 'Center', opacity: 0.2 },
{ text: 'Page header', position: 'TopCenter', fontSize: 12 }
]);
Bookmarks
import { addBookmarks, extractBookmarks } from 'printwell';
const pdfData = await readFile('input.pdf');
// Add bookmarks
const result = addBookmarks(pdfData, [
{ title: 'Chapter 1', page: 1 },
{ title: 'Chapter 2', page: 5, children: [
{ title: 'Section 2.1', page: 5 },
{ title: 'Section 2.2', page: 8 }
]},
{ title: 'Chapter 3', page: 12 }
]);
// Extract existing bookmarks
const bookmarks = extractBookmarks(pdfData);
console.log(bookmarks);
Annotations
import { addAnnotations, listAnnotations, removeAnnotations } from 'printwell';
// Add highlight annotation
const result = addAnnotations(pdfData, [
{
type: 'Highlight',
page: 1,
rect: { x: 100, y: 700, width: 200, height: 20 },
color: { r: 255, g: 255, b: 0 },
opacity: 0.5
},
{
type: 'Text', // Sticky note
page: 1,
rect: { x: 50, y: 600, width: 24, height: 24 },
contents: 'Review this section',
author: 'Reviewer'
}
]);
// List annotations
const annotations = listAnnotations(pdfData);
// Remove all highlight annotations
const cleaned = removeAnnotations(pdfData, {
types: ['Highlight']
});
Encryption
import { encryptPdf, decryptPdf } from 'printwell';
// Encrypt PDF
const encrypted = encryptPdf(pdfData, {
ownerPassword: 'admin123',
userPassword: 'user123',
permissions: {
print: true,
copy: false,
modify: false,
annotate: true
},
algorithm: 'Aes256'
});
await writeFile('encrypted.pdf', encrypted);
// Decrypt PDF
const decrypted = decryptPdf(encrypted, 'admin123');
Digital Signatures
import { signPdf, signPdfVisible, verifySignatures } from 'printwell';
const pdfData = await readFile('document.pdf');
const certData = await readFile('certificate.p12');
// Invisible signature
const signed = signPdf(pdfData, certData, 'certificate_password', {
reason: 'Approved',
location: 'New York',
signatureLevel: 'PadesB'
});
// Visible signature
const signedVisible = signPdfVisible(pdfData, certData, 'password', {
reason: 'Approved'
}, {
page: 1,
x: 400,
y: 50,
width: 200,
height: 75,
showName: true,
showDate: true
});
// Verify signatures
const verifications = verifySignatures(signedData);
for (const v of verifications) {
console.log(`Signer: ${v.signerName}, Valid: ${v.isValid}`);
}
Form Fields
import { addFormFields, validateFormFields } from 'printwell';
// Add form fields
const result = addFormFields(pdfData, [
{
fieldType: 'text',
name: 'full_name',
page: 1,
rect: { x: 100, y: 700, width: 200, height: 20 },
required: true
},
{
fieldType: 'checkbox',
name: 'agree_terms',
page: 1,
rect: { x: 100, y: 650, width: 15, height: 15 },
checked: false
},
{
fieldType: 'dropdown',
name: 'country',
page: 1,
rect: { x: 100, y: 600, width: 150, height: 20 },
options: ['USA', 'Canada', 'UK', 'Other']
}
]);
// Validate form fields
const validation = validateFormFields(formElements, [
{ fieldName: 'full_name', required: true, minLength: 2 },
{ fieldName: 'email', required: true, pattern: '^[^@]+@[^@]+$' }
]);
console.log(`Valid: ${validation.allValid}`);
PDF/A Compliance
import { validatePdfa, addPdfaMetadata } from 'printwell';
// Validate PDF/A compliance
const result = validatePdfa(pdfData, 'PdfA2b');
console.log(`Compliant: ${result.isCompliant}`);
for (const issue of result.issues) {
console.log(`${issue.severity}: ${issue.message}`);
}
// Add PDF/A metadata
const pdfaDoc = addPdfaMetadata(pdfData, 'PdfA2b', {
title: 'Archived Document',
author: 'Author Name'
});
PDF/UA Accessibility
import { validatePdfua, addPdfuaMetadata } from 'printwell';
// Validate accessibility
const result = validatePdfua(pdfData, 'PdfUA1');
console.log(`Accessible: ${result.isCompliant}`);
// Add accessibility metadata
const accessibleDoc = addPdfuaMetadata(pdfData, 'PdfUA1', {
language: 'en',
title: 'Accessible Document',
generateOutline: true
});
Error Handling
import { Converter } from 'printwell';
try {
const converter = new Converter();
const result = await converter.htmlToPdf(html);
await result.writeToFile('output.pdf');
} catch (error) {
if (error.code === 'CONVERSION_ERROR') {
console.error('Failed to convert HTML:', error.message);
} else if (error.code === 'RESOURCE_ERROR') {
console.error('Failed to load resource:', error.message);
} else {
throw error;
}
}
Express.js Integration
import express from 'express';
import { Converter } from 'printwell';
const app = express();
const converter = new Converter();
app.get('/generate-pdf', async (req, res) => {
try {
const html = `<h1>Generated at ${new Date().toISOString()}</h1>`;
const result = await converter.htmlToPdf(html);
res.setHeader('Content-Type', 'application/pdf');
res.setHeader('Content-Disposition', 'attachment; filename="document.pdf"');
res.send(result.data);
} catch (error) {
res.status(500).json({ error: error.message });
}
});
app.listen(3000);