gpdf

package module
v1.0.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 23, 2026 License: MIT Imports: 8 Imported by: 0

README

gpdf

Go Reference CI coverage Go Report Card Go Version Website

English | 日本語 | 中文 | 한국어 | Español | Português

A pure Go, zero-dependency PDF generation library with a layered architecture and declarative builder API.

Features

  • Zero dependencies — only the Go standard library
  • Layered architecture — low-level PDF primitives, document model, and high-level template API
  • 12-column grid system — Bootstrap-style responsive layout
  • TrueType font support — embed custom fonts with subsetting
  • CJK ready — full CJK text support from day one
  • Tables — headers, column widths, striped rows, vertical alignment
  • Headers & Footers — consistent across all pages with page numbers
  • Lists — bulleted and numbered lists
  • QR codes — pure Go QR code generation with error correction levels
  • Barcodes — Code 128 barcode generation
  • Text decorations — underline, strikethrough, letter spacing, text indent
  • Page numbers — automatic page number and total page count
  • Go template integration — generate PDFs from Go templates
  • Reusable components — pre-built Invoice, Report, and Letter templates
  • JSON schema — define documents entirely in JSON
  • Multiple units — pt, mm, cm, in, em, %
  • Color spaces — RGB, Grayscale, CMYK
  • Images — JPEG and PNG embedding with fit options
  • Absolute positioning — place elements at exact XY coordinates on the page
  • Existing PDF overlay — open existing PDFs and add text, images, stamps on top
  • PDF merging — combine multiple PDFs into one with page range selection
  • Document metadata — title, author, subject, creator
  • Encryption — AES-256 encryption (ISO 32000-2, Rev 6) with owner/user passwords and permissions
  • PDF/A — PDF/A-1b and PDF/A-2b conformance with ICC profiles and XMP metadata
  • Digital signatures — CMS/PKCS#7 signatures with RSA/ECDSA keys and optional RFC 3161 timestamping

Benchmark

Comparison with go-pdf/fpdf, signintech/gopdf, and maroto v2. Median of 5 runs, 100 iterations each. Apple M1, Go 1.25.

Execution time (lower is better):

Benchmark gpdf fpdf gopdf maroto v2
Single page 13 µs 132 µs 423 µs 237 µs
Table (4x10) 108 µs 241 µs 835 µs 8.6 ms
100 pages 683 µs 11.7 ms 8.6 ms 19.8 ms
Complex document 133 µs 254 µs 997 µs 10.4 ms

Memory usage (lower is better):

Benchmark gpdf fpdf gopdf maroto v2
Single page 16 KB 1.2 MB 1.8 MB 61 KB
Table (4x10) 209 KB 1.3 MB 1.9 MB 1.6 MB
100 pages 909 KB 121 MB 83 MB 4.0 MB
Complex document 246 KB 1.3 MB 2.0 MB 2.0 MB
Why is gpdf fast?
  • Single page — Single-pass build→layout→render pipeline with no intermediate data structures. Concrete struct types throughout (no interface{} boxing), so the document tree is built with minimal heap allocations.
  • Table — Cell content is written directly as PDF content stream commands via a reusable strings.Builder buffer. No per-cell object wrapping or repeated font lookups; the font is resolved once per document.
  • 100 pages — Layout scales linearly O(n). Overflow pagination passes remaining nodes by slice reference (no deep copies). The font is parsed once and shared across all pages.
  • Complex document — Single-pass layout without re-measurement combines all the above. Font subsetting embeds only the glyphs actually used, and Flate compression is applied by default, keeping both memory and output size small.

Run benchmarks yourself:

cd _benchmark && go test -bench=. -benchmem -count=5

Architecture

┌─────────────────────────────────────┐
│  gpdf (entry point)                 │
├─────────────────────────────────────┤
│  template  — Builder API, Grid      │  Layer 3
├─────────────────────────────────────┤
│  document  — Nodes, Style, Layout   │  Layer 2
├─────────────────────────────────────┤
│  pdf       — Writer, Fonts, Streams │  Layer 1
└─────────────────────────────────────┘

Requirements

  • Go 1.22 or later

Install

go get github.com/gpdf-dev/gpdf

Quick Start

package main

import (
	"os"

	"github.com/gpdf-dev/gpdf"
	"github.com/gpdf-dev/gpdf/document"
	"github.com/gpdf-dev/gpdf/template"
)

func main() {
	doc := gpdf.NewDocument(
		gpdf.WithPageSize(gpdf.A4),
		gpdf.WithMargins(document.UniformEdges(document.Mm(20))),
	)

	page := doc.AddPage()
	page.AutoRow(func(r *template.RowBuilder) {
		r.Col(12, func(c *template.ColBuilder) {
			c.Text("Hello, World!", template.FontSize(24), template.Bold())
		})
	})

	data, _ := doc.Generate()
	os.WriteFile("hello.pdf", data, 0644)
}

Examples

Text Styling

Font size, weight, style, color, background color, and alignment:

page.AutoRow(func(r *template.RowBuilder) {
	r.Col(12, func(c *template.ColBuilder) {
		c.Text("Large bold title", template.FontSize(24), template.Bold())
		c.Text("Italic text", template.Italic())
		c.Text("Bold + Italic", template.Bold(), template.Italic())
		c.Text("Red text", template.TextColor(pdf.Red))
		c.Text("Custom color", template.TextColor(pdf.RGBHex(0x336699)))
		c.Text("With background", template.BgColor(pdf.Yellow))
		c.Text("Centered", template.AlignCenter())
		c.Text("Right aligned", template.AlignRight())
	})
})
CJK Fonts (Japanese / Chinese / Korean)

Embed TrueType fonts for CJK text rendering. Each language needs its own Noto Sans font:

fontData, _ := os.ReadFile("NotoSansJP-Regular.ttf")

doc := gpdf.NewDocument(
	gpdf.WithPageSize(gpdf.A4),
	gpdf.WithFont("NotoSansJP", fontData),
	gpdf.WithDefaultFont("NotoSansJP", 12),
)

page := doc.AddPage()
page.AutoRow(func(r *template.RowBuilder) {
	r.Col(12, func(c *template.ColBuilder) {
		c.Text("こんにちは世界", template.FontSize(18))
	})
})

For multi-language documents, register multiple fonts and switch with FontFamily():

jpFont, _ := os.ReadFile("NotoSansJP-Regular.ttf")
scFont, _ := os.ReadFile("NotoSansSC-Regular.ttf")
krFont, _ := os.ReadFile("NotoSansKR-Regular.ttf")

doc := gpdf.NewDocument(
	gpdf.WithFont("NotoSansJP", jpFont),
	gpdf.WithFont("NotoSansSC", scFont),
	gpdf.WithFont("NotoSansKR", krFont),
	gpdf.WithDefaultFont("NotoSansJP", 12),
)

