safeer-pdf-generator
Version:
Framework-agnostic PDF generation library with chunking, merging, S3 upload, and email delivery
67 lines (55 loc) ⢠2.63 kB
JavaScript
// Local file output + lifecycle events (v1.3.6)
// Demonstrates writing the generated PDF to disk alongside the buffer return,
// and how the file:saved event composes with the rest of the lifecycle.
import { generatePdf, PdfEventEmitter, consoleLogger } from 'safeer-pdf-generator';
import * as path from 'path';
import * as os from 'os';
async function main() {
const outputDir = path.join(os.tmpdir(), 'safeer-pdf-demo');
const events = new PdfEventEmitter();
events.onEvent('generation:started', ({ title, rowCount }) => {
console.log(`š Started: "${title}" (${rowCount} rows)`);
});
events.onEvent('chunk:processed', ({ chunkIndex, totalChunks, sizeBytes }) => {
const pct = (((chunkIndex + 1) / totalChunks) * 100).toFixed(0);
console.log(` š¦ Chunk ${chunkIndex + 1}/${totalChunks} done (${sizeBytes} B) ā ${pct}%`);
});
events.onEvent('file:saved', ({ path: filePath, sizeBytes }) => {
console.log(`š¾ Saved: ${filePath} (${(sizeBytes / 1024).toFixed(1)} KB)`);
});
events.onEvent('generation:complete', ({ result }) => {
console.log(`ā
Complete: ${result.pageCount} pages, ${result.durationMs}ms`);
});
events.onEvent('error', ({ error, phase }) => {
console.error(`ā Error during ${phase}: ${error.message}`);
});
// Generate 500 rows ā 5 chunks ā 5 chunk:processed events + 1 file:saved
const rows = Array.from({ length: 500 }, (_, i) => ({
id: i + 1,
product: `Product ${i + 1}`,
amount: Math.round(Math.random() * 1000 * 100) / 100,
}));
const result = await generatePdf({
title: 'Sales Report',
data: rows,
columns: [
{ key: 'id', title: 'ID', dataIndex: 'id' },
{ key: 'product', title: 'Product', dataIndex: 'product' },
{ key: 'amount', title: 'Amount', dataIndex: 'amount' },
],
chunking: { enabled: true, chunkSize: 100, maxConcurrency: 2 },
localFs: {
path: outputDir, // directory; created if missing
// filename: 'custom.pdf', // override the auto-generated filename
// overwrite: false, // throw if target exists
},
events,
logging: consoleLogger,
});
// result.localFs is populated; result.buffer is also available
console.log('\nš Result:');
console.log(' buffer.length:', result.buffer.length);
console.log(' localFs.path :', result.localFs?.path);
console.log(' localFs.size :', result.localFs?.sizeBytes, 'bytes');
}
main().catch(console.error);