Generating PDF reports in GO

OK. Now generating PDFs in GO!

Page content

Generating PDF documents programmatically can be an important feature in your application. Here we explore and give short review with examples of the libraries available in the Go programming language (Golang) for generating PDF files.

Suitable solutions might be different for for example simple document creation, or complex and feature-rich PDF generation.

go, pdf! Yes, the image is AI-generated, the model is Flux1.Dev.

Libraries and Tools

gofpdf

GoPdf is a straightforward library for creating PDFs. It allows adding text, images, shapes, tables, and handling multiple pages. Suitable for simple to moderately complex PDF creation tasks.

Maintainer: Jung Kurt (discontinued but still used).

Limitation: Lack of updates, though existing usage persists.

Example:

package main

import (
    "github.com/jung-kurt/gofpdf"
)

func main() {
    pdf := gofpdf.New("P", "mm", "A4", "")
    pdf.AddPage()
    pdf.SetFont("Arial", "B", 16)
    pdf.Cell(40, 10, "Hello World!")
    err := pdf.OutputFileAndClose("hello.pdf")
    if err != nil {
        panic(err)
    }
}

gopdf

Maintainer: signintech (actively maintained).

In the Go programming language, one of the libraries that stands out for this purpose is gopdf, developed by SignInTech. This library provides a straightforward way to create PDFs programmatically without relying on external dependencies or C libraries.

gopdf is a pure Go library designed specifically for creating PDF documents. It offers a simple and efficient API focused primarily on PDF generation, making it easier to use for basic tasks while maintaining the flexibility needed for more complex operations.

Key Features:

  • Pure Go Implementation: No external dependencies or C libraries required.
  • Simple API: Easy-to-use functions for generating PDFs.
  • Efficient Performance: Optimized for quick and efficient PDF creation.

Example Usage

To illustrate how gopdf can be used, let’s look at a basic example of creating a simple PDF document:

package main

import (
    "github.com/signintech/gopdf"
)

func main() {
    // Create a new PDF instance
    pdf := gopdf.New()

    // Set the page size and margins
    pdf.SetPageSize(gopdf.PageSizeA4)
    pdf.AddPage()

    // Add some text to the PDF
    pdf.SetFont("Arial", "", 12)
    pdf.Write(50, 50, "Hello, World!")

    // Save the PDF to a file
    err := pdf.SaveToFile("example.pdf")
    if err != nil {
        panic(err)
    }
}

This example demonstrates how to create a new PDF document, add text to it, and save it as a file.

gopdf Advanced features:

  • Adding Images: You can insert images into your PDF documents using the AddImage method.
  • Drawing Shapes: The library provides functions to draw lines, rectangles, and other shapes.
  • PDF Protection: You can set password protection on your PDFs to restrict access.

pdfcpu

Another one of the powerful libraries available for PDF manipulation in Go is pdfcpu. This library offers a comprehensive suite of features for creating, modifying, and inspecting PDF files through both an API and a command-line interface (CLI). Below, we delve into the description, usage examples, and key functionalities of pdfcpu.

pdfcpu is a Go-based PDF processing library that supports encryption and offers robust tools for handling various aspects of PDF documents. It is compatible with all PDF versions, including ongoing improvements for PDF 2.0 (ISO-32000-2). The library aims to provide a comprehensive range of PDF processing features, making it suitable for both simple and complex use cases.

Key Features

  • Encryption Support: pdfcpu supports encryption, allowing developers to secure their PDF documents effectively.
  • API and CLI: It offers both an API for programmatic access and a command-line interface (CLI) for quick operations.
  • Batch Processing: Strong support for batch processing via the rich command line makes it efficient for handling multiple files at once.
  • Compatibility: Compatible with all PDF versions, including basic support and ongoing improvements for PDF 2.0.

To get started with pdfcpu, you need to install it using Go’s package management system:

go get github.com/pdfcpu/pdfcpu

Basic Command-Line Operations

pdfcpu provides a variety of commands for different operations. Here are some examples:

Creating a PDF from Images

You can convert one or more image files into a PDF file with the following command:

