¡Absolutamente! Apache PDFBox es una poderosa librería Java de código abierto para trabajar con documentos PDF. Aquí tienes un “cheatsheet” completo y bien estructurado de Apache PDFBox, optimizado para ser claro y conciso para una IA conversacional.


📄 Apache PDFBox Cheatsheet Completo 📄

Apache PDFBox es una biblioteca de código abierto que permite crear, manipular, extraer y procesar documentos PDF. Escrita completamente en Java, proporciona una API para manejar casi todos los aspectos de un archivo PDF, desde la creación de nuevas páginas hasta la extracción de texto y la manipulación de formularios.


1. 🌟 Conceptos Clave


2. 🛠️ Configuración Inicial (Maven)

Añade la dependencia principal en tu pom.xml:

<dependencies>
    <dependency>
        <groupId>org.apache.pdfbox</groupId>
        <artifactId>pdfbox</artifactId>
        <version>2.0.30</version> &lt;!-- Usar la versión más reciente y estable -->
    </dependency>
    &lt;!-- Opcional: Para el módulo de pre-vuelo (validación PDF/A) -->
    <dependency>
        <groupId>org.apache.pdfbox</groupId>
        <artifactId>pdfbox-tools</artifactId>
        <version>2.0.30</version>
    </dependency>
    &lt;!-- Opcional: Para renderizar PDFs a imágenes (requiere Ghostscript en algunos casos) -->
    <dependency>
        <groupId>org.apache.pdfbox</groupId>
        <artifactId>pdfbox-app</artifactId>
        <version>2.0.30</version>
    </dependency>
</dependencies>

3. 🚀 Operaciones Básicas de Documentos

3.1. Crear un Nuevo Documento PDF

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;

import java.io.IOException;

public class CreatePdf {
    public static void main(String[] args) throws IOException {
        PDDocument document = new PDDocument(); // Crear un documento vacío
        PDPage page = new PDPage(); // Crear una página vacía
        document.addPage(page); // Añadir la página al documento

        document.save("MyNewDocument.pdf"); // Guardar el documento
        document.close(); // Cerrar el documento (¡muy importante!)
        System.out.println("PDF 'MyNewDocument.pdf' creado exitosamente.");
    }
}

3.2. Cargar un Documento PDF Existente

import org.apache.pdfbox.pdmodel.PDDocument;

import java.io.File;
import java.io.IOException;

public class LoadPdf {
    public static void main(String[] args) throws IOException {
        File file = new File("MyExistingDocument.pdf");
        if (!file.exists()) {
            System.out.println("Archivo no encontrado: MyExistingDocument.pdf");
            return;
        }

        PDDocument document = null;
        try {
            document = PDDocument.load(file);
            System.out.println("PDF 'MyExistingDocument.pdf' cargado. Número de páginas: " + document.getNumberOfPages());
        } finally {
            if (document != null) {
                document.close();
            }
        }
    }
}

3.3. Guardar y Cerrar un Documento


4. 📄 Lectura y Extracción de Contenido

4.1. Extraer Texto de un PDF

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;

import java.io.File;
import java.io.IOException;

public class ExtractText {
    public static void main(String[] args) throws IOException {
        File file = new File("DocumentWithText.pdf");
        if (!file.exists()) {
            System.out.println("Archivo no encontrado: DocumentWithText.pdf");
            return;
        }

        try (PDDocument document = PDDocument.load(file)) {
            PDFTextStripper pdfStripper = new PDFTextStripper();

            // Opcional: Extraer texto de páginas específicas
            // pdfStripper.setStartPage(1);
            // pdfStripper.setEndPage(1);

            String text = pdfStripper.getText(document);
            System.out.println("Texto extraído:\n" + text);
        }
    }
}

4.2. Extraer Imágenes de un PDF

Este es un proceso más complejo que implica iterar sobre los recursos de cada página.

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
import org.apache.pdfbox.pdmodel.PDResources;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Map;

public class ExtractImages {
    public static void main(String[] args) throws IOException {
        File file = new File("DocumentWithImages.pdf");
        if (!file.exists()) {
            System.out.println("Archivo no encontrado: DocumentWithImages.pdf");
            return;
        }

        try (PDDocument document = PDDocument.load(file)) {
            for (int i = 0; i &lt; document.getNumberOfPages(); i++) {
                PDPage page = document.getPage(i);
                PDResources resources = page.getResources();
                if (resources != null) {
                    Map<String, PDImageXObject> images = resources.getImages();
                    if (images != null) {
                        for (Map.Entry<String, PDImageXObject> entry : images.entrySet()) {
                            PDImageXObject image = entry.getValue();
                            BufferedImage bufferedImage = image.getImage();
                            File outputfile = new File("image_" + (i + 1) + "_" + entry.getKey() + ".png");
                            ImageIO.write(bufferedImage, "png", outputfile);
                            System.out.println("Imagen guardada: " + outputfile.getName());
                        }
                    }
                }
            }
        }
    }
}

4.3. Extraer Metadatos (Información del Documento)

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDDocumentInformation;

