htmlpdf

package module
v0.0.0-...-ec46ea1 Latest Latest
Warning

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

Go to latest
Published: Feb 18, 2026 License: Apache-2.0 Imports: 22 Imported by: 0

README

go-html-pdf

Go library (package htmlpdf) with two complementary PDF capabilities under a single import:

Capability What it does
HTML + CSS → PDF Converts modern HTML5/CSS3 to PDF via headless Chrome (CDP)
PDF → text Extracts plain text from PDF files — pure Go, no external deps
go get github.com/porticus-lab/go-html-pdf
import htmlpdf "github.com/porticus-lab/go-html-pdf"

Requirements: Go 1.24+. Chrome/Chromium in PATH for the HTML→PDF side (or use WithAutoDownload()). No requirements for the PDF→text side.


HTML + CSS to PDF

The library renders HTML through a headless Chrome instance via the Chrome DevTools Protocol. Every CSS feature your browser supports works out of the box — flexbox, grid, custom properties, @media print, web fonts, gradients.

Quick Start
package main

import (
    "context"
    "log"

    htmlpdf "github.com/porticus-lab/go-html-pdf"
)

func main() {
    c, err := htmlpdf.NewConverter()
    if err != nil {
        log.Fatal(err)
    }
    defer c.Close()

    html := `<!DOCTYPE html>
<html>
<head><style>
  body { font-family: system-ui, sans-serif; padding: 2rem; }
  h1   { color: #1e40af; }
</style></head>
<body><h1>Hello, PDF!</h1></body>
</html>`

    res, err := c.ConvertHTML(context.Background(), html, nil)
    if err != nil {
        log.Fatal(err)
    }
    res.WriteToFile("hello.pdf", 0o644)
}

Pass nil as page config to get defaults: A4, portrait, 1 cm margins, scale 1.0, backgrounds on.

Input Sources
res, err := c.ConvertHTML(ctx, "<h1>Hello</h1>", page)
res, err  = c.ConvertFile(ctx, "report.html", page)
res, err  = c.ConvertURL(ctx, "https://example.com", page)
Page Configuration
page := &htmlpdf.PageConfig{
    Size:            htmlpdf.Letter,
    Orientation:     htmlpdf.Landscape,
    Margin:          htmlpdf.Margin{Top: 2, Right: 2.5, Bottom: 2, Left: 2.5},
    Scale:           0.9,
    PrintBackground: true,
}
Available page sizes
Name Dimensions (cm)
A3 29.7 × 42.0
A4 21.0 × 29.7
A5 14.8 × 21.0
Letter 21.59 × 27.94
Legal 21.59 × 35.56
Tabloid 27.94 × 43.18
PageConfig fields
Field Type Default Description
Size PageSize A4 Paper dimensions
Orientation Orientation Portrait Portrait or Landscape
Margin Margin 1 cm all Top/Right/Bottom/Left in centimetres
Scale float64 1.0 Content scale (0.1–2.0)
PrintBackground bool true Include background colors/images
DisplayHeaderFooter bool false Enable header/footer templates
HeaderTemplate string "" HTML header template
FooterTemplate string "" HTML footer template
PreferCSSPageSize bool false Honor CSS @page size
Converter Options
c, err := htmlpdf.NewConverter(
    htmlpdf.WithTimeout(60 * time.Second),      // default: 30s
    htmlpdf.WithChromePath("/usr/bin/chromium"), // custom browser path
    htmlpdf.WithNoSandbox(),                    // required in Docker / root
    htmlpdf.WithAutoDownload(),                 // auto-download Chromium
)

WithAutoDownload() caches Chromium in ~/.cache/rod/browser (Unix) or %APPDATA%\rod\browser (Windows). First run: 10–30 s; subsequent: ~1 ms overhead. Ignored when WithChromePath is set.

One-off Conversions
// No need to create a Converter explicitly
res, err := htmlpdf.ConvertHTML(ctx, html, page, htmlpdf.WithNoSandbox())
res, err  = htmlpdf.ConvertURL(ctx, "https://example.com", page)
res, err  = htmlpdf.ConvertFile(ctx, "report.html", page)