page := doc.AddPage()
page.AutoRow(func(r *template.RowBuilder) {
	r.Col(4, func(c *template.ColBuilder) {
		c.Text("日本語", template.FontFamily("NotoSansJP"))
	})
	r.Col(4, func(c *template.ColBuilder) {
		c.Text("中文", template.FontFamily("NotoSansSC"))
	})
	r.Col(4, func(c *template.ColBuilder) {
		c.Text("한국어", template.FontFamily("NotoSansKR"))
	})
})

Recommended fonts (all free, OFL license):

Font Language
Noto Sans JP Japanese
Noto Sans SC Simplified Chinese
Noto Sans KR Korean
12-Column Grid Layout

Build layouts using a Bootstrap-style 12-column grid:

// Two equal columns
page.AutoRow(func(r *template.RowBuilder) {
	r.Col(6, func(c *template.ColBuilder) {
		c.Text("Left half")
	})
	r.Col(6, func(c *template.ColBuilder) {
		c.Text("Right half")
	})
})

// Sidebar + main content
page.AutoRow(func(r *template.RowBuilder) {
	r.Col(3, func(c *template.ColBuilder) {
		c.Text("Sidebar")
	})
	r.Col(9, func(c *template.ColBuilder) {
		c.Text("Main content")
	})
})

// Four equal columns
page.AutoRow(func(r *template.RowBuilder) {
	r.Col(3, func(c *template.ColBuilder) { c.Text("Col 1") })
	r.Col(3, func(c *template.ColBuilder) { c.Text("Col 2") })
	r.Col(3, func(c *template.ColBuilder) { c.Text("Col 3") })
	r.Col(3, func(c *template.ColBuilder) { c.Text("Col 4") })
})
Fixed-Height Rows

Use Row() with a specific height, or AutoRow() for content-based height:

// Fixed height: 30mm
page.Row(document.Mm(30), func(r *template.RowBuilder) {
	r.Col(12, func(c *template.ColBuilder) {
		c.Text("This row is 30mm tall")
	})
})

// Auto height (fits content)
page.AutoRow(func(r *template.RowBuilder) {
	r.Col(12, func(c *template.ColBuilder) {
		c.Text("Height adjusts to content")
	})
})
Tables

Basic table:

c.Table(
	[]string{"Name", "Age", "City"},
	[][]string{
		{"Alice", "30", "Tokyo"},
		{"Bob", "25", "New York"},
		{"Charlie", "35", "London"},
	},
)

Styled table with header colors, column widths, and stripe rows:

c.Table(
	[]string{"Product", "Category", "Qty", "Unit Price", "Total"},
	[][]string{
		{"Laptop Pro 15", "Electronics", "2", "$1,299.00", "$2,598.00"},
		{"Wireless Mouse", "Accessories", "10", "$29.99", "$299.90"},
		{"USB-C Hub", "Accessories", "5", "$49.99", "$249.95"},
	},
	template.ColumnWidths(30, 20, 10, 20, 20),
	template.TableHeaderStyle(
		template.TextColor(pdf.White),
		template.BgColor(pdf.RGBHex(0x1A237E)),
	),
	template.TableStripe(pdf.RGBHex(0xF5F5F5)),
)
Images

Embed JPEG and PNG images with optional fit options:

// Default size (original dimensions)
c.Image(imgData)

// Fit to specific width (maintains aspect ratio)
c.Image(imgData, template.FitWidth(document.Mm(80)))

// Fit to specific height (maintains aspect ratio)
c.Image(imgData, template.FitHeight(document.Mm(30)))

Images in grid columns:

page.AutoRow(func(r *template.RowBuilder) {
	r.Col(6, func(c *template.ColBuilder) {
		c.Text("Image 1")
		c.Image(pngData)
	})
	r.Col(6, func(c *template.ColBuilder) {
		c.Text("Image 2")
		c.Image(jpegData)
	})
})
Lines & Spacers

Horizontal rules with color and thickness:

c.Line()                                           // Default (gray, 1pt)
c.Line(template.LineColor(pdf.Red))                 // Colored
c.Line(template.LineThickness(document.Pt(3)))      // Thick
c.Line(template.LineColor(pdf.Blue),                // Combined
	template.LineThickness(document.Pt(2)))

Vertical spacing:

c.Spacer(document.Mm(5))   // 5mm gap
c.Spacer(document.Mm(15))  // 15mm gap
Lists

Bulleted and numbered lists:

// Bulleted list
c.List([]string{"First item", "Second item", "Third item"})

// Numbered list
c.OrderedList([]string{"Step one", "Step two", "Step three"})
QR Codes

Generate QR codes with configurable size and error correction:

// Basic QR code
c.QRCode("https://gpdf.dev")

// Custom size and error correction level
c.QRCode("https://gpdf.dev",
	template.QRSize(document.Mm(30)),
	template.QRErrorCorrection(qrcode.LevelH))
Barcodes

Generate Code 128 barcodes:

// Basic barcode
c.Barcode("INV-2026-0001")

// Custom width
c.Barcode("INV-2026-0001", template.BarcodeWidth(document.Mm(80)))
Page Numbers

Automatic page numbers and total page count:

doc.Footer(func(p *template.PageBuilder) {
	p.AutoRow(func(r *template.RowBuilder) {
		r.Col(6, func(c *template.ColBuilder) {
			c.Text("Generated by gpdf", template.FontSize(8))
		})
		r.Col(6, func(c *template.ColBuilder) {
			c.PageNumber(template.AlignRight(), template.FontSize(8))
		})
	})
})

doc.Header(func(p *template.PageBuilder) {
	p.AutoRow(func(r *template.RowBuilder) {
		r.Col(12, func(c *template.ColBuilder) {
			c.TotalPages(template.AlignRight(), template.FontSize(9))
		})
	})
})
Text Decorations

Underline, strikethrough, letter spacing, and text indent:

c.Text("Underlined text", template.Underline())
c.Text("Strikethrough text", template.Strikethrough())
c.Text("Wide spacing", template.LetterSpacing(3))
c.Text("Indented paragraph...", template.TextIndent(document.Pt(24)))
Headers & Footers

Define headers and footers that repeat on every page:

doc.Header(func(p *template.PageBuilder) {
	p.AutoRow(func(r *template.RowBuilder) {
		r.Col(6, func(c *template.ColBuilder) {
			c.Text("ACME Corporation", template.Bold(), template.FontSize(10))
		})
		r.Col(6, func(c *template.ColBuilder) {
			c.Text("Confidential", template.AlignRight(), template.FontSize(10),
				template.TextColor(pdf.Gray(0.5)))
		})
	})
	p.AutoRow(func(r *template.RowBuilder) {
		r.Col(12, func(c *template.ColBuilder) {
			c.Line(template.LineColor(pdf.RGBHex(0x1565C0)))
			c.Spacer(document.Mm(5))
		})
	})
})

