JRBeanCollectionDataSource: trabajando con colecciones de datos básicos en Jasper Report.

11
61225

JRBeanCollectionDataSource: trabajando con colecciones de datos básicos en Jasper Report.

0. Índice de contenidos.


1. Introducción

Son muchos los tutoriales publicados en adictos al trabajo sobre jasperReport e iReport y, en concreto, ya vimos de la
mano de Saúl como disponer de una fuente de datos basada en una colección de beans.

En este tutorial vamos a ir un poco más allá porque no vamos a tener fuente de datos ;),
usaremos el mismo concepto pero en vez de obtener una colección de beans de una fuente de datos,
trabajaremos con una colección de «tipos básicos» pasada como parámetro.

Parece un contrasentido pero no, en iReport no es necesario definir una fuente de datos tipada para la generación de nuestros informes.
Imaginad que no necesitamos iterar, que únicamente necesitamos la facilidad de exportar en distintos formatos o que queremos hacer uso
de la plantilla para un remplazo de huecos.

En este tutorial vamos revisar dos cuestiones:

  • cómo trabajar con parámetros definiendo una fuente de datos vacía, y
  • cómo iterar por una colección de tipos básicos para imprimir su contenido.

El ejemplo que vamos a usar es la generación de la ficha de un cliente, una empresa que tiene distinta información no necesariamente tipada y que
no se obtiene de base de datos en la propia generación del informe. Vamos a realizar una prueba simple pasando como parámetro al informe una colección de empleados,
solo los nombres como cadenas.


2. Entorno.

El tutorial está escrito usando el siguiente entorno:

  • Hardware: Portátil MacBook Pro 15′ (2.4 GHz Intel Core i7, 8GB DDR3 SDRAM).
  • Sistema Operativo: Mac OS X Lion 10.7.4
  • iReport 4.7.1
  • Jasper Report 4.7.1


3. Creación de la plantilla jrxml.

Lo primero es crear una plantilla vacía dentro del entorno de iReport, le añadimos una cabecera y un pie de página y
seleccionamos como fuente de datos un «Empty Datasource»:

Como no vamos a trabajar con una fuente de datos, lo siguiente es crear un parámetro, para ello «botón derecho» sobre «Parameters» > «Agregar Parameter»:

Le asignamos un nombre, en nuestro caso «empleados»:

Y accediendo a la ventana de propiedades, le damos una tipología en «Parameter Class», en nuestro caso «java.util.List» y, además:

  • con «Use as prompt» le indicamos si queremos que, en el entorno del iReport, muestre una ventana de petición del valor para las pruebas, y
  • en «Default Value Expression» podemos indicar un valor por defecto para la propiedad.

Pulsando sobre «Default Value Expression» podemos asignar algo como lo siguiente para añadir un List<String>

Con ello, ya tenemos preparado nuestro parámetro para el entorno de pruebas y ahora vamos a añadir un componente visual de tipo
lista para iterar por su contenido y mostrar el nombre de los empleados.

Pulsando sobre icono anterior y arrantrándolo al area de la plantilla lo tendremos disponible para su edición:

Una vez incluido en la sección correspondiente de la plantilla «botón derecho» > «Edit datasource» mostrará una ventana como la que sigue:

En este punto son importantes dos cuestiones:

  • «Sub dataset» definirá los parámetros de entrada, campos, variables,… que vivirán en el ámbito de la lista y que, no tienen por qué coincidir
    con los de la plantilla padre, ahí será donde definiremos un campo «ad hoc»,
  • Connection / Datasource Expression: indica la fuente de datos para la lista que puede ser la misma fiente de datos que el informe padre u otra,
    en nuestro caso definimos una expresión usando la clase net.sf.jasperreports.engine.data.JRBeanCollectionDataSource y pasando
    como argumento al constructor una referencia al parámetro anteriormente definido.

Lo siguiente será definir un campo que haga referencia a cada uno de los items de la colección, si tuviéramos un objeto tipado,
añadiríamos los campos a mostrar de la clase o el bean en cuestión, como trabajamos con tipos básicos añadiremos un campo con la
palabra reservada _THIS, que hará referencia a cada una de las cadenas dentro de la iteración interna de la lista.

Sobre el dataset1, el que usa la lista, pulsamos «botón derecho» en «Fields» > «Agregar Field»

El nombre para nuestro campo es la palabra reservada _THIS

Con ello podemos arrastar dentro del contenido del componente de lista el campo ${_THIS}