For repeated conversions prefer NewConverter — it reuses the browser process and is significantly faster.

Headers and Footers
page := &htmlpdf.PageConfig{
    DisplayHeaderFooter: true,
    HeaderTemplate: `<div style="font-size:10px;text-align:center;width:100%">
        <span class="title"></span></div>`,
    FooterTemplate: `<div style="font-size:10px;text-align:center;width:100%">
        Page <span class="pageNumber"></span> of <span class="totalPages"></span></div>`,
}

Available template classes: date, title, url, pageNumber, totalPages.

Result Object
res.Bytes()                       // []byte
res.Base64()                      // string (RFC 4648)
res.Reader()                      // *bytes.Reader — io.Reader + io.Seeker
res.WriteTo(w)                    // io.WriterTo
res.WriteToFile("out.pdf", 0o644)
res.Len()                         // int
Cloud Storage Upload
// GCP Cloud Storage
w := client.Bucket(bucket).Object(object).NewWriter(ctx)
w.ContentType = "application/pdf"
res.WriteTo(w); w.Close()

// AWS S3
client.PutObject(ctx, &s3.PutObjectInput{
    Bucket: &bucket, Key: &key,
    Body: res.Reader(), ContentType: aws.String("application/pdf"),
})

// JSON API
json.NewEncoder(w).Encode(map[string]string{"pdf": res.Base64()})
Running in Docker

Chrome requires --no-sandbox inside containers. Always pair WithNoSandbox() with any Docker deployment:

c, err := htmlpdf.NewConverter(htmlpdf.WithNoSandbox())

You can install Chromium in the image or let the library download it automatically:

c, err := htmlpdf.NewConverter(
    htmlpdf.WithAutoDownload(),
    htmlpdf.WithNoSandbox(),
)
Option A — Auto-download (smallest image, fastest to set up)

No need to install Chromium in the image. The library downloads it on first run and caches it in ~/.cache/rod/browser. Only the shared libraries Chrome needs at runtime are required:

FROM golang:1.24-alpine AS builder

WORKDIR /app
COPY go.* ./
RUN go mod download
COPY . ./
RUN go build -o server

FROM alpine:latest

# Runtime shared libraries for headless Chromium (no browser package needed)
RUN apk add --no-cache \
    nss atk at-spi2-core cups-libs libdrm \
    libxcomposite libxdamage libxrandr mesa-gbm pango \
    cairo alsa-lib libxshmfence font-noto

COPY --from=builder /app/server /app/server
CMD ["/app/server"]
c, err := htmlpdf.NewConverter(
    htmlpdf.WithAutoDownload(),
    htmlpdf.WithNoSandbox(),
)
Option B — System Chromium (larger image, no first-run download)
FROM golang:1.24-alpine AS builder

WORKDIR /app
COPY go.* ./
RUN go mod download
COPY . ./
RUN go build -o server

FROM alpine:latest

RUN apk add --no-cache chromium

COPY --from=builder /app/server /app/server
CMD ["/app/server"]
c, err := htmlpdf.NewConverter(
    htmlpdf.WithChromePath("/usr/bin/chromium-browser"),
    htmlpdf.WithNoSandbox(),
)

PDF to Text

Pure-Go PDF text extraction. Go port of zpdf — no CGo, no external dependencies.

Quick Start
doc, err := htmlpdf.Open("document.pdf")
if err != nil {
    log.Fatal(err)
}

ext := htmlpdf.NewExtractor(doc)
pages, err := ext.ExtractAll()
for i, text := range pages {
    fmt.Printf("=== Page %d ===\n%s\n", i+1, text)
}
Opening Documents
doc, err := htmlpdf.Open("report.pdf")        // from disk
doc, err  = htmlpdf.Load(data)               // from []byte (embed.FS, HTTP body, …)
Text Extraction
ext := htmlpdf.NewExtractor(doc)

