π A powerful Go web service that generates template-based PDF documents on-the-fly with multi-page support, custom page sizes, and automatic page breaks.
GoPdfSuit is a flexible web service built with Go and the Gin framework. It features a custom template-based PDF generator that creates professional documents from JSON templates, supporting multiple page sizes, automatic page breaks, tables, borders, checkboxes, font styling (bold, italic, underline), and custom layouts without external dependencies.
- Go
1.20+(project currently targets Go 1.23) - Dependencies: Automatically managed via Go modules
git clone https://github.com/chinmay-sawant/gopdfsuit.git
cd gopdfsuitgo mod download# From repository root
go run ./cmd/gopdfsuitπ Server listening on: http://localhost:8080
New Feature: Interactive web-based PDF viewer and template editor.
Endpoint: GET / (Root endpoint)
Query Parameters:
file(optional): JSON template filename to load automatically
Examples:
http://localhost:8080/
http://localhost:8080/?file=temp_multiplepage.json
New Feature: Visual drag-and-drop PDF template editor.
Endpoint: GET /editor
Query Parameters:
file(optional): JSON template filename to load automatically
Examples:
http://localhost:8080/editor
http://localhost:8080/editor?file=temp_multiplepage.json
Features:
- π¨ Drag-and-Drop Interface: Visual template building with drag-and-drop components
- π Real-time JSON Generation: Live JSON template generation as you build
- π§ Component Properties: Editable properties panel for each component
- π Live PDF Preview: Generate and preview PDFs instantly
- πΎ Template Loading: Load existing templates for editing
- π± Responsive Design: Works on desktop, tablet, and mobile devices
- π¨ Theme Support: Multiple gradient themes and dark/light mode
Endpoint: GET /api/v1/template-data
Query Parameters:
file(required): JSON template filename
Security Features:
- β Path Traversal Protection: Only filenames (no directories) allowed
- β
File Extension Validation: Only
.jsonfiles accepted - β JSON Validation: Template structure validation before serving
Example:
curl "http://localhost:8080/api/v1/template-data?file=temp_multiplepage.json"Endpoint: POST /api/v1/generate/template-pdf
Headers:
Content-Type: application/json
Request Body Structure:
{
"config": {
"pageBorder": "1:1:1:1",
"page": "A4",
"pageAlignment": 1
},
"title": {
"props": "font1:24:100:center:0:0:1:0",
"text": "Multi-Page Document Title"
},
"table": [
{
"maxcolumns": 4,
"rows": [
{
"row": [
{
"props": "font1:12:100:left:1:1:1:1",
"text": "Bold Field Name:"
},
{
"props": "font1:12:000:left:1:1:1:1",
"text": "Normal Field Value"
},
{
"props": "font1:12:010:left:1:1:1:1",
"text": "Italic Text"
},
{
"props": "font1:12:111:right:1:1:1:1",
"text": "Bold+Italic+Underline"
}
]
}
]
}
],
"footer": {
"font": "font1:10:001:center",
"text": "Multi-page Footer"
}
}Template Configuration Properties:
- config.pageBorder:
"left:right:top:bottom"- Border widths for page edges - config.page: Page size specification
"A4"- 8.27 Γ 11.69 inches (595 Γ 842 points) - Default"LETTER"- 8.5 Γ 11 inches (612 Γ 792 points)"LEGAL"- 8.5 Γ 14 inches (612 Γ 1008 points)"A3"- 11.69 Γ 16.54 inches (842 Γ 1191 points)"A5"- 5.83 Γ 8.27 inches (420 Γ 595 points)
- config.pageAlignment: Page orientation
1- Portrait (vertical) - Default2- Landscape (horizontal)
- config.watermark: (optional) Text rendered diagonally (bottom-left to top-right) in light gray across every page. Automatically sized proportionally to page size.
Template Properties Explained:
- props:
"fontname:fontsize:style:alignment:left:right:top:bottom"fontname: Font identifier (font1, font2, etc.)fontsize: Font size in pointsstyle: 3-digit style code for text formatting:- First digit (Bold):
1= bold,0= normal weight - Second digit (Italic):
1= italic,0= normal style - Third digit (Underline):
1= underlined,0= no underline - Examples:
000= Normal text100= Bold text010= Italic text001= Underlined text110= Bold + Italic101= Bold + Underlined011= Italic + Underlined111= Bold + Italic + Underlined
- First digit (Bold):
alignment: left, center, or rightleft:right:top:bottom: Border widths for cell edges
- chequebox: Boolean value for checkbox state (true = checked, false = unchecked)
Automatic Page Break Features:
- β Height Tracking: Monitors content height and automatically creates new pages
- β Page Size Aware: Respects selected page dimensions for break calculations
- β Border Preservation: Page borders are drawn on every new page
- β Content Continuity: Tables and content flow seamlessly across pages
- β Page Numbering: Automatic "Page X of Y" numbering in bottom right corner
Response:
- Content-Type:
application/pdf - File:
template-pdf-<timestamp>.pdf(auto-download)
-
Direct Access:
http://localhost:8080/ -
Load Template via URL:
http://localhost:8080/?file=temp_multiplepage.json -
Interactive Workflow:
- Enter filename in the input field
- Click "Load Template" to fetch JSON data
- Review the syntax-highlighted JSON structure
- Click "Generate PDF" to create and preview the PDF
- Use navigation controls to browse multi-page documents
- Download the generated PDF with one click
- Navigate to:
http://localhost:8080/?file=temp_multiplepage.json - The interface will automatically load and display the template
- Click "Generate PDF" to create a multi-page healthcare form
- Use the page navigation controls to browse through pages
- Download the PDF using the download button
curl -X POST "http://localhost:8080/api/v1/generate/template-pdf" \
-H "Content-Type: application/json" \
-d '{
"config": {
"pageBorder": "2:2:2:2",
"page": "LETTER",
"pageAlignment": 1
},
"title": {
"props": "font1:20:110:center:0:0:2:0",
"text": "Patient Encounter Form - Multi Page"
},
"table": [
{
"maxcolumns": 4,
"rows": [
{
"row": [
{
"props": "font1:12:100:left:1:0:1:1",
"text": "Patient Name:"
},
{
"props": "font1:12:000:left:0:1:1:1",
"text": "John Doe"
},
{
"props": "font1:12:100:left:1:0:1:1",
"text": "DOB:"
},
{
"props": "font1:12:010:left:0:1:1:1",
"text": "01/15/1980"
}
]
}
]
}
],
"footer": {
"font": "font1:10:001:center",
"text": "Confidential Medical Document - Auto Pagination"
}
}' \
--output patient-form-multipage.pdfimport requests
import json
url = "http://localhost:8080/api/v1/generate/template-pdf"
template = {
"config": {
"pageBorder": "1:1:1:1",
"page": "A4",
"pageAlignment": 2 # Landscape orientation
},
"title": {
"props": "font1:22:111:center:0:0:2:0",
"text": "Landscape Survey Form"
},
"table": [
{
"maxcolumns": 6, # More columns fit in landscape
"rows": [
{
"row": [
{
"props": "font1:14:100:left:1:1:1:1",
"text": "Question 1:"
},
{
"props": "font1:12:000:center:1:1:1:1",
"chequebox": True
},
{
"props": "font1:12:010:left:1:1:1:1",
"text": "Excellent"
},
{
"props": "font1:12:000:center:1:1:1:1",
"chequebox": False
},
{
"props": "font1:12:010:left:1:1:1:1",
"text": "Good"
},
{
"props": "font1:12:000:left:1:1:1:1",
"text": "Average"
}
]
}
]
}
],
"footer": {
"font": "font1:10:001:right",
"text": "Landscape Page Layout"
}
}
response = requests.post(url, json=template)
with open("survey-landscape.pdf", "wb") as f:
f.write(response.content){
"config": {
"pageBorder": "1:1:1:1",
"page": "LEGAL",
"pageAlignment": 1
},
"title": {
"props": "font1:18:100:center:0:0:1:0",
"text": "Large Multi-Page Document"
},
"table": [
{
"maxcolumns": 2,
"rows": [
// Add many rows here - system will automatically create new pages
{
"row": [
{
"props": "font1:12:100:left:1:1:1:1",
"text": "Section 1: Introduction"
},
{
"props": "font1:12:000:left:1:1:1:1",
"text": "This document demonstrates automatic page breaks..."
}
]
}
// ... more rows will automatically flow to new pages
]
}
],
"footer": {
"font": "font1:10:000:center",
"text": "Document continues across multiple pages automatically"
}
}- π― Template-based: JSON-driven PDF generation
- π₯οΈ Web Interface: Interactive HTML viewer with real-time preview
- π Tables & Forms: Support for complex table layouts with automatic page breaks
- βοΈ Checkboxes: Interactive checkbox elements
- π¨ Font Styling: Bold, italic, and underline text support
- π Multi-page Support: Automatic page breaks and multi-page documents
- π’ Page Numbering: Automatic page numbering in "Page X of Y" format
- π Custom Page Sizes: A4, Letter, Legal, A3, A5 support
- π Page Orientation: Portrait and landscape orientations
- π€ Flexible Typography: Custom fonts, sizes, and alignments
- π² Border Control: Granular border configuration
- π‘οΈ Diagonal Watermark: Optional per-template watermark text across all pages
- β‘ Fast: In-memory PDF generation with height tracking
- π¦ Self-contained: Single binary deployment
- π Cross-platform: Runs on Windows, Linux, macOS
- π± Responsive: Mobile-friendly web interface
- π Secure: Path traversal protection and input validation
GoPdfSuit/
βββ π cmd/
β βββ π gopdfsuit/ # π― Application entrypoint
β βββ main.go
βββ π internal/
β βββ π handlers/ # π HTTP handlers and route registration
β β βββ handlers.go
β βββ π models/ # π Template data models
β β βββ models.go
β βββ π pdf/ # π Template-based PDF generation
β βββ pdf.go
βββ π web/ # π Web interface assets
β βββ π static/
β β βββ π css/
β β β βββ viewer.css # π¨ PDF viewer styles
β β βββ π js/
β β βββ viewer.js # β‘ PDF viewer functionality
β βββ π templates/
β βββ pdf_viewer.html # π PDF viewer HTML template
βββ π go.mod # π¦ Go modules file
βββ π temp_multiplepage.json # π Example multi-page template file
βββ π .gitignore # π« Git ignore rules
βββ π README.md # π This file
This project includes a simple AcroForm/XFDF fill feature that accepts PDF bytes and XFDF (field data) and returns a filled PDF.
Endpoints and UI
POST /api/v1/fillβ accepts multipart/form-data with two file fields:pdf(the source PDF) andxfdf(the XFDF file). Returnsapplication/pdfwith the filled document as an attachment.GET /fillerβ simple web UI where users can upload a PDF and an XFDF file and download the filled PDF (uses the/api/v1/fillendpoint).
Quick curl example (multipart file upload):
curl -X POST "http://localhost:8080/api/v1/fill" \
-F "pdf=@patient.pdf;type=application/pdf" \
-F "xfdf=@patient.xfdf;type=application/xml" \
--output filled.pdfServer-run example (UI):
- Start server from repo root:
go run ./cmd/gopdfsuit- Open
http://localhost:8080/fillerin your browser and upload PDF + XFDF.
Behaviour and limitations
- The filler uses a best-effort, byte-oriented approach implemented in the
internal/pdfpackage: it parses XFDF, searches for AcroForm field names (heuristic/T (name)), and writes or inserts/V (value)tokens into the PDF bytes. - For many simple AcroForm PDFs this works and the code sets
/NeedAppearances truein the AcroForm so viewers regenerate appearances. - Limitations: PDFs using compressed object streams, indirect references for field values, non-literal strings, or requiring generated appearance streams (
/AP) may not render values correctly in all viewers. For robust, production-grade appearance updates, integrate a PDF library (e.g., pdfcpu or unidoc) to rebuild field appearance streams.
If you'd like, I can add a library-backed implementation that guarantees visual appearances across viewers.
- π₯οΈ Web-based PDF viewer and template editor
- π Multi-page document support with automatic page breaks
- π Security features (path traversal protection, input validation)
- π§ͺ Add comprehensive unit tests
- π¨ Support for colors and advanced styling
- π Image embedding support
- π³ Docker containerization
- π Metrics and health check endpoints
- π Authentication and rate limiting
- πΎ Template storage and management
- π§ Email delivery integration
- π Template editor with validation
- π Real-time collaborative editing
# Build for current platform
go build -o bin/gopdfsuit ./cmd/gopdfsuit
# Build for different platforms
GOOS=linux GOARCH=amd64 go build -o bin/gopdfsuit-linux ./cmd/gopdfsuit
GOOS=windows GOARCH=amd64 go build -o bin/gopdfsuit.exe ./cmd/gopdfsuit# Run all tests
go test ./...
# Run tests with coverage
go test -cover ./...Page Break Logic:
- The system tracks current Y position on each page
- When content would exceed page boundaries (considering margins), a new page is automatically created
- Each new page includes configured page borders
- Content flows seamlessly from one page to the next
Supported Page Sizes:
| Page Size | Dimensions (inches) | Dimensions (points) | Best For |
|---|---|---|---|
| A4 | 8.27 Γ 11.69 | 595 Γ 842 | International standard |
| Letter | 8.5 Γ 11 | 612 Γ 792 | US standard |
| Legal | 8.5 Γ 14 | 612 Γ 1008 | Legal documents |
| A3 | 11.69 Γ 16.54 | 842 Γ 1191 | Large format |
| A5 | 5.83 Γ 8.27 | 420 Γ 595 | Small format |
β οΈ Important: The current PDF generator creates basic layouts suitable for forms and simple documents.
For production environments, consider:
- Implementing comprehensive input validation
- Adding request size limits
- Setting up proper logging and monitoring
- Implementing caching for frequently used templates
- Adding support for custom fonts and advanced layouts
- π΄ Fork the repository
- π Create a feature branch (
git checkout -b feature/amazing-feature) - π« Commit your changes (
git commit -m 'Add amazing feature') - π€ Push to the branch (
git push origin feature/amazing-feature) - π Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
Made with β€οΈ and β by Chinmay Sawant
β Star this repo if you find it helpful!