import java.io.File;
import java.io.IOException;

public class ExtractMetadata {
    public static void main(String[] args) throws IOException {
        File file = new File("MyDocument.pdf");
        if (!file.exists()) {
            System.out.println("Archivo no encontrado: MyDocument.pdf");
            return;
        }

        try (PDDocument document = PDDocument.load(file)) {
            PDDocumentInformation info = document.getDocumentInformation();
            System.out.println("Título: " + info.getTitle());
            System.out.println("Autor: " + info.getAuthor());
            System.out.println("Asunto: " + info.getSubject());
            System.out.println("Palabras Clave: " + info.getKeywords());
            System.out.println("Creador: " + info.getCreator());
            System.out.println("Productor: " + info.getProducer());
            System.out.println("Fecha de Creación: " + info.getCreationDate());
            System.out.println("Fecha de Modificación: " + info.getModificationDate());
        }
    }
}

5. ✍️ Modificación y Añadir Contenido

5.1. Añadir Texto a una Página Existente

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.apache.pdfbox.pdmodel.font.Standard14Fonts;

import java.io.File;
import java.io.IOException;

public class AddTextToPdf {
    public static void main(String[] args) throws IOException {
        File file = new File("ExistingDocument.pdf");
        if (!file.exists()) {
            System.out.println("Archivo no encontrado: ExistingDocument.pdf. Creando uno nuevo...");
            try (PDDocument doc = new PDDocument()) {
                doc.addPage(new PDPage());
                doc.save("ExistingDocument.pdf");
            }
        }

        try (PDDocument document = PDDocument.load(file)) {
            PDPage page = document.getPage(0); // Obtener la primera página

            try (PDPageContentStream contentStream = new PDPageContentStream(document, page, PDPageContentStream.AppendMode.APPEND, true, true)) {
                contentStream.beginText();
                contentStream.setFont(new PDType1Font(Standard14Fonts.FontName.HELVETICA_BOLD), 12); // Fuente y tamaño
                contentStream.setLeading(14.5f); // Espaciado entre líneas

                contentStream.newLineAtOffset(25, 750); // Posición inicial (x, y)
                contentStream.showText("Este es un nuevo texto añadido.");
                contentStream.newLine(); // Nueva línea
                contentStream.showText("¡Más texto en la siguiente línea!");
                contentStream.endText();
            }

            document.save("DocumentWithNewText.pdf");
            System.out.println("Texto añadido a 'DocumentWithNewText.pdf'.");
        }
    }
}

5.2. Añadir Imagen a una Página Existente

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

public class AddImageToPdf {
    public static void main(String[] args) throws IOException {
        File file = new File("DocumentForImage.pdf");
        if (!file.exists()) {
            System.out.println("Archivo no encontrado: DocumentForImage.pdf. Creando uno nuevo...");
            try (PDDocument doc = new PDDocument()) {
                doc.addPage(new PDPage());
                doc.save("DocumentForImage.pdf");
            }
        }
      
        // Crear una imagen de ejemplo si no existe
        File imageFile = new File("example.png");
        if (!imageFile.exists()) {
            BufferedImage dummyImage = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB);
            ImageIO.write(dummyImage, "png", imageFile);
            System.out.println("Imagen de ejemplo 'example.png' creada.");
        }

        try (PDDocument document = PDDocument.load(file)) {
            PDPage page = document.getPage(0); // Obtener la primera página

            PDImageXObject pdImage = PDImageXObject.createFromFile("example.png", document); // Cargar la imagen

            try (PDPageContentStream contentStream = new PDPageContentStream(document, page, PDPageContentStream.AppendMode.APPEND, true, true)) {
                contentStream.drawImage(pdImage, 50, 600, 100, 100); // x, y, ancho, alto
            }

            document.save("DocumentWithImage.pdf");
            System.out.println("Imagen añadida a 'DocumentWithImage.pdf'.");
        }
    }
}

5.3. Dibujar Formas y Líneas

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.apache.pdfbox.pdmodel.font.Standard14Fonts;
import java.awt.Color;
import java.io.File;
import java.io.IOException;

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

        try (PDPageContentStream contentStream = new PDPageContentStream(document, page)) {
            // Dibujar una línea
            contentStream.setStrokingColor(Color.BLUE); // Color del trazo
            contentStream.setLineWidth(2); // Ancho de línea
            contentStream.moveTo(100, 500);
            contentStream.lineTo(200, 550);
            contentStream.stroke(); // Dibujar el trazo

            // Dibujar un rectángulo
            contentStream.setStrokingColor(Color.BLACK);
            contentStream.setLineWidth(1);
            contentStream.addRect(250, 450, 100, 50); // x, y, ancho, alto
            contentStream.stroke();

            // Dibujar un rectángulo relleno
            contentStream.setNonStrokingColor(Color.GREEN); // Color de relleno
            contentStream.addRect(250, 350, 100, 50);
            contentStream.fill(); // Rellenar

            // Dibujar texto con color
            contentStream.beginText();
            contentStream.setFont(new PDType1Font(Standard14Fonts.FontName.TIMES_ROMAN), 18);
            contentStream.setNonStrokingColor(Color.RED); // Color del texto
            contentStream.newLineAtOffset(50, 100);
            contentStream.showText("Texto en Rojo!");
            contentStream.endText();
        }

        document.save("ShapesAndText.pdf");
        document.close();
        System.out.println("PDF 'ShapesAndText.pdf' creado con formas y texto.");
    }
}

