Retrospectiva

Estándar

De nuevo se apareció otro de esos enfadosos periodos sin actividad :P, chance sea cosa de buscar inspiración en el pasado, un comic que no he puesto aqui, el primero de los comics que publique en un blog y el debut del protagonista de los comics que he puesto, en su version 1.0 (ya perdí la cuenta de en que numero voy XD)

Debut

Debut

Si ha cambiado bastante, ¿no?

 

Elenco

Estándar

No se si les he dicho, pero la idea con los comics que he hecho es hacer un webComic ya propiamente dicho y bueno en lo que resuelvo los detalles que aun me faltan para es (guiones, ver como hacer un comic sobre programación, etc) aqui va una foto con el potencial elenco :P.

Elenco

Elenco

Encabezados, pie de pagina y conteo de paginas en iText 7

Estándar

Recientemente la librería iText ha liberado su nueva versión la 7.0.2 y en algo que honestamente espero no se haga costumbre (aunque hay mal precedente si recuerda el cambio de la versión 4 a la 5…) las clases y varios de los métodos han sido re escritos desde cero, ¿Como le afecta esto? pues si quiere hacer uso de la versión mas reciente toca hacer una reescritura significativa ya que la versión 5 y 7 no son compatibles entre si y no espere que los ejemplos previos le ayuden.

Esto es particularmente latoso si ya estaba creando encabezado y conteos de pagina como se había descrito en este blog previamente (para la versión 5 de iText), pero no desespere, aquí esta como hacerlo en iText 7

Documento pdf con encabezado y pie de pagina

Documento pdf con encabezado y pie de pagina

En esta entrada veremos como usar iText 7 y el nuevo modelo de eventos para crear un encabezado con un mensaje personalizable y un pie de pagina con el numero de pagina actual, para evitar confundirlo si no a usado iText antes y que esta entrada sea demasiado larga, no se haran comparaciones con la versión anterior y nos enfocaremos en como hacerlo en iText 7.

Agregando iText 7 a su proyecto

Configuración Maven de iText 7

Configuración Maven de iText 7

Para este ejemplo usaremos Maven para agregar las librerias al proyecto, puede usar ya sea el pom.xml o agregar la dependencia itext7-core via NetBeans en este ejemplo usaremos la versión 7.0.2.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>mx.hashSoft</groupId>
    <artifactId>iText7</artifactId>
    <version>1.0</version>
    <packaging>jar</packaging>
    <dependencies>
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itext7-core</artifactId>
            <version>7.0.2</version>
            <type>pom</type>
        </dependency>
    </dependencies>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.7</maven.compiler.source>
        <maven.compiler.target>1.7</maven.compiler.target>
    </properties>
</project>

Eventos de documento

El ejemplo que usaremos para explicar el uso de iText 7 es bastante sencillo, crea un documento pdf el cual solo contendrá lineas y lineas de “Hola Mundo!” y que tendrá un encabezado con el mensaje “Departamento de Recursos Humanos” y un pie de pagina con el numero de pagina actual.

El pie de pagina y encabezado son creados por una clase que implementa la interfaz IEventHandler esta clase se agrega como manejador de evento al objecto documento y se indica cual evento manejara, de modo que se pueden tener múltiples clases manejando diferentes eventos en el mismo documento.

En este caso particular manejaremos el evento PdfDocumentEvent.END_PAGE el cual se activa cuando se llega al final de la pagina, en este punto agregamos el encabezado, pie de pagina y obtendremos el numero de pagina en el que vamos.

Canvas y rectángulos

Al ver el código de la clase EventoPagina seguramente notara que aparte de las tablas que contienen el texto que deseamos mostrar notara que se crean varios objectos Canvas y Rectangle estos cumplen una función muy simple ya que nos permiten colocar los objectos Table donde queramos, sin mover los demás elementos, el objeto Rectangle indica el área donde colocaremos la tabla y con el objecto Canvas lo dibujaremos en ese lugar.

Código

Ahora si vamos a lo bueno, para este ejemplo usaremos dos clases la ya mencionada EventoPagina la cual manejara el evento PdfDocumentEvent.END_PAGE e iText7 esta clase crea el documento Pdf y su contenido, ambas clases tienen comentarios que espero sean suficientes para hacer comprensible su función.

package mx.hashsoft.itext7;

import com.itextpdf.kernel.events.PdfDocumentEvent;
import com.itextpdf.kernel.geom.PageSize;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.Paragraph;
import java.io.FileNotFoundException;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author david
 */
public class iText7 {