pages, err := ext.ExtractAll()              // []string — one per page
text, err  := ext.ExtractPage(0)           // single page, 0-indexed
text, err  = ext.ExtractPageDict(pageDict) // from a Dict directly

How extraction works:

  1. Font resources are resolved and encoding tables built per page.
  2. Content streams are decompressed and parsed.
  3. Text operators (Tj, TJ, ', ") emit positioned spans.
  4. Spans are grouped into lines by Y coordinate (±50 % of average font size).
  5. Lines sorted top-to-bottom; spans left-to-right; spaces inserted when gap > 30 % of font size.
Document API
doc.Version()                  // string — e.g. "1.7"
doc.Pages()                    // ([]Dict, error)
doc.GetPageInfo(page)          // PageInfo{Width, Height float64; Rotation int}
doc.ContentStreams(page)       // ([]byte, error) — decompressed content
doc.PageFonts(page)            // (map[string]*Object, error)
doc.Catalog()                  // (Dict, error)
doc.ResolveRef(ref Reference)  // (*Object, error)
doc.Resolve(obj *Object)       // (*Object, error)

PageInfo: Width and Height in points (1 pt = 1/72 inch), Rotation in degrees (0, 90, 180, 270).

Decompression
raw, err := htmlpdf.DecompressStream(streamObj.Dict, streamObj.Stream)
Filter Aliases Notes
FlateDecode Fl zlib + PNG predictors + TIFF predictor
ASCII85Decode A85
ASCIIHexDecode AHx
LZWDecode LZW MSB-first, litWidth=8
RunLengthDecode RL PackBits
DCTDecode, CCITTFaxDecode, JBIG2Decode, JPXDecode, Crypt Passed through as-is

256 MB limit on decompressed output (DoS guard).

Font Encoding
enc := htmlpdf.NewFontEncoding(fontObj)
text := enc.Decode(rawBytes)

Decoding priority: ToUnicode CMap > Encoding dict > Named encoding > Default.

Named encodings: WinAnsiEncoding, MacRomanEncoding, StandardEncoding, PDFDocEncoding. /Differences resolved via Adobe Glyph List (~300 glyph names). CID/Type0 fonts use multi-byte CMap lookup.

Low-level Object Model
p := htmlpdf.NewParser(data, 0)
obj, err := p.ParseObject()
p.Pos(); p.SetPos(n)
Type Description
Object Tagged union for any PDF object
ObjectType ObjNull, ObjBool, ObjInt, ObjFloat, ObjString, ObjName, ObjArray, ObjDict, ObjStream, ObjRef
Reference {Number int, Gen int}
Dict map[string]*Object — helpers: GetInt, GetName, GetArray, GetDict
PageInfo {Width, Height float64; Rotation int}

Chrome Dependencies

The HTML→PDF side launches a headless Chromium process. Chromium needs several system libraries that are absent in minimal base images. The PDF→text side has no system dependencies — it uses only the Go standard library.

Alpine Linux
# Shared libraries only (use with WithAutoDownload)
apk add --no-cache \
    nss atk at-spi2-core cups-libs libdrm \
    libxcomposite libxdamage libxrandr mesa-gbm pango \
    cairo alsa-lib libxshmfence font-noto

# Or install the full browser package (pulls all deps automatically)
apk add --no-cache chromium
Debian / Ubuntu
# Shared libraries only (use with WithAutoDownload)
apt-get install -y --no-install-recommends \
    libnss3 libatk1.0-0 libatk-bridge2.0-0 libcups2 libdrm2 \
    libxcomposite1 libxdamage1 libxrandr2 libgbm1 libpango-1.0-0 \
    libcairo2 libasound2 libxshmfence1 fonts-noto

# Or install the full browser package
apt-get install -y --no-install-recommends chromium
macOS

No extra steps. Chrome/Chromium from the standard .app install is found automatically, or use WithAutoDownload().

Windows

No extra steps. Chrome is found via standard registry paths, or use WithAutoDownload().

Tip: WithAutoDownload() is the easiest cross-platform option — it downloads a pinned Chromium build the first time and reuses it on every subsequent run (~1 ms overhead).


Architecture

├── doc.go            # Package documentation
├── page.go           # PageSize, Orientation, Margin, PageConfig
├── options.go        # Functional options (WithTimeout, WithChromePath, …)
├── errors.go         # Sentinel errors (ErrClosed)
├── result.go         # Result type (Bytes, Base64, Reader, WriteTo, WriteToFile)
├── browser.go        # Chromium auto-download via go-rod/rod/lib/launcher
├── converter.go      # Converter + package-level convenience functions
│
├── parser.go         # Recursive-descent PDF object parser
├── document.go       # Document loading, XRef, page tree, object resolution
├── decompress.go     # Stream filters: FlateDecode, ASCII85, LZW, RunLength
├── encoding.go       # Font encoding tables + ToUnicode CMap parser
└── extractor.go      # Content-stream text extraction + line assembly
Dependencies
Package License Purpose
chromedp/chromedp MIT Headless Chrome driver
chromedp/cdproto MIT Chrome DevTools Protocol types
go-rod/rod MIT Chromium auto-download

The PDF→text side uses only the Go standard library.

License

Apache 2.0 — see LICENSE.

Documentation

Overview

Package htmlpdf provides two complementary PDF capabilities under a single import:

  • HTML + CSS → PDF conversion via headless Chrome (Chrome DevTools Protocol)
  • PDF → plain-text extraction, pure Go, no external dependencies

HTML to PDF

For one-off conversions use the package-level helpers:

res, err := htmlpdf.ConvertHTML(ctx, "<h1>Hello</h1>", nil)

For repeated conversions create a Converter, which reuses the browser process:

c, err := htmlpdf.NewConverter()
if err != nil {
    log.Fatal(err)
}
defer c.Close()

res, err := c.ConvertHTML(ctx, "<h1>Hello</h1>", nil)
res, err  = c.ConvertURL(ctx, "https://example.com", nil)
res, err  = c.ConvertFile(ctx, "report.html", nil)

Use PageConfig to control paper size, orientation, margins, and scale:

page := &htmlpdf.PageConfig{
    Size:        htmlpdf.A4,
    Orientation: htmlpdf.Landscape,
    Margin:      htmlpdf.UniformMargin(2.0),
}
res, err := c.ConvertHTML(ctx, html, page)

A Result gives flexible access to the generated PDF bytes:

res.Bytes()                       // []byte
res.Base64()                      // base64 string (RFC 4648)
res.Reader()                      // *bytes.Reader
res.WriteTo(w)                    // io.WriterTo
res.WriteToFile("out.pdf", 0o644) // write to disk

Chrome or Chromium must be available in PATH, or use WithAutoDownload:

c, err := htmlpdf.NewConverter(htmlpdf.WithAutoDownload())

PDF to Text

Open a PDF from disk or raw bytes:

doc, err := htmlpdf.Open("document.pdf")
doc, err  = htmlpdf.Load(data) // from []byte

Extract text page by page:

ext := htmlpdf.NewExtractor(doc)

pages, err := ext.ExtractAll()     // []string, one per page
text, err  := ext.ExtractPage(0)   // single page, 0-indexed

Access low-level page metadata:

pages, err := doc.Pages()
info := doc.GetPageInfo(pages[0]) // PageInfo{Width, Height, Rotation}
Example
package main

import (
	"context"
	"fmt"
	"log"

	htmlpdf "github.com/porticus-lab/go-html-pdf"
)

func main() {
	// Create a converter (reuses the browser across conversions).
	c, err := htmlpdf.NewConverter(htmlpdf.WithNoSandbox())
	if err != nil {
		log.Fatal(err)
	}
	defer c.Close()

	// Convert HTML to PDF with default page settings (A4, portrait).
	res, err := c.ConvertHTML(context.Background(), "<h1>Hello World</h1>", nil)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("Generated PDF: %d bytes\n", res.Len())
}
Example (ModernCSS)
package main

import (
	"context"
	"fmt"
	"log"

	htmlpdf "github.com/porticus-lab/go-html-pdf"
)

func main() {
	c, err := htmlpdf.NewConverter(htmlpdf.WithNoSandbox())
	if err != nil {
		log.Fatal(err)
	}
	defer c.Close()

	html := `<!DOCTYPE html>
<html>
<head><style>
  :root { --accent: #6366f1; }
  body { font-family: system-ui; padding: 2rem; }
  .grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 1rem;
  }
  .card {
    background: linear-gradient(135deg, var(--accent), #8b5cf6);
    color: white;
    padding: 1.5rem;
    border-radius: 12px;
  }
</style></head>
<body>
  <h1>CSS Grid + Gradients</h1>
  <div class="grid">
    <div class="card"><h3>One</h3></div>
    <div class="card"><h3>Two</h3></div>
    <div class="card"><h3>Three</h3></div>
  </div>
</body>
</html>`

	res, err := c.ConvertHTML(context.Background(), html, &htmlpdf.PageConfig{
		PrintBackground: true,
	})
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("Modern CSS PDF: %d bytes\n", res.Len())
}
Example (ResultOutputFormats)
package main

import (
	"context"
	"fmt"
	"log"

	htmlpdf "github.com/porticus-lab/go-html-pdf"
)

func main() {
	c, err := htmlpdf.NewConverter(htmlpdf.WithNoSandbox())
	if err != nil {
		log.Fatal(err)
	}
	defer c.Close()

	res, err := c.ConvertHTML(context.Background(), "<h1>Output formats</h1>", nil)
	if err != nil {
		log.Fatal(err)
	}

	// Raw bytes — for any io.Writer or low-level use.
	_ = res.Bytes()

	// Base64 string — for JSON APIs or services that accept base64.
	_ = res.Base64()

	// io.Reader — for streaming uploads (GCP Cloud Storage, AWS S3, etc.).
	_ = res.Reader()

	// Write directly to a file.
	_ = res.WriteToFile("/tmp/output.pdf", 0o644)

	// io.WriterTo — write to any io.Writer.
	// res.WriteTo(w)

	fmt.Printf("PDF ready: %d bytes\n", res.Len())
}
Example (WithPageConfig)
package main

import (
	"context"
	"fmt"
	"log"
	"time"

	htmlpdf "github.com/porticus-lab/go-html-pdf"
)

func main() {
	c, err := htmlpdf.NewConverter(
		htmlpdf.WithTimeout(60*time.Second),
		htmlpdf.WithNoSandbox(),
	)
	if err != nil {
		log.Fatal(err)
	}
	defer c.Close()

	page := &htmlpdf.PageConfig{
		Size:            htmlpdf.Letter,
		Orientation:     htmlpdf.Landscape,
		Margin:          htmlpdf.Margin{Top: 2, Right: 2.5, Bottom: 2, Left: 2.5},
		Scale:           1.0,
		PrintBackground: true,
	}

	html := `<!DOCTYPE html>
<html><body>
  <h1 style="color: navy;">Landscape Report</h1>
  <p>This PDF uses Letter size in landscape orientation.</p>
</body></html>`

	res, err := c.ConvertHTML(context.Background(), html, page)
	if err != nil {
		log.Fatal(err)
	}

	if err := res.WriteToFile("/tmp/report.pdf", 0o644); err != nil {
		log.Fatal(err)
	}
	fmt.Println("PDF saved to /tmp/report.pdf")
}

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	A3      = PageSize{Width: 29.7, Height: 42.0}
	A4      = PageSize{Width: 21.0, Height: 29.7}
	A5      = PageSize{Width: 14.8, Height: 21.0}
	Letter  = PageSize{Width: 21.59, Height: 27.94}
	Legal   = PageSize{Width: 21.59, Height: 35.56}
	Tabloid = PageSize{Width: 27.94, Height: 43.18}
)

