docpdf

package module
v0.0.82 Latest Latest
Warning

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

Go to latest
Published: May 10, 2025 License: MIT Imports: 13 Imported by: 0

README

docpdf

An open-source Go library for generating PDFs with a minimalist and intuitive API, similar to writing in Word. Optimized to run in the browser with WebAssembly without dependencies.

Description

docpdf is a Go library that allows you to generate PDF documents with an intuitive and simple API. It is designed to be easy to use, with an approach similar to writing in a word processor like Word. The library is optimized to work in the browser with WebAssembly.

The main focus of this library is to compile into a compact binary size using TinyGo for frontend usage, as standard Go binaries tend to be large. This makes it ideal for web applications where binary size matters.

Font Convention

By default, docpdf expects the following font files in the fonts/ directory (relative to your application's execution path or as specified in Font.Path):

  • regular.ttf: For the normal text style.
  • bold.ttf: For the bold text style.
  • italic.ttf: For the italic text style.

You can override these defaults by providing a custom Font configuration when creating the document:

customFont := docpdf.Font{
    Regular: "MyCustomFont-Regular.ttf",
    Bold:    "MyCustomFont-Bold.ttf",
    Italic:  "MyCustomFont-Italic.ttf",
    Path:    "assets/fonts/", // Optional: specify a different path
}
doc := docpdf.NewDocument(customFont)

If you only provide Regular, the library will use the regular font for bold and italic styles as well.

TinyGo Compatibility Checklist

The following standard libraries will be replaced or modified as they are not 100% compatible with TinyGo, in order to reduce the binary size:

  • bufio
  • crypto/sha1
  • errors
  • fmt
  • golang.org/x/image
  • io
  • os
  • path/filepath
  • sort
  • strings
  • sync
  • time

Getting Started

Creating a new document is simple. A file writer function is optional but can be provided to customize how the PDF is saved:

// Basic usage with default file writer (uses os.WriteFile in backend environments)
doc := NewDocument()

// With custom file writer
doc := NewDocument(os.WriteFile)

// For web applications (example using a fictional HTTP response interface)
doc := NewDocument(func(filename string, data []byte) error {
    resp.Header().Set("Content-Type", "application/pdf")
    resp.Header().Set("Content-Disposition", "attachment; filename="+filename)
    _, err := resp.Write(data)
    return err
})

Page Size Options

The library offers multiple ways to specify page sizes for your documents:

  1. Using predefined page sizes:

    doc := NewDocument(PageSizeA4)  // Use A4 page size
    doc := NewDocument(PageSizeLetter)  // Use Letter page size
    
  2. Using the new PageSize struct with unit specification:

    // Create an A4 page size (210mm x 297mm) with millimeter units
    doc := NewDocument(PageSize{Width: 210, Height: 297, Unit: UnitMM})
    
    // Create a US Letter page size (8.5in x 11in) with inch units
    doc := NewDocument(PageSize{Width: 8.5, Height: 11, Unit: UnitIN})
    
  3. Combining options:

    doc := NewDocument(
       PageSize{Width: 210, Height: 297, Unit: UnitMM},  // A4 size
       margins.Margins{Left: 15, Top: 10, Right: 10, Bottom: 10},  // Custom margins.Margins
       os.WriteFile  // Custom file writer (optional)
    )
    

Usage Example:

Page 1

image

Page 2

image

This example shows the main features of the library:

	// Create a document with default settings
	doc := NewDocument()

	// Or with custom file writer
	// doc := NewDocument(os.WriteFile)

	// Setup header and footer with the new API
	doc.SetPageHeader().
		SetLeftText("Header Left").
		SetCenterText("Document Example").
		SetRightText("Confidential").
		// ShowOnFirstPage()

		// Add footer with page numbers in format X/Y
		doc.SetPageFooter().
		SetLeftText("Created: 2023-10-01").
		SetCenterText("footer center example").
		WithPageTotal(Right).
		ShowOnFirstPage()

	// add logo image
	doc.AddImage("test/res/logo.png").Height(35).Inline().Draw()

	// add date and time aligned to the right
	doc.AddText("date: 2024-10-01").AlignRight().Inline().Draw()

	// Add a centered header
	doc.AddHeader1("Example Document").AlignCenter().Draw()

	// Add a level 2 header
	doc.AddHeader2("Section 1: Introduction").Draw()

	// Add normal text
	doc.AddText("This is a normal text paragraph that shows the basic capabilities of the gopdf library. " +
		"We can create documents with different text styles and formats.").Draw()

	// Add text with different styles
	doc.AddText("This text is in bold.").Bold().Draw()

	doc.AddText("This text is in italic.").Italic().Draw()

	// Add right-aligned text (ensuring it's in regular style, not italic)
	doc.AddText("This text is right-aligned.").Regular().AlignRight().Draw()

	// Create and add a bar chart using the new API instead of static image
	barChart := doc.AddBarChart().
		Title("Monthly Sales").
		Height(320).	
		AlignCenter().
		BarWidth(50).
		BarSpacing(10)

	// Add data to the chart
	barChart.AddBar(120, "Jan").
		AddBar(140, "Feb").
		AddBar(160, "Mar").
		AddBar(180, "Apr").
		AddBar(120, "May").
		AddBar(140, "Jun")

	// Configurar el gráfico para mostrar los ejes
	barChart.WithAxis(true, true)

	// Renderizar el gráfico
	barChart.Draw()

	// Save the document to a file
	err := doc.WritePdf("example_document.pdf")
	if err != nil {
		log.Fatalf("Error writing PDF: %v", err)
	}

Current Development Focus: Direct Chart Rendering

We are currently working on improving how charts are rendered within PDF documents.

Problem: The current method renders charts as intermediate images (SVG/PNG), which are then embedded as raster images in the PDF. This is inefficient, leads to loss of vector quality, and relies on dependencies like freetype, hindering the goal of creating a lightweight library suitable for TinyGo and browser environments.

Solution in Progress: We are implementing a direct rendering approach. This involves:

  1. Creating a new internal chartengine package (starting with bar charts) that calculates layout using PDF units (points).
  2. Developing a pdfRenderer that translates drawing commands from chartengine directly into vector drawing commands for the underlying PDF engine (PdfEngine).

This will result in true vector graphics for charts within the PDF, eliminate the freetype dependency for charts, improve performance, and align with the goal of a smaller, browser-friendly library.

Acknowledgements

This library would not have been possible without github repositories:

  • signintech/gopdf
  • wcharczuk/go-chart

Important

this library is still in development and not all features are implemented yet. please check the issues for more information.

Documentation

Overview

filepath: c:\Users\Cesar\Packages\Internal\docpdf\docChart.go

Index

Constants

View Source
const (
	FontRegular = "regular"
	FontBold    = "bold"
	FontItalic  = "italic"
)

FontStyle defines the available font styles

Variables

This section is empty.

Functions

This section is empty.

Types

type Document

type Document struct {
	*pdfengine.PdfEngine
	// contains filtered or unexported fields
}

func NewDocument

func NewDocument(configs ...any) *Document

NewDocument creates a new PDF document with configurable settings Accepts optional configurations:

Optional configurations include:

  • config.TextStyles: Custom text styles for different sections
  • config.FontFamily: Custom font family
  • canvas.Margins: Custom canvas.Margins in millimeters (more intuitive than points)
  • canvas.PageSize: Custom page size with desired units
  • *canvas.Rect: Predefined page size (like PageSizeLetter, canvas.PageSizeA4, etc.)
  • func(string, []byte) error: Custom file writer function (if not provided, defaults to env.SetupDefaultFileWriter())

Examples:

  • NewDocument() // Uses default file writer
  • NewDocument(os.WriteFile) // Custom file writer
  • NewDocument(canvas.Margins{config.Left: 15, config.Top: 10, config.Right: 10, config.Bottom: 10})
  • NewDocument(canvas.PageSize{Width: 210, Height: 297, Unit: canvas.UnitMM}) // A4 size in mm
  • NewDocument(canvas.PageSizeA4) // Using predefined page size
  • NewDocument(os.WriteFile, canvas.PageSizeA4, canvas.Margins{config.Left: 20, config.Top: 10, config.Right: 20, config.Bottom: 10})

For web applications:

  • NewDocument(func(filename string, data []byte) error { response.Header().Set("Content-Type", "application/pdf") _, err := response.Write(data) return err })

func (*Document) AddFootnote

func (d *Document) AddFootnote(text string) *docText

AddFootnote crea una nota al pie

func (*Document) AddHeader1

func (d *Document) AddHeader1(text string) *docText

AddHeader1 crea un encabezado nivel 1

func (*Document) AddHeader2

func (d *Document) AddHeader2(text string) *docText

AddHeader2 crea un encabezado nivel 2

func (*Document) AddHeader3

func (d *Document) AddHeader3(text string) *docText

AddHeader3 crea un encabezado nivel 3

func (*Document) AddImage

func (doc *Document) AddImage(imagePathOrContent any) *docImage

AddImage creates a new image element in the document supporting both absolute and relative paths or image data in []byte format eg: doc.AddImage("path/to/image.png") or doc.AddImage([]byte{...})

func (*Document) AddJustifiedText

func (d *Document) AddJustifiedText(text string) *docText

AddJustifiedText crea texto justificado directamente

func (*Document) AddPage

func (doc *Document) AddPage()

AddPage añade una nueva página y actualiza el contador de páginas para el header y footer

func (*Document) AddPageFooter

func (d *Document) AddPageFooter(text string) *docText

AddPageFooter adds a footer to the document (legacy method for backward compatibility)

func (*Document) AddPageHeader

func (d *Document) AddPageHeader(text string) *docText

AddPageHeader adds a header to the document (legacy method for backward compatibility)

func (*Document) AddPageWithOption

func (doc *Document) AddPageWithOption(opt pdfengine.PageOption)

AddPageWithOption añade una nueva página con opciones y actualiza el contador de páginas para el header y footer

func (*Document) AddText

func (d *Document) AddText(text string) *docText

AddText crea texto normal

func (*Document) Chart added in v0.0.48

func (doc *Document) Chart() *docCharts

Chart es el punto de entrada para la API de gráficos

func (*Document) EnsureElementFits added in v0.0.61

func (doc *Document) EnsureElementFits(height float64, minBottomMargin ...float64) float64

EnsureElementFits checks if an element with the specified height will fit on the current page. If it doesn't fit, it adds a new page and returns the new Y config.Alignment. Parameters:

  • height: height of the element in document units
  • minBottomMargin: optional minimum margin to leave at bottom of page

Returns:

  • positionY: the Y config.Alignment where the element should be drawn
  • newPageAdded: true if a new page was added

func (*Document) GetLineHeight

func (doc *Document) GetLineHeight() float64

GetLineHeight returns the current line height based on the active font and size

func (*Document) NewStyledCell

func (doc *Document) NewStyledCell(content string, style config.Cell) styledCell

NewStyledCell creates a new cell with custom styling

func (*Document) NewTable

func (doc *Document) NewTable(headers ...string) *docTable

NewTable creates a new table with the specified headers Headers can include formatting options in the following format.

Format: "headerTitle|option1,option2,option3,..."

Available options:

  • Header alignment: "HL" (left), "HC" (center, default), "HR" (right)
  • Column alignment: "CL" (left, default), "CC" (center), "CR" (right)
  • Prefix/Suffix: "P:value" (adds prefix), "S:value" (adds suffix)
  • Width: "W:number" (fixed width), "W:number%" (percentage width) Note: If width is not specified, auto width is used by default

Examples:

  • "Name" - Normal header, left-aligned column, auto width
  • "Price|HR,CR" - config.Right-aligned header, right-aligned column
  • "Price|HR,CR,P:$" - config.Right-aligned header, right-aligned column with "$" prefix
  • "Percentage|HC,CC,S:%" - config.Center-aligned header, center-aligned column with "%" suffix
  • "Name|HL,CL,W:30%" - config.Left-aligned header, left-aligned column with 30% of available width
  • "Age|HC,CR,W:20" - config.Center-aligned header, right-aligned column with fixed width of 20 units

func (*Document) RedrawHeaderFooter

func (doc *Document) RedrawHeaderFooter()

RedrawHeaderFooter fuerza el redibujado del encabezado y pie de página en la página actual

func (*Document) SetPageFooter

func (d *Document) SetPageFooter() *headerFooter

SetPageFooter sets the document footer

func (*Document) SetPageHeader

func (d *Document) SetPageHeader() *headerFooter

SetPageHeader sets the document header

func (*Document) SpaceBefore

func (d *Document) SpaceBefore(spaces ...float64)

SpaceBefore adds vertical space (in font spaces) example: SpaceBefore(2) adds 2 spaces before the text

Directories

Path Synopsis
Package config contains configuration structures for docpdf.
Package config contains configuration structures for docpdf.
cmd
The freetype package provides a convenient API to draw text onto an image.
The freetype package provides a convenient API to draw text onto an image.
raster
Package raster provides an anti-aliasing 2-D rasterizer.
Package raster provides an anti-aliasing 2-D rasterizer.
truetype
Package truetype provides a parser for the TTF and TTC file formats.
Package truetype provides a parser for the TTF and TTC file formats.
filepath: c:\Users\Cesar\Packages\Internal\docpdf\pdfengine\pdfEngineExtra.go
filepath: c:\Users\Cesar\Packages\Internal\docpdf\pdfengine\pdfEngineExtra.go

Jump to

Keyboard shortcuts

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