6. 📁 Trabajar con Formularios (AcroForms)

6.1. Rellenar Campos de Formulario

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
import org.apache.pdfbox.pdmodel.interactive.form.PDTextField;

import java.io.File;
import java.io.IOException;

public class FillForm {
    public static void main(String[] args) throws IOException {
        File file = new File("MyForm.pdf"); // Asegúrate de que este PDF tiene campos de formulario
        if (!file.exists()) {
            System.out.println("Archivo de formulario no encontrado: MyForm.pdf");
            return;
        }

        try (PDDocument document = PDDocument.load(file)) {
            PDAcroForm acroForm = document.getDocumentCatalog().getAcroForm();
            if (acroForm != null) {
                PDTextField nameField = (PDTextField) acroForm.getField("NameField"); // Reemplaza con el nombre de tu campo
                if (nameField != null) {
                    nameField.setValue("John Doe");
                    System.out.println("Campo 'NameField' rellenado.");
                } else {
                    System.out.println("Campo 'NameField' no encontrado.");
                }

                PDTextField emailField = (PDTextField) acroForm.getField("EmailField");
                if (emailField != null) {
                    emailField.setValue("john.doe@example.com");
                    System.out.println("Campo 'EmailField' rellenado.");
                } else {
                    System.out.println("Campo 'EmailField' no encontrado.");
                }
            } else {
                System.out.println("No se encontró AcroForm en el documento.");
            }

            document.save("FilledForm.pdf");
            System.out.println("Formulario rellenado y guardado como 'FilledForm.pdf'.");
        }
    }
}

6.2. Aplanar Formulario (Hacer los campos no editables)

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;

import java.io.File;
import java.io.IOException;

public class FlattenForm {
    public static void main(String[] args) throws IOException {
        File file = new File("FilledForm.pdf"); // Usa el formulario rellenado del ejemplo anterior
        if (!file.exists()) {
            System.out.println("Archivo no encontrado: FilledForm.pdf");
            return;
        }

        try (PDDocument document = PDDocument.load(file)) {
            PDAcroForm acroForm = document.getDocumentCatalog().getAcroForm();
            if (acroForm != null) {
                acroForm.flatten(); // Esto elimina la interactividad de los campos
                System.out.println("Formulario aplanado.");
            } else {
                System.out.println("No se encontró AcroForm para aplanar.");
            }

            document.save("FlattenedForm.pdf");
            System.out.println("Formulario aplanado y guardado como 'FlattenedForm.pdf'.");
        }
    }
}

7. 🔒 Seguridad (Cifrado)

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.encryption.AccessPermission;
import org.apache.pdfbox.pdmodel.encryption.StandardProtectionPolicy;

import java.io.File;
import java.io.IOException;

public class EncryptPdf {
    public static void main(String[] args) throws IOException {
        File file = new File("MyDocumentToEncrypt.pdf");
        if (!file.exists()) {
            System.out.println("Archivo no encontrado: MyDocumentToEncrypt.pdf. Creando uno nuevo...");
            try (PDDocument doc = new PDDocument()) {
                doc.addPage(new PDPage());
                try (PDPageContentStream cs = new PDPageContentStream(doc, doc.getPage(0))) {
                    cs.beginText();
                    cs.setFont(new PDType1Font(Standard14Fonts.FontName.HELVETICA), 12);
                    cs.newLineAtOffset(50, 700);
                    cs.showText("Contenido secreto.");
                    cs.endText();
                }
                doc.save("MyDocumentToEncrypt.pdf");
            }
        }

        try (PDDocument document = PDDocument.load(file)) {
            // Definir permisos de acceso
            AccessPermission ap = new AccessPermission();
            ap.setCanPrint(false); // No permitir imprimir
            ap.setCanFillInForm(true); // Permitir rellenar formularios
            // ap.setCanExtractContent(false); // No permitir copiar texto/imágenes

            // Definir la política de protección
            // (owner password, user password, permissions)
            StandardProtectionPolicy spp = new StandardProtectionPolicy("ownerPass", "userPass", ap);
            spp.setEncryptionKeyLength(128); // 40, 128 (estándar), 256
            spp.setPermissions(ap); // Reestablecer permisos por si acaso

            document.protect(spp); // Aplicar la protección

            document.save("EncryptedDocument.pdf");
            System.out.println("PDF 'EncryptedDocument.pdf' cifrado.");
        }
    }
}

8. 💡 Buenas Prácticas y Consejos


Este cheatsheet te proporciona una referencia completa de Apache PDFBox, cubriendo desde las operaciones básicas de documentos hasta la manipulación de contenido, formularios y seguridad, junto con consideraciones clave para un uso efectivo.