doc.Footer(func(p *template.PageBuilder) {
	p.AutoRow(func(r *template.RowBuilder) {
		r.Col(12, func(c *template.ColBuilder) {
			c.Spacer(document.Mm(5))
			c.Line(template.LineColor(pdf.Gray(0.7)))
			c.Spacer(document.Mm(2))
		})
	})
	p.AutoRow(func(r *template.RowBuilder) {
		r.Col(12, func(c *template.ColBuilder) {
			c.Text("Generated by gpdf", template.AlignCenter(),
				template.FontSize(8), template.TextColor(pdf.Gray(0.5)))
		})
	})
})
Multi-Page Documents
for i := 1; i <= 5; i++ {
	page := doc.AddPage()
	page.AutoRow(func(r *template.RowBuilder) {
		r.Col(12, func(c *template.ColBuilder) {
			c.Text("Page content here")
		})
	})
}
Existing PDF Overlay

Open an existing PDF and overlay content using the same builder API:

// Open an existing PDF
doc, err := gpdf.Open(existingPDFBytes)

// Add a "DRAFT" watermark on page 1
doc.Overlay(0, func(p *template.PageBuilder) {
	p.Absolute(document.Mm(50), document.Mm(140), func(c *template.ColBuilder) {
		c.Text("DRAFT", template.FontSize(72),
			template.TextColor(pdf.Gray(0.85)))
	})
})

// Add page numbers to every page
count, _ := doc.PageCount()
doc.EachPage(func(i int, p *template.PageBuilder) {
	p.Absolute(document.Mm(170), document.Mm(285), func(c *template.ColBuilder) {
		c.Text(fmt.Sprintf("%d / %d", i+1, count), template.FontSize(10))
	}, template.AbsoluteWidth(document.Mm(20)))
})

result, _ := doc.Save()
PDF Merging

Combine multiple PDFs into a single document with optional page range selection:

// Merge multiple PDFs
merged, _ := gpdf.Merge(
	[]gpdf.Source{
		{Data: coverPage},
		{Data: report},
		{Data: appendix, Pages: gpdf.PageRange{From: 1, To: 3}}, // only first 3 pages
	},
	gpdf.WithMergeMetadata("My Document", "Author", ""),
)
JSON Schema

Define documents entirely in JSON:

schema := []byte(`{
	"page": {"size": "A4", "margins": "20mm"},
	"metadata": {"title": "Report", "author": "gpdf"},
	"body": [
		{"row": {"cols": [
			{"span": 12, "text": "Hello from JSON", "style": {"size": 24, "bold": true}}
		]}},
		{"row": {"cols": [
			{"span": 12, "table": {
				"header": ["Name", "Value"],
				"rows": [["Alpha", "100"], ["Beta", "200"]],
				"headerStyle": {"bold": true, "color": "white", "background": "#1A237E"}
			}}
		]}}
	]
}`)

doc, err := template.FromJSON(schema, nil)
data, _ := doc.Generate()
Go Template Integration

Use Go templates with JSON schema for dynamic content:

schema := []byte(`{
	"page": {"size": "A4", "margins": "20mm"},
	"metadata": {"title": "{{.Title}}"},
	"body": [
		{"row": {"cols": [
			{"span": 12, "text": "{{.Title}}", "style": {"size": 24, "bold": true}}
		]}}
	]
}`)

data := map[string]any{"Title": "Dynamic Report"}
doc, err := template.FromJSON(schema, data)

For more control, use a pre-parsed Go template:

tmpl, _ := gotemplate.New("doc").Funcs(template.TemplateFuncMap()).Parse(schemaStr)
doc, err := template.FromTemplate(tmpl, data)
Reusable Components

Generate common document types with a single function call:

Invoice:

doc := template.Invoice(template.InvoiceData{
	Number:  "#INV-2026-001",
	Date:    "March 1, 2026",
	DueDate: "March 31, 2026",
	From:    template.InvoiceParty{Name: "ACME Corp", Address: []string{"123 Main St"}},
	To:      template.InvoiceParty{Name: "Client Inc.", Address: []string{"456 Side St"}},
	Items: []template.InvoiceItem{
		{Description: "Web Development", Quantity: "40 hrs", UnitPrice: 150, Amount: 6000},
		{Description: "UI/UX Design", Quantity: "20 hrs", UnitPrice: 120, Amount: 2400},
	},
	TaxRate: 10,
	Notes:   "Thank you for your business!",
})
data, _ := doc.Generate()

Report:

doc := template.Report(template.ReportData{
	Title:    "Quarterly Report",
	Subtitle: "Q1 2026",
	Author:   "ACME Corp",
	Sections: []template.ReportSection{
		{
			Title:   "Executive Summary",
			Content: "Revenue increased by 15% compared to Q4 2025.",
			Metrics: []template.ReportMetric{
				{Label: "Revenue", Value: "$12.5M", ColorHex: 0x2E7D32},
				{Label: "Growth", Value: "+15%", ColorHex: 0x2E7D32},
			},
		},
		{
			Title: "Revenue Breakdown",
			Table: &template.ReportTable{
				Header: []string{"Division", "Q1 2026", "Change"},
				Rows:   [][]string{{"Cloud", "$5.2M", "+26.8%"}, {"Enterprise", "$3.8M", "+8.6%"}},
			},
		},
	},
})

Letter:

doc := template.Letter(template.LetterData{
	From:     template.LetterParty{Name: "ACME Corp", Address: []string{"123 Main St"}},
	To:       template.LetterParty{Name: "Mr. John Smith", Address: []string{"456 Side St"}},
	Date:     "March 1, 2026",
	Subject:  "Partnership Proposal",
	Greeting: "Dear Mr. Smith,",
	Body:     []string{"We are writing to propose a strategic partnership..."},
	Closing:  "Sincerely,",
	Signature: "Jane Doe",
})
Encryption

AES-256 encryption with owner/user passwords and permission control:

// Owner password only (PDF opens without password, editing restricted)
doc := gpdf.NewDocument(
	gpdf.WithPageSize(gpdf.A4),
	gpdf.WithEncryption(
		encrypt.WithOwnerPassword("owner-secret"),
	),
)

// Both passwords with permission control
doc := gpdf.NewDocument(
	gpdf.WithPageSize(gpdf.A4),
	gpdf.WithEncryption(
		encrypt.WithOwnerPassword("owner-pass"),
		encrypt.WithUserPassword("user-pass"),
		encrypt.WithPermissions(encrypt.PermPrint|encrypt.PermCopy),
	),
)
PDF/A Conformance

