Como gerar PDFs

Os PDFs são amplamente utilizados para compartilhar documentos de maneira consistente e confiável. Seja para gerar relatórios, faturas ou certificados, criar PDFs programaticamente é uma necessidade comum em muitas aplicações modernas.

O vasto universo open source de packages Go oferece várias bibliotecas para manipulação de PDFs. Um dos mais populares é o gopdf, que fornece uma API intuitiva para criar PDFs sem a necessidade de packages externos pesados ou dependência de outros softwares instalados no sistema.

Neste post, você aprenderá como usar o gopdf para criar, personalizar e exportar PDFs em Go. Vamos explorar desde um exemplo simples até recursos mais avançados, como adicionar imagens e tabelas, além de exportar PDFs via HTTP.

O package gopdf

O gopdf é um package poderoso e leve para gerar PDFs em Go. Projetado para ser simples e eficiente, ele oferece uma variedade de funcionalidades:

  • Suporte a múltiplas fontes e estilos.
  • Possibilidade de adicionar imagens, formas e gráficos.
  • Controle preciso sobre o layout e posicionamento de elementos.
  • Sem dependências externas complexas.

Com um equilíbrio entre funcionalidade e desempenho, o gopdf é ideal para aplicações que precisam criar PDFs de forma eficiente e customizável.

“Hello PDF”

Para começar, vamos criar um exemplo simples que gera um PDF com o texto “Hello, PDF!”.

package main

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

func main() {
	pdf := gopdf.GoPdf{}
	pdf.Start(gopdf.Config{PageSize: *gopdf.PageSizeA4}) // Formato A4
	pdf.AddPage()

	// Adiciona a fonte
	err := pdf.AddTTFFont("Arial", "./arial.ttf")
	if err != nil {
		panic(err)
	}

	err = pdf.SetFont("Arial", "", 16)
	if err != nil {
		panic(err)
	}

	pdf.Cell(nil, "Hello, PDF!")
	err = pdf.WritePdf("hello.pdf")
	if err != nil {
		panic(err)
	}
}

Um ponto muito importante desse código é a chamada do método pdf.AddTTFFont. Note que o segundo parâmetro é o caminho para o local onde o arquivo da fonte se encontra.

Embora possa ser um pouco chato, ter que adicionar o caminho de onde o arquivo de fonte se encontra evita um erro em produção por falta de uma fonte que teoricamente deveria existir no sistema operacional.

Por isso, certifique-se de ter o arquivo de fonte arial.ttf no diretório da sua aplicação ou forneça o caminho correto para o arquivo de fonte.

Ao executar este código, você terá um arquivo hello.pdf gerado no diretório atual com o texto “Hello, PDF!”.

Adicionando Elementos

Agora que já criamos um PDF básico, vamos explorar como adicionar elementos personalizados, como fontes, cores, imagens e tabelas.

Caso queira adicionar todos esses exemplos ao código inicial, recomendo colocar um pdf.Br(20) antes de cada snippet, afim de adicionar uma quebra de linha.

Mudando a cor da fonte

O package gopdf oferece dois métodos para mudar a cor das fontes, sendo um para RGB (SetTextColor) e outro para CMYK (SetTextColorCMYK).

No exemplo abaixo, utilizamos o método para RGB.

// Definir a cor do texto (vermelho)
pdf.SetTextColor(255, 0, 0)

// Definir a fonte e o tamanho
err = pdf.SetFont("Arial", "", 14)
if err != nil {
	panic(err)
}

// Escrever o texto
pdf.Cell(nil, "Texto em vermelho com Arial!")

Adicionando uma imagem

Seja para adicionar a logo da empresa ou algum print de gráficos, sem dúvida alguma, outra função muito comum e necessária ao se gerar um PDF é fazer a adição de imagens.

No exemplo abaixo, adicionamos uma imagem chamada logo.png com as coordenadas X=40 e Y=60.

// Adicionar uma imagem
err = pdf.Image("logo.png", 40, 60, nil)
if err != nil {
	panic(err)
}

As coordenadas X e Y nada mais são do que a posição onde a imagem ficará.

