Layout
Grid Layout
The 12-column grid system supports full-width, multi-column, and asymmetric layouts.
doc := template.New(
template.WithPageSize(document.A4),
template.WithMargins(document.UniformEdges(document.Mm(15))),
)
page := doc.AddPage()
// Title
page.AutoRow(func(r *template.RowBuilder) {
r.Col(12, func(c *template.ColBuilder) {
c.Text("12-Column Grid Layout", template.FontSize(18), template.Bold())
c.Spacer(document.Mm(5))
})
})
// Full width (12 columns)
page.AutoRow(func(r *template.RowBuilder) {
r.Col(12, func(c *template.ColBuilder) {
c.Text("Col 12 (full width)", template.BgColor(pdf.RGBHex(0xE3F2FD)))
})
})
page.AutoRow(func(r *template.RowBuilder) {
r.Col(12, func(c *template.ColBuilder) {
c.Spacer(document.Mm(3))
})
})
// Two columns (6 + 6)
page.AutoRow(func(r *template.RowBuilder) {
r.Col(6, func(c *template.ColBuilder) {
c.Text("Col 6 (left)", template.BgColor(pdf.RGBHex(0xE8F5E9)))
})
r.Col(6, func(c *template.ColBuilder) {
c.Text("Col 6 (right)", template.BgColor(pdf.RGBHex(0xFFF3E0)))
})
})
page.AutoRow(func(r *template.RowBuilder) {
r.Col(12, func(c *template.ColBuilder) {
c.Spacer(document.Mm(3))
})
})
// Three columns (4 + 4 + 4)
page.AutoRow(func(r *template.RowBuilder) {
r.Col(4, func(c *template.ColBuilder) {
c.Text("Col 4", template.BgColor(pdf.RGBHex(0xFCE4EC)))
})
r.Col(4, func(c *template.ColBuilder) {
c.Text("Col 4", template.BgColor(pdf.RGBHex(0xF3E5F5)))
})
r.Col(4, func(c *template.ColBuilder) {
c.Text("Col 4", template.BgColor(pdf.RGBHex(0xE8EAF6)))
})
})
page.AutoRow(func(r *template.RowBuilder) {
r.Col(12, func(c *template.ColBuilder) {
c.Spacer(document.Mm(3))
})
})
// Four columns (3 + 3 + 3 + 3)
page.AutoRow(func(r *template.RowBuilder) {
r.Col(3, func(c *template.ColBuilder) {
c.Text("Col 3", template.BgColor(pdf.RGBHex(0xE0F7FA)))
})
r.Col(3, func(c *template.ColBuilder) {
c.Text("Col 3", template.BgColor(pdf.RGBHex(0xE0F2F1)))
})
r.Col(3, func(c *template.ColBuilder) {
c.Text("Col 3", template.BgColor(pdf.RGBHex(0xFFF9C4)))
})
r.Col(3, func(c *template.ColBuilder) {
c.Text("Col 3", template.BgColor(pdf.RGBHex(0xFFECB3)))
})
})
page.AutoRow(func(r *template.RowBuilder) {
r.Col(12, func(c *template.ColBuilder) {
c.Spacer(document.Mm(3))
})
})
// Asymmetric layout (3 + 9)
page.AutoRow(func(r *template.RowBuilder) {
r.Col(3, func(c *template.ColBuilder) {
c.Text("Sidebar (3)", template.BgColor(pdf.RGBHex(0xD7CCC8)))
})
r.Col(9, func(c *template.ColBuilder) {
c.Text("Main content (9)", template.BgColor(pdf.RGBHex(0xF5F5F5)))
})
})
page.AutoRow(func(r *template.RowBuilder) {
r.Col(12, func(c *template.ColBuilder) {
c.Spacer(document.Mm(3))
})
})
// Asymmetric layout (8 + 4)
page.AutoRow(func(r *template.RowBuilder) {
r.Col(8, func(c *template.ColBuilder) {
c.Text("Article area (8)", template.BgColor(pdf.RGBHex(0xE1F5FE)))
})
r.Col(4, func(c *template.ColBuilder) {
c.Text("Side panel (4)", template.BgColor(pdf.RGBHex(0xFBE9E7)))
})
})
page.AutoRow(func(r *template.RowBuilder) {
r.Col(12, func(c *template.ColBuilder) {
c.Spacer(document.Mm(3))
})
})
// Multiple content in columns
page.AutoRow(func(r *template.RowBuilder) {
r.Col(6, func(c *template.ColBuilder) {
c.Text("Left column - line 1")
c.Text("Left column - line 2")
c.Text("Left column - line 3")
})
r.Col(6, func(c *template.ColBuilder) {
c.Text("Right column - line 1")
c.Text("Right column - line 2")
c.Text("Right column - line 3")
})
})
Fixed-Height Rows
Use Row() with an explicit height instead of AutoRow() for fixed-height rows.
doc := template.New(
template.WithPageSize(document.A4),
template.WithMargins(document.UniformEdges(document.Mm(20))),
)
page := doc.AddPage()
page.AutoRow(func(r *template.RowBuilder) {
r.Col(12, func(c *template.ColBuilder) {
c.Text("Fixed-Height Row Examples", template.FontSize(18), template.Bold())
c.Spacer(document.Mm(5))
})
})
// Fixed height row: 30mm
page.Row(document.Mm(30), func(r *template.RowBuilder) {
r.Col(12, func(c *template.ColBuilder) {
c.Text("This row is 30mm tall", template.BgColor(pdf.RGBHex(0xE3F2FD)))
})
})
page.AutoRow(func(r *template.RowBuilder) {
r.Col(12, func(c *template.ColBuilder) {
c.Spacer(document.Mm(3))
})
})
// Fixed height row: 50mm
page.Row(document.Mm(50), func(r *template.RowBuilder) {
r.Col(6, func(c *template.ColBuilder) {
c.Text("Left: 50mm row", template.BgColor(pdf.RGBHex(0xE8F5E9)))
})
r.Col(6, func(c *template.ColBuilder) {
c.Text("Right: 50mm row", template.BgColor(pdf.RGBHex(0xFFF3E0)))
})
})
page.AutoRow(func(r *template.RowBuilder) {
r.Col(12, func(c *template.ColBuilder) {
c.Spacer(document.Mm(3))
})
})
// Auto-height row for comparison
page.AutoRow(func(r *template.RowBuilder) {
r.Col(12, func(c *template.ColBuilder) {
c.Text("This row has auto height (fits content)", template.BgColor(pdf.RGBHex(0xFCE4EC)))
})
})
Lines
Horizontal rules with customizable color and thickness.
doc := template.New(
template.WithPageSize(document.A4),
template.WithMargins(document.UniformEdges(document.Mm(20))),
)
page := doc.AddPage()
page.AutoRow(func(r *template.RowBuilder) {
r.Col(12, func(c *template.ColBuilder) {
c.Text("Line / Horizontal Rule Examples", template.FontSize(18), template.Bold())
c.Spacer(document.Mm(5))
})
})
// Default line
page.AutoRow(func(r *template.RowBuilder) {
r.Col(12, func(c *template.ColBuilder) {
c.Text("Default line (gray, 1pt):")
c.Line()
c.Spacer(document.Mm(5))
})
})
// Colored lines
page.AutoRow(func(r *template.RowBuilder) {
r.Col(12, func(c *template.ColBuilder) {
c.Text("Red line:")
c.Line(template.LineColor(pdf.Red))
c.Spacer(document.Mm(3))
c.Text("Blue line:")
c.Line(template.LineColor(pdf.Blue))
c.Spacer(document.Mm(3))
c.Text("Green line:")
c.Line(template.LineColor(pdf.Green))
c.Spacer(document.Mm(5))
})
})
// Thick lines
page.AutoRow(func(r *template.RowBuilder) {
r.Col(12, func(c *template.ColBuilder) {
c.Text("Thin line (0.5pt):")
c.Line(template.LineThickness(document.Pt(0.5)))
c.Spacer(document.Mm(3))
c.Text("Medium line (2pt):")
c.Line(template.LineThickness(document.Pt(2)))
c.Spacer(document.Mm(3))
c.Text("Thick line (5pt):")
c.Line(template.LineThickness(document.Pt(5)))
c.Spacer(document.Mm(5))
})
})
// Combined: color + thickness
page.AutoRow(func(r *template.RowBuilder) {
r.Col(12, func(c *template.ColBuilder) {
c.Text("Thick red line (3pt):")
c.Line(template.LineColor(pdf.Red), template.LineThickness(document.Pt(3)))
c.Spacer(document.Mm(3))
c.Text("Thick blue line (4pt):")
c.Line(template.LineColor(pdf.Blue), template.LineThickness(document.Pt(4)))
})
})
Spacers
Add vertical spacing between elements.
doc := template.New(
template.WithPageSize(document.A4),
template.WithMargins(document.UniformEdges(document.Mm(20))),
)
page := doc.AddPage()
page.AutoRow(func(r *template.RowBuilder) {
r.Col(12, func(c *template.ColBuilder) {
c.Text("Spacer Examples", template.FontSize(18), template.Bold())
})
})
page.AutoRow(func(r *template.RowBuilder) {
r.Col(12, func(c *template.ColBuilder) {
c.Text("Text before 5mm spacer")
c.Spacer(document.Mm(5))
c.Text("Text after 5mm spacer")
})
})
page.AutoRow(func(r *template.RowBuilder) {
r.Col(12, func(c *template.ColBuilder) {
c.Text("Text before 15mm spacer")
c.Spacer(document.Mm(15))
c.Text("Text after 15mm spacer")
})
})
page.AutoRow(func(r *template.RowBuilder) {
r.Col(12, func(c *template.ColBuilder) {
c.Text("Text before 30mm spacer")
c.Spacer(document.Mm(30))
c.Text("Text after 30mm spacer")
})
})
Page Sizes
Supports A4, A3, Letter, Legal, and custom sizes.
sizes := []struct {
name string
size document.Size
file string
}{
{"A4 (210mm x 297mm)", document.A4, "15a_pagesize_a4.pdf"},
{"A3 (297mm x 420mm)", document.A3, "15b_pagesize_a3.pdf"},
{"Letter (8.5in x 11in)", document.Letter, "15c_pagesize_letter.pdf"},
{"Legal (8.5in x 14in)", document.Legal, "15d_pagesize_legal.pdf"},
}
for _, s := range sizes {
doc := template.New(
template.WithPageSize(s.size),
template.WithMargins(document.UniformEdges(document.Mm(20))),
)
page := doc.AddPage()
page.AutoRow(func(r *template.RowBuilder) {
r.Col(12, func(c *template.ColBuilder) {
c.Text("Page Size: "+s.name, template.FontSize(20), template.Bold())
c.Spacer(document.Mm(10))
c.Text("This page demonstrates the " + s.name + " page format.")
})
})
}
Margins
Custom asymmetric margins for book-style layouts.
doc := template.New(
template.WithPageSize(document.A4),
template.WithMargins(document.Edges{
Top: document.Mm(10),
Right: document.Mm(40),
Bottom: document.Mm(10),
Left: document.Mm(40),
}),
)
page := doc.AddPage()
page.AutoRow(func(r *template.RowBuilder) {
r.Col(12, func(c *template.ColBuilder) {
c.Text("Custom Margins", template.FontSize(18), template.Bold())
c.Spacer(document.Mm(5))
c.Text("This page has asymmetric margins: 10mm top/bottom, 40mm left/right. " +
"The wide side margins create a narrower text area, similar to a book layout.")
c.Spacer(document.Mm(5))
c.Line()
c.Spacer(document.Mm(5))
c.Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit. " +
"Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. " +
"Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris.")
})
})
Absolute Positioning
Place elements at exact XY coordinates on the page, independent of the grid flow. Useful for watermarks, stamps, overlays, and fixed-position elements.
doc := template.New(
template.WithPageSize(document.A4),
template.WithMargins(document.UniformEdges(document.Mm(20))),
template.WithMetadata(document.Metadata{Title: "Absolute Positioning"}),
)
page := doc.AddPage()
// Normal flow content
page.AutoRow(func(r *template.RowBuilder) {
r.Col(12, func(c *template.ColBuilder) {
c.Text("Absolute Positioning Example", template.FontSize(18), template.Bold())
c.Spacer(document.Mm(5))
c.Text("This document demonstrates absolute positioning. Elements below are placed at exact XY coordinates.")
})
})
// Absolute: CONFIDENTIAL stamp
page.Absolute(document.Mm(120), document.Mm(20), func(c *template.ColBuilder) {
c.Text("CONFIDENTIAL", template.FontSize(20), template.Bold(), template.TextColor(pdf.Red))
})
// Absolute: DRAFT watermark using page origin
page.Absolute(document.Mm(30), document.Mm(140), func(c *template.ColBuilder) {
c.Text("DRAFT", template.FontSize(60), template.Bold(),
template.TextColor(pdf.RGBHex(0xCCCCCC)))
}, gpdf.AbsoluteOriginPage())
// Absolute: QR code at bottom
page.Absolute(document.Mm(0), document.Mm(220), func(c *template.ColBuilder) {
c.QRCode("https://gpdf.dev", template.QRSize(document.Mm(20)))
}, gpdf.AbsoluteWidth(document.Mm(25)), gpdf.AbsoluteHeight(document.Mm(25)))