Generate PDF/A-1b or PDF/A-2b compliant documents:

doc := gpdf.NewDocument(
	gpdf.WithPageSize(gpdf.A4),
	gpdf.WithPDFA(
		pdfa.WithLevel(pdfa.LevelA2b),
		pdfa.WithMetadata(pdfa.MetadataInfo{
			Title:  "Archived Report",
			Author: "gpdf",
		}),
	),
)
Digital Signatures

Sign PDFs with CMS/PKCS#7 using RSA or ECDSA keys:

data, _ := doc.Generate()

signed, err := gpdf.SignDocument(data, signature.Signer{
	Certificate: cert,
	PrivateKey:  key,
	Chain:       intermediates,
},
	signature.WithReason("Approved"),
	signature.WithLocation("Tokyo"),
	signature.WithTimestamp("http://tsa.example.com"),
)
Document Metadata
doc := gpdf.NewDocument(
	gpdf.WithPageSize(gpdf.A4),
	gpdf.WithMetadata(document.DocumentMetadata{
		Title:   "Annual Report 2026",
		Author:  "gpdf Library",
		Subject: "Example of document metadata",
		Creator: "My Application",
	}),
)
Page Sizes & Margins
// Available page sizes
document.A4      // 210mm x 297mm
document.A3      // 297mm x 420mm
document.Letter  // 8.5in x 11in
document.Legal   // 8.5in x 14in

// Uniform margins
template.WithMargins(document.UniformEdges(document.Mm(20)))

// Asymmetric margins
template.WithMargins(document.Edges{
	Top:    document.Mm(10),
	Right:  document.Mm(40),
	Bottom: document.Mm(10),
	Left:   document.Mm(40),
})
Output Options
// Generate returns []byte
data, err := doc.Generate()

// Render writes to any io.Writer
var buf bytes.Buffer
err := doc.Render(&buf)

// Write directly to a file
f, _ := os.Create("output.pdf")
defer f.Close()
doc.Render(f)

API Reference

Document Options
Function Description
WithPageSize(size) Set page size (A4, A3, Letter, Legal)
WithMargins(edges) Set page margins
WithFont(family, data) Register a TrueType font
WithDefaultFont(family, size) Set the default font
WithMetadata(meta) Set document metadata
WithEncryption(opts...) Enable AES-256 encryption
WithPDFA(opts...) Enable PDF/A conformance
Column Content
Method Description
c.Text(text, opts...) Add text with styling options
c.Table(header, rows, opts...) Add a table
c.Image(data, opts...) Add an image (JPEG/PNG)
c.QRCode(data, opts...) Add a QR code
c.Barcode(data, opts...) Add a barcode (Code 128)
c.List(items, opts...) Add a bulleted list
c.OrderedList(items, opts...) Add a numbered list
c.PageNumber(opts...) Add current page number
c.TotalPages(opts...) Add total page count
c.Line(opts...) Add a horizontal line
c.Spacer(height) Add vertical space
Page-Level Content
Method Description
page.AutoRow(fn) Add an auto-height row
page.Row(height, fn) Add a fixed-height row
page.Absolute(x, y, fn, opts...) Place content at exact XY coordinates
Absolute Positioning Options
Option Description
gpdf.AbsoluteWidth(value) Set explicit width (default: remaining space)
gpdf.AbsoluteHeight(value) Set explicit height (default: remaining space)
gpdf.AbsoluteOriginPage() Use page corner as origin instead of content area
Existing PDF Operations
Function / Method Description
gpdf.Open(data, opts...) Open an existing PDF for overlay
doc.PageCount() Get the number of pages
doc.Overlay(page, fn) Add content on top of a specific page
doc.EachPage(fn) Apply overlay to every page
doc.Save() Save the modified PDF
gpdf.Merge(sources, opts...) Merge multiple PDFs into one
WithMergeMetadata(title, author, producer) Set metadata on merged output
Text Options
Option Description
template.FontSize(size) Set font size in points
template.Bold() Bold weight
template.Italic() Italic style
template.FontFamily(name) Use a registered font
template.TextColor(color) Set text color
template.BgColor(color) Set background color
template.Underline() Underline decoration
template.Strikethrough() Strikethrough decoration
template.LetterSpacing(pts) Set letter spacing in points
template.TextIndent(value) Set first-line indent
template.AlignLeft() Left align (default)
template.AlignCenter() Center align
template.AlignRight() Right align
Table Options
Option Description
template.ColumnWidths(w...) Set column width percentages
template.TableHeaderStyle(opts...) Style the header row
template.TableStripe(color) Set alternating row color
template.TableCellVAlign(align) Set cell vertical alignment (Top/Middle/Bottom)
Image Options
Option Description
template.FitWidth(value) Scale to fit width (keeps aspect ratio)
template.FitHeight(value) Scale to fit height (keeps aspect ratio)
QR Code Options
Option Description
template.QRSize(value) Set QR code size
template.QRErrorCorrection(level) Set error correction (L/M/Q/H)
template.QRScale(n) Set module scale factor
Barcode Options
Option Description
template.BarcodeWidth(value) Set barcode width
template.BarcodeHeight(value) Set barcode height
template.BarcodeFormat(fmt) Set barcode format (Code 128)
Encryption Options
Option Description
encrypt.WithOwnerPassword(pw) Set owner password
encrypt.WithUserPassword(pw) Set user password
encrypt.WithPermissions(perm) Set document permissions (PermPrint, PermCopy, PermModify, etc.)
PDF/A Options
Option Description
pdfa.WithLevel(level) Set conformance level (LevelA1b, LevelA2b)
pdfa.WithMetadata(info) Set XMP metadata (Title, Author, Subject, etc.)
Digital Signature
Function / Option Description
gpdf.SignDocument(data, signer, opts...) Sign a PDF with a digital signature
signature.WithReason(reason) Set signing reason
signature.WithLocation(location) Set signing location
signature.WithTimestamp(tsaURL) Enable RFC 3161 timestamping
signature.WithSignTime(t) Set signing time
Template Generation
Function Description
template.FromJSON(schema, data) Generate document from JSON schema
template.FromTemplate(tmpl, data) Generate document from Go template
template.TemplateFuncMap() Get template helper functions (includes toJSON)
Reusable Components
Function Description
template.Invoice(data) Generate a professional invoice PDF
template.Report(data) Generate a structured report PDF
template.Letter(data) Generate a business letter PDF
Line Options
Option Description
template.LineColor(color) Set line color
template.LineThickness(value) Set line thickness
Units
document.Pt(72)    // Points (1/72 inch)
document.Mm(10)    // Millimeters
document.Cm(2.5)   // Centimeters
document.In(1)     // Inches
document.Em(1.5)   // Relative to font size
document.Pct(50)   // Percentage
Colors
pdf.RGB(0.2, 0.4, 0.8)   // RGB (0.0–1.0)
pdf.RGBHex(0xFF5733)      // RGB from hex
pdf.Gray(0.5)             // Grayscale
pdf.CMYK(0, 0.5, 1, 0)   // CMYK