Standard paper sizes.

View Source
var (
	// ErrClosed is returned when attempting to use a closed [Converter].
	ErrClosed = errors.New("htmlpdf: converter is closed")
)

Sentinel errors returned by the library.

Functions

func DecompressStream

func DecompressStream(dict Dict, data []byte) ([]byte, error)

DecompressStream decompresses a PDF stream given its dictionary and raw bytes. It handles filter chains (multiple filters applied in sequence).

Types

type Converter

type Converter struct {
	// contains filtered or unexported fields
}

Converter converts HTML content to PDF documents.

A Converter manages a headless browser instance that is reused across multiple conversions for performance. It is safe for concurrent use.

Call Converter.Close when the Converter is no longer needed to release browser resources.

func NewConverter

func NewConverter(opts ...Option) (*Converter, error)

NewConverter creates a Converter with the given options.

It starts a headless browser in the background. The caller must call Converter.Close when finished.

func (*Converter) Close

func (c *Converter) Close() error

Close releases all resources held by the Converter, including the browser process. Close is idempotent.

func (*Converter) ConvertFile

func (c *Converter) ConvertFile(ctx context.Context, path string, pg *PageConfig) (*Result, error)

ConvertFile converts a local HTML file to a PDF document. If page is nil, DefaultPageConfig values are used.

