Páginas

7/8/15

Ejemplo de un reporte pdf con iText desde Java.

Ejemplo de un reporte pdf con iText desde Java.

Como hacer un reporte pdf desde Java con iText 5.5.6. Ejemplo iText.




iText Dato Java icon iText pdf es una librería muy potente y fácil de usar para generar reportes desde Java , si lo que necesitas es hacer un reporte rápido, sencillo y sin muchas complicaciones esta es la librería para ti, solo la descargamos y la agregamos al proyecto, hay que recordar que la construcción del reporte pdf va ser enteramente en el código fuente Java a diferencia de Jasper Reports que utiliza archivos externos y después los invocamos desde el código. En este tutorial de iText vamos a generar un reporte pdf que tendrá algunas párrafos, listas, tablas y celdas para mostrar un poco las funcionalidades que podemos conseguir con la misma.

Vamos hacer una breve reseña de una cámara y sus características, este es el resultado que queremos conseguir:
Reporte pdf con iText
Reporte pdf con iText
Se ve chévere el ejemplo así que manos al teclado, primero nos vamos a la página de souceforge y nos descargamos la última versión de iText, en este momento la última versión de iText es la 5.5.6, después de descargarla vamos a crear un proyecto Java llamado iTextDatoJava, creamos un paquete llamado itextDJ y dentro de ese paquete creamos la clase que generará el reporte pdf llamada DJiTextEjemplo, ahora descomprimimos el archivo itext-***.zip que descargamos anteriormente y vamos a importar la librería itextpdf-***.jar
a nuestro build path. Así debería verse nuestro proyecto hasta ahora:


Proyecto iText
Proyecto iText
Para comenzar tenemos con el código que crear un atributo Document de tipo com.itextpdf.text.Document con la cantidad de espacio entre sus márgenes y el tamaño del mismo, creamos el FileOutputStream con su nombre, obtenemos la instancia PDFWriter con el documento y el archivo antes creado y abrimos el documento para comenzar a construirlo.
   // Creacion del documento con los margenes
   Document document = new Document(PageSize.A4, 35, 30, 50, 50);

   // El archivo pdf que vamos a generar
   FileOutputStream fileOutputStream = new FileOutputStream(
     "reportePDFDatoJava.pdf");
   
   // Obtener la instancia del PdfWriter
   PdfWriter.getInstance(document, fileOutputStream);

   // Abrir el documento
   document.open();
   
Esto es fundamental para la creación del reporte pdf con iText, el reporte que queremos generar posee varias imágenes y distintos tipos de fuentes, este es el código para lograr hacer eso:
   Image image = null;

   // Obtenemos el logo de datojava
   image = Image.getInstance("fotoDJ.png");
   image.scaleAbsolute(80f, 60f);

   // Crear las fuentes para el contenido y los titulos
   Font fontContenido = FontFactory.getFont(
     FontFactory.TIMES_ROMAN.toString(), 11, Font.NORMAL,
     BaseColor.DARK_GRAY);
   Font fontTitulos = FontFactory.getFont(
     FontFactory.TIMES_BOLDITALIC, 11, Font.UNDERLINE,
     BaseColor.RED);
   
Ahí cargamos el logo de DatoJava que es una imagen que está en la carpeta del proyecto y creamos las fuentes, para añadir la imagen al documento vamos a crear una PdfPTable y una PdfPCell a la cual vamos añadirle la imagen, a esta celda hay que establecerle unas cuantas propiedades, alinearla a la derecha, sin borde, etc... Añadirla a la tabla y después añadir la tabla al documento.
   // Creacion de una tabla
   PdfPTable table = new PdfPTable(1);

   // Agregar la imagen anterior a una celda de la tabla
   PdfPCell cell = new PdfPCell(image);

   // Propiedades de la celda
   cell.setColspan(5);
   cell.setBorderColor(BaseColor.WHITE);
   cell.setHorizontalAlignment(Element.ALIGN_RIGHT);

   // Agregar la celda a la tabla
   table.addCell(cell);

   // Agregar la tabla al documento
   document.add(table);
   