// Predefined
pdf.Black, pdf.White, pdf.Red, pdf.Green, pdf.Blue
pdf.Yellow, pdf.Cyan, pdf.Magenta

License

MIT

Documentation

Overview

Package gpdf is a pure Go, zero-dependency PDF generation library.

gpdf provides a layered architecture for PDF creation:

  • pdf (Layer 1): Low-level PDF primitives — objects, streams, fonts, images
  • document (Layer 2): Document model — nodes, box model, layout engine, renderer
  • template (Layer 3): High-level declarative API — builders, grids, components

Most users should start with the template package for the simplest API:

doc := gpdf.NewDocument(
    gpdf.WithPageSize(document.A4),
    gpdf.WithMargins(document.UniformEdges(document.Mm(15))),
)
page := doc.AddPage()
page.AutoRow(func(r *template.RowBuilder) {
    r.Col(12, func(c *template.ColBuilder) {
        c.Text("Hello, World!", template.FontSize(24))
    })
})
data, err := doc.Generate()
Example (Barcode)
package main

import (
	"fmt"

	gpdf "github.com/gpdf-dev/gpdf"
	"github.com/gpdf-dev/gpdf/document"
	"github.com/gpdf-dev/gpdf/template"
)

func main() {
	doc := gpdf.NewDocument()
	page := doc.AddPage()
	page.AutoRow(func(r *template.RowBuilder) {
		r.Col(12, func(c *template.ColBuilder) {
			c.Text("Order barcode:")
			c.Barcode("INV-2026-0001", template.BarcodeWidth(document.Mm(80)))
		})
	})
	data, _ := doc.Generate()
	fmt.Println("PDF starts with:", string(data[:5]))
}
Output:
PDF starts with: %PDF-
Example (Colors)
package main

import (
	"fmt"

	gpdf "github.com/gpdf-dev/gpdf"
	"github.com/gpdf-dev/gpdf/pdf"
	"github.com/gpdf-dev/gpdf/template"
)

func main() {
	doc := gpdf.NewDocument()
	page := doc.AddPage()
	page.AutoRow(func(r *template.RowBuilder) {
		r.Col(4, func(c *template.ColBuilder) {
			c.Text("RGB", template.TextColor(pdf.RGB(0.2, 0.4, 0.8)))
		})
		r.Col(4, func(c *template.ColBuilder) {
			c.Text("Hex", template.TextColor(pdf.RGBHex(0xFF6600)))
		})
		r.Col(4, func(c *template.ColBuilder) {
			c.Text("Gray", template.TextColor(pdf.Gray(0.5)))
		})
	})
	data, _ := doc.Generate()
	fmt.Println("PDF starts with:", string(data[:5]))
}
Output:
PDF starts with: %PDF-
Example (GridLayout)
package main

import (
	"fmt"

	gpdf "github.com/gpdf-dev/gpdf"
	"github.com/gpdf-dev/gpdf/template"
)

func main() {
	doc := gpdf.NewDocument()
	page := doc.AddPage()
	// Two-column layout (6+6 = 12)
	page.AutoRow(func(r *template.RowBuilder) {
		r.Col(6, func(c *template.ColBuilder) {
			c.Text("Left column")
		})
		r.Col(6, func(c *template.ColBuilder) {
			c.Text("Right column")
		})
	})
	// Three-column layout (4+4+4 = 12)
	page.AutoRow(func(r *template.RowBuilder) {
		r.Col(4, func(c *template.ColBuilder) { c.Text("Col 1") })
		r.Col(4, func(c *template.ColBuilder) { c.Text("Col 2") })
		r.Col(4, func(c *template.ColBuilder) { c.Text("Col 3") })
	})
	data, _ := doc.Generate()
	fmt.Println("PDF starts with:", string(data[:5]))
}
Output:
PDF starts with: %PDF-
Example (HeaderFooter)
package main

import (
	"fmt"

	gpdf "github.com/gpdf-dev/gpdf"
	"github.com/gpdf-dev/gpdf/template"
)

func main() {
	doc := gpdf.NewDocument()
	doc.Header(func(p *template.PageBuilder) {
		p.AutoRow(func(r *template.RowBuilder) {
			r.Col(6, func(c *template.ColBuilder) {
				c.Text("Company Name", template.Bold())
			})
			r.Col(6, func(c *template.ColBuilder) {
				c.Text("Report", template.AlignRight())
			})
		})
	})
	doc.Footer(func(p *template.PageBuilder) {
		p.AutoRow(func(r *template.RowBuilder) {
			r.Col(12, func(c *template.ColBuilder) {
				c.Text("Confidential", template.AlignCenter(), template.FontSize(8))
			})
		})
	})
	page := doc.AddPage()
	page.AutoRow(func(r *template.RowBuilder) {
		r.Col(12, func(c *template.ColBuilder) {
			c.Text("Page content goes here")
		})
	})
	data, _ := doc.Generate()
	fmt.Println("PDF starts with:", string(data[:5]))
}
Output:
PDF starts with: %PDF-
Example (Image)
package main

import (
	"bytes"
	"fmt"
	"image"
	"image/color"
	"image/png"

	gpdf "github.com/gpdf-dev/gpdf"
	"github.com/gpdf-dev/gpdf/document"
	"github.com/gpdf-dev/gpdf/template"
)

func main() {
	// Create a small 2x2 test PNG image.
	img := image.NewRGBA(image.Rect(0, 0, 2, 2))
	for y := range 2 {
		for x := range 2 {
			img.Set(x, y, color.RGBA{R: 0, G: 100, B: 200, A: 255})
		}
	}
	var buf bytes.Buffer
	_ = png.Encode(&buf, img)

	doc := gpdf.NewDocument()
	page := doc.AddPage()
	page.AutoRow(func(r *template.RowBuilder) {
		r.Col(12, func(c *template.ColBuilder) {
			c.Text("Embedded image:")
			c.Image(buf.Bytes(), template.FitWidth(document.Mm(30)))
		})
	})
	data, _ := doc.Generate()
	fmt.Println("PDF starts with:", string(data[:5]))
}
Output:
PDF starts with: %PDF-
Example (List)
package main

import (
	"fmt"

	gpdf "github.com/gpdf-dev/gpdf"
	"github.com/gpdf-dev/gpdf/document"
	"github.com/gpdf-dev/gpdf/template"
)

