17 de abril de 2009

Creación de Reportes con JasperRepots y iReports - Parte 6: Grupos

Visita la parte 1 de este tutorial: Reportes con Conexión a Bases de Datos
Visita la parte 2 de este tutorial: Usando DataSources Personalizados
Visita la parte 3 de este tutorial: Parámetros y Variables
Visita la parte 4 de este tutorial: Reportes en aplicaciones web
Visita la parte 5 de este tutorial: Gráficas en Reportes
Visita la parte 7 de este tutorial: Subreportes

En el tutorial anterior vimos como usar grupos para generar la gráfica de los datos de un reporte. Es esa ocasión los grupos fueron un elemento secundario que usamos para auxiliarnos en la generación de dicha gráfica.

Ahora veremos cómo deben ser usados los grupos para, bueno, agrupar un conjunto de datos relacionados y mostrar estos grupos de forma clara en el reporte. Usaremos la misma idea del tutorial anterior, en la que se mostraron las ventas de las consolas de última generación (Wii, XBox 360, y PS3). Solo que en este caso mostraremos por cada consola el nombre de los jugadores que las han comprado, separados claramente de los que han comprado las otras consolas.


Para comenzar creamos un nuevo proyecto en NetBeans (File -> New Project... -> Java -> Java Application). Damos un nombre y una ubicación a nuestro proyecto y presionamos el botón "Finish" para que la clase Main aparezca en nuestro editor.

Recuerden agregar al nodo "Libraries" del panel "Projects" la biblioteca "JasperReports" que creamos en la primer parte del tutorial y el jar "commons-logging-1.1.1.jar".

Usaremos la misma clase "Jugador" en en el tutorial anterior para mantener los datos que serán mostrados en el reporte. La clase quedó de la siguiente forma:

public class Jugador
{ 
    private int id; 
    private String nombre; 
    private String consola;  

    public Jugador(int id, String nombre, String consola) 
    { 
        this.id = id; 
        this.nombre = nombre; 
        this.consola = consola; 
    }  

    public String getConsola() 
    { 
        return consola; 
    }  

    public void setConsola(String consola) 
    { 
        this.consola = consola; 
    }  

    public int getId() 
    { 
        return id; 
    }  

    public void setId(int id) 
    { 
        this.id = id; 
    }  
    
    public String getNombre() 
    { 
        return nombre; 
    }  

    public void setNombre(String nombre) 
    { 
        this.nombre = nombre; 
    } 
}
El código que colocaremos en la clase Main es el mismo que en el tutorial anterior. Solo que en este caso en vez de tener 100 jugadores, modificaremos los ciclos for para tener solo 10. Por lo tanto quedan de la siguiente forma:

for (int i = 1; i <= 4; i++) 
{ 
    listaJugadores.add(new Jugador(i, "Jugador " + i , "Wii")); 
}  

for(int i = 5; i <= 7; i++) 
{ 
    listaJugadores.add(new Jugador(i, "Jugador " + i , "XBox")); 
}  

for(int i = 8; i <= 10; i++) 
{ 
    listaJugadores.add(new Jugador(i, "Jugador " + i , "PS3")); 
}

El resto de la clase es igual que en el tutorial anterior.

Ahora abrimos iReport y creamos un nuevo reporte vacio (Archivo -> New... -> Empty Report). En la ventana que se abre le damos un nombre al reporte (reporteGrupo.jrxml) y lo guardamos en el directorio raíz del proyecto de NetBeans. Presionamos el botón "Finalizar" para que aparezca la plantilla vacio de nuestro reporte.

Colocamos el título del reporte en la banda "Title" usando un texto estático. También agregamos los fields correspondientes para los datos de los objetos Jugador (id, nombre, y consola). En esta ocasión en la banda "Detail" solamente colocamos los fields id y nombre (ya que los grupos serán formados en base al field consola). Y no colocamos nada en la banda "Column Header":