Ese código es solo para añadir el logo, ahora vamos añadir la otra imagen y todo el contenido textual del reporte.
   // Creacion del parrafo
   Paragraph paragraph = new Paragraph();

   // Agregar un titulo con su respectiva fuente
   paragraph.add(new Phrase("Características:", fontTitulos));

   // Agregar saltos de linea
   paragraph.add(new Phrase(Chunk.NEWLINE));
   paragraph.add(new Phrase(Chunk.NEWLINE));

   // Agregar contenido con su respectiva fuente
   paragraph
     .add(new Phrase(
       "El sensor de la X-E1 presenta el mismo excelente rendimiento que el X-Trans CMOS "
         + "de 16 megapíxeles del modelo superior de la serie X, la X-Pro1. Gracias la matriz "
         + "de filtro de color con disposición aleatoria de los píxeles, desarrollada originalmente"
         + " por Fujifilm, el sensor X-Trans CMOS elimina la necesidad del filtro óptico de paso bajo"
         + " que se utiliza en los sistemas convencionales para inhibir el muaré a expensas de la"
         + " resolución. Esta matriz innovadora permite al sensor X-Trans CMOS captar la luz sin filtrar"
         + " del objetivo y obtener una resolución sin precedentes. La exclusiva disposición aleatoria de"
         + " la matriz de filtro de color resulta asimismo muy eficaz para mejorar la separación de ruido"
         + " en la fotografía de alta sensibilidad. Otra ventaja del gran sensor APS-C es la capacidad"
         + " para crear un hermoso efecto “bokeh”, el estético efecto desenfocado que se crea al disparar"
         + " con poca profundidad de campo.",
       fontContenido));

   paragraph.add(new Phrase(Chunk.NEWLINE));
   paragraph.add(new Phrase(Chunk.NEWLINE));
   paragraph.add(new Phrase(Chunk.NEWLINE));
   paragraph.add(new Phrase("Otras Caracaterísticas:", fontTitulos));

   // Agregar el parrafo al documento
   document.add(paragraph);

   // La lista final
   List listaFinal = new List(List.UNORDERED);
   ListItem listItem = new ListItem();
   List list = new List();

   // Crear sangria en la lista
   list.setListSymbol(new Chunk("   "));
   ListItem itemNuevo = new ListItem("   ");

   // ZapfDingbatsListm, lista con simbolos
   List listSymbol = new ZapfDingbatsList(51);

   // Agregar contenido a la lista
   listSymbol
     .add(new ListItem(
       "Sensor CMOS X-Trans – Consigue una calidad de imagen superior",
       fontContenido));
   listSymbol
     .add(new ListItem(
       "Visor electrónico OLED de 2,36 pulgadas de alta resolución y luminosidad",
       fontContenido));
   listSymbol.add(new ListItem("Diseño y accesorios", fontContenido));
   listSymbol.add(new ListItem("Rápida respuesta", fontContenido));

   itemNuevo.add(listSymbol);
   list.add(itemNuevo);
   listItem.add(list);

   // Agregar todo a la lista final
   listaFinal.add(listItem);

   // Agregar la lista
   document.add(listaFinal);

   paragraph = new Paragraph();
   paragraph.add(new Phrase(Chunk.NEWLINE));
   paragraph.add(new Phrase(Chunk.NEWLINE));
   document.add(paragraph);
   
Repasando el código anterior, en la línea 45 hay algo interesante, ahí estamos utilizando una lista de tipo com.itextpdf.text.ZapfDingbatsList la cual posee un constructor que recibe un int y así podemos elegir entre distintos símbolos que la lista nos proporciona, esta es la lista de símbolos que posee actualmente ZapfDingbatsList. Ahora solo falta agregar las ultimas imágenes al documento y terminamos el tutorial de iText.
   // Crear tabla nueva con dos posiciones
   table = new PdfPTable(2);
   float[] longitudes = { 5.0f, 5.0f };

   // Establecer posiciones de celdas
   table.setWidths(longitudes);
   cell = new PdfPCell();

   // Cargar imagenes del producto y agregarlas
   image = Image.getInstance("fujifilmex1-2.png");
   image.scaleAbsolute(40f, 20f);
   table.getDefaultCell().setBorderColor(BaseColor.WHITE);
   table.addCell(image);
   image = Image.getInstance("fujifilmex1-3.png");
   image.scaleAbsolute(40f, 20f);
   table.addCell(image);

   // Agregar la tabla al documento
   document.add(table);

   // Cerrar el documento
   document.close();

   // Abrir el archivo
   File file = new File("reportePDFDatoJava.pdf");
   Desktop.getDesktop().open(file);
   
