Reportes en java con JasperReports y iReports

Con motivo de estreno de este nuevo blog y además con un objetivo de facilitar mucho la programación en cuanto a generar reportes, aquí va un tutorial que les será de gran ayuda.

En lo que nos centraremos en este tutorial es en la creación de un reporte en formato PDF, previamente diseñando una plantilla mediante iReport. Se usará una lista enlazada (LinkedList) como origen de los datos a mostrar y se trabajará en el entorno NetBeans.

Primero necesitaremos de lo siguiente:
- JasperReports
- iReport (diseñador gráfico de plantillas para JasperReports)
NOTA: Es recomendable usar la misma versión de JasperReports que la de iReports caso contrario pueden dar errores el ejecutar el programa.

Configuración de NetBeans

Configuraremos NetBeans para que nos permita usar todas las librerías de JasperReports en nuestros proyectos.

Primero descomprimimos el archivo que descargamos de JasperReports, pues usaremos varias de sus librerías localizadas en las carpetas dist y lib.

Iremos al menú Herramientas – Bibliotecas.
toolsmenu

Creamos una nueva Biblioteca de nombre JasperReports (aunque puedes elegir el nombre que desees).
newlibrary

En la parte derecha damos presionamos en “Agregar archivo JAR/Carpeta…” para agregar los siguientes archivos (ubicados en las carpetas lib y dist de JasperReports como mencionamos anteriormente):

  • - jasperreports-3.7.5.jar
  • - jasperreports-javaflow-3.7.5.jar
  • - commons-beanutils-1.8.0.jar
  • - commons-collections-2.1.1.jar
  • - commons-digester-1.7.jar
  • - commons-javaflow-10060411.jar
  • - iText-2.1.7.jar
  • - png-encoder-1.5.jar
  • - poi-3.6.jar
  • - commons-logging-1.0.4.jar
  • - groovy-all-1.5.5.jar

Con esto bastará solo agregar la biblioteca JasperReports (o el nombre que le hayamos puesto) al proyecto en el cual deseemos generar reportes.

Creación de un nuevo proyecto de prueba

Lo que se realizará es un ejemplo de una clase Empleado que dispone de una cédula, un nombre y el sueldo.

Primero vamos al menú Archivo – Nuevo Proyecto – Java – Aplicación Java.
selectproject

Al proyecto le pondremos de nombre “ReporteEmpleados”.

Ahora creamos una nueva clase a la cual llamaremos Empleado.
new class

Le añadimos todos los Setters y Getters correspondientes además del constructor, quedando al final como sigue:

Tenemos lo básico, ahora diseñaremos el reporte con iReport

Diseño de la plantilla con iReport

Una vez abierto iReport, para crear una nueva plantilla nos dirigimos al menú Archivo – New. En la nueva ventana elegimos “Blank A4” y presionamos en “Open this template”.

new report dlg

Damos un nombre a nuestro reporte, dejaremos de momento el que trae por defecto “report1”.

Dispondremos de 8 secciones en nuestro reporte:
- Title: Para colocar el título del reporte, irá en la primera página.
- Page Header: Una cabecera que irá en cada página
- Column Header: Las etiquetas de las cabeceras de cada columna.
- Detail 1: Los datos en sí del reporte.
- Column Footer: Para colocar información al final de los datos.
- Page Footer: Sección inferior de la página.
- Summary
- Background: Un fondo

Ahora nos dispondremos a añadir información, en la parte derecha encontraremos la paleta de elementos que podremos agregar (si no aparece ir al menú Ventana – Paleta).

Para el título seleccionamos “Static Text” y lo arrastramos a la sección “Title”. Una vez que el elemento esté en la página, si le damos doble clic podremos cambiar su texto, además de la fuente, el tamaño, entre otros.



Ahora añadimos las columnas de los datos que vamos a mostrar, o sea añadimos más “Static Text” para indicar la cédula, el nombre y el sueldo.



Ahora estamos listos para añadir campos donde irán los datos, mucha atención a lo siguiente…
Anteriormente añadimos texto estático (que no cambia) pero los datos de cada empleado como sabemos cambia, no serán los mismos, entonces necesitaremos de un campo dinámico.

Los campos dinámicos tenemos varios como son:
- Fields: Sirven para mostrar información provenientes de un DataSource (que puede ser una base de datos o una lista ligada).
- Variables: Muestran información del reporte o cálculos. Las variables disponibles las puedes encontrar aquí.
- Parámetros: Son datos que por lo general son pasados desde el programa. Algunos de los parámetros solo se pueden leer y no modificar, aquí la lista completa.