Si compilamos el informe para una previsualización en el entorno de iReport, primero nos solicita un valor para nuestro
parámetro «empleados», si os fijais en el «suggest» indica el tipo y un ejemplo

Si pulsamos sobre «Use default» usará lo definido por defecto a nivel de parámetro y debería mostrar un informe
como el siguiente:

Podeis descargar el jrxml usado en el ejemplo en el siguiente enlace:
Ficha de empresa en formato jrxml.


4. Generación del informe desde java.

Si el informe anterior lo tuviéramos que generar desde código bastaría con un servicio como el siguiente:

package com.autentia.training.jasperReports;

import java.util.Map;

import net.sf.jasperreports.engine.JREmptyDataSource;
import net.sf.jasperreports.engine.JRException;
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.JasperReport;
import net.sf.jasperreports.engine.design.JasperDesign;
import net.sf.jasperreports.engine.xml.JRXmlLoader;

public class ReportExporter {

	public void toPDF(String reportName, Map<String,Object> parameters) throws JRException {

		final String reportSource = getClass().getClassLoader().getResource(reportName).getPath();
		
		final JasperDesign jd = JRXmlLoader.load(reportSource);

		final JasperReport report = JasperCompileManager.compileReport(jd);

		final JasperPrint print = JasperFillManager.fillReport(report, parameters, new JREmptyDataSource());

		final String reportTarget = reportSource.substring(0,reportSource.lastIndexOf('/')).concat(reportName).concat(".pdf");
		
		JasperExportManager.exportReportToPdfFile(print, reportTarget);

	}

}

Recibe como parámetro el nombre de fuente jrxm y un mapa de parámetros a pasar al informe.

Obtenemos la ubicación en disco para escribir el informe en el mismo path, usamos un JREmptyDataSource y
le pasamos el mapa de parámetros.

Podemos realizar una prueba de generación a través de un método main, pasándo un listado de empleados como cadenas dentro del mapa de parámetros:

	private static final List<String> empleados = 
			Arrays.asList("Jose Manuel Sánchez", "Alfonso Blanco", "Angel García", "Rubén Aguilera");
	
	public static void main(String[] args) throws JRException {
		final Map<String,Object> parameters = new HashMap<String,Object>();
		parameters.put("empleados", empleados);
		final ReportExporter reportExporter = new ReportExporter();
		reportExporter.toPDF("fichaEmpresa.jrxml", parameters);
	}

El resultado será el mismo que el obtenido desde el entorno de iReport.


5. Conclusiones.

Lo ideal es trabajar con objetos tipados, pero esta posibilidad nos abre las puertas para trabajar con objetos desnormalizados.

Un saludo.

Jose

jmsanchez@autentia.com

11 COMENTARIOS

  1. Excelente tutorial.,. De casualidad tendras un ejemplo, pero con php? Estoy tratando de hacer un reporte dinamico, enviando parametros con php

  2. Muy buen post! En mi caso particular me gustaría pasar como parámetro un ArrayList<Map pero no consigo hacerlo, sabrías de algún ejemplo?

  3. Como puedo hacer para que los items de la lista me aparezcan en un grid o se muestren horizontal, ya he probado con el Horizontal Layout y el GridLayout y siempre me aparecen en vertical. Gracias.

  4. Para los que tienen el ‘Arrays cannot be resolved’ solo quiten el valor por defecto del parametro ‘empleados’. y ejecutenlo mandandole los valores desde Java, que funciona perfectamente.

    Gracias por el aporte me has sacado de una (y);

    • He sacado, pero no muestra el valor del campo _THIS, en cambio si coloco solo el campo _THIS en el reporte (esto es fuera de la lista, me muestra el valor del campo. En cambio si está adentro de la lista no me muestra nada, ¿a qué puede deberse esto?

  5. Hola, al tratar de darle valor al parámetro que definis, te arrija un error que dice Arrays.asList cannot be resolved to a type, realicé todos los ajustes al CLASSPATH de Ireport en netbeans, incluso agregué la clase Arrays.class al classpath y nada, no toma el valor por default del parámetro que sería la colección que mostrás en este ejemplo, como tampoco me lee el campo _THIS ¿qué puede estar pasando?

DEJA UNA RESPUESTA

Por favor ingrese su comentario!

He leído y acepto la política de privacidad

Por favor ingrese su nombre aquí

Información básica acerca de la protección de datos

  • Responsable:
  • Finalidad:
  • Legitimación:
  • Destinatarios:
  • Derechos:
  • Más información: Puedes ampliar información acerca de la protección de datos en el siguiente enlace:política de privacidad