Qué tal, bienvenido a esta nueva publicación, el día de hoy les mostraré como crear reportes dinámicos con Primefaces y JasperReports.
La historia comienza con una necesidad que tenía para mis proyectos de aplicación web, en los cuales tenía que mostrar reportes en ciertas secciones de una pantalla que constantemente cambiarían de información, es decir dependían de ciertos valores para su generación.
La idea inicial era que pudiera ser capaz de mostrar un pdf que a lo largo del ciclo de vida de la aplicación siempre estaría cambiando de forma, por lo que se me vino a la cabeza que podía generar un archivo .pdf y después mostrarlo en pantalla, pero, ¿cómo podría hacer esto?.
Después de investigar un poco me di cuenta que PrimeFaces nos proporciona un componente para mostrar todo tipo de contenidos entre estos un pdf, hablo del Componente Media que hablando en términos más técnicos de programación hace uso de un objeto StreamedContent para renderizar contenidos.
Ahora, la idea había evolucionado, si con el método exportReportToPdfStream de JasperExportManager puedo guardar el pdf generado en un OutputStream entonces este lo podría utilizar para crear un StreamedContent y aquí la prueba:
Esta es la clase que utilizaré para mantener la información del reporte, el archivo .jasper ya te imaginarás que el diseño solo consta de 2 columnas id y name.
report.xhtml
Lo siento, solo mostraré lo necesario de este archivo, se conforma de un formulario que contiene un inputText, un commandButton que llama al método generateReport, el commandButton Descargar que llama al método downloadFile, el componente Media y algunas condiciones de renderizado.
Nota: el componente media debe tener en false la propiedad cache, de otra forma te dará un buen dolor de cabeza.
JasperReportUtil.java
La clase de utilería JasperReportUtil contiene 3 métodos:
- getOutputStreamFromReport que retorna un ByteArrayOutputStream a partir de la lista de elementos que deseas renderizar en tu reporte, algún mapa con parámetros y el path del archivo .jasper,
- getStreamContentFromOutputStream que retorna un StreamedContent a partir de un objeto ByteArrayOutputStream, una cadena con el tipo de contenido a generar y el nombre del archivo.
- getStreamContentReport este método es el camino corto (fusiona los 2 métodos anteriores [lo pensaba utilizar en un caso especial, no necesito explicarlo]).
ReportTestController.java
De esta clase seré breve, los 2 métodos que se llaman son generateReport y downloadFile.
El primero genera datos dummys y haciendo uso de la clase de utilería antes mencionada genera el StreamedContent para que el componente media lo utilice y muestre el pdf.
El segundo método permite descargar el archivo pdf, observar que PrimeFaces ya provee un componente para descargar pero si intentas guardar el pdf o utilizar el componente FileDownload el archivo se descargar corrupto, desconozco la razón.
9 comentarios:
Write comentariosHola, no he logrando que se pinte en la pantalla, si lo descarga pero no lo renderiza, sabes a que se puede deber esto?
ResponderEliminarMuchas gracias, me ha servido para descargarlo
ResponderEliminarHola, es posible tan solo descargar el reporte sin necesidad de generarlo?
ResponderEliminarHola!
ResponderEliminarNo podía llenar un reporte con una Lista, tenía días con ese problema hasta que encontré tu post, tuve que modificar el JasperUtil y agregar el CollectionDataSource. Muchas gracias :)
son nesesarios los import para logs??
ResponderEliminarmuchas gracias! me quedo super en mi proyecto.
ResponderEliminarme duelve el siguiente error alguna idea que puede estar pasando?
ResponderEliminarSEVERE
[org.primefaces.application.resource.StreamedContentHandler] (default task-15) Error in streaming dynamic resource. null
me pude ayudar con el projecto
ResponderEliminarmuchas gracias, me servio el tutorial!
ResponderEliminar