Nosotros usaremos Fields, entonces en la parte izquierda de iReport damos clic derecho sobre Fields y elegimos Agregar Field.
add field

Cada Field tiene un tipo de dato que por defecto es String, pero en nuestro caso donde el sueldo es de tipo Integer, entonces elegimos java.lang.Integer como Field Class en las propiedades del Field.
select integer

Ahora arrastramos cada field hacia “Detail 1”. Seguramente en la sección “Column Header” de la hoja se te crearon más etiquetas, las puedes eliminar tranquilamente. Además debes achicar la altura de “Detail 1” puesto que ese espacio es el que usará una sola fila y por el que viene por defecto es bastante grande. Una vez realizado estos cambios el resultado podría quedar como sigue:



Y aunque no lo creas, ya tenemos lista nuestra plantilla, sencillita por cierto, pero a la final la creamos nosotros mismos. Ahora solo damos clic en Preview:



Esto compilará la plantilla para generar el archivo report1.jasper el cual es el que haremos referencia en el código. Dicho archivo lo debemos colocar en la raíz de nuestro proyecto.

Nos aparece los datos como “null” debido a que no existe una fuente de información (un DataSource), pero no te preocupes que en nuestro programa lo vamos a indicar.

Completando el ejemplo de la clase Empleado

Habíamos dejado solo definida la clase Empleado con sus atributos y métodos respectivos, ahora estamos listos para crear el reporte.

Primero damos clic derecho a la carpeta “Bibliotecas” de nuestro proyecto, elegimos “Agregar Biblioteca”.
addnewlibrary
De la lista de bibliotecas, seleccionamos el que habíamos creado, o sea “JasperReports”.
jasperreportsselected

En el main de nuestro proyecto añadiremos el siguiente código

LinkedList<Empleado> listaEmpleados = new LinkedList<Empleado>();
listaEmpleados.add(new Empleado("1234567890", "Juan Pérez", 450));
listaEmpleados.add(new Empleado("0987654321", "Marcelo C", 500));
listaEmpleados.add(new Empleado("1234509876", "Don Bill", 5000));
try
{
    JasperReport reporte = (JasperReport) JRLoader.loadObject("report1.jasper");
    JasperPrint jasperPrint = JasperFillManager.fillReport(reporte, null, new JRBeanCollectionDataSource(listaEmpleados));
    JRExporter exporter = new JRPdfExporter();
    exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
    exporter.setParameter(JRExporterParameter.OUTPUT_FILE, new java.io.File("reporteEnPdf.pdf"));
    exporter.exportReport();
}
catch(JRException e)
{
    e.printStackTrace();
}

Seguramente al pegar el código faltarán algunos imports, esto se soluciona dando clic derecho sobre el código que da error y eligiendo “Reparar importaciones”.
fiximports

Ahora si ejecutamos el programa (presionando F6 en NetBeans) y… ¡voilá! tenemos nuestro reporte en PDF, excelente ¿no?.
Para cualquier duda o sugerencia, la puedes dejar en los comentarios.

16 comentarios:

jessica arelly dijo...

ola yo estoy haciendo reportes con iReport en ambiente web, hasta ahora todo va bien pero ¿como le puedo hacer para que cambie el titulo del reporte dinamicamente? dependiendo de un parametro que le envio.

Martin Balog dijo...

Hola en primer medida te felicito por el tuto, tengo un inconveniente no hay forma de q me funcione en la linea JasperReport reporte = (JasperReport) JRLoader.loadObject("report1.jasper");
Cuando hago el paso por paso de esa linea pasa al final, no se que puede suceder. Probe colocando la ruta completa donde esta almacenado el archivo y tampoco funciona. Si tenes idea cual es el inconveniente desde ya te lo agradeceria toda la ayuda que me podes suministrar.

esteban dijo...

si es verdad a mi tambien me genera error esa linea quisiera saber que puedo hacer lo que sucede es que tengo que entregar una aplicacion mañana para programacion y pues eso es lo unico que me falta

lekio dijo...

Hola, a ver si me puedes ayudar por favor. Imaginemos que he creado un reporte parecido al tuyo, donde se va llenando con los datos de los empleados. Pues bien una vez terminado de rellenar los datos de alumnos, en la misma hoja porque los datos de los alumnos no ocupa mucho, quiero poner los datos de..... digamos sucursales de bancos en la ciudad, como veras no estan relacionados para nada unos datos con los anteriores, pero no se como podria hacer para mostrarlos ya que no puedo agregar otra banda de header columns para poner la cabecera de los datos. Muchas gracias de antemano.

ilrojano dijo...

hago este ejemplo y me sale el siguiente error, sabeis a que es debido:
net.sf.jasperreports.engine.JRException: Error retrieving field value from bean : Pasillo
at net.sf.jasperreports.engine.data.JRAbstractBeanDataSource.getBeanProperty(JRAbstractBeanDataSource.java:127)
Java Result: 1

giovanny dijo...

Saludos.
Mi tema de tesis es un sistema de facturación en java web y para los reportes estoy trabajando con Jasper Ireports 4.0.2, despues de tanto buscar en la web ya puedo generar el reporte de una factura con su respectivo detalle.
Ahora necesito generar el reporte de varias facturas pero en el mismo archivo, como puedo hacer esto.
Ya que para cada factura se me genera un solo archivo, y cuando genero las facturas por ejemplo de la número 1 a la 5 se me abren 5 reportes.
como puedo hacer para que todo se me habra en un solo archivo o reporte, para poderlo imprimir.
Mi tambien como puedo enviar directamente a la impresora sin que se abra el reporte???

Espero que me puedan ayudar gracias.

Julián Quiroz dijo...

genial.. aun no lo he provado pero la explicación esta exelente... felicitaciones y es una herramienta muy buena gracias

Julián Quiroz dijo...

@Ilrojano

tengo la solución a tu problema por que ami me paso lo mismo...
y fue lo siguiente...

Es por que los nombres de las variables las pusiste en mayúsculas y van en minúsculas..

"Pasillo"

Debe ir en minúsculas tanto en el documento.jasper y en las variables de la clase que hiciste en netBeans el que usas como bean... y listo..

No se por que marca el error pero eso mismo e paso y cambie todo a minúsculas y funciono perfecto

gerardo dijo...

Hola, muy bueno e interesante tu blog. Fíjate que estoy desarrollando y tengo un problema en la generación de un reporte.

Necesito que dicho reporte se ajuste a una sola hoja, como funciona en Excel, que se le puede decir que se ajuste a una sola hoja y todo el contenido del mismo se ajusta.

Espero me puedas ayudar. Gracias.

David Lopez dijo...

Buenas noches!!!!!!! URGENTE! Tengo una duda, lo que necesito es que, el tamaño de letra de los fields se autoajusten. Es decir, darle un especio determinado a unos field, o por mas que tengan 100 datos, que el tamaño se autoajuste al espacio que le eh dado, para que no me ocupe mas de una hoja, asi la letra se vea chiquita no importa. O hacer q mi subconsulta se auto ajuste a un espacio que ya le di.

De ante mano muchas gracias! me tiene como loco esto y tengo que entregarlo lo antes posible!

Jesus Penas dijo...

Hola Buenas tardes. He probado lo de crear un atchivo PDF y me graba un archivo pdf correctamente. Pero y si quiero que el adobe lo deje abierto en lugar de grabarlo, para que pueda escoger el nombre y la ubicacion?
Y además tengo un problema, cuando imprimo reportes en una impresora canon, me salen perfectos, pero ahora los estoy imprimiendo en una HP desjet 3055A y me sale con letras grandes, como si pensase que tiene un A·en horizonta, sinembargo si guardo el archivo en pdf y despues lo imprimo, entonces sale bien. Alguna idea. Gracias

David Silva dijo...

Lo que tienen que hacer es copiar los archivos creados al hacer el reporte y llevarlos a NetBeansProjects y copiarlos. Osea, buscar los archivos "report1.jasper" y el .jrxml que se produce al crear el reporte en su ireport y pegarlos en el la carpeta que denante mencioné. Después compilan en java y se crea el PDF, saludos

Livio dijo...

Hola, tengo el mismo problem que @Jesus Penas. Alguna idea? Los reportes generados en una impresora Hp 3055A salen con mucho zoom

Isis dijo...

Que tal muchas gracias por el ejemplo, te comento que tengo un problema, y quisiera saber si me podrías ayudar, cuando genero el reporte en lugar de salirme los datos me produce: field1, field2, field3, en lugar de mostrarme los datos de la cedula, del nombre y el sueldo, muchas gracias por tu ayuda:D

Juan Sebastián Peláez Villa dijo...

Cuando corro el reporte me sale exitoso pero no me muestra el resultado alguien sabe porque??

Clemente Saldivar dijo...

como puedo hacer para que el texto de un field se ajuste al tamaño del field..

Publicar un comentario en la entrada