JasperReports

RECU-0237 (Recurso Ficha Técnica)

Descripción

Es una potente herramienta en código abierto de generación de informes que permite generar información detallada en formato PDF, HTML, XLS, CSV o XML. Ha sido desarrollada completamente en Java, por lo que puede ser usada en una amplia variedad de aplicaciones Java para generar contenido dinámico.

JasperReports trabaja de forma muy similar a un compilador y un interprete. Se siguen los siguientes pasos:

  1. EL desarrollador diseña el reporte codificándolo en XML de acuerdo a las etiquetas y atributos definidos en jasperreports.dtd. En el XML, el desarrollador puede definir todo le formato del informe describiendo la posición del texto, gráficos, dibujos, realizar cálculos, etc,...
  2. El archivo XML es compilado mediante el método compileReport(), localizado en la clase net.sf.jasperreports.engine.JasperCompileManager  
  3. Una vez obtenido el archivo .jasper, se necesitan datos dinámicos que cumplimenten el reporte. Por ello se acude al JRDataSource. Para rellenar el informe, se pueden usar los métodos *fillReportXXX()* de la clase net.sf.jasperreports.engine.JasperFillManager. Estos métodos reciben como parámetro el objeto del diseño del informe, o un fichero que representa tal objeto, en un formulario serializado, así como una conexión JDBC a la base de datos en donde se almacenan los datos que rellenarán el informe o un Bean que contenga estos datos.
  4. Se obtiene un archivo .print exportable en varios formatos PDF, HTML, XML, XSL, CVS.

A continuación presentamos un modelo gráfico con la secuencia

La creación del XML que da soporte a la creación  del archivo suele ser compleja, especialmente para los desarrolladores con poca experiencia. Por ello, se utiliza con frecuencia algunas librerías de apoyo para la edición y exportación de contenidos.

Ejemplos de uso

Para desarrollar este ejemplo, lo primero que ha de hacerse es el diseño del informe, utilizando para ello la herramienta gráfica iReport. Se trata de un diseño muy sencillo en el que va a haber sólo dos campos de texto: uno que mostrará el título del informe y otro que simplemente contendrá un nombre.

El funcionamiento es bien sencillo. El usuario ha de introducir dos valores: la tarea a ejecutar y la ubicación del fichero a manipular. Si se sigue el proceso completo, es decir, si se parte del diseño de iReport sin compilar, cuya extensión es .jrxml, se debe ejecutar la aplicación con los siguientes argumentos:

    1. Usar el jrxml para generar el diseño compilado jasper, mediante el método compileReportToFile:
compile E:/eclipse/workspace/JasperConfluence/src/prueba3
    1. Usar el jasper para generar el fichero jrprint, mediante el método fillReportToFile. En este caso, se utilizan tres argumentos: la ruta del fichero jasper, un map con los parámetros con los que se rellenará el informe (el título y un nombre) y un datasource vacío (JREmptyDataSource), diseñado para que JasperReports prescinda de utilizar el datasource que todo informe de iReport obliga a tener. En este caso, prueba3.jrxml disponía de una conexión Hsql.
fill E:/eclipse/workspace/JasperConfluence/src/prueba3
    1. Usar el jrprint para generar el fichero final, en este caso PDF, mediante la función exportReportToPdfFile. Además, se envían dos parámetros: el título del informe (en la variable que hemos denominado ReportTitle) y un nombre (en la variable que hemos llamado Name).
pdf E:/eclipse/workspace/JasperConfluence/src/prueba3
    1. Opcionalmente, si se desea enviar el informe a la impresora, también emplea el jrprint. Usa el método printReport y, como es obvio, no se genera ningún otro fichero.
print E:/eclipse/workspace/JasperConfluence/src/prueba3

package com.cassiopea.ejemplo;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import net.sf.jasperreports.engine.JREmptyDataSource;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRExporterParameter;
import net.sf.jasperreports.engine.JasperCompileManager;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperPrintManager;
import net.sf.jasperreports.engine.export.JExcelApiExporter;
import net.sf.jasperreports.engine.export.JRCsvExporter;
import net.sf.jasperreports.engine.export.JRXlsExporter;
import net.sf.jasperreports.engine.export.JRXlsExporterParameter;
import net.sf.jasperreports.engine.util.JRLoader;

/**
 * Clase en la que se ejecuta cada uno de los pasos de la generación de informes
 *
 * por separado pasándole como primer argumento la acción a realizar:
 *
 * compile | fill | print | pdf | xml | xmlembed | html | xls | csv
 * 
 * y como segundo argumento el path absoluto del fichero del informe
 *
 */
public class EjemploPorPasos
{
    private static final Log logger = LogFactory.getLog(EjemploPorPasos.class);

    private static final String TASK_COMPILE = "compile";
    private static final String TASK_FILL = "fill";
    private static final String TASK_PRINT = "print";
    private static final String TASK_PDF = "pdf";
    private static final String TASK_XML = "xml";
    private static final String TASK_XML_EMBED = "xmlembed";
    private static final String TASK_HTML = "html";
    private static final String TASK_XLS = "xls";
    private static final String TASK_XLS2 = "xls2";
    private static final String TASK_CSV = "csv";
   

