Hoy vamos a ver iText una librería PDF en Java que nos permite crear, analizar, modificar y mantener documentos en el formato PDF. iText no es usado solo por Java también se utiliza en .NET, Android and GAE para aportar a sus aplicaciones funcionalidades con PDF.

iText logo

¿Qué nos proporciona iText ?

iText es una librería PDF que nos permite crear, adaptar, revisar y mantener documentos en el formato de documento PDF, algunas de las principales características son:

  • Generar documentos y los informes extraídos de un fichero XML o de una base de datos
  • Crear mapas y libros, incorporando características interactivas en formato PDF
  • Añadir marcadores, números de página, marcas de agua, y otras características a los documentos PDF existentes
    Split o concatenar las páginas de los archivos PDF existentes
  • Rellenar formularios interactivos.
  • Servir generado dinámicamente o manipular documentos PDF en un navegador web.

Java iText PDF – Creando un pdf en Java con iText

  1. Añadimos las librerías y creamos la clase
  2. Creación del documento y metadatos
  3. Creamos nuestra primera página
  4. Añadimos más elementos de iText a nuestro PDF
  5. Uso de tablas en iText: PDFPTable
  6. Resultado Final (Código completo)
  7. Documentación utilizada

Software y herramientas utilizadas


 

1. Añadimos las librerías y creamos la clase

Empezaremos descargando la la última versión de está librería, puedes acceder a Sourceforge o descargarla desde este enlace: Descarga de itext desde Sourceforge.

Configuramos el proyecto

Para este proyecto vamos a utilizar Netbeans que proporciona un gran soporte para el desarrollo de aplicaciones con Java.

Para ello abrimos Netbeans y buscamos la opción New Project , al abrirse el wizard seleccionamos Java > Java Application, después únicamente le daremos nombre a nuestro proyecto y su ubicación.

Puedes usar cualquier otro IDE para Java lo único que necesitarás realmente es añadir las librerías de iText.

Creamos la clase

Para crear una nueva clase nos situamos sobre el proyecto y en el menú pop-up seleccionamos New > Java Class, ahí introduciremos el nombre de la clase y el paquete donde la queremos ubicar, en mi caso:

  • Nombre de la clase: GeneratePDFFileIText.java
  • Paquete: org.xulescode.itext

Este código pretende ser la más sencillo posible, así que colocaremos todo el código dentro del método: public void createPDF(File pdfNewFile) para poder seguir a modo de guión como creamos un documento PDF, añado ya unas variables de fuentes y una ubicación para una imagen que utilizaré en el ejemplo:

package org.xulescode.itext;

import com.itextpdf.*;
import java.io.*; 

/**
 * Example of using the iText library to work with PDF documents on Java, 
 * lets you create, analyze, modify and maintain documents in this format.
 * Ejemplo de uso de la librería iText para trabajar con documentos PDF en Java, 
 * nos permite crear, analizar, modificar y mantener documentos en este formato.
 *
 * @author xules You can follow me on my website http://www.codigoxules.org/en
 * Puedes seguirme en mi web http://www.codigoxules.org
 */
public class GeneratePDFFileIText {

    private static final Font chapterFont = FontFactory.getFont(FontFactory.HELVETICA, 26, Font.BOLDITALIC);
    private static final Font paragraphFont = FontFactory.getFont(FontFactory.HELVETICA, 12, Font.NORMAL);
        
    private static final Font categoryFont = new Font(Font.FontFamily.TIMES_ROMAN, 18, Font.BOLD);
    private static final Font subcategoryFont = new Font(Font.FontFamily.TIMES_ROMAN, 16, Font.BOLD);
    private static final Font blueFont = new Font(Font.FontFamily.TIMES_ROMAN, 12, Font.NORMAL, BaseColor.RED);    
    private static final Font smallBold = new Font(Font.FontFamily.TIMES_ROMAN, 12, Font.BOLD);
    
    private static final String iTextExampleImage = "/home/xules/codigoxules/iText-Example-image.png";
    /**
     * We create a PDF document with iText using different elements to learn 
     * to use this library.
     * Creamos un documento PDF con iText usando diferentes elementos para aprender 
     * a usar esta librería.
     * @param pdfNewFile  <code>String</code> 
     *      pdf File we are going to write. 
     *      Fichero pdf en el que vamos a escribir. 
     */
    public void createPDF(File pdfNewFile) {
        // Aquí introduciremos el código para crear el PDF.
    }
}


 

