https://github.com/priom7/json2pdf
A lightweight, browserless REST API that generates print-ready PDF question papers from structured JSON data using PDFKit โ ideal for educational platforms that require professional formatting without the overhead of headless browsers like Puppeteer.
https://github.com/priom7/json2pdf
devtool json nodejs npm-package opensource pdf tool
Last synced: 8 months ago
JSON representation
A lightweight, browserless REST API that generates print-ready PDF question papers from structured JSON data using PDFKit โ ideal for educational platforms that require professional formatting without the overhead of headless browsers like Puppeteer.
- Host: GitHub
- URL: https://github.com/priom7/json2pdf
- Owner: Priom7
- License: mit
- Created: 2025-04-15T09:54:44.000Z (9 months ago)
- Default Branch: main
- Last Pushed: 2025-05-08T15:36:55.000Z (8 months ago)
- Last Synced: 2025-05-12T08:07:11.346Z (8 months ago)
- Topics: devtool, json, nodejs, npm-package, opensource, pdf, tool
- Language: JavaScript
- Homepage: https://www.npmjs.com/package/@priom7/json2pdf
- Size: 5.55 MB
- Stars: 3
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# ๐ Custom PDF Generator for Question Papers
A lightweight, browserless REST API that generates print-ready PDF question papers from structured JSON data using **PDFKit** โ ideal for educational platforms that require professional formatting without the overhead of headless browsers like Puppeteer.
---
## ๐ Features
- ๐ Generates PDF directly from JSON using [PDFKit](https://github.com/foliojs/pdfkit)
- ๐งพ Structured two-column question format
- โ
Supports multiple question types: **MCQ, numerical, descriptive**
- ๐ Separate sections for **questions**, **answer key**, and **solutions**
- โ๏ธ Clean and print-friendly layout
- โก Fast and efficient (no browser required)
- ๐ผ๏ธ Supports images, formulas (SVG), and custom logos/fonts
---
---
## ๐ ๏ธ Setup Instructions
### ๐ Prerequisites
- Node.js (v14 or higher)
- npm or yarn
### ๐ฆ Installation
```bash
git clone https://github.com/Priom7/JSON-to-PDF-Generator.git
cd JSON-to-PDF-Generator
# Install dependencies
npm install
# Start the server
npm start
```
API will be available at:
**`http://localhost:3000/api/generate-pdf`**
---
## ๐ก API Documentation
### ๐ Endpoint
```
POST /api/generate-pdf
```
**Content-Type**: `application/json`
**Response**: `application/pdf`
### ๐ฅ Request Body Example
```json
{
"title": "Physics Examination Paper",
"subject": "Physics",
"date": "April 15, 2025",
"duration": "3 hours",
"totalMarks": 100,
"instructions": [
"All questions are compulsory",
"There is no negative marking"
],
"questions": [
{
"type": "mcq",
"text": "A particle moves along the x-axis...",
"options": ["300 J", "900 J", "1000 J", "3000 J"],
"correctOption": 3,
"solution": "Work done = โซF(x)dx from x=0 to x=10..."
}
]
}
```
### โ
Success Response
- `Status: 200 OK`
- `Content-Type: application/pdf`
- Body: Binary PDF file
### โ Error Responses
- `400 Bad Request` โ Invalid JSON
- `500 Internal Server Error` โ PDF generation failed
---
## ๐ JSON Schema
| Field | Type | Description |
| ------------- | ------------------ | ------------------------------------------ |
| `title` | `String` | Title of the examination paper |
| `subject` | `String` | Subject name |
| `date` | `String` | Exam date |
| `duration` | `String` | Exam duration (e.g., `"3 hours"`) |
| `totalMarks` | `Number` | Total marks |
| `instructions`| `Array` | Exam instructions |
| `questions` | `Array` | List of questions |
### ๐ฏ Question Object
| Field | Type | Description |
| -------------- | ------------------ | --------------------------------------------------------- |
| `type` | `String` | `"mcq"`, `"numerical"`, or `"descriptive"` |
| `text` | `String` | Question text |
| `options` | `Array` | (For MCQ) Answer options |
| `correctOption`| `Number` | (For MCQ) Index of correct option |
| `answer` | `String` | Correct answer (numerical/descriptive) |
| `solution` | `String` | Detailed solution explanation |
| `images` | `Array` | (Optional) Images with `path`, `width`, `height`, `position` |
---
## ๐จ Customization
### ๐งฑ Layout Configuration (`pdfGenerator.js`)
```js
const CONFIG = {
pageSize: 'A4',
margin: { top: 50, bottom: 50, left: 40, right: 40 },
columns: 2,
columnGap: 20,
fonts: {
regular: 'Helvetica',
bold: 'Helvetica-Bold',
italic: 'Helvetica-Oblique'
},
fontSize: {
title: 16,
header: 12,
subHeader: 10,
normal: 10,
small: 8
}
};
```
### ๐ก Custom Fonts
1. Add your `.ttf` font files to a `fonts/` directory.
2. Register them in `pdfGenerator.js`:
```js
doc.registerFont('CustomFont', 'fonts/CustomFont.ttf');
```
Update config:
```js
fonts: {
regular: 'CustomFont',
bold: 'CustomFont-Bold',
italic: 'CustomFont-Italic'
}
```
### ๐ผ๏ธ Logo Support
Include in JSON:
```json
"logoPath": "path/to/logo.png"
```
---
## ๐ข Math & Image Support
- **Simple Math**: Unicode math characters
- **Complex Math**: Include `` in question text or integrate [mathjax-node](https://github.com/mathjax/MathJax-node)
- **Images**:
```json
"images": [
{
"path": "path/to/image.png",
"width": 300,
"height": 200,
"position": "center"
}
]
```
---
## ๐ Page Numbering
Add to `pdfGenerator.js`:
```js
doc.on('pageAdded', () => {
const pageCount = doc.bufferedPageRange().count;
doc.switchToPage(pageCount - 1);
doc.fontSize(8)
.text(`Page ${pageCount}`, doc.page.width / 2, doc.page.height - 20, { align: 'center' });
});
```
---
## ๐ณ Docker Deployment
### ๐งพ Dockerfile
```dockerfile
FROM node:16-alpine
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]
```
### ๐ฆ Build & Run
```bash
docker build -t pdf-generator .
docker run -p 3000:3000 pdf-generator
```
---
## โ๏ธ Cloud Deployment
### AWS Elastic Beanstalk
```bash
eb init
eb create pdf-generator-env
eb deploy
```
### Heroku
```bash
heroku create
git push heroku main
```
---
## ๐งช Test Script
Create `sample-data.json`, then run:
```bash
node test.js
```
**`test.js`** example:
```js
const fs = require('fs');
const path = require('path');
const { generatePDF } = require('./pdfGenerator');
async function testPDFGeneration() {
const dataPath = path.join(__dirname, 'sample-data.json');
if (!fs.existsSync(dataPath)) return console.error('sample-data.json not found');
const data = JSON.parse(fs.readFileSync(dataPath, 'utf8'));
const pdf = await generatePDF(data);
fs.writeFileSync('output-test.pdf', pdf);
console.log('PDF generated โ output-test.pdf');
}
testPDFGeneration().catch(console.error);
```
---
## ๐ก๏ธ Security & Optimization
- โ
Input validation & sanitization
- ๐ Add authentication for production
- โณ Use queues for batch requests
- ๐ง Add caching for templates
- ๐ซ Rate limiting to prevent abuse
---
## ๐ Troubleshooting
| Issue | Solution |
| ------------------------------ | ------------------------------------------------------------- |
| Large JSON payload | `bodyParser.json({ limit: '50mb' })` |
| Fonts not rendering | Ensure correct path and supported format (TTF/OTF) |
| Images not displaying | Check file path and permissions |
| Memory issues with large PDFs | Use streaming instead of buffering |
Enable debug logs:
```bash
DEBUG=true node server.js
```
---
## ๐ค Contributing
1. Fork the repo
2. Create a feature branch: `git checkout -b feature/your-feature`
3. Commit: `git commit -m "Add your feature"`
4. Push: `git push origin feature/your-feature`
5. Open a Pull Request ๐