func main() {
	doc := gpdf.NewDocument()
	page := doc.AddPage()
	page.AutoRow(func(r *template.RowBuilder) {
		r.Col(12, func(c *template.ColBuilder) {
			c.Text("Bullet list:", template.Bold())
			c.List([]string{"First item", "Second item", "Third item"})
			c.Spacer(document.Mm(5))
			c.Text("Numbered list:", template.Bold())
			c.OrderedList([]string{"Step one", "Step two", "Step three"})
		})
	})
	data, _ := doc.Generate()
	fmt.Println("PDF starts with:", string(data[:5]))
}
Output:
PDF starts with: %PDF-
Example (PageNumbers)
package main

import (
	"fmt"

	gpdf "github.com/gpdf-dev/gpdf"
	"github.com/gpdf-dev/gpdf/template"
)

func main() {
	doc := gpdf.NewDocument()
	doc.Footer(func(p *template.PageBuilder) {
		p.AutoRow(func(r *template.RowBuilder) {
			r.Col(6, func(c *template.ColBuilder) {
				c.PageNumber(template.FontSize(8))
			})
			r.Col(6, func(c *template.ColBuilder) {
				c.TotalPages(template.AlignRight(), template.FontSize(8))
			})
		})
	})
	for range 3 {
		page := doc.AddPage()
		page.AutoRow(func(r *template.RowBuilder) {
			r.Col(12, func(c *template.ColBuilder) {
				c.Text("Content page")
			})
		})
	}
	data, _ := doc.Generate()
	fmt.Println("PDF starts with:", string(data[:5]))
}
Output:
PDF starts with: %PDF-
Example (QrCode)
package main

import (
	"fmt"

	gpdf "github.com/gpdf-dev/gpdf"
	"github.com/gpdf-dev/gpdf/document"
	"github.com/gpdf-dev/gpdf/template"
)

func main() {
	doc := gpdf.NewDocument()
	page := doc.AddPage()
	page.AutoRow(func(r *template.RowBuilder) {
		r.Col(12, func(c *template.ColBuilder) {
			c.Text("Scan to visit our site:")
			c.QRCode("https://gpdf.dev", template.QRSize(document.Mm(30)))
		})
	})
	data, _ := doc.Generate()
	fmt.Println("PDF starts with:", string(data[:5]))
}
Output:
PDF starts with: %PDF-
Example (RenderToWriter)
package main

import (
	"bytes"
	"fmt"

	gpdf "github.com/gpdf-dev/gpdf"
	"github.com/gpdf-dev/gpdf/template"
)

func main() {
	doc := gpdf.NewDocument()
	page := doc.AddPage()
	page.AutoRow(func(r *template.RowBuilder) {
		r.Col(12, func(c *template.ColBuilder) {
			c.Text("Written via Render(io.Writer)")
		})
	})
	var buf bytes.Buffer
	_ = doc.Render(&buf)
	fmt.Println("PDF starts with:", string(buf.Bytes()[:5]))
}
Output:
PDF starts with: %PDF-
Example (RichText)
package main

import (
	"fmt"

	gpdf "github.com/gpdf-dev/gpdf"
	"github.com/gpdf-dev/gpdf/pdf"
	"github.com/gpdf-dev/gpdf/template"
)

func main() {
	doc := gpdf.NewDocument()
	page := doc.AddPage()
	page.AutoRow(func(r *template.RowBuilder) {
		r.Col(12, func(c *template.ColBuilder) {
			c.RichText(func(rt *template.RichTextBuilder) {
				rt.Span("This is ")
				rt.Span("bold", template.Bold())
				rt.Span(" and this is ")
				rt.Span("red italic", template.Italic(), template.TextColor(pdf.Red))
				rt.Span(" in one line.")
			})
		})
	})
	data, _ := doc.Generate()
	fmt.Println("PDF starts with:", string(data[:5]))
}
Output:
PDF starts with: %PDF-
Example (Table)
package main

import (
	"fmt"

	gpdf "github.com/gpdf-dev/gpdf"
	"github.com/gpdf-dev/gpdf/template"
)

func main() {
	doc := gpdf.NewDocument()
	page := doc.AddPage()
	page.AutoRow(func(r *template.RowBuilder) {
		r.Col(12, func(c *template.ColBuilder) {
			c.Table(
				[]string{"Name", "Age", "City"},
				[][]string{
					{"Alice", "30", "Tokyo"},
					{"Bob", "25", "New York"},
					{"Charlie", "35", "London"},
				},
			)
		})
	})
	data, _ := doc.Generate()
	fmt.Println("PDF starts with:", string(data[:5]))
}
Output:
PDF starts with: %PDF-
Example (TableStyled)
package main

import (
	"fmt"

	gpdf "github.com/gpdf-dev/gpdf"
	"github.com/gpdf-dev/gpdf/pdf"
	"github.com/gpdf-dev/gpdf/template"
)

func main() {
	doc := gpdf.NewDocument()
	page := doc.AddPage()
	page.AutoRow(func(r *template.RowBuilder) {
		r.Col(12, func(c *template.ColBuilder) {
			c.Table(
				[]string{"Product", "Qty", "Price"},
				[][]string{
					{"Widget", "10", "$9.99"},
					{"Gadget", "5", "$24.99"},
				},
				template.ColumnWidths(50, 25, 25),
				template.TableHeaderStyle(
					template.TextColor(pdf.White),
					template.BgColor(pdf.RGBHex(0x1A237E)),
				),
				template.TableStripe(pdf.RGBHex(0xF5F5F5)),
			)
		})
	})
	data, _ := doc.Generate()
	fmt.Println("PDF starts with:", string(data[:5]))
}
Output:
PDF starts with: %PDF-
Example (TextStyling)
package main

import (
	"fmt"

	gpdf "github.com/gpdf-dev/gpdf"
	"github.com/gpdf-dev/gpdf/pdf"
	"github.com/gpdf-dev/gpdf/template"
)

func main() {
	doc := gpdf.NewDocument()
	page := doc.AddPage()
	page.AutoRow(func(r *template.RowBuilder) {
		r.Col(12, func(c *template.ColBuilder) {
			c.Text("Large bold title", template.FontSize(24), template.Bold())
			c.Text("Italic subtitle", template.Italic())
			c.Text("Red text", template.TextColor(pdf.Red))
			c.Text("Centered", template.AlignCenter())
			c.Text("Underlined", template.Underline())
			c.Text("Yellow background", template.BgColor(pdf.Yellow))
		})
	})
	data, _ := doc.Generate()
	fmt.Println("PDF starts with:", string(data[:5]))
}
Output:
PDF starts with: %PDF-
Example (Units)
package main

import (
	"fmt"

	gpdf "github.com/gpdf-dev/gpdf"
	"github.com/gpdf-dev/gpdf/document"
	"github.com/gpdf-dev/gpdf/template"
)

