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())
}
Output:
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())
}
Output:
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())
}
Output:
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")
}
Output:
Index ¶
- Variables
- func DecompressStream(dict Dict, data []byte) ([]byte, error)
- type Converter
- func (c *Converter) Close() error
- func (c *Converter) ConvertFile(ctx context.Context, path string, pg *PageConfig) (*Result, error)
- func (c *Converter) ConvertHTML(ctx context.Context, html string, pg *PageConfig) (*Result, error)
- func (c *Converter) ConvertURL(ctx context.Context, rawURL string, pg *PageConfig) (*Result, error)
- type Dict
- type Document
- func (doc *Document) Catalog() (Dict, error)
- func (doc *Document) ContentStreams(page Dict) ([]byte, error)
- func (doc *Document) GetPageInfo(page Dict) PageInfo
- func (doc *Document) PageFonts(page Dict) (map[string]*Object, error)
- func (doc *Document) Pages() ([]Dict, error)
- func (doc *Document) Resolve(obj *Object) (*Object, error)
- func (doc *Document) ResolveRef(ref Reference) (*Object, error)
- func (doc *Document) Version() string
- type Extractor
- type FontEncoding
- type Margin
- type Object
- type ObjectType
- type Option
- type Orientation
- type PageConfig
- type PageInfo
- type PageSize
- type Parser
- type Reference
- type Result
- func ConvertFile(ctx context.Context, path string, pg *PageConfig, opts ...Option) (*Result, error)
- func ConvertHTML(ctx context.Context, html string, pg *PageConfig, opts ...Option) (*Result, error)
- func ConvertURL(ctx context.Context, rawURL string, pg *PageConfig, opts ...Option) (*Result, error)
- type XRefEntry
Examples ¶
Constants ¶
This section is empty.
Variables ¶
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.
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 ¶
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 ¶
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 ¶
Close releases all resources held by the Converter, including the browser process. Close is idempotent.
func (*Converter) ConvertFile ¶
ConvertFile converts a local HTML file to a PDF document. If page is nil, DefaultPageConfig values are used.
func (*Converter) ConvertHTML ¶
ConvertHTML converts an HTML string to a PDF document. If page is nil, DefaultPageConfig values are used.
func (*Converter) ConvertURL ¶
ConvertURL converts the web page at rawURL to a PDF document. If page is nil, DefaultPageConfig values are used.
type Dict ¶
Dict is a PDF dictionary (name -> object).
type Document ¶
type Document struct {
// contains filtered or unexported fields
}
Document represents a loaded PDF file.
func (*Document) ContentStreams ¶
ContentStreams returns the combined decompressed content stream data for a page.
func (*Document) GetPageInfo ¶
GetPageInfo extracts dimensions and rotation for a page.
func (*Document) ResolveRef ¶
ResolveRef follows an indirect reference and returns the pointed-to object.
type Extractor ¶
type Extractor struct {
// contains filtered or unexported fields
}
Extractor extracts plain text from PDF pages.
func NewExtractor ¶
NewExtractor creates a text extractor for the given document.
func (*Extractor) ExtractAll ¶
ExtractAll returns the plain text for all pages, one page per element.
func (*Extractor) ExtractPage ¶
ExtractPage returns the plain text for a single page (0-indexed).
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 ¶
Margin represents page margins in centimeters.
func UniformMargin ¶
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 ¶
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 ¶
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 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
// 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 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 (*Parser) ParseObject ¶
ParseObject parses one PDF object at the current position.
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 ¶
ConvertFile converts a local HTML file to PDF using a temporary Converter.
func ConvertHTML ¶
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 ¶
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) 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 ¶
WriteTo writes the full PDF content to w. It implements io.WriterTo.