JasperReports

De Dos Ideas.
Saltar a: navegación, buscar

JasperReports es una libreria Java para la generación de reportes, pudiendolos exportar a diferentes formatos (usualmente PDF).

Es una de las herramientas de reportes open source más usadas, y es especificamente para y realizada en Java.

Posee una muy buena documentación, así como muchísimos ejemplos (En cada uno de estos ejemplos podemos ver las variantes que nos permite este software). Los reportes además de obviamente poder ser impresos, pueden ser exportados a:

  • PDF
  • HTML
  • XLS
  • CVS
  • XML

El Diseño de un reporte se realiza editando un archivo XML, que representa a la estructura de dicho reporte. Pero a no asustarnos, la misma gente que desarrolló JasperReports, desarrolló también una herramienta (iReport) que facilita la edición del archivo XML, y nos evita esta horrible tarea.

Es decir, por encima de la arquitectura JasperReports, podemos utilizar iReport, que es una herramienta visual que nos ayuda a diseñar y construir nuestro reportes.

iReport

iReport también es Software Libre, y si bien los manuales oficiales son pagos, en internet hay gran cantidad de tutoriales que combinan a JasperReports con iReport.

JasperReports en Unix

Si JasperReports se ejecuta en un entorno Unix, deben estar disponibles las librerias de X11 para la exportación a PDF. De no estar instaladas, se deberá incluir la libreria PJA Toolkit en la aplicación, y configurarla.

Setear las propiedades

Una vez agregado pja.jar al classpath de la aplicación, es necesario setear las siguientes propiedades de entorno previo a la ejecución de JasperReports:

System.setProperty("java.awt.headless","true");
System.setProperty("java.awt.toolkit","com.eteks.awt.PJAToolkit");
System.setProperty("java.awt.graphicsenv","com.eteks.java2d.PJAGraphicsEnvironment");
System.setProperty("java2d.font.usePlatformFont","false");


Configurar la máquina virtual

Por último, es necesario pasarle a la máquina virtual el siguiente parámetro cuando se inicia la aplicación:

-Xbootclasspath/a:/ubicacion/de/pja.jar -Djava.awt=com.eteks.awt.PJAToolkit

Por ejemplo:

java "-Xbootclasspath/a:/ubicacion/de/pja.jar -Djava.awt=com.eteks.awt.PJAToolkit" -jar dosideas.jar

Si la aplicación se ejecuta en un Servidor de Aplicaciones será necesario agregar dicha línea al script de inicio del mismo.


Problemas conocidos de JasperReports

Internet Explorer

Con algunas versiones del Internet Explorer, como la 6.0.2900.2180 o la 5, la exportación de un reporte a través de un servlet no funciona.

Situación

Exportar un reporte usando un servlet.

En el servlet se obtiene el ServletOutputStream y se lo pasa a un objeto para que se encargue de buscar los datos del reporte y crearlo. Entonces, dentro de este objeto usariamos el jasperRunManager:

//Crea el reporte y lo guarda en el servletOutputStream.
JasperRunManager.runReportToPdfStream(reportStream, servletOutputStream, parametros, new JREmptyDataSource());

Problema

Cada vez intentaba crear el reporte desde el objeto, JasperReports lanza una exception:

java.net.SocketException: Connection reset by peer: socket write error

o

java.net.SocketException: Brocken pipe exception.

Se perdía la conexión entre el servlet y jasper pero solo con algunas versiones del Explorer.

A pesar de la exception que tiraba, se creaba el reporte:

  • La primera vez el servletOutputStream tenia un reporte vació.
  • La segunda y posteriores el servletOutputStream tenia el reporte completo.

Solución

La única "solución" encontrada fue pasar la creación del reporte principal en la clase del servlet.

Dentro del BO creo los subreportes y guardo los datos de nuestro reporte principal dentro de un Hashmap. Desde el servlet creo el reporte principal, hago la llamada al jasperRunManager:

JasperRunManager.runReportToPdfStream(reportStream, servletOutputStream, parametros, new JREmptyDataSource());

Bug de hoja en blanco

Supongamos que tenemos un reporte muy simple, que muestra por pantalla dos valores, uno obtenido como resultado de un Query que realizamos desde dentro del reporte; y el otro valor se lo hemos pasado como parámetro al reporte.

Ahora supongamos que se da la situación de que el query que ejecutamos desde dentro del reporte no trae ningún resultado. Lo que sucederá es que al exportar el reporte a algun formato para verlo por pantalla (por ejemplo PDF) obtendremos una hoja totalmente en blanco. Es decir, el reporte obvió de mostrar tanto el valor que le habíamos pasado como parámetro, como también todo el texto estático que el reporte contenía.

Solución

Hay muchas soluciones posibles, dado que en JasperReports no sólo se puede usar como data source uno obtenido a través de una conexión a una base, sino que también es posible utilizar como data source un XML, una clase Java, más de un data source, entre otras posibilidades.

Vemos el caso particular de pasar los mismos como parámetros al Reporte. Luego sólo hay que tener en cuenta dos detalles, para que nuestro reporte no aparezca en blanco:

  • Desde iReport, ir al Menú Edit / Report Properties y en la solapa "More", opción "When no data" seleccionar la opción "All sections, no details".
  • Al momento de ejecutar nuestro reporte desde java, deberemos indicarle que use un data source ficticio o vacío:
JasperRunManager.runReportToPdfStream(reportStream, outputStream, parametros, new JREmptyDataSource(1));


Ver también