Geração de relatórios PDF em Java com iText e Apache PDFBox

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Geração de relatórios PDF em Java: visão geral das bibliotecas iText e Apache PDFBox

Criar documentos PDF é uma das tarefas comuns em aplicações Java corporativas. Relatórios, faturas, notas fiscais, certificados — tudo isso pode ser gerado programaticamente. No ecossistema Java, existem duas bibliotecas principais para trabalhar com PDF: iText (padrão da indústria, mas com licença comercial para versões novas) e Apache PDFBox (totalmente gratuita e de código aberto). Neste artigo, abordaremos ambas, mostraremos exemplos de código e ajudaremos você a escolher a ferramenta adequada para o seu projeto.



1. Apache PDFBox — alternativa gratuita com amplas funcionalidades

Apache PDFBox é uma biblioteca de código aberto (licença Apache 2.0). Ela permite criar PDFs do zero, editar PDFs existentes, extrair texto e metadados. O PDFBox não requer licença comercial, tornando-o a escolha ideal para startups e projetos de código aberto.

Principais funcionalidades:

  • Criação de documentos com texto, imagens e tabelas.
  • Trabalho com fontes (incluindo cirílico).
  • Adição de marcadores, hiperlinks e marcas d'água.
  • Criptografia e proteção por senha.
  • Extração de texto e imagens de PDFs existentes.


Exemplo: criação de um relatório PDF simples com tabela

import org.apache.pdfbox.pdmodel.PDDocument;import org.apache.pdfbox.pdmodel.PDPage;import org.apache.pdfbox.pdmodel.PDPageContentStream;import org.apache.pdfbox.pdmodel.font.PDType0Font;import org.apache.pdfbox.pdmodel.common.PDRectangle;import java.io.File;import java.io.IOException;

public class PdfBoxReport { public static void main(String[] args) throws IOException { try (PDDocument document = new PDDocument()) { PDPage page = new PDPage(PDRectangle.A4); document.addPage(page);

// Carregar fonte com suporte a cirílico PDType0Font font = PDType0Font.load(document, new File("fonts/arial.ttf"));

try (PDPageContentStream cs = new PDPageContentStream(document, page)) { // Título cs.beginText(); cs.setFont(font, 18); cs.newLineAtOffset(50, 750); cs.showText("Relatório de vendas do Q1 2025"); cs.endText();

// Tabela (implementação simples com linhas e texto) cs.setFont(font, 12); // Desenhar cabeçalhos das colunas float margin = 50; float yStart = 700; float tableWidth = 500; float rowHeight = 25; String[] headers = {"Produto", "Quantidade", "Preço, R$"}; String[][] data = {{"Notebook", "10", "85000"}, {"Mouse", "50", "1500"}, {"Teclado", "30", "3500"}};

// Cabeçalho da tabela cs.setLineWidth(1f); for (int i = 0; i < headers.length; i++) { cs.addRect(margin + i * (tableWidth / 3), yStart - rowHeight, tableWidth / 3, rowHeight); cs.stroke(); cs.beginText(); cs.newLineAtOffset(margin + i * (tableWidth / 3) + 5, yStart - rowHeight + 5); cs.showText(headers[i]); cs.endText(); }

// Dados float yPos = yStart - rowHeight; for (String[] row : data) { yPos -= rowHeight; for (int i = 0; i < row.length; i++) { cs.addRect(margin + i * (tableWidth / 3), yPos, tableWidth / 3, rowHeight); cs.stroke(); cs.beginText(); cs.newLineAtOffset(margin + i * (tableWidth / 3) + 5, yPos + 5); cs.showText(row[i]); cs.endText();

Recommendations