func (*Converter) ConvertHTML

func (c *Converter) ConvertHTML(ctx context.Context, html string, pg *PageConfig) (*Result, error)

ConvertHTML converts an HTML string to a PDF document. If page is nil, DefaultPageConfig values are used.

func (*Converter) ConvertURL

func (c *Converter) ConvertURL(ctx context.Context, rawURL string, pg *PageConfig) (*Result, error)

ConvertURL converts the web page at rawURL to a PDF document. If page is nil, DefaultPageConfig values are used.

type Dict

type Dict map[string]*Object

Dict is a PDF dictionary (name -> object).

func (Dict) GetArray

func (d Dict) GetArray(key string) ([]*Object, bool)

GetArray returns the array value of a Dict entry.

func (Dict) GetDict

func (d Dict) GetDict(key string) (Dict, bool)

GetDict returns the dict value of a Dict entry.

func (Dict) GetInt

func (d Dict) GetInt(key string) (int64, bool)

GetInt returns the integer value of a Dict entry.

func (Dict) GetName

func (d Dict) GetName(key string) (string, bool)

GetName returns the name value of a Dict entry.

type Document

type Document struct {
	// contains filtered or unexported fields
}

Document represents a loaded PDF file.

func Load

func Load(data []byte) (*Document, error)

Load parses a PDF from raw bytes.

