Basic Usage

Creating a Document

Every PDF starts with creating a Document using template.New():

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

doc := template.New(
    template.WithPageSize(document.A4),
    template.WithMargins(document.UniformEdges(document.Mm(20))),
)

Document Options

OptionDescription
WithPageSize(size)Page dimensions — document.A4, A3, Letter, Legal
WithMargins(edges)Page margins using document.UniformEdges() or custom document.Edges{}
WithFont(family, data)Register a TrueType font (pass font file bytes)
WithDefaultFont(family, size)Set the default font family and size
WithMetadata(meta)Set title, author, subject, creator

Adding Pages and Content

Content is organized in a hierarchy: Document → Page → Row → Column → Elements

page := doc.AddPage()

page.AutoRow(func(r *template.RowBuilder) {       // Auto-height row
    r.Col(12, func(c *template.ColBuilder) {       // Full-width column
        c.Text("Hello, World!", template.FontSize(24), template.Bold())
    })
})
┌─ Page ────────────────────────────────┐
│ ┌─ Row ─────────────────────────────┐ │
│ │ ┌─ Col(12) ─────────────────────┐ │ │
│ │ │  Hello, World!                │ │ │
│ │ └───────────────────────────────┘ │ │
│ └───────────────────────────────────┘ │
└───────────────────────────────────────┘

Text Styling

Apply styles as functional options on c.Text():

page.AutoRow(func(r *template.RowBuilder) {
    r.Col(12, func(c *template.ColBuilder) {
        // Font sizes
        c.Text("Font Size 8pt", template.FontSize(8))
        c.Text("Font Size 12pt (default)", template.FontSize(12))
        c.Text("Font Size 24pt", template.FontSize(24))
        c.Text("Font Size 36pt", template.FontSize(36))

        // Weight and style
        c.Text("Normal text")
        c.Text("Bold text", template.Bold())
        c.Text("Italic text", template.Italic())
        c.Text("Bold + Italic text", template.Bold(), template.Italic())

        // Colors
        c.Text("Red text", template.TextColor(pdf.Red))
        c.Text("Custom color", template.TextColor(pdf.RGB(1.0, 0.5, 0.0)))
        c.Text("Hex color", template.TextColor(pdf.RGBHex(0x336699)))

        // Background
        c.Text("Yellow background", template.BgColor(pdf.Yellow))
        c.Text("White on dark",
            template.TextColor(pdf.White),
            template.BgColor(pdf.RGBHex(0x333333)),
        )

        // Alignment
        c.Text("Left aligned (default)", template.AlignLeft())
        c.Text("Center aligned", template.AlignCenter())
        c.Text("Right aligned", template.AlignRight())
    })
})
┌─────────────────────────────────────────────┐
│  Font Size 8pt                              │  ← small text
│  Font Size 12pt (default)                   │
│  Font Size 24pt                             │  ← large text
│  Font Size 36pt                             │  ← very large text
│                                             │
│  Normal text                                │
│  Bold text                                  │  ← bold
│  Italic text                                │  ← italic
│  Bold + Italic text                         │  ← both
│                                             │
│  Red text                                   │  ← colored
│  Custom color                               │  ← RGB(1.0, 0.5, 0.0)
│  Hex color                                  │  ← #336699
│                                             │
│  Yellow background                          │  ← highlighted
│  White on dark                              │  ← inverted
│                                             │
│  Left aligned (default)                     │
│                  Center aligned             │
│                          Right aligned      │
└─────────────────────────────────────────────┘

Two-Column Layout

Use the 12-column grid to create multi-column layouts:

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")
    })
})
┌──────────────────────┬──────────────────────┐
│  Left column         │  Right column        │
└──────────────────────┴──────────────────────┘

Tables

Create tables with headers and data rows:

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"},
                {"Diana", "28", "Paris"},
            },
        )
    })
})
┌─────────────────────────────────────────┐
│  Name      │  Age  │  City              │  ← header
├────────────┼───────┼────────────────────┤
│  Alice     │  30   │  Tokyo             │
│  Bob       │  25   │  New York          │
│  Charlie   │  35   │  London            │
│  Diana     │  28   │  Paris             │
└────────────┴───────┴────────────────────┘

Styled Tables

Add custom column widths, header styles, and stripe colors:

darkBlue := pdf.RGBHex(0x1A237E)
lightGray := pdf.RGBHex(0xF5F5F5)

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(darkBlue),
    ),
    template.TableStripe(lightGray),
)
┌─────────────────────────────────────────────────────────┐
│  Product      │ Category    │ Qty │ Unit Price │ Total  │ ← white on dark blue
├───────────────┼─────────────┼─────┼────────────┼────────┤
│  Laptop Pro   │ Electronics │  2  │ $1,299.00  │$2,598  │ ← white bg
│  Wireless..   │ Accessories │ 10  │    $29.99  │  $299  │ ← light gray stripe
│  USB-C Hub    │ Accessories │  5  │    $49.99  │  $249  │ ← white bg
└───────────────┴─────────────┴─────┴────────────┴────────┘

Lines and Spacers

// Horizontal rule
c.Line()
c.Line(template.LineColor(pdf.Red), template.LineThickness(document.Pt(2)))

// Vertical spacing
c.Spacer(document.Mm(10))

Output

// Option 1: Get PDF as byte slice
data, err := doc.Generate()
if err != nil {
    log.Fatal(err)
}
os.WriteFile("output.pdf", data, 0644)

// Option 2: Write to any io.Writer (http.ResponseWriter, file, buffer...)
err := doc.Render(w)

Complete Example: Invoice

doc := template.New(
    template.WithPageSize(document.A4),
    template.WithMargins(document.UniformEdges(document.Mm(20))),
    template.WithMetadata(document.DocumentMetadata{
        Title:  "Invoice #INV-2026-001",
        Author: "ACME Corporation",
    }),
)

page := doc.AddPage()

// Company header
page.AutoRow(func(r *template.RowBuilder) {
    r.Col(6, func(c *template.ColBuilder) {
        c.Text("ACME Corporation", template.FontSize(24), template.Bold(),
            template.TextColor(pdf.RGBHex(0x1A237E)))
        c.Text("123 Business Street")
        c.Text("San Francisco, CA 94105")
    })
    r.Col(6, func(c *template.ColBuilder) {
        c.Text("INVOICE", template.FontSize(28), template.Bold(),
            template.AlignRight(), template.TextColor(pdf.RGBHex(0x1A237E)))
        c.Text("#INV-2026-001", template.AlignRight(), template.FontSize(12))
        c.Text("Date: March 1, 2026", template.AlignRight())
    })
})

// Separator
page.AutoRow(func(r *template.RowBuilder) {
    r.Col(12, func(c *template.ColBuilder) {
        c.Spacer(document.Mm(5))
        c.Line(template.LineColor(pdf.RGBHex(0x1A237E)), template.LineThickness(document.Pt(2)))
        c.Spacer(document.Mm(5))
    })
})

// Items table
page.AutoRow(func(r *template.RowBuilder) {
    r.Col(12, func(c *template.ColBuilder) {
        c.Table(
            []string{"Description", "Qty", "Unit Price", "Amount"},
            [][]string{
                {"Web Development - Frontend", "40 hrs", "$150.00", "$6,000.00"},
                {"Web Development - Backend", "60 hrs", "$150.00", "$9,000.00"},
                {"UI/UX Design", "20 hrs", "$120.00", "$2,400.00"},
            },
            template.ColumnWidths(40, 15, 20, 25),
            template.TableHeaderStyle(
                template.TextColor(pdf.White),
                template.BgColor(pdf.RGBHex(0x1A237E)),
            ),
            template.TableStripe(pdf.RGBHex(0xF5F5F5)),
        )
    })
})

// Total
page.AutoRow(func(r *template.RowBuilder) {
    r.Col(8, func(c *template.ColBuilder) {})
    r.Col(4, func(c *template.ColBuilder) {
        c.Text("Total: $17,400.00", template.AlignRight(),
            template.Bold(), template.FontSize(14))
    })
})

data, _ := doc.Generate()
┌─ A4 ──────────────────────────────────────────────┐
│                                                   │
│  ACME Corporation              INVOICE            │
│  123 Business Street      #INV-2026-001           │
│  San Francisco, CA 94105  Date: March 1, 2026     │
│  ───────────────────────────────────────────────   │
│                                                   │
│  ┌─────────────┬────────┬───────────┬──────────┐  │
│  │ Description │  Qty   │Unit Price │  Amount  │  │
│  ├─────────────┼────────┼───────────┼──────────┤  │
│  │ Frontend    │ 40 hrs │  $150.00  │$6,000.00 │  │
│  │ Backend     │ 60 hrs │  $150.00  │$9,000.00 │  │
│  │ UI/UX       │ 20 hrs │  $120.00  │$2,400.00 │  │
│  └─────────────┴────────┴───────────┴──────────┘  │
│                                                   │
│                       Total: $17,400.00           │
│                                                   │
└───────────────────────────────────────────────────┘

Next Steps

  • Grid Layout — Master the 12-column grid system
  • Styling — Colors, text decoration, and typography
  • Elements — All available content elements