Generación de informes PDF en Java con iText y Apache PDFBox

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Generación de informes PDF en Java: descripción general de las bibliotecas iText y Apache PDFBox

La creación de documentos PDF es una de las tareas más comunes en aplicaciones Java empresariales. Informes, facturas, albaranes, certificados: todo esto se puede generar fácilmente mediante programación. En el ecosistema Java existen dos bibliotecas principales para trabajar con PDF: iText (estándar industrial, pero con licencia comercial para versiones nuevas) y Apache PDFBox (completamente gratuita y de código abierto). En este artículo analizaremos ambas, mostraremos ejemplos de código y le ayudaremos a elegir la herramienta adecuada para su proyecto.



1. Apache PDFBox: una alternativa gratuita con amplias capacidades

Apache PDFBox es una biblioteca de código abierto (licencia Apache 2.0). Permite crear PDF desde cero, editar archivos existentes, extraer texto y metadatos. PDFBox no requiere licencia comercial, lo que la convierte en la opción ideal para startups y proyectos de código abierto.

Características principales:

  • Creación de documentos con texto, imágenes y tablas.
  • Trabajo con fuentes (incluyendo cirílico).
  • Adición de marcadores, hipervínculos y marcas de agua.
  • Cifrado y protección con contraseña.
  • Extracción de texto e imágenes de PDF existentes.


Ejemplo: creación de un informe PDF simple con tabla

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);

// Cargamos la fuente con soporte para 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("Informe de ventas Q1 2025"); cs.endText();

// Tabla (implementación simple mediante líneas y texto) cs.setFont(font, 12); // Dibujamos los encabezados de las columnas float margin = 50; float yStart = 700; float tableWidth = 500; float rowHeight = 25; String[] headers = {"Producto", "Cantidad", "Precio, RUB"}; String[][] data = {{"Portátil", "10", "85000"}, {"Ratón", "50", "1500"}, {"Teclado", "30", "3500"}};

// Encabezado de la tabla 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(); }

// Datos 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