func Open

func Open(path string) (*Document, error)

Open reads a PDF file from disk.

func (*Document) Catalog

func (doc *Document) Catalog() (Dict, error)

Catalog returns the document catalog dictionary.

func (*Document) ContentStreams

func (doc *Document) ContentStreams(page Dict) ([]byte, error)

ContentStreams returns the combined decompressed content stream data for a page.

func (*Document) GetPageInfo

func (doc *Document) GetPageInfo(page Dict) PageInfo

GetPageInfo extracts dimensions and rotation for a page.

func (*Document) PageFonts

func (doc *Document) PageFonts(page Dict) (map[string]*Object, error)

PageFonts returns the font resource objects for a page.

func (*Document) Pages

func (doc *Document) Pages() ([]Dict, error)

Pages returns all page dictionaries in order.

func (*Document) Resolve

func (doc *Document) Resolve(obj *Object) (*Object, error)

Resolve returns the object, following any indirect reference.

func (*Document) ResolveRef

func (doc *Document) ResolveRef(ref Reference) (*Object, error)

ResolveRef follows an indirect reference and returns the pointed-to object.

func (*Document) Version

func (doc *Document) Version() string

Version returns the PDF version string (e.g. "1.7").

type Extractor

type Extractor struct {
	// contains filtered or unexported fields
}

Extractor extracts plain text from PDF pages.

