Está en la página 1de 18

JasperReports, iReport y Subreportes

Francesc Ros s A lbiol Novie mbr e 2004 v. 1.0

INTRODUCCIN Y JUSTIFICACIN
ltimamente, han aparecido en los frums de javaHispano diversas preguntas sobre un mismo tema: la incorporacin de subreportes en JasperReports. Hasta la fecha, no he tenido que usar subreportes, pero siempre hay una primera vez y, finalmente, me he tenido que enfrentar a ello. Lo primero que hice fue buscar informacin al respecto y me top con la cruda realidad: Hay poca o no me alcanza para lo que quiero hacer. En la documentacin de JasperReports, y ms concretamente en el documento Tutorial (http://jasperreports.sourceforge.net/tutorial/index.html), aparece un apartado que lleva por ttulo Subreports, pero al acceder a l me encuentro con tres lneas y un aviso en rojo: Documentation pending.... Afortunadamente, en las demos de JasperReports aparece un ejemplo que proporciona varias ideas al respecto. Acto seguido, voy a ver qu hay en mi interficie grfica favorita para la generacin de reportes: iReport-Designer for JasperReports (http://ireport.sourceforge.net/). All encuentro ms informacin al respecto. En el manual, slo dice que iReport soporta subreportes, pero encuentro un par de tutoriales1 sobre el tema. El primero, How to create a subreport (http://ireport.sourceforge.net/subreport_tutorial.zip), de Shailesh Kadam, es del 2003 y lo encuentro un poco incongruente. Se basa en dos tablas, una de empleados y otra de direcciones, y nos dice que un empleado puede tener cero o ms direcciones asociadas. La verdad es que no s cmo asocia direcciones a un empleado, ya que no hay ningn campo que enlace ambas tablas ni tabla alguna que enlace empleados y direcciones. Adems, si existiera el enlace, no hara falta el uso de subreportes para mostrar las direcciones asociadas a un empleado. Un simple grupo nos resolvera el problema. El segundo es un vdeo creado por unos usuarios hawaianos (http://ireport.sourceforge.net/swf/Subreport_viewlet_swf.htm) y parece ms reciente. Una vez ms, nos encontramos con un ejemplo basado en una relacin maestro-detalle: disponemos de una tabla de pases y otra de estados o provincias de cada pas. El tutorial muestra la mecnica bastante bien, pero el ejemplo, a mi entender, no es del todo bueno porque puede resolverse usando grupos. El objetivo de este tutorial es, pues, intentar cubrir la falta de documentacin sobre el uso de subreportes en JasperReports. No pretendo en ningn momento que este tutorial se convierta en un tutorial de JasperReports ni de iReport. Doy por supuesto que el lector conoce el funcionamiento de ambos productos y que slo desea profundizar en el uso de subreportes. Tampoco quiero cubrir todas las posibilidades de los subreportes. Me centrar en un ejemplo
1 Parece ser que la Real Academia de la Lengua Espaola todava no acepta la palabra tutorial (-es). Sin embargo, yo la uso porque entiendo que un tutorial es un subtipo de manual y no hallo otra palabra en castellano que pueda usar.

1 de 18

concreto que, creo y deseo, sirva de inspiracin al lector para usar subreportes.

ESCENARIO
Nuestro escenario va a ser un proceso de matrcula a una serie de cursos. Una persona se matricula a uno o ms cursos y debe saber qu le va a costar en total. La inscripcin en un curso supone el pago de una matrcula inicial y una serie de mensualidades. Nuestro informe debe generar una simulacin de la factura de la matrcula y, adems, mostrar el precio de cada mensualidad, el total de mensualidades a pagar y el importe total de mensualidades. Para ello, hemos diseado una base de datos con la siguiente estructura:

Figura 1: Esquema de tablas

El significado de la mayor parte de las columnas de las tablas se puede deducir fcilmente de su nombre. Quiz la tabla menos clara sea la de Cursos. Comento, pues, las columnas que la forman: Colu mna ID NOMBRE MATRICULA MENSUALIDAD Com entario Es la clave primaria. Un entero autoincrementado Contiene los nombres de los cursos (p.e. Curso 1, Curso 2, etc.) Contiene los precios de las matrculas de los distintos cursos Contiene los precios de cada una de las mensualidades a pagar por cada curso

MENSUALIDADES Contiene el nmero de mensualidades a pagar por cada curso


Tabla 1: Descripcin de la tabla Cursos

Obsrvese que el informe que deseamos no se corresponde con el tpico maestro-detalle. En realidad estamos hablando de dos informes en uno. El primero nos va a mostrar los datos de la persona, en este caso slo nombre y apellidos, y los gastos detallados que va a tener que pagar en concepto de matrculas. El segundo nos va a mostrar cunto va a tener que pagar al mes por cada uno de los cursos matriculados, durante cuntos meses y el importe total por curso. Como la descripcin de una imagen nunca le hace justicia, veamos, pues, qu es lo que realmente queremos obtener en nuestro informe: 2 de 18

Figura 2: Aspecto del informe final

Nuestro reporte tiene cuatro partes diferenciadas: 1. Un ttulo: Presupuesto de cursos 2. Informacin sobre la persona: ARAGN LPEZ, Pedro 3. Informacin sobre la matrcula 4. Informacin sobre las mensualidades Las partes 1, 2, y 3 configuran el reporte maestro y la 4, mensualidades, es el subreport.

REPORTES Y SUBREPORTES
Un reporte es un informe resultado del proceso, ms o menos complejo, de datos que pueden proceder de diversas fuentes. Lo ms frecuente, en el mbito informtico, es que los datos procedan de una base de datos. No hay diferencia entre un reporte y un subreporte. Todo reporte pasa a convertirse en subreporte en cuanto forma parte de otro reporte. Este concepto es importante, ya que nos indica que no hay que hacer nada especial para disear un subreporte. Se disea de la misma manera que un reporte cualquiera. En este tutorial, llamaremos reporte maestro a aqul que contiene algn otro reporte, y a los reportes 3 de 18

que forman parte del maestro, los llamaremos subreportes.

ESTRATEGIA DISEO
Como he comentado ms arriba, no hay diferencia entre reporte y subreporte ya que ambos son reportes, sin embargo para conseguir el informe que deseamos, hemos de enlazarlos. As pues, el grueso de este tutorial se centrar en cmo establecer el enlace entre el reporte maestro y el subreporte. Nuestra estrategia es sencilla: 1. Disear el reporte maestro un elemento vaco de subreporte 2. Disear el subreporte como un reporte ms 3. Definir los enlaces entre el reporte maestro y el subreporte Despus de llevar a cabo los puntos 1 y 2 debemos ser capaces de visualizar por separado reporte y subreporte usando iReport. La siguiente imagen muestra el resultado de la visualizacin de nuestro reporte maestro antes de ligarlo al subreporte:

Figura 3: Vista previa del reporte maestro

Y la que sigue nos muestra la visualizacin del subreporte por separado:

4 de 18

Figura 4: Vista previa del subreporte

DISEO DE REPORTE MAESTRO Y SUBREPORTE


No es mi intencin, como ya he comentado, extenderme demasiado en la descripcin de los diseos del reporte y subreporte. El tutorial incluye los fuentes de los reportes y de la clase Java que los muestra, as que slo comentar los puntos ms significativos.

Re porte maestro
Consulta
El reporte maestro nos muestra la informacin existente en nuestra base de datos sobre la matrcula de una persona en concreto. Para obtener dicha informacin, usamos la siguiente consulta SQL:
SELECT P.ID, P.NOMBRE AS NOMBRE, P.APELLIDOS, C.NOMBRE AS CURSO, C.MATRICULA FROM PERSONAS P, CURSOS C, PERSONA_CURSOS PC WHERE P.ID = $P{PERSONA_ID} AND PC.ID_PERSONA = P.ID AND PC.ID_CURSO = C.ID

Obsrvese que para identificar a la persona sobre la que queremos realizar el reporte usamos un parmetro: $P{PERSONA_ID}.2 Este parmetro deber ser pasado por nuestro programa a la instancia de net.sf.jasperreports.engine.JasperReport para que en el momento de llenado del reporte, ste sepa de qu persona debe obtener los datos. Obsrvese, tambin, que a la columna C.NOMBRE de la tabla CURSO, le asignamos el alias CURSO. Dicha columna contiene el nombre del curso.

Campos
Los campos se generan a partir de la consulta SQL. La siguiente tabla presenta una descripcin
2 Es conveniente crear el parmetro PERSONA_ID antes de crear la consulta, ya que si no existe, no puede ser referenciado en la consulta.

5 de 18

somera de los mismos: Cam po APELLIDOS CURSO ID MATRICULA NOMBRE Los apellidos de la persona El nombre del curso El identificador nico de la persona El precio de la matrcula del curso El nombre de la persona Descripcin

Tabla 2: Descripcin de los campos

Estructura: Bandas
Trabajamos con cuatro de las bandas que nos ofrece JasperReports:

Title

Ttulo del reporte: Presupuesto de cursos El texto esttico MATRCULA El campo ID, que se usa como dato de corte para el grupo. Este campo ser invisible. La variable PERSONA: resultado de la concatenacin de los campos APELLIDOS y NOMBRE, pasando los apellidos a maysculas y separndolos del nombre por una coma Los textos estticos Concepto, Base Imponible, IVA 16% y Total Los campos de texto asociados a los campos CURSO y MATRICULA La variable IVA, resultado de multiplicar el campo MATRICULA por 0,16 La variable MATR_SUBTOT, resultado de sumar el campo MATRICULA a la variable IVA El texto esttico TOTAL MATRCULAS La variable MATR_TOTAL_IVA, resultado de sumar los valores de la variable IVA para cada registro La variable MATR_TOTAL, resultado de sumar los valores de la variable MATR_SUBTOT para cada registro El texto esttico MENSUALIDADES El elemento SUBREPORT La fecha y el nmero de pgina

Group Header

Detail

Group Footer

Page Footer

Estructura: Grupo
Como nuestro reporte hace referencia a una sola persona, no tiene mucho sentido crear un grupo ya que slo podemos agrupar a nuestra persona con ella misma.

6 de 18

Sin embargo, nos conviene crearlo desde el punto de vista de la facilidad de presentacin. Si no lo tuviramos, deberamos emplear la banda Column Footer para presentar los totales de matrcula y el subreporte de mensualidades. El resultado sera que dicha banda nos presentara los resultados al final de la pgina y quedara poco esttico.3 Para evitar este efecto no deseado, he optado por usar un grupo. Los grupos proporcionan la banda Group Footer interesante para nuestro ejemplo porque nos permite ubicar en ella, a nuestra conveniencia, tanto los totales de matrcula como el subreporte.

Sub reporte
Consulta
El subreporte nos presentar informacin sobre las mensualidades que una persona en concreto deber pagar por cada uno de los cursos matriculados. Para obtener dicha informacin, usaremos la siguiente consulta SQL:
SELECT C.NOMBRE AS CURSO, C.MENSUALIDAD, C.MENSUALIDADES FROM PERSONAS P, CURSOS C, PERSONA_CURSOS PC WHERE P.ID = $P{PERSONA_ID} AND PC.ID_PERSONA = P.ID AND PC.ID_CURSO = C.ID

Como en la consulta del reporte maestro, tambin aqu usamos un parmetro, $P{PERSONA_ID} para identificar a la persona.4 A diferencia de ste, como veremos ms adelante, el valor del parmetro no se lo proporcionar nuestro programa, sino que lo tomar directamente del reporte maestro.

Campos
La siguiente tabla describe someramente los campos que se desprenden de la consulta SQL del subreporte: Cam po CURSO MENSUALIDAD MENSUALIDADES Nombre del curso Importe de cada mensualidad de un curso Nmero de mensualidades a abonar Descrip cin

Tabla 3: Campos a partir de la consulta SQL

Estructura: bandas
La estructura de bandas en el subreporte es mucho ms sencilla que en el reporte. Slo usaremos dos:

Column Header

Los textos estticos Concepto, Mensualidad, Mensualidades y Total Los campos de texto asociados a los campos CURSO, MENSUALIDAD y

Detail

3 Es muy posible que esto no sea as y que haya alguna manera de evitar el efecto no deseado de la Column Footer, pero yo la desconozco y creo que es poco relevante para el objetivo principal de este artculo. 4 Como como hemos visto en la descripcin el reporte maestro, aqu tambin es conveniente crear el parmetro PERSONA_ID antes de definir la consulta.

7 de 18

MENSUALIDADES

La variable SUBTOTAL_MENSUALIDADES, resultado de multiplicar los valores del campo MENSUALIDAD por los del campo MENSUALIDADES

Inclusin del subr eporte en iR eport


La inclusin de un subreporte en un reporte usando iReport supone lo mismo que incluir un campo de texto o un texto esttico. Simplemente hay que pulsar el botn de Subreport tool de la barra de herramientas y despus arrastrar el ratn en la banda que nos interese hasta conseguir el tamao deseado para nuestro subreporte. La siguiente imagen muestra la parte de la barra de herramientas que incluye el botn de subreportes:

Figura 5: Botn de inclusin de subreporte

ENLACE REPORTE MAESTRO SUBREPORTE


Hemos visto hasta ahora cmo disear el reporte maestro y el subreporte y cmo reservar un espacio para ste en el reporte maestro. Fijmonos en el detalle. En realidad hemos reservado un espacio en el reporte maestro. ste no sabe absolutamente nada del subreporte que tiene que presentar. Pensemos en lo que necesitara saber el reporte maestro para poder presentar el subreporte.

Quin es? Dnde est?


Lo primero que se nos ocurre es que necesita tenerlo para poderlo cargar en el espacio que le hemos reservado. Fijmonos que la manera ms cmoda de pasrselo es mediante un parmetro. Nuestro programa crear una instancia de java.util.Map que contendr la informacin necesaria para que el reporte maestro cargue el subreporte. Una estrategia sera definir un parmetro de tipo String que nuestro programa rellenar con el path completo de nuestro reporte. En alguno de los ejemplos que he consultado, han optado por esta solucin. Sin embargo, yo le veo un problema si lo que pretendo es que el subreporte forme parte del archivo jar que contendr nuestra aplicacin. Lo que haremos, pues, es definir en el reporte maestro un parmetro, al que llamaremos SUBREPORT, de tipo net.sf.jasperreports.engine.JasperReport. Para ello, abriremos la vista de parmetros del men View y accederemos a la ventana de definicin de parmetros. En esta ventana, pulsaremos el botn New para acceder al dilogo que nos permitir definir nuestro parmetro. La siguiente figura intenta sintetizar lo dicho hasta ahora:

8 de 18

Figura 6: Definicin del parmetro SUBREPORT

Obsrvese que en la ventana de definicin de parmetro, bajo el ttulo Parameter class type, hay un desplegable. Es posible que ste no contenga el tipo que nos interesa: net.sf.jasperreports.engine.JasperReport. Si es as, no hay problema ya que el desplegable es editable y lo podremos escribir. Una vez entrados los datos del parmetro, pulsamos OK y ya lo tendremos definido. Bien, ya hemos establecido el mecanismo para que nuestro reporte maestro sepa qu tiene que poner en el espacio reservado para el subreporte.

Cmo lo lleno?
Claro que con saber qu reporte ocupar el espacio reservado para el subreporte no hay bastante. Hemos de establecer los mecanismos para que este subreporte se pueda llenar con los datos pertinentes. Como hemos visto, nuestra fuente de datos es una base de datos. Para acceder a nuestra base de datos necesitamos una conexin con ella. Desde nuestro programa Java solemos abrir una conexin con la base de datos que queda plasmada en un objeto de tipo java.sql.Connection. Esta instancia es la que usamos para llenar nuestro reporte maestro de datos, pasndosela como parmetro al mtodo fillReport() de la clase net.sf.jasperreports.engine.JasperFillManager:
JasperPrint masterPrint = JasperFillManager.fillReport(masterReport, masterParams, con);

Ms adelante, comentaremos esta llamada con ms detalle. De momento, nos conformamos con saber que nuestro reporte maestro dispone de una conexin a la base de datos que va a usar para ejecutar la consulta SQL que hemos comentado ms arriba. 9 de 18

Esta conexin est guardada en un parmetro interno de nuestro reporte maestro que JasperReports se encarga de crear para nosotros: REPORT_CONNECTION. Curiosamente, iReport no muestra dicho parmetro en la ventana de definicin de parmetros, pero hay que tenerlo muy presente. El parmetro existe. El lector, llegado a este punto, estar preguntndose el porqu de tanto prembulo. Bien, es importante entender qu hace un reporte para poder acceder y presentar despus los datos. Hasta el momento, hemos visto que el reporte maestro tiene informacin suficiente para ejecutar su consulta y presentar sus datos, pero nos queda todava entender cmo se las arreglar para que el subreporte haga lo propio ya que es el reporte maestro quien lanza el llenado del subreporte, al formar ste parte de l. Lo primero que hay que indicar es el mtodo utilizado por el subreporte para acceder a los datos. Para ello, hacemos doble clic en el elemento subreporte, que hemos incluido en el reporte maestro, para acceder a sus propiedades y seleccionamos la segunda pestaa (Subreport):

Figura 7: Propiedades del subreporte - Subreport

Bajo el ttulo Connection / Datasource expression, vemos una lista desplegable. De ella, podemos seleccionar el mtodo que usar nuestro subreport para obtener los datos. En nuestro caso, seleccionamos el elemento Use connection expression ya que los vamos a obtener de una base de datos mediante una conexin. A continuacin, escribimos la expresin que nos va a llevar a la conexin deseada. En nuestro caso, el parmetro REPORT_CONNECTION comentado ms arriba. Es decir, nuestro reporte maestro le va a pasar a nuestro subreporte la conexin referenciada en el parmetro REPORT_CONNECTION para que pueda ejecutar su consulta SQL.

10 de 18

Volviendo a la lista desplegable, observamos que nos ofrece dos posibilidades ms:

Don't use connection or datasource Use datasource expression

La primera, no uses nada, es til si lo que le pasamos es un subreporte que no necesita ni de una fuente de datos ni de una conexin. Por ejemplo, si los datos de los que se nutre le son proporcionados por parmetros. La segunda, Usa una expresin de datasource, se utilizara en el caso de que el subreporte se llenara directamente a partir de una fuente de datos que implementase la interficie net.sf.jasperreports.engine.JRDataSource como la clase net.sf.jasperreports.engine.data.JRTableModelDataSource que se basa en un un modelo de javax.swing.JTable. En este caso, definiramos un parmetro de tipo JRTableModelDataSource que contuviera la referencia a la fuente de datos deseada. Acabamos de ver que dependiendo del mtodo que nuestro subreporte use para obtener los datos (base de datos, fuente de datos, nada), ser conveniente pasarle una cosa u otra. En nuestro caso, como lo tiene que llenar, le pasamos un JasperReport que deber obtener sus datos mediante una conexin a una base de datos y una consulta SQL. Pues bien, qu le pasamos tambin hay que indicrselo. Para ello, seleccionaremos la tercera pestaa del dilogo de propiedades del subreporte (Subreport (Other)). All le diremos que le vamos a proporcionar un objeto del tipo net.sf.jasperreports.engine.JasperReport y que su referencia la puede encontrar en el parmetro SUBREPORT. La siguiente imagen nos lo muestra:

11 de 18

Figura 8: Propiedades del subreporte - Subreport (Other)

Con quin me lleno?


Bueno, esta es la pregunta existencial que nuestro subreporte se hace. Se tiene que rellenar con los datos de la misma persona que el reporte maestro. Recordemos que el reporte maestro tiene un parmetro llamado PERSONA_ID y que, curiosamente, nuestro subreporte tiene otro con el mismo nombre y del mismo tipo. En ambos casos, el valor del parmetro se utiliza para discriminar la persona sobre la que se va a realizar el reporte. En este caso, al llamarse igual y ser del mismo tipo, el reporte maestro se lo pasar al subreporte de manera que ste sabr que tiene que obtener los datos de una persona concreta, y para ser ms exactos, la misma de la que obtendr datos el reporte maestro. Si la cosa no fuera tan sencilla y tuviramos que pasarle ms parmetros o los parmetros del subreporte, por ejemplo, no tuvieran el mismo nombre que el del reporte maestro o hubiera que realizar algn clculo previo, etc., etc., los podramos especificar en la tercera pestaa del dilogo de propiedades del subreporte, en el apartado Subreport Parameters:

12 de 18

EL PROGRAMA
Una vez diseados el reporte maestro y el subreporte por separado y cumplimentadas las especificaciones de localizacin y rellenado, seguimos sin tener nada! Si intentamos visualizar el reporte maestro desde iReport, veremos slo el reporte maestro. En el espacio del subreporte, no veremos nada. La razn es simple, no le hemos pasado al reporte maestro todos los datos necesarios para que pueda mostrarnos el subreporte. Simplemente le hemos indicado dnde los puede encontrar. La aplicacin iReport no sabe crear un objeto JaspeReport y pasrselo en un parmetro al reporte maestro. Para ver el resultado final de nuestra obra de arte, escribiremos un pequeo programa en Java que nos acabar de llenar los huecos que iReport no puede. Describir slo las partes ms relevantes del programa. El fuente del programa est disponible.

Obtencin de URL s de los archivos de reportes


Lo primero que hago es conseguir la ubicacin de los archivos previamente compilados de los reportes. Estos archivos se encuentran en el subdirectorio reports de mi proyecto. Es decir, estarn en el subdirectorio reports de mi archivo jar. Para referirme a ellos, crear sendas URLs usando el mtodo getResource() de la clase Class. La referencia ser, pues, a partir del path interno, del path de la clase. Este es el mtodo habitual de cargar recursos y evita aquello tan pesado de no encuentro el recurso en cuanto sales del IDE.
SubreportsSample t1 = new SubreportsSample(); URL urlMaestro = t1.getClass().getResource

13 de 18

("/reports/TUTORIAL_SUBREPORTS_MASTER.jasper"); URL urlSubreporte = t1.getClass().getResource ("/reports/TUTORIAL_SUBREPORTS_SUBREPORT.jasper");

Cre acin de los obje tos JasperReport


A continuacin, voy a crear los objetos JasperReport a partir de los reportes compilados:
JasperReport masterReport = (JasperReport) JRLoader.loadObject (urlMaestro); JasperReport subReport = (JasperReport) JRLoader.loadObject (urlSubreporte);

Parmet ros
Hemos visto que slo nuestro reporte maestro necesita parmetros ya que el subreporte, en este ejemplo, los toma del maestro. Creamos, pues un java.util.Map y lo llenamos con los parmetros:
Map masterParams = new HashMap(); masterParams.put("SUBREPORT", subReport); masterParams.put("PERSONA_ID", new Integer(3));

Con ellos el reporte maestro sabr de qu persona tiene que obtener los datos (PERSONA_ID) y dispondr del subreporte para llenar su hueco (SUBREPORT).

Ll enado
Para que podamos ver el resultado, tenemos que llenar con los datos nuestros reportes. Para ello, slo hay que rellenar el reporte maestro ya que el subreporte se llenar en cascada desde el maestro. El siguiente cdigo muestra cmo se llena:
JasperPrint masterPrint = JasperFillManager.fillReport(masterReport, masterParams, con);

Obsrvese que aqu le pasamos todo lo necesario:


El reporte maestro: masterReport Los valores de los parmetros del reporte maestro: masterParams La conexin a la base de datos: con

El resultado es un objeto JasperPrint, listo para ser visualizado, convertido en HTML, en PDF, etc.

Vi sualizacin
Por fin, vamos a ver el resultado de nuestros esfuerzos. Para ello, usaremos el mtodo esttico viewReport() de la clase JasperViewer:
JasperViewer.viewReport(masterPrint, false);

El segundo parmetro de viewReport ,false, indica que la aplicacin no debe cerrarse al cerrar la ventana de visualizacin. En este caso, lo prefiero as porque quiero cerrar la conexin con la base de datos despus de visualizar el reporte.

14 de 18

RESUMEN
Intentar resumir aqu los principales conceptos y pasos a seguir necesarios para construir un subreporte.

Conceptos

Un subre port e no es otra cosa que un reporte. Por lo tanto, su diseo no difiere del de otros reportes. Un repo rte m aestro es un reporte que contiene un elemento ms, llamado subreporte. Este elemento reserva espacio para el reporte que actuar como subreporte. Las propiedades del elemento subreporte permiten enlazar el reporte maestro con el subreporte de manera que el reporte maestro sepa localizarlo y pueda pasar la informacin necesaria al reporte que acta como subreporte para que ste se pueda llenar con los datos pertinentes.

Pasos a seguir
1. Disear el reporte maestro: 1. Disear como un reporte normal 1. Definir uno o ms parmetros, si fuera necesario, que nos permitan acotar nuestra consulta (p.e. PERSONA_ID, para identificar a una persona en concreto)5 2. Definir la consulta SQL usando, si fuera necesario, los parmetros del punto anterior. Por ejemplo: SELECT P.ID, P.NOMBRE AS NOMBRE, P.APELLIDOS, C.NOMBRE AS CURSO, C.MATRICULA FROM PERSONAS P, CURSOS C, PERSONA_CURSOS PC WHERE P.ID = $P{PERSONA_ID} AND PC.ID_PERSONA = P.ID AND PC.ID_CURSO = C.ID. 2. Incluir un elemento de tipo subreporte en el diseo que reservar espacio para que se muestre el reporte que actuar como subreporte 3. Compilar y visualizar el reporte maestro6 verificando que el resultado sea el esperado, sin tener en cuenta el subreporte 2. Disear el subreporte: 1. Disear como un reporte normal 1. Definir uno o ms parmetros, si fuera necesario, que nos permitan acotar nuestra consulta. Si hemos de enlazar el subreporte con el reporte maestro, es conveniente que dichos parmetros compartan el nombre y el tipo con los del reporte maestro (p.e. PERSONA_ID) 2. Definir la consulta SQL usando, si fuera necesario, los parmetros del punto anterior. Por ejemplo: SELECT C.NOMBRE AS CURSO, C.MENSUALIDAD, C.MENSUALIDADES
5 Obsrvese que no es posible utilizar en la definicin de la consulta parmetros que an no se han definido. La aplicacin iReport nos dara un error si as lo hiciramos. 6 En la visualizacin no aparecer el subreporte.

15 de 18

FROM PERSONAS P, CURSOS C, PERSONA_CURSOS PC WHERE P.ID = $P{PERSONA_ID} AND PC.ID_PERSONA = P.ID AND PC.ID_CURSO = C.ID. 3. Compilar y visualizar el subreporte verificando que el resultado es el esperado, sin tener en cuenta el subreporte 2. Enlazar reporte maestro y subreporte: 1. Definicin en el reporte maestro del parmetro que contendr el subreporte:7 1. Definimos un parmetro llamado, por ejemplo, SUBREPORT. 2. Asignamos como tipo de parmetro net.sf.jasperreports.engine.JasperReport. 2. Asignacin de este parmetro al elemento subreporte 1. Abrimos el dilogo de propiedades del subreporte haciendo doble clic en el elemento subreporte del reporte maestro 2. Seleccionamos la pestaa Subreport (Other) del dilogo de propiedades 3. En la lista desplegable que lleva por ttulo Image Expression Class, seleccionamos el tipo net.sf.jasperreports.engine.JasperReport 4. En el campo que lleva por ttulo Subreport Expression, especificamos el parmetro que contendr nuestro subreport: $P{SUBREPORT} 3. Especificacin del mtodo usado por el subreport para obtener los datos: 1. Seleccionamos la pestaa Subreport del dilogo de propiedades del subreport 2. De la lista desplegable Connection / Datasource Expression, seleccionamos el elemento Use connection expression para indicar que los datos se van a obtener mediante una conexin a una base de datos 3. En el campo de texto que se encuentra debajo de la lista de seleccin del punto anterior, especificamos el parmetro que va a proporcionar la conexin a la base de datos: $P{REPORT_CONNECTION} 4. Creacin del programa: Para poder visualizar los resultados de nuestro trabajo, debemos crear un pequeo programa que proporcione al reporte maestro aquellos datos que iReport no puede obtener. Dicho programa tendr la siguiente estructura: 1. Obtencin de las URLs de los archivos que contienen el reporte maestro y el subreporte: URL urlMaestro = t1.getClass().getResource ("/reports/TUTORIAL_SUBREPORTS_MASTER.jasper"); URL urlSubreporte = t1.getClass().getResource ("/reports/TUTORIAL_SUBREPORTS_SUBREPORT.jasper"); 2. Crear los objetos JasperReport, correspondientes al reporte maestro y al subreporte, a partir de las URLs obtenidas en el punto anterior 3. Definir el objeto java.util.Map que contendr los parmetros correspondientes al reporte maestro
7 El valor de dicho parmetro ser asignado desde nuestra aplicacin Java, como veremos ms adelante.

16 de 18

4. Incluir las parejas nombre de parmetro valor en el Map definido en el punto anterior 5. Llenar el reporte maestro con los valores para obtener un objeto JasperPrint capaz de ser visualizado 6. Visualizacin del reporte maestro (que ahora ya incluye el subreporte) mediante el mtodo esttico viewReport() de JasperViewer

QU HE USADO?
Herrami entas de reportes
He usado la versin 0.6.1 de JasperReports (http://jasperreports.sourceforge.net/), si bien, mientras escriba este tutorial ha aparecido la versin 0.6.2, cuyos cambios no afectan en nada a este tutorial. He utilizado la ltima versin de iReport -Designer for JasperReports (http://ireport.sourceforge.net/): la 0.4.0. Para crear la clase Java de visualizacin, he utilizado la versin 3.0.1 de Eclipse (http://www.eclipse.org/).

Gestor es de bases de datos


He usado la versin 4.1.7-nt de MySQL (http://www.mysql.com) como gestor de bases de datos principal. Sobre l he desarrollado la aplicacin y he relizado pruebas. Tambin he usado HSQLDB 1.7.2.8 (http://hsqldb.sourceforge.net/). Sin embargo, no he realizado pruebas contra HSQLDB. Para la generacin del modelo de datos y los DDLs, he usado la versin 1.0.5 del plugin de Eclipse Clay Database Modeling (http://www.azzurri.jp/en/software/clay/index.jsp). El plugin tambin se ha utilizado para convertir el modelo de datos de MySQL a HSQLDB.

Procesador de textos
Para escribir el tutorial y para generar el PDF, he utilizado el extraordinario OpenOfiice 1.1.3 (http://www.openoffice.org).

CONTENIDO DEL ARCHIVO ZIP


El archivo SUBREPORTS.ZIP contiene:

El archivo LEEME.TXT que contiene esta informacin en formato texto [directorio raz] El tutorial en PDF, SUBREPORTS_TUTORIAL.pdf [directorio raz] Los DDL que permiten crear tablas e insertar datos de ejemplos para MySQL y para HSQLDB [directorio subreports\database] Los reportes maestro y subreporte compilados (*.jasper) y sin compilar (*.jrxml) [directorio subreports\reports] La clase de ejemplo, SubreportsSample, en fuente y compilada [directorio subreports] 17 de 18

PARA TERMINAR
Decir que este tutorial es el resultado de mi primer trabajo con subreportes de JasperReport, por lo que seguro que est tapizado de agujeros y errores, que espero que el lector sabr disculpar y poner de manifiesto en el apartado de comentarios de javaHispano. Toda crtica ser bien recibida y contribuir a la generacin de una versin ms completa de este tutorial. Espero y deseo que, a pesar de todo, este tutorial cubra una buena parte de las expectativas de los desarrolladores.

18 de 18

También podría gustarte