An open API service indexing awesome lists of open source software.

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.

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

---
JSON to PDF Generator
---

## ๐Ÿ› ๏ธ 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 ๐Ÿš€