safeer-pdf-generator
Version:
Framework-agnostic PDF generation library with chunking, merging, S3 upload, and email delivery
321 lines (258 loc) • 8.38 kB
Markdown
# safeer-pdf-generator
[](https://badge.fury.io/js/safeer-pdf-generator)
[](https://opensource.org/licenses/MIT)
[](https://www.npmjs.com/package/safeer-pdf-generator)
A powerful, framework-agnostic TypeScript library for generating PDF reports with chunking, merging, S3 upload, and email delivery.
## ✨ Features
- 🚀 **High Performance** - Concurrent processing with memory optimization
- 📊 **Rich Templates** - Built-in templates with charts and styling
- 🔧 **Framework Agnostic** - Works with Express, NestJS, Fastify, or standalone
- ☁️ **S3 Integration** - Direct upload to Amazon S3 with presigned URLs
- 📧 **Email Delivery** - Send PDFs as attachments or download links
- 🔀 **PDF Operations** - Merge, split, and manipulate existing PDFs
- 💾 **Memory Efficient** - Handle large datasets (100k+ records)
- 🛡️ **TypeScript** - Full type safety and IntelliSense support
## 📦 Installation
### Prerequisites
This package requires Chromium to be installed on your system for PDF generation:
```bash
# Install Chromium
sudo apt-get install chromium-browser
# Or set custom path
export PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium-browser
```
### Package Installation
```bash
npm install safeer-pdf-generator
# Optional peer dependencies for S3 and email
npm install @aws-sdk/client-s3 nodemailer
```
## 🚀 Quick Start
### Basic PDF Generation
```typescript
import { generatePdf } from 'safeer-pdf-generator';
const result = await generatePdf({
title: 'Sales Report',
data: [
{ name: 'John Doe', sales: 1200, region: 'North' },
{ name: 'Jane Smith', sales: 1500, region: 'South' },
],
columns: [
{ key: 'name', title: 'Name', dataIndex: 'name' },
{ key: 'sales', title: 'Sales', dataIndex: 'sales', format: 'currency' },
{ key: 'region', title: 'Region', dataIndex: 'region' },
],
});
console.log('PDF generated!', result.buffer);
```
### Complete Example with S3 & Email
```typescript
import { generatePdf, consoleLogger } from 'safeer-pdf-generator';
const result = await generatePdf({
title: 'Monthly Report',
data: salesData,
columns: [
{ key: 'name', title: 'Sales Rep', dataIndex: 'name' },
{ key: 'sales', title: 'Sales', dataIndex: 'sales', format: 'currency' },
{ key: 'commission', title: 'Commission', dataIndex: 'commission', format: 'percentage' },
],
// S3 Upload
s3: {
bucket: process.env.S3_BUCKET_NAME || 'your-default-bucket',
region: process.env.AWS_REGION || 'us-east-1',
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
},
// Email Delivery
email: {
to: 'recipient@example.com',
attachmentMode: 'link', // or 'attachment'
smtp: {
host: process.env.SMTP_HOST || 'smtp.example.com',
port: process.env.SMTP_PORT ? Number(process.env.SMTP_PORT) : 587,
secure: process.env.SMTP_SECURE === 'true',
auth: {
user: process.env.SMTP_USER,
pass: process.env.SMTP_PASS,
},
},
},
logging: consoleLogger,
});
console.log(`PDF generated: ${result.s3?.url}`);
console.log(`Processing time: ${result.durationMs}ms`);
```
## 🏗️ Framework Examples
### Express.js
```typescript
import express from 'express';
import { generatePdf } from 'safeer-pdf-generator';
const app = express();
app.post('/generate-report', async (req, res) => {
try {
const result = await generatePdf({
title: 'User Report',
data: req.body.data,
columns: req.body.columns,
});
res.setHeader('Content-Type', 'application/pdf');
res.setHeader('Content-Disposition', 'attachment; filename="report.pdf"');
res.send(result.buffer);
} catch (error) {
res.status(500).json({ error: 'PDF generation failed' });
}
});
```
### NestJS
```typescript
import { Injectable } from '@nestjs/common';
import { generatePdf } from 'safeer-pdf-generator';
@Injectable()
export class PdfService {
async createReport(data: any[]) {
return await generatePdf({
title: 'Report',
data,
columns: [
{ key: 'id', title: 'ID', dataIndex: 'id' },
{ key: 'name', title: 'Name', dataIndex: 'name' },
],
});
}
}
```
### Next.js API Route
```typescript
// pages/api/generate-pdf.ts
import { NextApiRequest, NextApiResponse } from 'next';
import { generatePdf } from 'safeer-pdf-generator';
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
if (req.method !== 'POST') {
return res.status(405).json({ message: 'Method not allowed' });
}
try {
const result = await generatePdf({
title: 'Report',
data: req.body.data,
columns: req.body.columns,
});
res.setHeader('Content-Type', 'application/pdf');
res.send(result.buffer);
} catch (error) {
res.status(500).json({ error: 'Failed to generate PDF' });
}
}
```
## 📊 Advanced Features
### Large Dataset Handling
```typescript
import { generatePdf } from 'safeer-pdf-generator';
// Handle 100k+ records efficiently
const result = await generatePdf({
title: 'Large Report',
data: largeDataset, // 100,000+ records
columns: columns,
chunkSize: 1000, // Process in chunks
performance: {
concurrent: true,
maxConcurrency: 4,
},
});
```
### PDF Merging
```typescript
import { mergePdfs } from 'safeer-pdf-generator';
const mergedPdf = await mergePdfs({
files: ['report1.pdf', 'report2.pdf', 'report3.pdf'],
// or use buffers
buffers: [buffer1, buffer2, buffer3],
});
```
### Custom Styling
```typescript
const result = await generatePdf({
title: 'Styled Report',
data: data,
columns: columns,
styling: {
headerBackground: '#2563eb',
headerTextColor: '#ffffff',
alternateRowBackground: '#f8fafc',
fontSize: 12,
fontFamily: 'Inter',
},
});
```
## 📧 Email Templates
The library includes smart email templates with automatic configuration:
```typescript
// Automatic SMTP detection and validation
const result = await generatePdf({
// ... pdf config
email: {
to: 'user@example.com',
subject: 'Your Report is Ready',
attachmentMode: 'link', // Smart S3 link or attachment
// SMTP auto-configured from common providers
},
});
```
## 🔧 Configuration Options
### Column Configuration
```typescript
const columns = [
{
key: 'name',
title: 'Name',
dataIndex: 'name',
width: 200,
align: 'left'
},
{
key: 'amount',
title: 'Amount',
dataIndex: 'amount',
format: 'currency', // Built-in formatters
align: 'right'
},
{
key: 'date',
title: 'Date',
dataIndex: 'date',
format: 'date',
dateFormat: 'MM/DD/YYYY'
}
];
```
### Performance Options
```typescript
const result = await generatePdf({
// ... other config
performance: {
concurrent: true,
maxConcurrency: 4,
chunkSize: 1000,
memoryLimit: '512MB',
},
});
```
## 🌟 Why Choose safeer-pdf-generator?
- **Production Ready**: Used in enterprise applications
- **Memory Efficient**: Handles massive datasets without memory issues
- **Developer Friendly**: Excellent TypeScript support and documentation
- **Framework Agnostic**: Works with any Node.js framework
- **Full Featured**: Everything you need for PDF generation in one package
- **Active Maintenance**: Regular updates and community support
## �� Documentation
- [API Reference](https://github.com/Safeersoft/pdf-reporter/blob/main/docs/api.md)
- [Examples](https://github.com/Safeersoft/pdf-reporter/tree/main/examples)
- [Migration Guide](https://github.com/Safeersoft/pdf-reporter/blob/main/docs/migration.md)
## 🤝 Contributing
We welcome contributions! Please see our [Contributing Guide](https://github.com/Safeersoft/pdf-reporter/blob/main/CONTRIBUTING.md) for details.
## 📄 License
MIT © [Safeersoft](https://github.com/Safeersoft)
## 🔗 Links
- [NPM Package](https://www.npmjs.com/package/safeer-pdf-generator)
- [GitHub Repository](https://github.com/Safeersoft/pdf-reporter)
- [Issues & Support](https://github.com/Safeersoft/pdf-reporter/issues)
- [Changelog](https://github.com/Safeersoft/pdf-reporter/blob/main/CHANGELOG.md)