func NewExtractor

func NewExtractor(doc *Document) *Extractor

NewExtractor creates a text extractor for the given document.

func (*Extractor) ExtractAll

func (e *Extractor) ExtractAll() ([]string, error)

ExtractAll returns the plain text for all pages, one page per element.

func (*Extractor) ExtractPage

func (e *Extractor) ExtractPage(pageIndex int) (string, error)

ExtractPage returns the plain text for a single page (0-indexed).

func (*Extractor) ExtractPageDict

func (e *Extractor) ExtractPageDict(page Dict) (string, error)

ExtractPageDict extracts text from a page dictionary.

type FontEncoding

type FontEncoding struct {
	// contains filtered or unexported fields
}

FontEncoding decodes PDF glyph codes to Unicode strings. Priority (highest to lowest): ToUnicode CMap > Encoding dict > Built-in tables.

func NewFontEncoding

func NewFontEncoding(fontObj *Object) *FontEncoding

NewFontEncoding builds a FontEncoding from a PDF font object.

func (*FontEncoding) Decode

func (e *FontEncoding) Decode(data []byte) string

Decode converts a byte sequence from a PDF text string to a UTF-8 string.

type Margin

type Margin struct {
	Top    float64
	Right  float64
	Bottom float64
	Left   float64
}

Margin represents page margins in centimeters.

func UniformMargin

func UniformMargin(cm float64) Margin

UniformMargin returns a Margin with the same value on all sides.

type Object

type Object struct {
	Type   ObjectType
	Bool   bool
	Int    int64
	Float  float64
	Str    []byte
	Name   string
	Array  []*Object
	Dict   Dict
	Stream []byte // raw stream data
	Ref    Reference
}

Object holds any PDF object value.

type ObjectType

type ObjectType int

ObjectType identifies the kind of a PDF object.

const (
	ObjNull ObjectType = iota
	ObjBool
	ObjInt
	ObjFloat
	ObjString
	ObjName
	ObjArray
	ObjDict
	ObjStream
	ObjRef
)

type Option

type Option func(*converterConfig)

Option configures a Converter.

func WithAutoDownload

func WithAutoDownload() Option

WithAutoDownload enables automatic download of a compatible Chromium binary when no browser is found in the system PATH. The binary is cached in ~/.cache/rod/browser (Unix) or %APPDATA%\rod\browser (Windows) and reused on subsequent calls. The first invocation may take 10–30 s depending on network speed; subsequent calls add only ~1 ms to check the cache.

This option is ignored when WithChromePath is also set.

func WithChromePath

func WithChromePath(path string) Option

WithChromePath sets the path to the Chrome or Chromium executable. By default the library searches standard locations automatically.

func WithNoSandbox

func WithNoSandbox() Option

WithNoSandbox disables the Chrome sandbox. This is required when running as root, for example inside Docker containers.

func WithTimeout

func WithTimeout(d time.Duration) Option

WithTimeout sets the maximum duration for a single conversion. Defaults to 30 seconds. A zero or negative value disables the timeout.

type Orientation

type Orientation int

Orientation represents the page orientation.

const (
	// Portrait is the default vertical orientation.
	Portrait Orientation = iota
	// Landscape rotates the page to horizontal orientation.
	Landscape
)

type PageConfig

type PageConfig struct {
	// Size specifies the paper size. Defaults to A4.
	Size PageSize

	// Orientation specifies portrait or landscape. Defaults to Portrait.
	Orientation Orientation

	// Margin specifies page margins in centimeters. Defaults to 1 cm on all sides.
	Margin Margin

	// Scale of the webpage rendering. Must be between 0.1 and 2.0. Defaults to 1.0.
	Scale float64

	// PrintBackground enables printing of background colors and images.
	// Defaults to true.
	PrintBackground bool

	// DisplayHeaderFooter enables the header and footer templates.
	DisplayHeaderFooter bool

	// HeaderTemplate is an HTML template for the print header.
	// It uses the same format as Chrome's print header template, supporting
	// the classes: date, title, url, pageNumber, totalPages.
	HeaderTemplate string

	// FooterTemplate is an HTML template for the print footer.
	// It uses the same format as Chrome's print footer template.
	FooterTemplate string

	// PreferCSSPageSize gives precedence to any CSS @page size declared
	// in the document over the Size field.
	PreferCSSPageSize bool
}