func main() {
	doc := gpdf.NewDocument(
		gpdf.WithMargins(document.Edges{
			Top:    document.Cm(2),   // centimeters
			Right:  document.In(0.5), // inches
			Bottom: document.Mm(15),  // millimeters
			Left:   document.Pt(36),  // points
		}),
	)
	page := doc.AddPage()
	page.Row(document.Mm(20), func(r *template.RowBuilder) {
		r.Col(12, func(c *template.ColBuilder) {
			c.Text("Fixed 20mm height row")
		})
	})
	page.AutoRow(func(r *template.RowBuilder) {
		r.Col(12, func(c *template.ColBuilder) {
			c.Text("Auto-height row")
		})
	})
	data, _ := doc.Generate()
	fmt.Println("PDF starts with:", string(data[:5]))
}
Output:
PDF starts with: %PDF-

Index

Examples

Constants

View Source
const Version = buildinfo.Version

Version is the library version.

Variables

View Source
var (
	// WithPageSize sets the page dimensions.
	WithPageSize = template.WithPageSize
	// WithMargins sets the page margins.
	WithMargins = template.WithMargins
	// WithFont registers a TrueType font.
	WithFont = template.WithFont
	// WithDefaultFont sets the default font family and size.
	WithDefaultFont = template.WithDefaultFont
	// WithMetadata sets document metadata (title, author, etc.).
	WithMetadata = template.WithMetadata
	// WithWriterSetup registers a Writer configuration hook for extensions.
	WithWriterSetup = template.WithWriterSetup
)

Re-export commonly used option functions for convenience.

View Source
var (
	A4     = document.A4
	A3     = document.A3
	Letter = document.Letter
	Legal  = document.Legal
)

Re-export commonly used page sizes for convenience.

View Source
var (
	// QRSize sets the display size of a QR code (width = height).
	QRSize = template.QRSize
	// QRErrorCorrection sets the QR error correction level.
	QRErrorCorrection = template.QRErrorCorrection
	// QRScale sets the pixels per QR module.
	QRScale = template.QRScale
)

Re-export QR code option functions for convenience.

View Source
var (
	// BarcodeWidth sets the display width of a barcode.
	BarcodeWidth = template.BarcodeWidth
	// BarcodeHeight sets the display height of a barcode.
	BarcodeHeight = template.BarcodeHeight
	// BarcodeFormat sets the barcode symbology.
	BarcodeFormat = template.BarcodeFormat
)

Re-export barcode option functions for convenience.

View Source
var (
	// AbsoluteWidth sets the width constraint for absolute-positioned content.
	AbsoluteWidth = template.AbsoluteWidth
	// AbsoluteHeight sets the height constraint for absolute-positioned content.
	AbsoluteHeight = template.AbsoluteHeight
	// AbsoluteOriginPage sets the coordinate origin to the page corner.
	AbsoluteOriginPage = template.AbsoluteOriginPage
)

Re-export absolute positioning option functions for convenience.

View Source
var (
	// FromJSON creates a Document from a JSON schema definition with
	// optional Go template data binding.
	FromJSON = template.FromJSON
	// FromTemplate creates a Document by executing a pre-parsed Go
	// template that produces JSON schema output.
	FromTemplate = template.FromTemplate
	// TemplateFuncMap returns helper functions (e.g., toJSON) for use
	// when parsing Go templates for FromTemplate.
	TemplateFuncMap = template.TemplateFuncMap
)

Re-export JSON schema / Go template integration functions.

View Source
var (
	// NewInvoice creates a ready-to-generate invoice PDF from structured data.
	NewInvoice = template.Invoice
	// NewReport creates a ready-to-generate report PDF from structured data.
	NewReport = template.Report
	// NewLetter creates a ready-to-generate business letter PDF from structured data.
	NewLetter = template.Letter
)

Re-export reusable component constructors for convenience.

Functions

func Merge added in v1.0.2

func Merge(sources []Source, opts ...MergeOption) ([]byte, error)

Merge combines pages from multiple PDF sources into a single PDF.

merged, err := gpdf.Merge(
    []gpdf.Source{
        {Data: coverPage},
        {Data: generated},
        {Data: attachment, Pages: gpdf.PageRange{From: 1, To: 3}},
    },
    gpdf.WithMergeMetadata("Policy Bundle", "Example Ltd", ""),
)

func NewDocument

func NewDocument(opts ...template.Option) *template.Document

NewDocument creates a new PDF document builder with the given options. This is the primary entry point for creating PDFs using the high-level API.

Example
package main

import (
	"fmt"

	gpdf "github.com/gpdf-dev/gpdf"
	"github.com/gpdf-dev/gpdf/document"
	"github.com/gpdf-dev/gpdf/template"
)

func main() {
	doc := gpdf.NewDocument(
		gpdf.WithPageSize(document.A4),
		gpdf.WithMargins(document.UniformEdges(document.Mm(20))),
	)
	page := doc.AddPage()
	page.AutoRow(func(r *template.RowBuilder) {
		r.Col(12, func(c *template.ColBuilder) {
			c.Text("Hello, World!", template.FontSize(24))
		})
	})
	data, _ := doc.Generate()
	fmt.Println("PDF starts with:", string(data[:5]))
}
Output:
PDF starts with: %PDF-
Example (WithOptions)
package main

import (
	"fmt"

	gpdf "github.com/gpdf-dev/gpdf"
	"github.com/gpdf-dev/gpdf/document"
	"github.com/gpdf-dev/gpdf/template"
)

func main() {
	doc := gpdf.NewDocument(
		gpdf.WithPageSize(document.Letter),
		gpdf.WithMargins(document.Edges{
			Top: document.Mm(25), Right: document.Mm(20),
			Bottom: document.Mm(25), Left: document.Mm(20),
		}),
		gpdf.WithMetadata(document.DocumentMetadata{
			Title:  "Annual Report",
			Author: "gpdf",
		}),
	)
	page := doc.AddPage()
	page.AutoRow(func(r *template.RowBuilder) {
		r.Col(12, func(c *template.ColBuilder) {
			c.Text("Custom page size, margins, and metadata")
		})
	})
	data, _ := doc.Generate()
	fmt.Println("PDF starts with:", string(data[:5]))
}
Output:
PDF starts with: %PDF-

func NewDocumentFromJSON added in v0.8.0

func NewDocumentFromJSON(schema []byte, data any, opts ...template.Option) (*template.Document, error)

NewDocumentFromJSON is an alias for FromJSON that creates a Document from a JSON schema, optionally resolving Go template expressions with data.

Example
package main

import (
	"fmt"

	gpdf "github.com/gpdf-dev/gpdf"
)