Ahora crearemos el grupo correspondiente a las consolas. Para esto hacemos click derecho en el nodo "report name" del panel "Report Inspector". Y en el menú contextual que aparece seleccionamos la opción "Add Report Group":

Con esto se abrirá la ventana "New group wizard". En ella debemos introducir el nombre del grupo, que en este caso será "CONSOLAS" y el campo sobre el cual se crearán los grupos que, como habiamos dicho, será el campo "consola":


Presionamos el botón "Siguiente >". En la pantalla siguiente dejamos seleccionadas las dos opciones ("Add the group header" y "Add the group footer"). Presionamos en botón "Finalizar" con lo que veremos que en la plantilla de nuestro reporte han aparecido dos nuevas bandas, "CONSOLAS Group Header" y "CONSOLAS Group Footer", además de una nueva variable, CONSOLAS_COUNT:


Agregaré un cuadro negro ("Rectangle" de la paleta de elementos del reporte) en la banda "CONSOLAS Group Header" para poder distinguirlo en el momento de generar el reporte final. Además arrastraré a esta banda el field $F{consola} que creamos anteriormente. Al arrastrar este field se nos preguntará qué es lo que queremos mostrar: el valor del campo ("The field value") o el resultado de una función de agregación ("The result of an aggregation fuction"). Como lo que queremos mostrar es el valor del campo dejamos seleccionada la primera opción (si queremos mostrar el número de los elementos del grupo podemos volver a arrastrar este field a la banda).


Si, al igual que yo, agregaron el cuadro negro en la banda, será neccesario que cambien el color de la letra del campo (Forecolor) a blanco para poder verlo.

El reporte final debe verse más o menos así:


Ahora cambiamos a la pestaña "Preview" para que se compile nuestro reporte y genere, en el mismo directorio en el que colocamos nuestro archivo "reporteGrupo.jrxml", el archivo "reporteGrupo.jasper".

Ahora regresamos al NetBeans y ejecutamos nuestra aplicación. Esto generará un archivo PDF en el mismo directorio que los archivos .jrxml y .jasper. El contenido del reporte el siguiente:



Como podemos ver, los tres grupos (uno por cada consola) se muestran de forma independiente uno de otro. Además en cada grupo se listan solo los jugadores que tienen la consola del grupo.

El código final de la clase Main es el siguiente:

public class Main
{ 
public static void main(String[] args) throws Exception 
  {     
        List listaJugadores = new ArrayList();      
    
        for (int i = 1; i <= 4; i++)     
        {         
            listaJugadores.add(new Jugador(i, "Jugador " + i, "Wii"));     
        }      

        for (int i = 5; i <= 7; i++)     
        {         
            listaJugadores.add(new Jugador(i, "Jugador " + i, "XBox"));     
        }      
        for (int i = 8; i <= 10; i++)     
        {         
            listaJugadores.add(new Jugador(i, "Jugador " + i, "PS3"));     
        }      

        JasperReport reporte = (JasperReport) JRLoader.loadObject("reporteGrupo.jasper");
        JasperPrint jasperPrint = JasperFillManager.fillReport(reporte, null, new JRBeanCollectionDataSource(listaJugadores));      

        JRExporter exporter = new JRPdfExporter();     
        exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);     
        exporter.setParameter(JRExporterParameter.OUTPUT_FILE, new File("reporte grafica.pdf"));      

        exporter.exportReport(); 
    }
}


Bueno, espero que este tutorial les sirva. No olviden dejar sus dudas, comentarios, y sugerencias.

Saludos.

Visita la parte 1 de este tutorial: Reportes con Conexión a Bases de Datos
Visita la parte 2 de este tutorial: Usando DataSources Personalizados
Visita la parte 3 de este tutorial: Parámetros y Variables
Visita la parte 4 de este tutorial: Reportes en aplicaciones web
Visita la parte 5 de este tutorial: Gráficas en Reportes
Visita la parte 7 de este tutorial: Subreportes