PageConfig controls the PDF output parameters.

A nil PageConfig or zero-value fields will use sensible defaults: A4 paper, portrait orientation, 1 cm margins, scale 1.0, with background graphics enabled.

func DefaultPageConfig

func DefaultPageConfig() PageConfig

DefaultPageConfig returns a PageConfig with sensible defaults.

type PageInfo

type PageInfo struct {
	Width    float64
	Height   float64
	Rotation int
}

PageInfo holds metadata about a single page.

type PageSize

type PageSize struct {
	Width  float64 // Width in centimeters.
	Height float64 // Height in centimeters.
}

PageSize represents paper dimensions in centimeters.

type Parser

type Parser struct {
	// contains filtered or unexported fields
}

Parser is a recursive-descent PDF object parser.

func NewParser

func NewParser(data []byte, pos int) *Parser

NewParser creates a parser for the given data at the given start position.

func (*Parser) ParseObject

func (p *Parser) ParseObject() (*Object, error)

ParseObject parses one PDF object at the current position.

func (*Parser) Pos

func (p *Parser) Pos() int

Pos returns the current parse position.

func (*Parser) SetPos

func (p *Parser) SetPos(pos int)

SetPos moves the parse position.

type Reference

type Reference struct {
	Number int
	Gen    int
}

Reference is an indirect object reference (N G R).

type Result

type Result struct {
	// contains filtered or unexported fields
}

Result holds a generated PDF and provides helpers for common output formats such as raw bytes, base64 encoding, and streaming readers.

A Result is returned by every conversion method. It is safe to call its methods multiple times — the underlying data is never modified.

func ConvertFile

func ConvertFile(ctx context.Context, path string, pg *PageConfig, opts ...Option) (*Result, error)

ConvertFile converts a local HTML file to PDF using a temporary Converter.

func ConvertHTML

func ConvertHTML(ctx context.Context, html string, pg *PageConfig, opts ...Option) (*Result, error)

ConvertHTML converts an HTML string to PDF using a temporary Converter. This is convenient for one-off conversions. For repeated use, create a Converter with NewConverter to reuse the browser instance.

func ConvertURL

func ConvertURL(ctx context.Context, rawURL string, pg *PageConfig, opts ...Option) (*Result, error)

ConvertURL converts a web page to PDF using a temporary Converter.

func (*Result) Base64

func (r *Result) Base64() string

Base64 returns the PDF encoded as a standard base64 string (RFC 4648). This is useful for embedding in JSON payloads or uploading to services that accept base64-encoded content.

func (*Result) Bytes

func (r *Result) Bytes() []byte

Bytes returns the raw PDF content.

func (*Result) Len

func (r *Result) Len() int

Len returns the size of the PDF in bytes.

func (*Result) Reader

func (r *Result) Reader() *bytes.Reader

Reader returns an *bytes.Reader over the PDF content. This is suitable for streaming uploads to cloud storage (GCP, AWS S3, etc.) or any API that accepts an io.Reader.

func (*Result) WriteTo

func (r *Result) WriteTo(w io.Writer) (int64, error)

WriteTo writes the full PDF content to w. It implements io.WriterTo.

func (*Result) WriteToFile

func (r *Result) WriteToFile(path string, perm os.FileMode) error

WriteToFile writes the PDF to the file at path, creating it if needed.

type XRefEntry

type XRefEntry struct {
	Offset     int64
	Generation int
	InUse      bool
	// For compressed objects (PDF 1.5+)
	Compressed  bool
	StreamObjID int
	IndexInStrm int
}

XRefEntry describes one entry in the cross-reference table.

Jump to

Keyboard shortcuts

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