Caso você não queira utilizar a imagem no seu tamanho original, ou seja, queira fazer um resize dela, é preciso passar um ponteiro da struct gopdf.Rect com o valor de largura (W) e altura (H) desejado.

// Adicionar uma imagem
err = pdf.Image("logo.png", 40, 60, &gopdf.Rect{W: 20, H: 30})
if err != nil {
	panic(err)
}

Criando uma tabela simples

Embora o gopdf não tenha um método específico para tabelas, você pode criar tabelas desenhando retângulos e adicionando texto.

headers := []string{"ID", "Nome", "Idade"}
data := [][]string{
	{"1", "João", "30"},
	{"2", "Maria", "25"},
	{"3", "José", "40"},
}

pdf.SetFont("Arial", "", 12)
cellWidth := 50.0 // largura das células
cellHeight := 20.0 // altura das células
startX := 10.0
startY := 50.0

// Desenhar os cabeçalhos
x := startX
for _, header := range headers {
	pdf.SetX(x)
	pdf.SetY(startY)
	pdf.RectFromUpperLeftWithStyle(x, startY, cellWidth, cellHeight, "D")
	pdf.CellWithOption(&gopdf.Rect{W: cellWidth, H: cellHeight}, header, gopdf.CellOption{Align: gopdf.Center})
	x += cellWidth
}

// Desenhar as linhas de dados
y := startY + cellHeight
for _, row := range data {
	x = startX
	for _, col := range row {
		pdf.SetX(x)
		pdf.SetY(y)
		pdf.RectFromUpperLeftWithStyle(x, y, cellWidth, cellHeight, "D")
		pdf.CellWithOption(&gopdf.Rect{W: cellWidth, H: cellHeight}, col, gopdf.CellOption{Align: gopdf.Center})
		x += cellWidth
	}
	y += cellHeight
}

Exportando PDF via HTTP

Para gerar PDFs dinamicamente e disponibilizá-los para download em uma aplicação web, precisamos duas coisas:

  1. Definir os headers Content-Type e Content-Disposition na response.
  2. Mudar o método de escrita do PDF de WritePdf para o método Write.
package main

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

func generatePDF(w http.ResponseWriter, r *http.Request) {
	pdf := gopdf.GoPdf{}
	pdf.Start(gopdf.Config{PageSize: *gopdf.PageSizeA4})
	pdf.AddPage()

	// Adicionar a fonte
	err := pdf.AddTTFFont("Arial", "./arial.ttf")
	if err != nil {
		http.Error(w, "Erro ao carregar a fonte", http.StatusInternalServerError)
		return
	}

	err = pdf.SetFont("Arial", "", 16)
	if err != nil {
		http.Error(w, "Erro ao definir a fonte", http.StatusInternalServerError)
		return
	}

	pdf.Cell(nil, "Hello PDF via HTTP!")

	w.Header().Set("Content-Type", "application/pdf")
	w.Header().Set("Content-Disposition", "attachment; filename=output.pdf")
	err = pdf.Write(w)
	if err != nil {
		http.Error(w, "Erro ao gerar PDF", http.StatusInternalServerError)
	}
}

func main() {
	http.HandleFunc("/download", generatePDF)
	http.ListenAndServe(":8080", nil)
}

Acesse http://localhost:8080/download para baixar o PDF diretamente pelo navegador.

Conclusão

Criar PDFs em Go usando o gopdf é uma tarefa simples e eficiente. Este pacote oferece recursos flexíveis para personalizar seus documentos, permitindo que você crie PDFs profissionais e dinâmicos para suas aplicações.

Se você gostou deste tutorial e quer receber mais conteúdos como este, inscreva-se na nossa newsletter e fique por dentro das melhores práticas de desenvolvimento em Go!

Até a próxima!


Faça parte da comunidade!

Receba os melhores conteúdos sobre Go, Kubernetes, arquitetura de software, Cloud e esteja sempre atualizado com as tendências e práticas do mercado.

Livros Recomendados

Abaixo listei alguns dos melhores livros que já li sobre GO.

Deixe uma resposta