2. Creación del documento y metadatos

En este primer paso con Java iText PDF necesitamos crear un documento para trabajar con él e ir añadiéndole las diferentes páginas que necesitemos para nuestro ejemplo: Document document = new Document();, una vez creado vamos a asociar el documento de trabajo con el fichero de salida esto lo hacemos con el método com.itextpdf.text.pdf.PdfWriter, este es el código que necesitamos:

        // We create the document and set the file name.        
        // Creamos el documento e indicamos el nombre del fichero.
        try {
            Document document = new Document();
            try {
                PdfWriter.getInstance(document, new FileOutputStream(pdfNewFile));
            } catch (FileNotFoundException fileNotFoundException) {
                System.out.println("No such file was found to generate the PDF "
                        + "(No se encontró el fichero para generar el pdf)" + fileNotFoundException);
            }
            document.open();

            // AQUÍ COMPLETAREMOS NUESTRO CÓDIGO PARA GENERAR EL PDF

            document.close();
            System.out.println("Your PDF file has been generated!(¡Se ha generado tu hoja PDF!");
        } catch (DocumentException documentException) {
            System.out.println("The file not exists (Se ha producido un error al generar un documento): " + documentException);
        }

Ahora vamos añadir información a nuestro documento creado con Java iText PDF introduciendo los metadatos, estos se añaden directamente en los valores del documento definido anteriormente: document:

            // We add metadata to PDF
            // Añadimos los metadatos del PDF
            document.addTitle("Table export to PDF (Exportamos la tabla a PDF)");
            document.addSubject("Using iText (usando iText)");
            document.addKeywords("Java, PDF, iText");
            document.addAuthor("Código Xules");
            document.addCreator("Código Xules");


 

3. Creamos nuestra primera página

Para la creación de está primera página usaremos los elementos generales:

Y el elemento com.itextpdf.text.Chapter que usamos para añadir unas sección especial y que es de donde vamos a colgar en este ejemplo los elementos anteriormente mencionados, lo puedes consultar en el código:

            // First page
            // Primera página 
            Chunk chunk = new Chunk("This is the title", chapterFont);
            chunk.setBackground(BaseColor.GRAY);
            // Let's create de first Chapter (Creemos el primer capítulo)
            Chapter chapter = new Chapter(new Paragraph(chunk), 1);
            chapter.setNumberDepth(0);
            chapter.add(new Paragraph("This is the paragraph", paragraphFont));
            // We add an image (Añadimos una imagen)
            Image image;
            try {
                image = Image.getInstance(iTextExampleImage);  
                image.setAbsolutePosition(2, 150);
                chapter.add(image);
            } catch (BadElementException ex) {
                System.out.println("Image BadElementException" +  ex);
            } catch (IOException ex) {
                System.out.println("Image IOException " +  ex);
            }
            document.add(chapter);


 

4. Añadimos más elementos de iText a nuestro PDF

Ahora simplemente añadimos unos elementos a nuestra nueva página para seguir probando elementos, en primer lugar creamos un nuevo capítulo al que le damos nombre utilizando com.itextpdf.text.Paragraph, también creamos otro que añadiremos a continuación:

            // Second page - some elements
            // Segunda página - Algunos elementos
            Chapter chapSecond = new Chapter(new Paragraph(new Anchor("Some elements (Añadimos varios elementos)")), 1);
            Paragraph paragraphS = new Paragraph("Do it by Xules (Realizado por Xules)", subcategoryFont);

Para mostrar que se pueden hacer muchas cosas añadimos un ejemplo de como subrayar un párrafo con una línea de puntos, ejemplo sacado del blog de Java iText PDF, y en el que se usa el elemento com.itextpdf.text.pdf.draw.DottedLineSeparator que dibuja una línea de puntos de izquierda a derecha:

            // Underline a paragraph by iText (subrayando un párrafo por iText)
            Paragraph paragraphE = new Paragraph("This line will be underlined with a dotted line (Está línea será subrayada con una línea de puntos).");
            DottedLineSeparator dottedline = new DottedLineSeparator();
            dottedline.setOffset(-2);
            dottedline.setGap(2f);
            paragraphE.add(dottedline);
            chapSecond.addSection(paragraphE);