    static public void main(String[] args) {
        try {
            // Creamos el escritor del archivo pdf
            PdfWriter pdfWriter = new PdfWriter("./ejemplo_itext7.pdf");
            // Creamos el documento PDF que se almacenara via el escritor
            PdfDocument pdfDoc = new PdfDocument(pdfWriter);
            // Creamos el documento pdf en si, con pagina tamaño letra
            Document doc = new Document(pdfDoc, PageSize.LETTER);
            // Creamos el manejador de evento de pagina, el cual agregara
            // el encabezado y pie de pagina
            EventoPagina evento = new EventoPagina(doc);

            // Indicamos que el manejador se encargara del evento END_PAGE
            pdfDoc.addEventHandler(PdfDocumentEvent.END_PAGE, evento);
            
            // Establecemos los margenes
            doc.setMargins(75, 36, 75, 36);

            // Creamos el contenido, por motivos de ejemplo es solo Hola Mundo!
            // una y otra vez
            for (int i = 0; i < 450; i++) {
                doc.add(new Paragraph("Hola Mundo!"));
            }

            // Cerramos el documento
            doc.close();

        } catch (FileNotFoundException ex) {
            Logger.getLogger(iText7.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}
package mx.hashsoft.itext7;

import com.itextpdf.kernel.events.Event;
import com.itextpdf.kernel.events.IEventHandler;
import com.itextpdf.kernel.events.PdfDocumentEvent;
import com.itextpdf.kernel.geom.Rectangle;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfPage;
import com.itextpdf.kernel.pdf.canvas.PdfCanvas;
import com.itextpdf.layout.Canvas;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.Table;

/**
 *
 * @author david
 */
public class EventoPagina implements IEventHandler {

    private final Document documento;

    public EventoPagina(Document doc) {
        documento = doc;
    }
    
    /**
     * Crea el rectangulo donde pondremos el encabezado
     * @param docEvent Evento de documento
     * @return Area donde colocaremos el encabezado
     */
    private Rectangle crearRectanguloEncabezado(PdfDocumentEvent docEvent) {
        PdfDocument pdfDoc = docEvent.getDocument();
        PdfPage page = docEvent.getPage();        
        
        float xEncabezado = pdfDoc.getDefaultPageSize().getX() + documento.getLeftMargin();
        float yEncabezado = pdfDoc.getDefaultPageSize().getTop() - documento.getTopMargin();
        float anchoEncabezado = page.getPageSize().getWidth() - 72;
        float altoEncabezado = 50F;

        Rectangle rectanguloEncabezado = new Rectangle(xEncabezado, yEncabezado, anchoEncabezado, altoEncabezado);
        
        return rectanguloEncabezado;        
    }
    
    /**
     * Crea el rectangulo donde pondremos el pie de pagina
     * @param docEvent Evento del documento
     * @return Area donde colocaremos el pie de pagina
     */
    private Rectangle crearRectanguloPie(PdfDocumentEvent docEvent) {
        PdfDocument pdfDoc = docEvent.getDocument();
        PdfPage page = docEvent.getPage();
        
        float xPie = pdfDoc.getDefaultPageSize().getX() + documento.getLeftMargin();
        float yPie = pdfDoc.getDefaultPageSize().getBottom() ;
        float anchoPie = page.getPageSize().getWidth() - 72;
        float altoPie = 50F;

        Rectangle rectanguloPie = new Rectangle(xPie, yPie, anchoPie, altoPie);
        
        return rectanguloPie;
    }
    
    /**
     * Crea la tabla que contendra el mensaje del encabezado
     * @param mensaje Mensaje que desplegaremos
     * @return Tabla con el mensaje de encabezado
     */
    private Table crearTablaEncabezado(String mensaje) {
        float[] anchos = {1F};
        Table tablaEncabezado = new Table(anchos);
        tablaEncabezado.setWidth(527F);

        tablaEncabezado.addCell(mensaje);
        
        return tablaEncabezado;
    }
    
    /**
     * Crea la tabla de pie de pagina, con el numero de pagina
     * @param docEvent Evento del documento
     * @return Pie de pagina con el numero de pagina
     */
    private Table crearTablaPie(PdfDocumentEvent docEvent) {
        PdfPage page = docEvent.getPage();
        float[] anchos = {1F};
        Table tablaPie = new Table(anchos);
        tablaPie.setWidth(527F);
        Integer pageNum = docEvent.getDocument().getPageNumber(page);
        
        tablaPie.addCell("Pagina " + pageNum);
        
        return tablaPie;
    }
    

    /**
     * Manejador del evento de cambio de pagina, agrega el encabezado y pie de pagina
     * @param event Evento de pagina
     */
    @Override
    public void handleEvent(Event event) {
        PdfDocumentEvent docEvent = (PdfDocumentEvent) event;
        PdfDocument pdfDoc = docEvent.getDocument();
        PdfPage page = docEvent.getPage();
        PdfCanvas canvas = new PdfCanvas(page.newContentStreamBefore(), page.getResources(), pdfDoc);        
        
        Table tablaEncabezado = this.crearTablaEncabezado("Departamento de Recursos Humanos");
        Rectangle rectanguloEncabezado = this.crearRectanguloEncabezado(docEvent);        
        Canvas canvasEncabezado = new Canvas(canvas, pdfDoc, rectanguloEncabezado);        
        canvasEncabezado.add(tablaEncabezado);      

        Table tablaNumeracion = this.crearTablaPie(docEvent);
        Rectangle rectanguloPie = this.crearRectanguloPie(docEvent);
        Canvas canvasPie = new Canvas(canvas, pdfDoc, rectanguloPie);        
        canvasPie.add(tablaNumeracion);
    }
}

Espero que esta entrada halla sido de utilidad y nos vemos en la próxima :).