    public static void main(String[] args){

        String fileName = null;
        String taskName = null;


        if(args.length != 2)
        {
            usage();
            return;
        }

        taskName=args[0].toLowerCase();
        fileName=args[1];
       

        logger.info("main(String[]) - taskName: " + taskName);
        logger.info("main(String[]) - fileName: " + fileName);

        System.exit(genera(taskName,fileName));
    }

   
    public static int genera(String taskName,String fileName)
    {
        try
        {
            long start = System.currentTimeMillis();
            //Compila el fichero del diseño del informe, creado con iReport, pasándole de .jrxml a .jasper
            if (TASK_COMPILE.equals(taskName)){
                JasperCompileManager.compileReportToFile(fileName + ".jrxml");
                logger.info("genera(String, String) - Compile time : " + (System.currentTimeMillis() - start));
            //Rellena el informe con dos parámetros: su título y un nombre. No utiliza ningún datasource   
            //Genera un fichero .jrprint, necesario para la exportación del informe a los diferentes formatos   
            }else if (TASK_FILL.equals(taskName)){
                Map param = new HashMap();
                param.put("ReportTitle", "Mi Primer Informe");
                param.put("Name", "mundo");
                JasperFillManager.fillReportToFile(fileName + ".jasper", param, new JREmptyDataSource());
                logger.info("genera(String, String) - Filling time : " + (System.currentTimeMillis() - start));
            }else if (TASK_PRINT.equals(taskName)){
                JasperPrintManager.printReport(fileName + ".jrprint", true);
                logger.info("genera(String, String) - Printing time : " + (System.currentTimeMillis() - start));
            }else if (TASK_PDF.equals(taskName)){
                JasperExportManager.exportReportToPdfFile(fileName + ".jrprint");
                logger.info("genera(String, String) - PDF creation time : " + (System.currentTimeMillis() - start));
            }else if (TASK_XML.equals(taskName)){
                JasperExportManager.exportReportToXmlFile(fileName + ".jrprint", false);
                logger.info("genera(String, String) - XML creation time : " + (System.currentTimeMillis() - start));
            }else if (TASK_XML_EMBED.equals(taskName)){
                JasperExportManager.exportReportToXmlFile(fileName + ".jrprint", true);
                logger.info("genera(String, String) - XML creation time : " + (System.currentTimeMillis() - start));
            }else if (TASK_HTML.equals(taskName)){
                JasperExportManager.exportReportToHtmlFile(fileName + ".jrprint");
                logger.info("genera(String, String) - HTML creation time : " + (System.currentTimeMillis() - start));
            }else if (TASK_XLS.equals(taskName)){  // uso de POI
                File sourceFile = new File(fileName + ".jrprint");
                JasperPrint jasperPrint = (JasperPrint)JRLoader.loadObject(sourceFile);
                File destFile = new File(sourceFile.getParent(), jasperPrint.getName() + ".xls");
                JRXlsExporter exporter = new JRXlsExporter();
                exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
                exporter.setParameter(JRExporterParameter.OUTPUT_FILE_NAME, destFile.toString());
                exporter.setParameter(JRXlsExporterParameter.IS_ONE_PAGE_PER_SHEET, Boolean.TRUE);
                exporter.exportReport();
                logger.info("genera(String, String) - XLS creation time : " + (System.currentTimeMillis() - start));
            }else if (TASK_XLS2.equals(taskName)){  // uso de jxl
                File sourceFile = new File(fileName + ".jrprint");
                JasperPrint jasperPrint = (JasperPrint)JRLoader.loadObject(sourceFile);
                File destFile = new File(sourceFile.getParent(), jasperPrint.getName() + "2.xls");           
                JExcelApiExporter jExcelApiExporter = new JExcelApiExporter();
                jExcelApiExporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
                jExcelApiExporter.setParameter(JRExporterParameter.OUTPUT_FILE_NAME, destFile.toString());
                jExcelApiExporter.exportReport();
                logger.info("genera(String, String) - XLS2 creation time : " + (System.currentTimeMillis() - start));
            }else if (TASK_CSV.equals(taskName)){
                File sourceFile = new File(fileName + ".jrprint");
                JasperPrint jasperPrint = (JasperPrint)JRLoader.loadObject(sourceFile);
                File destFile = new File(sourceFile.getParent(), jasperPrint.getName() + ".csv");
                JRCsvExporter exporter = new JRCsvExporter();
                exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);


                exporter.setParameter(JRExporterParameter.OUTPUT_FILE_NAME, destFile.toString());
                exporter.exportReport();
                logger.info("genera(String, String) - CSV creation time : " + (System.currentTimeMillis() - start));
            }else{
                usage();
            }
        }catch (JRException e){
            logger.error("genera(String, String)", e);
            return 1;
        }catch (Exception e){
            logger.error("genera(String, String)", e);
            return 1;
        }
        return 0;
    }

    private static void usage(){
        logger.info("usage() - JasperApp usage:");
        logger.info("usage() - tjava JasperApp task file");
        logger.info("usage() - tTasks : compile | fill | print | pdf | xml | xmlembed | html | xls | csv ");
    }
}

Usos y recomendaciones conocidos

  • Consejería de Vivienda de la Junta de Andalucía
  • OpenBravo ERP de software libre

Requisitos e incompatibilidades

  • Requiere JDK 1.4 o superior.
  • Dependencias:
    • commons-beanutil.jar
    • commons-collections.jar
    • commons-digester.jar
    • common-logging.jar
    • itext-.jar (para exportar a PDF)
    • poi.jar (para exportar a XLS)
    • jxl.jar (para exportar a XLS)
    • jfreechart.jar (para graficos)
    • jdt-compiler.jar

Contenidos relacionados

Pautas
Área: Desarrollo » Librerías y Módulos » Java
Código Título Tipo Carácter
LIBP-0344 Librerías para aplicaciones Java Libro de pautas Directriz Recomendada