func main() {
	schema := []byte(`{
		"page": {"size": "A4", "margins": "15mm"},
		"metadata": {"title": "JSON Example", "author": "gpdf"},
		"body": [
			{"row": {"cols": [
				{"span": 12, "text": "Generated from JSON schema", "style": {"size": 20, "bold": true}}
			]}},
			{"row": {"cols": [
				{"span": 6, "text": "Left column"},
				{"span": 6, "text": "Right column", "style": {"align": "right"}}
			]}}
		]
	}`)
	doc, _ := gpdf.NewDocumentFromJSON(schema, nil)
	data, _ := doc.Generate()
	fmt.Println("PDF starts with:", string(data[:5]))
}
Output:
PDF starts with: %PDF-
Example (WithData)
package main

import (
	"fmt"

	gpdf "github.com/gpdf-dev/gpdf"
)

func main() {
	schema := []byte(`{
		"page": {"size": "A4"},
		"body": [
			{"row": {"cols": [
				{"span": 12, "text": "Hello, {{.Name}}!", "style": {"size": 24}}
			]}}
		]
	}`)
	data := map[string]string{"Name": "World"}
	doc, _ := gpdf.NewDocumentFromJSON(schema, data)
	pdfData, _ := doc.Generate()
	fmt.Println("PDF starts with:", string(pdfData[:5]))
}
Output:
PDF starts with: %PDF-

func NewDocumentFromTemplate added in v0.8.0

func NewDocumentFromTemplate(tmpl *gotemplate.Template, data any, opts ...template.Option) (*template.Document, error)

NewDocumentFromTemplate creates a Document by executing a Go template that produces JSON schema output.

Example
package main

import (
	"fmt"

	gotemplate "text/template"

	gpdf "github.com/gpdf-dev/gpdf"
)

func main() {
	tmplStr := `{
		"page": {"size": "A4"},
		"body": [
			{"row": {"cols": [
				{"span": 12, "text": "Items: {{len .Items}}", "style": {"size": 18}}
			]}}
			{{- range .Items}},
			{"row": {"cols": [
				{"span": 8, "text": "{{.Name}}"},
				{"span": 4, "text": "{{.Price}}", "style": {"align": "right"}}
			]}}
			{{- end}}
		]
	}`
	funcMap := gpdf.TemplateFuncMap()
	tmpl := gotemplate.Must(gotemplate.New("").Funcs(funcMap).Parse(tmplStr))
	data := map[string]any{
		"Items": []map[string]string{
			{"Name": "Widget", "Price": "$9.99"},
			{"Name": "Gadget", "Price": "$24.99"},
		},
	}
	doc, _ := gpdf.NewDocumentFromTemplate(tmpl, data)
	pdfData, _ := doc.Generate()
	fmt.Println("PDF starts with:", string(pdfData[:5]))
}
Output:
PDF starts with: %PDF-

func Open added in v0.9.2

func Open(data []byte, opts ...template.Option) (*template.ExistingDocument, error)

Open creates an ExistingDocument from raw PDF data for reading and modifying. Use the returned document's Overlay method to add content on top of existing pages.

doc, err := gpdf.Open(pdfBytes, gpdf.WithFont("NotoSans", fontData))
doc.Overlay(0, func(p *template.PageBuilder) {
    p.AutoRow(func(r *template.RowBuilder) {
        r.Col(12, func(c *template.ColBuilder) {
            c.Text("APPROVED", template.FontSize(48))
        })
    })
})
result, err := doc.Save()

func SignDocument added in v1.0.0

func SignDocument(pdfData []byte, signer signature.Signer, opts ...signature.Option) ([]byte, error)

SignDocument adds a digital signature to a generated PDF. This is a post-processing step applied after document generation.

func WithEncryption added in v1.0.0

func WithEncryption(opts ...encrypt.Option) template.Option

WithEncryption returns a template.Option that enables AES-256 encryption.

func WithPDFA added in v1.0.0

func WithPDFA(opts ...pdfa.Option) template.Option

WithPDFA returns a template.Option that enables PDF/A conformance.

Types

type MergeOption added in v1.0.2

type MergeOption func(*mergeConfig)

MergeOption configures the merge operation.

func WithMergeMetadata added in v1.0.2

func WithMergeMetadata(title, author, producer string) MergeOption

WithMergeMetadata sets the document info on the merged output.

type PageRange added in v1.0.2

type PageRange struct {
	From int // 1-based; 0 means first page
	To   int // 1-based; 0 means last page
}

PageRange specifies a 1-based inclusive range of pages. Zero values mean "from start" / "to end".

type Source added in v1.0.2

type Source struct {
	Data  []byte    // raw PDF bytes
	Pages PageRange // which pages to include; zero value = all pages
}

Source represents one input PDF in a merge operation.

Directories

Path Synopsis
_examples
testutil
Package testutil provides shared test helpers for gpdf example tests.
Package testutil provides shared test helpers for gpdf example tests.
Package barcode implements barcode encoding and rendering for PDF generation.
Package barcode implements barcode encoding and rendering for PDF generation.
Package document provides the intermediate document model that bridges the high-level template API and the low-level PDF writer.
Package document provides the intermediate document model that bridges the high-level template API and the low-level PDF writer.
layout
Package layout provides layout engines that calculate the position and size of document nodes within the available space.
Package layout provides layout engines that calculate the position and size of document nodes within the available space.
render
Package render provides interfaces and implementations for drawing laid-out document content to an output target such as a PDF file.
Package render provides interfaces and implementations for drawing laid-out document content to an output target such as a PDF file.
Package encrypt provides AES-256 PDF encryption (ISO 32000-2, Rev 6).
Package encrypt provides AES-256 PDF encryption (ISO 32000-2, Rev 6).
internal
buildinfo
Package buildinfo holds build-time constants shared across gpdf packages.
Package buildinfo holds build-time constants shared across gpdf packages.
pdf
Package pdf provides low-level PDF object types, a streaming writer, and color utilities for producing valid PDF binary output.
Package pdf provides low-level PDF object types, a streaming writer, and color utilities for producing valid PDF binary output.
font
Package font provides TrueType font parsing, glyph metrics, text measurement, line breaking, and font subsetting for PDF generation.
Package font provides TrueType font parsing, glyph metrics, text measurement, line breaking, and font subsetting for PDF generation.
Package pdfa provides PDF/A conformance support for gpdf.
Package pdfa provides PDF/A conformance support for gpdf.
Package qrcode implements QR code encoding per ISO 18004.
Package qrcode implements QR code encoding per ISO 18004.
Package signature provides CMS/PKCS#7 digital signatures for PDF documents.
Package signature provides CMS/PKCS#7 digital signatures for PDF documents.
Package template provides a declarative, builder-pattern API for constructing PDF documents.
Package template provides a declarative, builder-pattern API for constructing PDF documents.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL