El día de hoy quiero continuar con el tutorial de JasperReport, he explicado una introducción a la estructura principal del reporte, el paso de parámetros al reporte y como llenar un reporte desde una base de datos incluyendo el Query dentro del jrxml, en esta ocasión explicaré como llenar un reporte por medio de una colección de objetos VO o DTO, como mejor los conozcas.
Objetivos.
Una vez definidos los objetivos se puede apreciar el alcance de este tutorial y así decidir si al lector le conviene continuar con la lectura de este tutorial.
Cómo poner acentos y eñes.
Lo primero es definir la cabecera del archivo jrxml, y dentro de este especificarle el encode a utilizar dentro del documento, generalmente el encode por de facto es UTF8, pero este encode no soporta los caracteres extendidos, que es donde se encuentran los acentuados y la eñe, es por eso que si no ponemos el encode correcto, al compilar el reporte obtendremos un error, para evitar esto, es necesario indicar que el encode a utilizar sea ISO-8859-1, el cual contiene los caracteres necesarios para el español.
Paso de parámetros e información.
Lo siguiente es pasarle algunos parámetros para desplegar el titulo, y el subtitulo, además de declararse las Fields de la información a desplegar en el reporte.
A diferencia del tutorial anterior, únicamente se le ha suprimido el Query que consultaba la base de datos, esto es por que ahora la información se le pasará directamente desde Java por medio de una colección de DTOs (Data Transfer Object).
Más adelante explicaré mas a detalle el paso de información, por ahora basta con declarar la información a desplegar en la parte del detail.
Poner una imagen en formato gif.
En esta sección se definirá el background y la cabecera del documento, en el tutorial anterior explique cómo hacerlo, el día de hoy será exactamente igual con la diferencia de que en lugar de pasarle una imagen JPG se le pasará una imagen GIF, además de que las medidas y posiciones son diferentes, todo esto escrito en código es:
Hasta aquí no hay nada nuevo, excepto que en el campo donde se despliega la fecha, en lugar de sacarla de la base de datos como en el tutorial anterior, ahora se generará directamente en el reporte, esto es muy sencillo de hacer, únicamente hay que crear una instancia de la clase Date dentro de la expresión del campo:
El formato es exactamente igual al tutorial anterior.
Poner títulos a las columnas.
Anteriormente no se le había agregado cabeceras a las columnas de la información, pero si había mencionado en la introducción que esto es posible, a continuación se muestra cómo por medio de la sección <columnHeader> se puede realizar.
Si te das cuenta, esta sección no tiene nada especial que no se haya cubierto en los tutoriales anteriores, simplemente son textos estáticos distribuidos en forma linear, es aquí donde se ha necesitado poner acentos, los cuales son correctamente soportados gracias a que se ha especificado el encoding correcto al inicio del documento.
Desplegar la información principal.
Esta es la sección principal del reporte, las columnas donde se muestra la información. En el tutorial anterior explicaba que esta sección es iterada sobre el data source provisto, anteriormente la consulta SQL generaba una colección de información regresada por la base de datos, en esta ocasión la colección se le pasará desde Java. Al diseñar el reporte esto no tiene ninguna implicación, simplemente se acomodan los campos en las posiciones deseadas, todo esto exactamente igual al tutorial anterior, pero con diferente información a desplegar.
El reporte completo.
Esto es todo en cuanto al diseño del reporte, todo ha sido semejante por no decir igual al reporte del tutorial anterior, únicamente cambiamos el encoding para que aceptara acentos, se le agregó una nueva sección al reporte para desplegar los titulos de las columnas, la fecha se ha generado directamente en el reporte y se suprimió la consulta SQL a la base de dato, el reporte completo es el siguiente.
Ahora viene la parte interesante en Java, la cual cambiará muy poco conforme al tutorial anterior.
Generar el reporte con Java.
Para generar el reporte son necesarios cuatro pasos, muy sencillos por cierto. El paso número uno es llenar el data source con la información a enviar, el paso dos compilar el reporte, paso tres llenarlo con la información y parámetros necesarios, paso cuatro exportar el reporte al formato deseado, en este caso pdf.
Lo mas importante a resaltar aquí es la clase net.sf.jasperreports.engine.data.JRBeanCollectionDataSource la cual es la encargada de entregar la información al reporte. Esta clase se instancia con una colección de Objetos DTO. En este caso el objeto es Universidad, que contiene las mismas propiedades que el reporte desplegará con sus respectivos getters y setters.
Para ejemplo se ha hardcodeado la información en el método populateData, en la vida real esto no se hace, este método debiera ser implementado de acuerdo a las necesidades del desarrollador, ya sea consultando una base de datos, un webservice, un archivo de texto, etc.
A continuación el bean necesario para llenar el reporte.
Lo más importante aquí es que las propiedades deben corresponder a los campos declarados en el reporte, de esta manera el motor de JasperReports puede relacionarlas y desplegar la información.
El código es muy claro y sencillo, si se siguen los cuatro pasos no se tendrá problema para generar el reporte, al igual que en los tutoriales anteriores voy a poner el proyecto para eclipse, con el ejemplo, para ser descargado.
Po último quiero dar una disculpa por referirme tanto al tutorial anterior, pero tanto este como el tutorial anterior son muy semejantes.
Saludos.
Muchisimas gracias me quebre la cabeza tratando de hacer un reporte asi (es la primera vez q hago un reporte) y esta es la unica pagina que me ayudo de verdad, muy bueno tu tutorial. Felicitaciones.
La verdad es de lo mejorcito que hay por ahí.
Lo que sí quería preguntarte es si existe alguna posibilidad de que un determinado texto (que ocupa bastante) pueda ajustarse al campo de texto en donde se encuentra y no me lo corte cuando ya llega al tope del textField donde está definido.
Y si existe alguna posibilidad (aunque creo que no, ya que he visto que el atributo height tiene que existir siempre) de que la línea donde aparezca el texto varíe de altura dependiendo del contenido, en este caso del tamaño de la cadena a mostrar.
Gracias y enhorabuena.
Ok. Solucionado.
Se hace con el atributo isStretchWithOverflow=”true”. Mi problema ahora es que si el texto está en el último registro de la página y es demasiado largo corta el texto y lo que falta lo pone en la siguiente página. Puedo controlar esto, o sea, que no me corte el texto del último registro de la página?
Gracias
Hola Crysfel!
Muchas gracias por este ejemplo, llevaba un tiempo buscando como hacerlo y al fin lo he conseguido.
Pero ahora el problema es que dentro de este informe maestro tengo subinformes y no consigo lograr que obtenga los datos del datasource que le he pasado.Simplemente lo muestra todo en blanco. ![]()
¿Tienes idea de hacerlo?
Gracias por todo!
excelente trabajo,
me ayudo muchisimo, este caso por lo que veo es una lista para la “banda detalle”
es posiblemandar 2 listas diferentes (Universidad, Facultades), e iterar ambas en la “banda detalle”
gracias de antemano
@MIRIAM
Hola, mira la verdad no he tenido la necesidad de pasarle una colección de beans a subreportes, lo que me ha funcionado siempre es meterle el SQL a cada subreporte en especifico y solo pasarle los parámetros necesarios a cada subreporte.
@MANUEL
La solución a lo que preguntas es hacer subreportes, esto es hacer reportes individuales y luego juntarlos todos en pequeñas secciones dentro de un reporte principal o maestro, de esta manera puedes tener diferente información en el “mismo reporte”.
Si con la SQL va genial, pero en mi caso cuando llamo al informe ya tengo el objeto, entonces hacer una consulta a la bbdd es una perdida de tiempo y recursos, sobretodo cuando la clase contiene muchos campos.
Al final ayer conseguí pasarle los datos al subinforme, pero de momento estoy probandolo.
Gracias y Un saludo!
Bueno mákina la verdad es que sabia muy poco de jasper y gracias a tu ayuda en media hora he montado un reporte de una colección, muchisimas gracias, hace falta más gente como tu.
Solo una cosa cambia el ‘vasta’
que tienes en el texto, que baja mucho la calidad del artículo.
un saludo.
@Paco
Gracias por el feedback, me alegra que te sirvió este tutorial. ![]()
Oye, muchas gracias por este tutorial, llevaba horas tratando de hacer un data source desde el ireports y nada, y pues con tus ejemplos y consejos pude avanzar demasiado, solo te tengo una pregunta y es saber si al mismo reporte, puedo agregarle otro bean, por ejemplo paises, con diferentes campos, y q si este reporte se llenaria de la misma forma como cuando uno maneja sql, q puede tener varias tablas, gracias de nuevo desde Colombia crisfel
Muchas gracias por tu aporte, me a servido de mucho. Adicional a lo que muestras aca me gustaria saber como recorrer una coleccion dentro de un javabeans. Ejemplo: teniendo la universidad un List de aulas con nombre y profesor. como hago para recorrer esto en el reporte. He intentado d todo y nada. No se como decirle que rrecorra el objeto y q saque sus valores. El convierte la lista dentro del bean a cadena. No se si es tan flexible como lo q se hace JSF. Por favor hazme saber. Gracias.
erda mijo ke barbaro.
MIs felicitaciones crys.
Hola Crysfel, te queria hacer una pregunta a ver si me puedes ayudar.
Necesito generar un reporte e incluirle una imagen en la cabecera, pero esta imagen dependerá del valor que tengamos en una tabla en Base de Datos.
Por ejemplo, si en base de datos tenemos ESP, pondremos la bandera de españa, si tenemos ING pondremos la bandera Inglesa y asi sucesivamente.
Un saludo.
@Hossain
Esas comparaciones las puedes hacer con java, antes de generar el reporte le asignas el al parámetro de la URL de la imagen, el path a donde esta la imagen adecuada.
saludos. :d