Para hacer un ejemplo sencillo de listas añadimos del ejemplo: List examples de iText, simplemente para mostrar un ejemplo de uso y ver lo sencillo que es de manejar com.itextpdf.text.List:

            Section paragraphMoreS = chapSecond.addSection(paragraphS);
            // List by iText (listas por iText)
            String text = "test 1 2 3 ";
            for (int i = 0; i < 5; i++) {
                text = text + text;
            }
            List list = new List(List.UNORDERED);
            ListItem item = new ListItem(text);
            item.setAlignment(Element.ALIGN_JUSTIFIED);
            list.add(item);
            text = "a b c align ";
            for (int i = 0; i < 5; i++) {
                text = text + text;
            }
            item = new ListItem(text);
            item.setAlignment(Element.ALIGN_JUSTIFIED);
            list.add(item);
            text = "supercalifragilisticexpialidocious ";
            for (int i = 0; i < 3; i++) {
                text = text + text;
            }
            item = new ListItem(text);
            item.setAlignment(Element.ALIGN_JUSTIFIED);
            list.add(item);
            paragraphMoreS.add(list);
            document.add(chapSecond);

Al finalizar, no podemos olvidarnos añadir nuestro código al documento con document.add(…).


 

5. Uso de tablas en iText: PDFPTable

En este apartado nos centramos en el uso de com.itextpdf.text.pdf.PdfPTable creando una nueva página, que se convertirán en varias como veremos, por la longitud de la tabla que implementaremos para ver el funcionamiento de com.itextpdf.text.pdf.PdfPTable.

En primer lugar en el código añadimos varios elementos para añadir título y subtítulo, que no explicaré más pues utilizamos elementos anteriormente explicados y para más detalles ya lo puedes ver directamente en el código.

Centrémonos en com.itextpdf.text.pdf.PdfPTable que es un elemento que nos permite crear una tabla cuya posición puede ser absoluta pero que también se puede añadir directamente al documento. En este ejemplo simplemente añadimos texto, pero será muy útil para rellenar por ejemplo con los datos obtenidos de la base de datos.

Los pasos que seguimos con los siguientes y los puedes consultar en el código:

  • Creamos la tabla: PdfPTable table = new PdfPTable(numColumns);
  • Añadimos las cabeceras de la tabla: columnHeader = new PdfPCell(new Phrase(«COL » + column));
  • Rellenamos el contenido de la tabla con un bucle for añadiendo cada celda con el código: table.addCell(«Row » + row + » – Col» + column);
  • Finalmente, añadiremos la tabla al documento, añadiéndola en este caso (no tiene porque ser así) al párrafo que creamos al principio para que vaya a continuación.

Este es el código:

            // How to use PdfPTable
            // Utilización de PdfPTable
            
            // We use various elements to add title and subtitle
            // Usamos varios elementos para añadir título y subtítulo
            Anchor anchor = new Anchor("Table export to PDF (Exportamos la tabla a PDF)", categoryFont);
            anchor.setName("Table export to PDF (Exportamos la tabla a PDF)");            
            Chapter chapTitle = new Chapter(new Paragraph(anchor), 1);
            Paragraph paragraph = new Paragraph("Do it by Xules (Realizado por Xules)", subcategoryFont);
            Section paragraphMore = chapTitle.addSection(paragraph);
            paragraphMore.add(new Paragraph("This is a simple example (Este es un ejemplo sencillo)"));
            Integer numColumns = 6;
            Integer numRows = 120;
            // We create the table (Creamos la tabla).
            PdfPTable table = new PdfPTable(numColumns); 
            // Now we fill the PDF table 
            // Ahora llenamos la tabla del PDF
            PdfPCell columnHeader;
            // Fill table rows (rellenamos las filas de la tabla).                
            for (int column = 0; column < numColumns; column++) {
                columnHeader = new PdfPCell(new Phrase("COL " + column));
                columnHeader.setHorizontalAlignment(Element.ALIGN_CENTER);
                table.addCell(columnHeader);
            }
            table.setHeaderRows(1);
            // Fill table rows (rellenamos las filas de la tabla).                
            for (int row = 0; row < numRows; row++) {
                for (int column = 0; column < numColumns; column++) {
                    table.addCell("Row " + row + " - Col" + column);
                }
            }
            // We add the table (Añadimos la tabla)
            paragraphMore.add(table);
            // We add the paragraph with the table (Añadimos el elemento con la tabla).
            document.add(chapTitle);
            document.close();
            System.out.println("Your PDF file has been generated!(¡Se ha generado tu hoja PDF!");


 

6. Resultado Final (Código completo)

Ya hemos completado nuestro código para generar un PDF con iText, ahora solo tenemos que ejecutarlo desde nuestro método main:

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        GeneratePDFFileIText generatePDFFileIText = new GeneratePDFFileIText();
        generatePDFFileIText.createPDF(new File("/home/xules/codigoxules/GeneratePDFFileIText.pdf"));
    }

En el enlace puedes descargar el código completo de este ejemplo:


 

También, puedes ver el código completo directamente:

package org.xulescode.itext;

import com.itextpdf.text.Anchor;
import com.itextpdf.text.BadElementException;
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Chapter;
import com.itextpdf.text.Chunk;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.FontFactory;
import com.itextpdf.text.Image;
import com.itextpdf.text.List;
import com.itextpdf.text.ListItem;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.Section;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.pdf.draw.DottedLineSeparator;
import java.io.*; 

/**
 * Example of using the iText library to work with PDF documents on Java, 
 * lets you create, analyze, modify and maintain documents in this format.
 * Ejemplo de uso de la librería iText para trabajar con documentos PDF en Java, 
 * nos permite crear, analizar, modificar y mantener documentos en este formato.
 *
 * @author xules You can follow me on my website http://www.codigoxules.org/en
 * Puedes seguirme en mi web http://www.codigoxules.org
 */
public class GeneratePDFFileIText {
    // Fonts definitions (Definición de fuentes).
    private static final Font chapterFont = FontFactory.getFont(FontFactory.HELVETICA, 26, Font.BOLDITALIC);
    private static final Font paragraphFont = FontFactory.getFont(FontFactory.HELVETICA, 12, Font.NORMAL);
        
    private static final Font categoryFont = new Font(Font.FontFamily.TIMES_ROMAN, 18, Font.BOLD);
    private static final Font subcategoryFont = new Font(Font.FontFamily.TIMES_ROMAN, 16, Font.BOLD);
    private static final Font blueFont = new Font(Font.FontFamily.TIMES_ROMAN, 12, Font.NORMAL, BaseColor.RED);    
    private static final Font smallBold = new Font(Font.FontFamily.TIMES_ROMAN, 12, Font.BOLD);
    
    private static final String iTextExampleImage = "/home/xules/codigoxules/iText-Example-image.png";
    /**
     * We create a PDF document with iText using different elements to learn 
     * to use this library.
     * Creamos un documento PDF con iText usando diferentes elementos para aprender 
     * a usar esta librería.
     * @param pdfNewFile  <code>String</code> 
     *      pdf File we are going to write. 
     *      Fichero pdf en el que vamos a escribir. 
     */
    public void createPDF(File pdfNewFile) {
        // We create the document and set the file name.        
        // Creamos el documento e indicamos el nombre del fichero.
        try {
            Document document = new Document();
            try {

                PdfWriter.getInstance(document, new FileOutputStream(pdfNewFile));

            } catch (FileNotFoundException fileNotFoundException) {
                System.out.println("No such file was found to generate the PDF "
                        + "(No se encontró el fichero para generar el pdf)" + fileNotFoundException);
            }
            document.open();
            // We add metadata to PDF
            // Añadimos los metadatos del PDF
            document.addTitle("Table export to PDF (Exportamos la tabla a PDF)");
            document.addSubject("Using iText (usando iText)");
            document.addKeywords("Java, PDF, iText");
            document.addAuthor("Código Xules");
            document.addCreator("Código Xules");
            
            // First page
            // Primera página 
            Chunk chunk = new Chunk("This is the title", chapterFont);
            chunk.setBackground(BaseColor.GRAY);
            // Let's create de first Chapter (Creemos el primer capítulo)
            Chapter chapter = new Chapter(new Paragraph(chunk), 1);
            chapter.setNumberDepth(0);
            chapter.add(new Paragraph("This is the paragraph", paragraphFont));
            // We add an image (Añadimos una imagen)
            Image image;
            try {
                image = Image.getInstance(iTextExampleImage);  
                image.setAbsolutePosition(2, 150);
                chapter.add(image);
            } catch (BadElementException ex) {
                System.out.println("Image BadElementException" +  ex);
            } catch (IOException ex) {
                System.out.println("Image IOException " +  ex);
            }
            document.add(chapter);
            
            // Second page - some elements
            // Segunda página - Algunos elementos
            Chapter chapSecond = new Chapter(new Paragraph(new Anchor("Some elements (Añadimos varios elementos)")), 1);
            Paragraph paragraphS = new Paragraph("Do it by Xules (Realizado por Xules)", subcategoryFont);
            
            // Underline a paragraph by iText (subrayando un párrafo por iText)
            Paragraph paragraphE = new Paragraph("This line will be underlined with a dotted line (Está línea será subrayada con una línea de puntos).");
            DottedLineSeparator dottedline = new DottedLineSeparator();
            dottedline.setOffset(-2);
            dottedline.setGap(2f);
            paragraphE.add(dottedline);
            chapSecond.addSection(paragraphE);
            
            Section paragraphMoreS = chapSecond.addSection(paragraphS);
            // List by iText (listas por iText)
            String text = "test 1 2 3 ";
            for (int i = 0; i < 5; i++) {
                text = text + text;
            }
            List list = new List(List.UNORDERED);
            ListItem item = new ListItem(text);
            item.setAlignment(Element.ALIGN_JUSTIFIED);
            list.add(item);
            text = "a b c align ";
            for (int i = 0; i < 5; i++) {
                text = text + text;
            }
            item = new ListItem(text);
            item.setAlignment(Element.ALIGN_JUSTIFIED);
            list.add(item);
            text = "supercalifragilisticexpialidocious ";
            for (int i = 0; i < 3; i++) {
                text = text + text;
            }
            item = new ListItem(text);
            item.setAlignment(Element.ALIGN_JUSTIFIED);
            list.add(item);
            paragraphMoreS.add(list);
            document.add(chapSecond);
            
            // How to use PdfPTable
            // Utilización de PdfPTable
            
            // We use various elements to add title and subtitle
            // Usamos varios elementos para añadir título y subtítulo
            Anchor anchor = new Anchor("Table export to PDF (Exportamos la tabla a PDF)", categoryFont);
            anchor.setName("Table export to PDF (Exportamos la tabla a PDF)");            
            Chapter chapTitle = new Chapter(new Paragraph(anchor), 1);
            Paragraph paragraph = new Paragraph("Do it by Xules (Realizado por Xules)", subcategoryFont);
            Section paragraphMore = chapTitle.addSection(paragraph);
            paragraphMore.add(new Paragraph("This is a simple example (Este es un ejemplo sencillo)"));
            Integer numColumns = 6;
            Integer numRows = 120;
            // We create the table (Creamos la tabla).
            PdfPTable table = new PdfPTable(numColumns); 
            // Now we fill the PDF table 
            // Ahora llenamos la tabla del PDF
            PdfPCell columnHeader;
            // Fill table rows (rellenamos las filas de la tabla).                
            for (int column = 0; column < numColumns; column++) {
                columnHeader = new PdfPCell(new Phrase("COL " + column));
                columnHeader.setHorizontalAlignment(Element.ALIGN_CENTER);
                table.addCell(columnHeader);
            }
            table.setHeaderRows(1);
            // Fill table rows (rellenamos las filas de la tabla).                
            for (int row = 0; row < numRows; row++) {
                for (int column = 0; column < numColumns; column++) {
                    table.addCell("Row " + row + " - Col" + column);
                }
            }
            // We add the table (Añadimos la tabla)
            paragraphMore.add(table);
            // We add the paragraph with the table (Añadimos el elemento con la tabla).
            document.add(chapTitle);
            document.close();
            System.out.println("Your PDF file has been generated!(¡Se ha generado tu hoja PDF!");
        } catch (DocumentException documentException) {
            System.out.println("The file not exists (Se ha producido un error al generar un documento): " + documentException);
        }
    }
    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        GeneratePDFFileIText generatePDFFileIText = new GeneratePDFFileIText();
        generatePDFFileIText.createPDF(new File("/home/xules/codigoxules/GeneratePDFFileIText.pdf"));
    }
}

 

Este es el PDF que se obtiene como resultado final de este ejemplo:


 

Documentación Java iText PDF

Java iText PDF

Espero que te haya sido útil.