pdfcpu img2pdf out.pdf image1.jpg image2.png

This command will create a PDF where each image is rendered onto a separate page.

To merge multiple PDF files into a single document, use the merge command:

pdfcpu merge output.pdf file1.pdf file2.pdf

pdfcpu Usage example

For more complex operations, you can use the API provided by pdfcpu. Here is an example of how to create a new PDF and add text using Go code:

package main

import (
    "github.com/pdfcpu/pdfcpu"
    "log"
)

func main() {
    // Create a new PDF document
    doc := pdfcpu.NewPDF(0, 0)
    defer doc.Close()

    // Add a page to the document
    page := doc.AddPage()
    page.SetMediaBox(pdfcpu.MediaBox{
        LLX: 0,
        LLY: 0,
        URX: 612,
        URY: 792,
    })

    // Add text to the page
    content := "Hello, World!"
    font := pdfcpu.NewFont("Helvetica", "")
    page.AddText(content, font, 12, 100, 750)

    // Save the document
    err := doc.Save("output.pdf")
    if err != nil {
        log.Fatal(err)
    }
}

This example demonstrates how to create a new PDF, add a page, and write text onto it using pdfcpu’s API.

Maroto

  • Maintainer: go-playground team (https://github.com/go-playground/maroto).
  • Use Cases: Developers preferring a design-first approach (similar to Bootstrap).
  • Inspired by Bootstrap; designed to be easy-to-use with a declarative style similar to HTML/CSS.
  • Built on top of gofpdf, it simplifies the creation process while maintaining powerful customization options.

Maroto is another Go library for creating PDFs, but it focuses on simplifying the process by abstracting away low-level details. It builds upon the gofpdf library and provides a more user-friendly API for generating documents.

Maroto Usage Example

Here’s an example of how you can use Maroto to create a simple PDF:

package main

import (
    "github.com/andreyhoffmann1103/maroto"
)

func main() {
    // Create a new PDF document with specified dimensions
    m := maroto.NewPDF(595, 842) // A4 size in points

    // Add some text to the first page
    m.AddText("Hello, Maroto!", 0, 0)

    // Save the PDF to a file
    err := m.OutputFileAndClose("example.pdf")
    if err != nil {
        panic(err)
    }
}

This example shows how to create a new PDF document with one page and add text to it using Maroto.

Unipdf

UniPDF is another powerful and comprehensive library for creating and processing PDF files in Golang (Go). It offers a wide range of features that make it popular among developers who need to generate, modify, and extract content from PDF documents.

  • Maintainer: UnidocLib (https://unidoc.io).
  • Use Cases: Advanced PDF processing (encryption, merging, scripting).
  • Powerful library for creating and processing PDFs (pure Go).
  • Offers extensive features including interactive elements like links, bookmarks, merging/splitting, encryption, and more.
  • Comprehensive API for reading and writing PDF objects (dictionaries, streams).
  • Suitable for applications needing robust PDF generation capabilities.

UniPDF Installation

To get started with UniPDF, you need to install the library. Follow these steps:

# Create a New Directory:
mkdir go-pdf-generator cd go-pdf-generator
# Initialize the Go Module:
go mod init go-pdf-generator
# Install UniPDF Library:
go get github.com/unidoc/unipdf/v3

This will set up your project and install the necessary dependencies.

Basic Usage Example

Here is a simple example to create a PDF document using UniPDF:

package main

import (
    "github.com/unidoc/unipdf/v3/core"
    "github.com/unidoc/unipdf/v3/model"
    "github.com/unidoc/unipdf/v3/creator"
)

func main() {
    // Create a new PDF document
    pdf := creator.New()

    // Add a page to the PDF
    page := pdf.NewPage()

    // Set up the content stream for the page
    contentStream := model.NewContentStream()
    page.SetContents(contentStream)

    // Add text to the page
    text := "Hello, UniPDF!"
    font := creator.NewStandardFont(creator.FontHelvetica)
    textObject := model.NewText(text, font, 12)
    contentStream.Add(textObject)

    // Save the PDF document
    err := pdf.WriteToFile("example.pdf")
    if err != nil {
        panic(err)
    }
}

This example demonstrates how to create a new PDF document, add a page, and write text to it. The resulting file example.pdf will contain the text “Hello, UniPDF!”.

wkhtmltopdf Wrapper

Features:

  • Converts HTML templates (rendered with Go’s html/template) to PDF.
  • Customizable margins, page orientation, and headers/footers.
  • Suitable when the document’s design is complex and involves HTML/CSS styling.
  • Uses wkhtmltopdf as a backend to convert HTML content into PDF format.

go-wkhtmltopdf usage example

import (
    "bytes"
    "github.com/SebastiaanKlippert/go-wkhtmltopdf"
    "html/template"
)

type PDFService struct {}

func NewPDFService() *PDFService {
    return &PDFService{}
}

func (p PDFService) GeneratePDF(data interface{}) ([]byte, error) {
    var templ *template.Template
    var err error

    if templ, err = template.ParseFiles("pdf-template.html"); err != nil {
        return nil, err
    }

    var body bytes.Buffer
    if err := templ.Execute(&body, data); err != nil {
        return nil, err
    }

    pdfg, err := wkhtmltopdf.NewPDFGenerator()
    if err != nil {
        return nil, err
    }

    page := wkhtmltopdf.NewPageReader(bytes.NewReader(body.Bytes()))
    page.EnableLocalFileAccess.Set(true)

    pdfg.AddPage(page)
    pdfg.MarginLeft.Set(0)
    pdfg.MarginRight.Set(0)
    pdfg.Dpi.Set(300)
    pdfg.PageSize.Set(wkhtmltopdf.PageSizeA4)
    pdfg.Orientation.Set(wkhtmltopdf.OrientationLandscape)

    err = pdfg.Create()
    if err != nil {
        return nil, err
    }

    return pdfg.Bytes(), nil
}

pdflib (from EndFirstCorp):

  • A command-line tool for various PDF operations like validation, optimization, splitting/merging.
  • Useful for batch processing and administrative tasks related to PDF documents.

Overview of pdflib

The pdflib library is designed to be a comprehensive PDF processor for the Go programming language. It supports various functionalities such as validating, optimizing, splitting, merging, extracting content from, and trimming PDFs. The library adheres to the PDF 32000-1:2008 (PDF 1.7) standard, ensuring compatibility with a wide range of PDF documents.

Key Features

  • Validation: Ensures that PDF files comply with the PDF 1.7 standard.
  • Optimization: Reduces file size by eliminating redundant resources.
  • Splitting and Merging: Allows for splitting multi-page PDFs into single-page PDFs or merging multiple PDFs into one.
  • Extraction: Extracts images, fonts, content, and pages from a PDF.
  • Trimming: Creates trimmed versions of PDF documents.

Installation

To use pdflib, you need to install it via Go’s package management system. You can do this by running:

go get github.com/EndFirstCorp/pdflib

Basic Usage Example - Validating a PDF

Here is a simple example demonstrating how to use the pdflib library to perform basic PDF operations:

To validate a PDF against the PDF 1.7 standard, you can use the following code:

package main

import ( "fmt" "github.com/EndFirstCorp/pdflib/cmd/pdflib" )

func main() {
   // Validate a PDF file
   err := pdflib.Validate("example.pdf")
   if err != nil {
     fmt.Println("Validation failed:", err)
   } else {
     fmt.Println("PDF is valid.")
   }
}

Conclusion

For generating PDFs in Go, the choice of library depends on the complexity and specific requirements of your project. The following recommendations are provided:

  • Simple Documents: Use gofpdf or Maroto. These libraries offer simplicity and ease of use for straightforward tasks.
  • Complex Designs with HTML/CSS: Utilize the wkhtmltopdf Wrapper, which leverages wkhtmltopdf to handle complex HTML content and styling.
  • Advanced PDF Processing: Opt for Unipdf or pdfcpu when your application requires advanced features such as encryption, interactive elements, detailed formatting, and comprehensive manipulation capabilities.

Each of these libraries offers unique strengths that cater to different needs in PDF generation, providing developers with a variety of tools to choose from based on their specific requirements.