Archivo

Entradas Etiquetadas ‘ireport’

Integración de JasperReports en aplicaciones Java

Domingo, 10 de octubre de 2010 Sin comentarios

Lo más complicado de integrar JasperReports en una aplicación Java es encontrar buena documentación de como hacerlo. JasperReports es muy potente y a la vez complejo que las alternativas que brinda son muchísimas. Fui encontrando distintos ejemplos y pequeños tutoriales que realmente no me sirvieron. Esta entrada está basada en el libro JasperReports 3.5 for Java Developers de David R. Heffelfinger. Para aquellos que no quieran comprar el libro, acá va un muy somero tutorial de como hacer funcionar esto. Básicamente es el tutorial que no pude encontrar en mi lucha y que hago como ayuda-memoria para mí y quizás sirva a alguien. Realmente recomiendo comprar el libro ya que es muchísimo más amplio que esta pequeña guía y muestra el uso de muchas más opciones y alternativas que simplemente voy a omitir. Se supone que el código que aparece en esta entrada debería ser correcto y funcionar, pero si encuentran algún error háganme saber y será corregido.

Todo el software necesario puede conseguirse en http://www.jaspersoft.com/

Otros links de interés:

iReport http://sourceforge.net/projects/ireport/files/

jFreeChart http://sourceforge.net/projects/jfreechart/

Breve introducción

Hay un par de conceptos que deben tenerse presentes a la hora de utilizar JasperReports para que no se convierta todo en un gran dolor de cabeza. Los pasos que daremos para alcanzar nuestro objetivo son los siguientes:

  1. crear una plantilla para el reporte (jrxml file)
  2. compilar la plantilla
  3. generar el reporte (a un archivo jrprint o a un pdf o por pantalla)

Creando la plantilla para el reporte

Esta parte es una de las más simples. Para la generación de la plantilla utilizamos iReport (yo estoy usando la versión 3.7.5). iReport tiene un muy buen wizard para la creación de plantillas y muchas opciones para cambiar el layout. Las plantillas pueden incluir elementos estáticos y dinámicos y tener embebidas las consultas sql necesarias para obtener los datos de una base de datos. También existe la posibilidad de pasar los datos programáticamente al reporte. Los ejemplos que están a continuación asumen que la consulta está embebida en el reporte y solo se hará referencia al objeto de datos que puede pasarse al reporte.

Las plantillas de reportes son archivos de extensión jrxml. El formato del archivo es en realidad un xml estándar con otra extensión.

Compilando el reporte

JasperReports no utiliza las plantillas de reportes tal como son guardadas por iReport sino que las compila. Durante este proceso el xml es parseado y la información se guarda como objetos serializados en archivos de extensión jasper. No me puse a escarbar aún en estos archivos así que no puedo decir mucho de ellos.

En la medida que las plantillas no cambien no tienen porque ser compiladas cada vez que necesitamos el reporte, sino que usaremos como entrada los archivos .jasper ya compilados.

El siguiente fragmento de código compila una plantilla (.jrxml) para convertirla en un reporte .jasper


import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperCompileManager;

public class compileReport {

public static void main(String[] args) {
    try {
        System.out.println("Compiling report...");
        JasperCompileManager.compileReportToFile("firstTestReport.jrxml");
       System.out.println("Done!");
    } catch (JRException e) {
        e.printStackTrace();
    }
}

La clase JasperCompileManager provee varios métodos para compilar las plantillas ya sea utilizando archivos o streams como salida. En este caso estamos mandando la salida a un archivo el cual tendrá el mismo nombre que la plantilla con extensión .jasper.

Generando el reporte a un archivo pdf
Una vez que tenemos nuestra plantilla compilada podemos llenar el reporte y utilizar distintas formas de salida para el mismo, ya sea un archivo pdf, html, excel, un visor en pantalla y una larga lista de etcéteras. El siguiente fragmento de código genera un archivo pdf

import java.io.File;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRExporterParameter;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.export.JRPdfExporter;
import net.sf.jasperreports.engine.util.JRLoader;

public class exportToPdf {
    public static void main(String[] args) {
        File file = new File("firstTestReport.jrprint");
        try {
            JasperPrint jasperPrint = (JasperPrint) JRLoader.loadObject(file);
            JRPdfExporter pdfExporter = new JRPdfExporter();
            pdfExporter.setParameter(JRExporterParameter.JASPER_PRINT,  jasperPrint);
            pdfExporter.setParameter(JRExporterParameter.OUTPUT_FILE_NAME,  "firstTestReport.pdf");
            System.out.println("Exporting report...");
            pdfExporter.exportReport();
            System.out.println("Done!");
        } catch (JRException e){ }
    }
}

Generando el reporte a pantalla

Ya mencionamos que los reportes podían generarse y enviarse a distintas salida, la pantalla es un muy buena alternativa para la pre visualización de reportes, así que acá va el fragmente de código que genera el reporte y lo envía a pantalla

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Properties;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.view.JasperViewer;

public class reportView {

    public static void main(String[] args) {
        try {
            JasperPrint print;
            String url = "jdbc:postgresql://miserver/midatabase/";
            Properties props = new Properties();
            props.setProperty("user","miuser");
            props.setProperty("password","mipassword");
            props.setProperty("port", "5432");
            Connection conn = DriverManager.getConnection(url, props);
            print = JasperFillManager.fillReport("firstTestReport.jasper", new HashMap(), conn);
            JasperViewer view = new JasperViewer(print);
            view.setVisible(true);
        } catch (JRException ex) {}
          catch ( SQLException e ){}
     }
}

En este caso estamos pasando una conexión al método fillReport, la cual será utilizada para conectarse a la base de datos y ejecutar las sentencias sql embebidas en la plantilla. El método también soporta, en lugar de una conexión, una fuente de datos que contenga los valores necesarios para el reporte. JasperReports provee de un data source vacio (JREmptyDataSource) que puede ser utilizado para probar los reportes sin datos.