UNPKG

safeer-pdf-generator

Version:

Framework-agnostic PDF generation library with chunking, merging, S3 upload, and email delivery

441 lines (340 loc) 10.6 kB
# Advanced Express.js PDF Generation API This example demonstrates how to build a comprehensive RESTful API for PDF generation using `pdf-reporter` with Express.js. ## Features - 🚀 **RESTful API Design** - Clean, intuitive endpoints - 📊 **Advanced PDF Generation** - Multiple templates and customization options - **Async Processing** - Background job processing for large datasets - 📈 **Performance Monitoring** - Built-in metrics and estimation - 🔒 **Rate Limiting** - Protection against abuse - 🛡️ **Error Handling** - Comprehensive error handling and validation - 📁 **File Operations** - PDF merging, splitting, and page extraction - 🔍 **PDF Analysis** - Analyze PDF properties and metadata - 📊 **Health Checks** - Service monitoring and diagnostics ## Quick Start ### Installation ```bash cd examples/express-app npm install ``` ### Start the Server ```bash # Development mode with auto-reload npm run dev # Production mode npm start ``` The API will be available at `http://localhost:3000` ## API Endpoints ### Core Endpoints | Method | Endpoint | Description | |--------|----------|-------------| | `GET` | `/` | API information and documentation | | `GET` | `/api/health` | Detailed health check | | `GET` | `/api/metrics` | Service metrics and statistics | ### Data Endpoints | Method | Endpoint | Description | |--------|----------|-------------| | `GET` | `/api/samples/:type` | Get sample data (customers/sales) | ### PDF Generation | Method | Endpoint | Description | |--------|----------|-------------| | `POST` | `/api/generate` | Generate PDF synchronously | | `POST` | `/api/generate/async` | Generate PDF asynchronously | | `POST` | `/api/estimate` | Estimate generation performance | ### PDF Operations | Method | Endpoint | Description | |--------|----------|-------------| | `POST` | `/api/merge` | Merge multiple PDFs | | `POST` | `/api/split` | Split PDF into individual pages | | `POST` | `/api/extract` | Extract specific pages from PDF | | `POST` | `/api/analyze` | Analyze PDF properties | ### Job Management | Method | Endpoint | Description | |--------|----------|-------------| | `GET` | `/api/job/:id` | Get async job status | | `GET` | `/api/job/:id/download` | Download completed PDF | ## Usage Examples ### 1. Get Sample Data ```bash curl -X GET "http://localhost:3000/api/samples/customers?count=50" ``` ### 2. Generate PDF Synchronously ```bash curl -X POST http://localhost:3000/api/generate \\ -H "Content-Type: application/json" \\ -d '{ "title": "Customer Report", "data": [ { "id": 1, "name": "John Doe", "email": "john@example.com", "amount": 1250.00, "status": "Active", "region": "North America" } ], "columns": [ {"key": "id", "title": "ID", "dataIndex": "id", "flex": 1}, {"key": "name", "title": "Name", "dataIndex": "name", "flex": 3}, {"key": "email", "title": "Email", "dataIndex": "email", "flex": 3}, {"key": "amount", "title": "Amount", "dataIndex": "amount", "flex": 2, "type": "currency"}, {"key": "status", "title": "Status", "dataIndex": "status", "flex": 2}, {"key": "region", "title": "Region", "dataIndex": "region", "flex": 2} ], "options": { "template": "modern-business", "format": "A4", "orientation": "portrait" }, "userInfo": { "companyName": "Your Company", "name": "Your Name" } }' \\ --output report.pdf ``` ### 3. Generate PDF Asynchronously ```bash # Start async job curl -X POST http://localhost:3000/api/generate/async \\ -H "Content-Type: application/json" \\ -d '{ "title": "Large Dataset Report", "data": [...], // Large dataset "columns": [...] }' # Response: {"jobId": "abc123", "status": "accepted", "checkStatusUrl": "/api/job/abc123"} # Check job status curl -X GET http://localhost:3000/api/job/abc123 # Download when complete curl -X GET http://localhost:3000/api/job/abc123/download --output large-report.pdf ``` ### 4. Estimate Performance ```bash curl -X POST http://localhost:3000/api/estimate \\ -H "Content-Type: application/json" \\ -d '{ "data": [...], // Your dataset "columns": [...], // Your columns "options": {"template": "modern-business"} }' # Response includes estimated time and memory usage ``` ### 5. Merge PDFs ```bash curl -X POST http://localhost:3000/api/merge \\ -H "Content-Type: application/json" \\ -d '{ "pdfs": [ "base64-encoded-pdf-1", "base64-encoded-pdf-2" ] }' \\ --output merged.pdf ``` ### 6. Split PDF ```bash curl -X POST http://localhost:3000/api/split \\ -H "Content-Type: application/json" \\ -d '{ "pdf": "base64-encoded-pdf-data" }' # Returns array of base64-encoded pages ``` ### 7. Extract Pages ```bash curl -X POST http://localhost:3000/api/extract \\ -H "Content-Type: application/json" \\ -d '{ "pdf": "base64-encoded-pdf-data", "pages": [1, 3, 5] }' \\ --output extracted-pages.pdf ``` ## Templates The API includes a advanced `modern-business` template with: - 🎨 Modern gradient design - 📊 Automatic metrics calculation - 📈 Status badges with color coding - 💫 Animated background patterns - 📱 Responsive layout - 🏢 Company branding support ## Configuration ### Environment Variables ```env PORT=3000 NODE_ENV=production ``` ### Rate Limiting - 100 requests per 15 minutes per IP - Configurable in the server setup ### File Storage The API creates these directories: - `uploads/` - Temporary file uploads - `output/` - Generated PDF storage - `cache/` - Cached results ### Job Management - Jobs are automatically cleaned up after 24 hours - In production, consider using Redis for job storage ## Error Handling The API provides comprehensive error responses: ```json { "error": "Error description", "message": "Detailed error message", "code": "ERROR_CODE", "timestamp": "2024-01-01T00:00:00.000Z" } ``` Common error codes: - `VALIDATION_ERROR` - Invalid request data - `PDF_GENERATION_ERROR` - PDF generation failed - `JOB_NOT_FOUND` - Async job not found - `RATE_LIMIT_EXCEEDED` - Too many requests ## Monitoring ### Health Check ```bash curl -X GET http://localhost:3000/api/health ``` ### Metrics ```bash curl -X GET http://localhost:3000/api/metrics ``` Metrics include: - Request counts and success rates - Average processing times - Memory usage - Active/completed jobs - Template usage statistics ## Production Deployment ### Docker ```dockerfile FROM node:18-alpine WORKDIR /app COPY package*.json ./ RUN npm ci --only=production COPY . . EXPOSE 3000 CMD ["npm", "start"] ``` ### Environment Setup ```bash # Install dependencies npm ci --only=production # Set environment export NODE_ENV=production export PORT=3000 # Start server npm start ``` ### Scaling Considerations - Use Redis for job storage in clustered environments - Implement proper logging (Winston, etc.) - Add authentication/authorization - Set up monitoring (Prometheus, New Relic, etc.) - Use a reverse proxy (Nginx) for SSL and load balancing ## Integration Examples ### Frontend Integration (JavaScript) ```javascript class PDFGeneratorClient { constructor(baseUrl = 'http://localhost:3000') { this.baseUrl = baseUrl; } async generatePDF(data) { const response = await fetch(\`\${this.baseUrl}/api/generate\`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data) }); if (!response.ok) { throw new Error(\`PDF generation failed: \${response.statusText}\`); } return response.blob(); } async generateAsync(data) { const response = await fetch(\`\${this.baseUrl}/api/generate/async\`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data) }); const job = await response.json(); return this.pollJob(job.jobId); } async pollJob(jobId, interval = 2000) { while (true) { const response = await fetch(\`\${this.baseUrl}/api/job/\${jobId}\`); const job = await response.json(); if (job.status === 'completed') { const pdfResponse = await fetch(\`\${this.baseUrl}/api/job/\${jobId}/download\`); return pdfResponse.blob(); } else if (job.status === 'failed') { throw new Error(\`Job failed: \${job.error}\`); } await new Promise(resolve => setTimeout(resolve, interval)); } } } // Usage const client = new PDFGeneratorClient(); const pdfBlob = await client.generatePDF({ title: "My Report", data: [...], columns: [...] }); ``` ### Python Integration ```python import requests import time import json class PDFGeneratorClient: def __init__(self, base_url="http://localhost:3000"): self.base_url = base_url def generate_pdf(self, data): response = requests.post( f"{self.base_url}/api/generate", json=data, headers={"Content-Type": "application/json"} ) response.raise_for_status() return response.content def generate_async(self, data): response = requests.post( f"{self.base_url}/api/generate/async", json=data ) job = response.json() return self.poll_job(job["jobId"]) def poll_job(self, job_id, interval=2): while True: response = requests.get(f"{self.base_url}/api/job/{job_id}") job = response.json() if job["status"] == "completed": pdf_response = requests.get(f"{self.base_url}/api/job/{job_id}/download") return pdf_response.content elif job["status"] == "failed": raise Exception(f"Job failed: {job['error']}") time.sleep(interval) # Usage client = PDFGeneratorClient() pdf_data = client.generate_pdf({ "title": "My Report", "data": [...], "columns": [...] }) with open("report.pdf", "wb") as f: f.write(pdf_data) ``` ## Contributing 1. Fork the repository 2. Create your feature branch 3. Make your changes 4. Add tests if applicable 5. Submit a pull request ## License MIT License - see the [LICENSE](../../LICENSE) file for details. ## Support - 📚 [Documentation](https://github.com/Safeersoft/pdf-reporter) - 🐛 [Issue Tracker](https://github.com/Safeersoft/pdf-reporter/issues) - 📧 [Email Support](mailto:support@safeersoft.com)