Para evitar excepciones con iText debemos cerrar el documento al finalizar la construcción del mismo, y si el archivo PDF que estamos intentando abrir ya se encuentra abierto también saltara una excepción. Como este ejemplo funciona para una aplicación de escritorio utilizamos la clase Desktop para abrir el archivo que por defecto en este momento se está generando dentro de la carpeta del proyecto en la raíz, desde ese mismo path obtenemos las imágenes. Este es el código de la clase DJiTextEjemplo completo:
Mostrar el codigo.
Ocultar el codigo.
   package itextDJ;

import java.awt.Desktop;
import java.io.File;
import java.io.FileOutputStream;

import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Chunk;
import com.itextpdf.text.Document;
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.PageSize;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.ZapfDingbatsList;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;

/**
 * 
 * @author http://datojava.blogspot.com/
 *
 */
public class DJiTextEjemplo {

 public static void main(String[] args) {

  // Creacion del documento con los margenes
  Document document = new Document(PageSize.A4, 35, 30, 50, 50);
  try {

   // El archivo pdf que vamos a generar
   FileOutputStream fileOutputStream = new FileOutputStream(
     "reportePDFDatoJava.pdf");
   
   // Obtener la instancia del PdfWriter
   PdfWriter.getInstance(document, fileOutputStream);

   // Abrir el documento
   document.open();
   
   Image image = null;

   // Obtenemos el logo de datojava
   image = Image.getInstance("fotoDJ.png");
   image.scaleAbsolute(80f, 60f);

   // Crear las fuentes para el contenido y los titulos
   Font fontContenido = FontFactory.getFont(
     FontFactory.TIMES_ROMAN.toString(), 11, Font.NORMAL,
     BaseColor.DARK_GRAY);
   Font fontTitulos = FontFactory.getFont(
     FontFactory.TIMES_BOLDITALIC, 11, Font.UNDERLINE,
     BaseColor.RED);

   // Creacion de una tabla
   PdfPTable table = new PdfPTable(1);

   // Agregar la imagen anterior a una celda de la tabla
   PdfPCell cell = new PdfPCell(image);

   // Propiedades de la celda
   cell.setColspan(5);
   cell.setBorderColor(BaseColor.WHITE);
   cell.setHorizontalAlignment(Element.ALIGN_RIGHT);

   // Agregar la celda a la tabla
   table.addCell(cell);

   // Agregar la tabla al documento
   document.add(table);

   // Cargar otra imagen
   image = Image.getInstance("fujifilmex1-1.png");
   image.scaleAbsolute(180f, 140f);

   // Agregar la imagen
   document.add(image);

   // Creacion del parrafo
   Paragraph paragraph = new Paragraph();

   // Agregar un titulo con su respectiva fuente
   paragraph.add(new Phrase("Características:", fontTitulos));

   // Agregar saltos de linea
   paragraph.add(new Phrase(Chunk.NEWLINE));
   paragraph.add(new Phrase(Chunk.NEWLINE));

   // Agregar contenido con su respectiva fuente
   paragraph
     .add(new Phrase(
       "El sensor de la X-E1 presenta el mismo excelente rendimiento que el X-Trans CMOS "
         + "de 16 megapíxeles del modelo superior de la serie X, la X-Pro1. Gracias la matriz "
         + "de filtro de color con disposición aleatoria de los píxeles, desarrollada originalmente"
         + " por Fujifilm, el sensor X-Trans CMOS elimina la necesidad del filtro óptico de paso bajo"
         + " que se utiliza en los sistemas convencionales para inhibir el muaré a expensas de la"
         + " resolución. Esta matriz innovadora permite al sensor X-Trans CMOS captar la luz sin filtrar"
         + " del objetivo y obtener una resolución sin precedentes. La exclusiva disposición aleatoria de"
         + " la matriz de filtro de color resulta asimismo muy eficaz para mejorar la separación de ruido"
         + " en la fotografía de alta sensibilidad. Otra ventaja del gran sensor APS-C es la capacidad"
         + " para crear un hermoso efecto “bokeh”, el estético efecto desenfocado que se crea al disparar"
         + " con poca profundidad de campo.",
       fontContenido));

   paragraph.add(new Phrase(Chunk.NEWLINE));
   paragraph.add(new Phrase(Chunk.NEWLINE));
   paragraph.add(new Phrase(Chunk.NEWLINE));
   paragraph.add(new Phrase("Otras Caracaterísticas:", fontTitulos));

   // Agregar el parrafo al documento
   document.add(paragraph);

   // La lista final
   List listaFinal = new List(List.UNORDERED);
   ListItem listItem = new ListItem();
   List list = new List();

   // Crear sangria en la lista
   list.setListSymbol(new Chunk("   "));
   ListItem itemNuevo = new ListItem("   ");

   // ZapfDingbatsListm, lista con simbolos
   List listSymbol = new ZapfDingbatsList(51);

   // Agregar contenido a la lista
   listSymbol
     .add(new ListItem(
       "Sensor CMOS X-Trans – Consigue una calidad de imagen superior",
       fontContenido));
   listSymbol
     .add(new ListItem(
       "Visor electrónico OLED de 2,36 pulgadas de alta resolución y luminosidad",
       fontContenido));
   listSymbol.add(new ListItem("Diseño y accesorios", fontContenido));
   listSymbol.add(new ListItem("Rápida respuesta", fontContenido));

   itemNuevo.add(listSymbol);
   list.add(itemNuevo);
   listItem.add(list);

   // Agregar todo a la lista final
   listaFinal.add(listItem);

   // Agregar la lista
   document.add(listaFinal);

   paragraph = new Paragraph();
   paragraph.add(new Phrase(Chunk.NEWLINE));
   paragraph.add(new Phrase(Chunk.NEWLINE));
   document.add(paragraph);

   // Crear tabla nueva con dos posiciones
   table = new PdfPTable(2);
   float[] longitudes = { 5.0f, 5.0f };

   // Establecer posiciones de celdas
   table.setWidths(longitudes);
   cell = new PdfPCell();

   // Cargar imagenes del producto y agregarlas
   image = Image.getInstance("fujifilmex1-2.png");
   image.scaleAbsolute(40f, 20f);
   table.getDefaultCell().setBorderColor(BaseColor.WHITE);
   table.addCell(image);
   image = Image.getInstance("fujifilmex1-3.png");
   image.scaleAbsolute(40f, 20f);
   table.addCell(image);

   // Agregar la tabla al documento
   document.add(table);

   // Cerrar el documento
   document.close();

   // Abrir el archivo
   File file = new File("reportePDFDatoJava.pdf");
   Desktop.getDesktop().open(file);
  } catch (Exception ex) {
   ex.printStackTrace();
  }
 }
}

   
Es fácil de usar, espero que este ejemplo de iText te haya servido de algo, aquí te dejo el proyecto para que lo descargues, ahí mismo tienes las imágenes, si tratas de compilar la clase sin las imágenes tendrás una excepción así que te cuidado con eso, no olvides compartir la entrada y si tienes alguna duda o sugerencia puedes comentarlo. Suerte my friend.



4 comentarios :

  1. buenos dias te queria molestar estoy haciendo un proyecto en matlab y necesito hacer un reporte en un pdf me dijeron que se puede usar una libreria de java para generarlo no se si puedo usar esto que has utilizado y no se si me puedes guiar para hacerlo si es posible

    ResponderEliminar
    Respuestas
    1. Hola Ernesto, esta librería funciona perfectamente para crear desde 0 todo el reporte, también puedes utilizar iReport para hacer el reporte y después ejecutarlo desde tu aplicación, revista esta entrada y cuéntame si tienes alguna duda:
      http://datojava.blogspot.com/2015/03/TutorialiReportPLSQLJavaPrimefaces1.html

      Suerte!!

      Eliminar
  2. Simplemente perfecto! Muchas gracias por el aporte. Justo esto estaba buscando y soluciono todo a la perfeccion.
    Gracias!
    Saludos!

    ResponderEliminar
    Respuestas
    1. Estimado Pedro Martinez, muchas gracias por tu comentario, que bueno que te funciono!

      Suerte!!

      Eliminar