A web application that automatically maps data to PDF templates to generate completed PDFs.
- ๐ PDF Template Upload: Upload and manage A4 PDF templates
- ๐จ Visual Field Mapping: Drag and drop to specify data paths for template fields
- โก Real-time Preview: Instantly check field placement
- ๐พ Real-time Testing: Test rendering before saving
- ๐ Automatic PDF Generation: Automatically generate completed PDFs from JSON data
- ๐ REST API: Use via HTTP API from programs
- Property Editing: Real-time adjustment of position (X, Y), size (width, height), font, alignment
- Field Management: Add, delete, select fields
- Template Management: Individual/bulk delete support
- FastAPI (0.104.1) - High-performance Python web framework
- PyMuPDF (fitz) (1.23.8) - PDF information extraction and image rendering
- pypdf (3.17.1) - PDF merging
- Uvicorn - ASGI server
- React (18.2.0) - UI framework
- Vite (5.0.8) - Fast build tool
- Axios (1.6.2) - HTTP client
- Python 3.9 or higher
- Node.js 16 or higher
- npm or yarn
git clone https://github.com/CobyApp/report.git
cd report# Start backend + frontend simultaneously
./start.sh
# Stop
./stop.sh
# Restart
./restart.shTerminal 1 - Backend:
cd backend
# Create virtual environment (first time only)
python3 -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
# Install packages (first time only)
pip install -r requirements.txt
# Run server
python -m app.mainTerminal 2 - Frontend:
cd frontend
# Install packages (first time only)
npm install
# Run development server
npm run dev- Frontend: http://localhost:3000
- Backend API: http://localhost:8000
- API Documentation:
- Swagger UI (Interactive): http://localhost:8000/docs
- ReDoc (Alternative): http://localhost:8000/redoc
- Access
http://localhost:3000in web browser - Click "Upload PDF Template" button
- Select A4 PDF template file
- Click uploaded template card to enter edit mode
- Drag on PDF preview to select field area
- Enter data path in input popup (e.g.,
customer.name,items[0].price) - Add fields as needed
- Click field to select
- Modify in right property panel:
- Data Path: JSON path to map to field
- X, Y: Field position (PDF coordinates)
- Width, Height: Field size
- Font Size: Text size
- Alignment: Left/Center/Right
- Click "๐งช Test Rendering" button
- Enter values for each field (prompt)
- Completed PDF automatically downloads
- Changes are reflected before saving
- Click "๐พ Save" button
- Template mapping information is saved to server
| Method | Path | Description |
|---|---|---|
POST |
/api/templates |
Upload PDF template |
GET |
/api/templates |
List templates |
GET |
/api/templates/{id} |
Get template details |
PUT |
/api/templates/{id}/mapping |
Save template mapping |
POST |
/api/render/{id} |
Generate PDF (requires data) |
GET |
/api/templates/{id}/preview |
Page preview image |
DELETE |
/api/templates/{id} |
Delete template |
DELETE |
/api/templates |
Delete all templates |
curl -X POST http://localhost:8000/api/templates \
-F "file=@template.pdf"Response:
{
"template_id": "uuid-here",
"filename": "template.pdf",
"page_count": 1,
"page_size": {"w_pt": 595.28, "h_pt": 841.89}
}curl -X PUT http://localhost:8000/api/templates/{template_id}/mapping \
-H "Content-Type: application/json" \
-d '{
"elements": [
{
"id": "elem1",
"type": "text",
"page": 1,
"bbox": {"x": 100, "y": 100, "w": 200, "h": 20},
"data_path": "customer.name",
"style": {"font": "Helvetica", "size": 10, "align": "left"}
}
]
}'Generate a completed PDF by providing field data that matches your template's data paths.
Request:
curl -X POST http://localhost:8000/api/render/{template_id} \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"customer": {
"name": "John Doe",
"email": "john@example.com",
"address": "123 Main St"
},
"items": [
{"name": "Item 1", "price": 10000, "quantity": 2},
{"name": "Item 2", "price": 20000, "quantity": 1}
],
"checked": true,
"total": 40000,
"date": "2024-01-17"
}' \
--output result.pdfResponse:
- Content-Type:
application/pdf - Body: Binary PDF file
- Filename:
rendered_{template_id}.pdf
Request Body Structure:
{
// Field data that matches template data paths
// Example: if template has "customer.name", provide:
"customer": {
"name": "John Doe"
},
// Array fields: use "items[0].price" in template
"items": [
{"name": "Item 1", "price": 10000}
],
// Simple boolean fields
"checked": true,
// Optional: Override template elements for testing
"_elements": [
{
"id": "elem1",
"type": "text",
"page": 1,
"bbox": {"x": 100, "y": 100, "w": 200, "h": 20},
"data_path": "customer.name"
}
]
}Error Responses:
-
400 Bad Request: Invalid data or template structure{"detail": "Template structure error: ..."} -
401 Unauthorized: Authentication required{"detail": "Authentication required"} -
403 Forbidden: Template does not belong to user{"detail": "Access denied"} -
404 Not Found: Template not found{"detail": "Template not found"}
Real-time elements transmission (test rendering):
Include _elements in the request body to override template elements without saving:
curl -X POST http://localhost:8000/api/render/{template_id} \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"customer": {"name": "John Doe"},
"_elements": [
{
"id": "elem1",
"type": "text",
"page": 1,
"bbox": {"x": 100, "y": 100, "w": 200, "h": 20},
"data_path": "customer.name"
}
]
}' \
--output result.pdfAPI Documentation:
For interactive API documentation and detailed request/response schemas, visit:
- Swagger UI: http://localhost:8000/docs
- ReDoc: http://localhost:8000/redoc
report/
โโโ backend/ # FastAPI backend
โ โโโ app/
โ โ โโโ main.py # FastAPI app and API endpoints
โ โ โโโ services/
โ โ โโโ pdf_service.py # PDF processing (upload, preview)
โ โ โโโ template_service.py # Template save/load
โ โ โโโ render_service.py # PDF rendering engine
โ โ โโโ auth_service.py # Authentication service
โ โโโ templates/ # Template JSON storage (auto-generated)
โ โโโ uploads/ # Uploaded PDFs and generated PDFs (auto-generated)
โ โโโ users/ # User data (auto-generated)
โ โโโ requirements.txt # Python package dependencies
โ
โโโ frontend/ # React frontend
โ โโโ src/
โ โ โโโ App.jsx # Main app component
โ โ โโโ components/
โ โ โโโ TemplateList.jsx # Template list
โ โ โโโ TemplateEditor.jsx # Template editor
โ โโโ package.json # Node.js package dependencies
โ โโโ vite.config.js # Vite configuration
โ
โโโ start.sh # Start backend + frontend simultaneously
โโโ stop.sh # Stop servers
โโโ restart.sh # Restart servers
โโโ README.md # This file
Templates are saved in JSON format:
{
"template_id": "uuid",
"filename": "template.pdf",
"page_size": {
"w_pt": 595.28,
"h_pt": 841.89
},
"pages": [
{
"page": 1,
"width": 595.28,
"height": 841.89,
"width_pt": 595.28,
"height_pt": 841.89
}
],
"elements": [
{
"id": "elem_1234567890",
"type": "text",
"page": 1,
"bbox": {
"x": 100,
"y": 200,
"w": 200,
"h": 20
},
"data_path": "customer.name",
"style": {
"font": "Helvetica",
"size": 10,
"align": "left"
},
"overflow": {
"mode": "shrink_to_fit",
"min_size": 7
}
}
],
"created_at": "2026-01-17T..."
}bbox: Field position and size (PDF coordinate system, point units)x,y: Top-left corner coordinates (stored in screen coordinates, converted during rendering)w,h: Width, height
data_path: JSON data path (e.g.,customer.name,items[0].price)style: Text style settingsoverflow: Text overflow handling (currently supportsshrink_to_fit)
- โ Text Fields: Data path mapping, alignment, auto-shrink
- โ Checkboxes: Boolean value display
- โ Repeat Tables: List data repeat rendering
- โ Multi-page: Multiple page support
- โ Real-time Editing: Test before saving
- โ Property Editing: Real-time adjustment of position, size, style
- โ User Authentication: Login/registration for user-specific data management
- Image fields (signatures, stamps, QR codes)
- Conditional display (if statements)
- Automatic page overflow handling
- Improved CJK font support
- Rich text (partial bold, colors, etc.)
- Data schema validation UI
- Template version management
- User authentication and permission management
# Check ports
lsof -ti:8000 # Backend
lsof -ti:3000 # Frontend
# Kill processes
kill -9 $(lsof -ti:8000)
kill -9 $(lsof -ti:3000)Backend:
# Check virtual environment
python3 -m venv venv
source venv/bin/activate
pip install --upgrade pip
pip install -r requirements.txtFrontend:
# Clear cache and reinstall
rm -rf node_modules package-lock.json
npm installIssues and pull requests are welcome!
MIT License
Project Link: https://github.com/CobyApp/report