Академический Документы
Профессиональный Документы
Культура Документы
5.CONFECCIÓN DE INFORMES
Se abrirá la ventana
de Connections /
Datasources y
clickamos en New
Seleccionamos
Database JDBC
Connection
Damos un nombre
cualquiera a la conexión.
Seleccionamos el JDBC
Driver de MySQL
En JDBC URL indicamos el
nombre de nuestra BBDD
Insertamos los datos de
nuestro login.
Pulsamos Test para
comprobar que todo
funciona correctamente.
Ahora nos dirigimos al menú superior File > New… y en Report seleccionamos una
plantilla (yo he seleccionado Wood) y pulsamos Launch Report Wizard
Los pasos interesantes son el 3 y el 4, así que será en estos en los que nos enfocaremos
más.
El paso 1 se realiza de forma automática, así que no tenemos mucho que hacer en él. En
el paso 2 (en donde comenzamos) seleccionamos el directorio en el que queremos
guardar nuestro reporte y el nombre que tendrá.
Hacemos clic en el botón "Next" para continuar con el paso 3. En este paso
debemos seleccionar el datasource desde el que los datos del reporte serán
tomados. Por default está seleccionado el "Empty datasource". Así que
nosotros seleccionamos el datasource "Conexion MySQL Pruebas" (el
datasource que creamos anteriormente).
La consulta que haremos será para obtener todos los datos de la tabla
"participantes", con excepción del "ID". Para esto hacemos doble clic sobre el
nombre de la tabla "participantes" en la segunda sección de la ventana que
tenemos abierta. Con esto aparecerá en la tercer sección otra ventana con el
título "participantes" y un conjunto de checkboxes, cada uno con un campo de
nuestra tabla. Para generar la consulta que nos interesa solamente
seleccionamos todos los checkboxes (con excepción del "ID") y veremos que la
consulta se genera en la primer sección. Ya solo damos clic en el botón "OK".
En este paso solo tenemos que seleccionar cuáles campos del query
generado en el paso anterior queremos que se muestren en el reporte.
Como nosotros queremos que se muestren todos pasamos todos los
campos del lado izquierdo al lado derecho y hacemos clic en el botón
"Next".
Si queremos ver como se verá el reporte final, en este caso, podemos ver
un preview con los datos reales si cambiamos a la vista de "preview" en la
ventana del editor.
Además cambiamos el título de cada una de las columnas por algo más
claro. Por ejemplo, podemos cambiar el título de la columna
"participantes_USERNAME" a "Usuario", "participantes_NOMBRE" a
"Nombre", etc.
jasperreports-3.7.6.jar
jasperreports-3.7.6-javaflow.jar
jasperreports-fonts-3.7.6.jar
commons-beanutils-1.8.0.jar
commons-collections-2.1.1.jar
commons-digester-1.7.jar
commons-logging-1.0.4.jar
commons-javaflow-20060411.jar
groovy-all-1.7.5.jar
iText-2.1.7.jar
png-encoder-1.5.jar
poi-3.6.jar
Algunos de estos jars se encuentran en el directorio "dist" y otros en el directorio "lib" del archivo .zip
de JasperRepots que bajamos anteriormente.
Hacemos clic en el botón "Add Jar/Folder" y con esto tendremos lista nuestra biblioteca
"JasperReports" para agregarla a nuestro proyecto.
Lo siguiente que debemos hacer ahora es crear una conexión a la base de datos que
creamos anteriormente.
Ahora el objeto "reporte" contiene la definición del reporte, pero aún hace falta
que llenemos este reporte con los datos que obtendrá de la base de datos. Para
esto usamos la clase "net.sf.jasperreports.engine.JasperFillManager". Esta clase
tiene un método estático, "fillReport", que nos permite llenar el reporte con
datos obtenidos de distintas fuentes de datos (una de estas fuentes es la
sentencia SQL que escribimos al generar el reporte con el wizard en iReports y la
conexión que usaremos en un momento, veremos qué otras fuentes de datos
existen y cómo usarlos en los siguientes posts). En este caso la fuente de datos
es la conexión directa a la base de datos que creamos anteriormente (el objeto
conexion):
exporter.setParameter(JRExporterParameter.JASPER_PRINT,jasperPrint);
exporter.setParameter(JRExporterParameter.OUTPUT_FILE,new java.io.File("reportePDF.pdf"));
exporter.exportReport();
PDF: net.sf.jasperreports.engine.exportJRPdfExporter
HTML: net.sf.jasperreports.engine.exportJRHtmlExporter
CSV: net.sf.jasperreports.engine.exportJRCsvExporter
RTF: net.sf.jasperreports.engine.exportJRRtfExporter
XLS: net.sf.jasperreports.engine.exportJRXlsExporter
XML: net.sf.jasperreports.engine.exportJRXmlExporter
TXT: net.sf.jasperreports.engine.exportJRTextExporter
XLSX: net.sf.jasperreports.engine.export.ooxml.JRXlsxExporter
DOCX: net.sf.jasperreports.engine.export.ooxml.JRDocxExporter
PPTX: net.sf.jasperreports.engine.export.ooxml.JRPptxExporter
exporter.setParameter(JRTextExporterParameter.CHARACTER_WIDTH, 12);//text
exporter
exporter.setParameter(JRTextExporterParameter.CHARACTER_HEIGHT, 12);//text
exporter
getFieldValue(JRField jrField)
next()
Para que podamos pasar datos a nuestro reporte es necesario que utilicemos un
datasource. En el ejemplo anterior veíamos que el datasource que usábamos
era la base de datos y la conexión a la misma. En esta ocasión el datasource será
una de nuestras clases. Esta clase deberá implementar la interface
"JRDataSource" y contendrá la lógica para pasar los datos correspondientes a
nuestro reporte.
Creamos una nueva clase haciendo clic derecho sobre el nodo "Source
Packages" de la ventana "Projects", o sobre el paquete que ya tenemos creado,
y en el menú contextual que se abre seleccionamos la opción "New -> Java
Class...".
public Participante()
{
}
public Participante(int id, String nombre, String username, String password, String comentarios)
{
this.id = id;
this.nombre = nombre;
this.username = username;
this.password = password;
this.comentarios = comentarios;
}
Background
Title
Page Header
Column Header
Detail 1
Column Footer
Page Footer
Last Page Footer
Summary
No Data
Los campos ("$F{}") le dicen al reporte dónde colocará los valores obtenidos a
través del datasource. Por ejemplo, nuestro objeto "Partcipante" tiene un
atributo llamado "username". Usando una expresión de campo indicamos en
cuál parte o sección del reporte debe aparecer el valor de ese atributo usando
"$F{username}". Esto quedará más claro un poco más adelante.
Cada uno de estos elementos tiene un nombre, un tipo (que debe corresponder
con un tipo de objeto Java como String o Integer), y una descripción opcional.
Además deben ser registrados para poder ser usados en tiempo de diseño y que
puedan ser entendidos al momento de compilar el reporte, y por lo tanto para
que nuestro reporte funcione correctamente en tiempo de ejecución. Esto lo
veremos un poco más adelante.
Los fields deben definirse antes de poder ser usados. Esta definición incluye el nombre del
field y su tipo. Los fields (así como el resto de las expresiones) se definen en la ventana
"Report Inspector" a la izquierda del diseñador del reporte. Ahí existe un nodo llamado
"Fields" que es donde se encuentran los fields que hemos definido y que por lo tanto
podemos usar.
Hacemos clic derecho en el nodo "Fields" de la ventana "Report Inspector". Con esto se
abre un menú contextual. Seleccionamos la opción "Add Field" (la única habilitada).
Podemos ver una vista previa del reporte haciendo clic en la pestaña "Preview".
Asegúrense de seleccionar el "Empty datasource" antes de ver el preview, de lo contrario
les aparecerá un error indicado que el documento no tiene páginas. Al final deben ver algo
como esto:
Creamos una nueva clase llamada "ParticipantesDatasource" y hacemos que esta nueva
clase implemente la interface "JRDataSource". Podemos hacer que NetBeans implemente
de forma automática los métodos de esta interface (proporcionando una implementación
vacía) presionando las teclas "Alt + Insert" y seleccionando la opción "Implement Method"
en el menú contextual que se abre.
if("nombre".equals(jrField.getName()))
{
valor = listaParticipantes.get(indiceParticipanteActual).getNombre();
}
return valor;
}
Ahora tal vez se estén preguntando ¿en qué momento se incrementa el contador?, o ¿cómo
sabe JasperReport cuántos participantes existen? Pues bien, ambas cosas ocurren gracias a
la implementación del método "next()".
Esto es todo lo que necesitamos para que nuestro datasource funcione para generar
reportes. Agregaré un método de utilidad a esta clase, llamado "addParticipante", que me
permita agregar un nuevo participante a la lista (aunque si lo prefieren pueden agregar el
setter de "listaParticipantes")
Bien, con esto vemos que podemos crear nuestros propios datasources y pasar datos para
generar reportes sin la necesidad de una conexión a base de datos. Es bastante sencillo,
solamente debemos proporcionar una clase que implemente la interface "JRDataSource" y
que regrese los valores correspondientes a los fields del reporte.
Aunque esto ya es bastante fácil y útil, existe una forma aún más simple para crear un
datasource, sin la necesitad de implementar la interface "JRDataSource". Esto es gracias a
un conjunto de clases que JasperReports ya nos proporciona y realizan básicamente la
misma función que la clase "ParticipantesDatasource" que acabamos de crear. Estas clases
son:
JRBeanCollectionDataSource
JRJpaDataSource
JRBeanArrayDataSource
Ahora eliminamos el elemento que teníamos como título del reporte (el
que contiene el texto estático "Reporte de Participantes") y lo
reemplazamos por el parámetro "titulo" arrastrándolo desde la ventana
del "Report Inspector" a la banda "Title".
Ahora agregamos el
segundo parámetro
("autor") en la banda
"Page Header", la cual se
repite en la parte
superior de cada una de
las páginas (en la primer
página aparece después
del título), arrastrándolo
a esta banda.
Veamos una vista previa del reporte, para esto hacemos clic en la pestaña "Preview". Nos
pedirá los valores de los dos parámetros. Si colocamos para el parámetro "titulo" el valor
"Reporte" y para el parámetro "autor" el valor "Alex" el preview que veremos será el siguiente:
Ahí nos dirigimos a la clase "Main" que creamos la última vez y buscamos la línea en donde
creamos nuestro objeto "JasperPrint":
Y antes de esta línea crearemos un objeto "java.util.Map" que contendrá nuestros parámetros.
Colocaremos el nombre de los parámetros (en este caso "autor" y "titulo") como llave y sus
respectivos valores, "Juan" para el autor y "Reporte Participantes" para el título, como valores.
La segunda variable que usaremos será una variable creada por nosotros
mismos y nos mostrará la suma de los puntos de los Participantes (en este
momento los Participantes no tienen puntos, por lo que tendremos que
agregarlos).
Ahora indicaremos la suma de cuáles valores son los que queremos que se
almacene en este variable. Para eso hacemos clic en el botón "..." de la
propiedad "Variable Expression", con lo que se abrirá una nueva ventana. Es
esta nueva ventana indicaremos de dónde se tomarán los valores para la
suma. Podemos usar una expresión tan compleja como necesitemos. Como
en este caso solo queremos realizar la suma de los puntos escribimos
“$F{puntos}". Y presionamos el botón "OK" para confirmar.
Ahora indicaremos la suma de cuáles valores son los que queremos que se
almacene en este variable. Para eso hacemos clic en el botón "..." de la
propiedad "Variable Expression", con lo que se abrirá una nueva ventana. Es
esta nueva ventana indicaremos de dónde se tomarán los valores para la
suma. Podemos usar una expresión tan compleja como necesitemos. Como
en este caso solo queremos realizar la suma de los puntos escribimos
"F{puntos}". Y presionamos el botón "OK" para confirmar.
Agregaré también un texto estático solo para indicar que el valor que estamos mostrando
corresponde al número de página. Al final el reporte queda así:
Para este ejemplo los datos que graficaremos son las ventas de consolas
de última generación (Wii, XBox360, y PS3). Tomaremos estos datos de
VG Chartz que, aunque no son cifras oficiales, mantiene sus datos
actualizados. En el momento de escribir este tutorial las ventas van:
Wii: 41.6% para nosotros será 41%
XBox 360: 29.6% para nosotros será 30%
PS3: 28.8% para nosotros será 29%
Adicionalmente debemos agregar dos jars más que nos permitirán generar las
gráficas. Puesto que JasperReports hace uso de JFreeChart para generar las
gráficas debemos agregar dos de sus jars: jfreechart.jar y jcommon.jar. Si
bajaron JasperReports en el archivo .zip que contiene las bibliotecas de soporte
entonces ya tienen estos jars (que se encuentran en el directorio lib del .zip
anterior), solo deben agregarlos al nodo "Libraries" del proyecto.
Esta clase tendrá tan solo tres atributos: un id , un nombre para distinguir al
usuario, y el nombre de la consola que tiene (que es el dato que nos interesa
para crear la gráfica).
No es muy obvio el que este grupo existe, de hecho los únicos indicadores que
tenemos son que se han agregado en la zona de las bandas del "Report
Inspector" dos nuevas bandas: "CONSOLAS Group Header" y "CONSOLAS Group
Footer", además se ha agregado una variable llamada "CONSOLAS_COUNT",
que es la variable que nos interesa y por la que hemos creado el grupo, que
mantendrá el número de jugadores que tienen cada una de las consolas:
La "Key expression" dice cuál será la base que se usará para cada uno de
las piezas de la gráfica. En nuestro caso queremos que cada trozo muestre
las consolas. Por lo que colocamos como valor $F{consola}.
Como podemos ver, los tres grupos (uno por cada consola) se muestran de
forma independiente uno de otro. Además en cada grupo se listan solo los
jugadores que tienen la consola del grupo.
El código final de la clase Main es el siguiente:
exporter.exportReport();
}
}
Jose Alberto Benítez Andrades– jose@indipro.es - @jabenitez88 147
PARTE 6: SUBREPORTES
Los subreportes son muy útiles cuando se crea un reporte maestro de detalles o
cuando la estructura de un solo reporte no es suficiente para describir la complejidad
del documento de salida deseado.
En esta última parte veremos cómo realizar subreportes .Veremos dos ejemplos, el
primero mostrará cómo hacer los subreportes mediante una conexión JDBC a la base
de datos. El segundo mostrará como hacerlo con un DataSource propio.
Lo primero que haremos es generar una base de datos de prueba. Yo hare uso de MySql 5.1,
pero pueden usar el manejador que más les guste. Creamos una base de datos llamada
"pruebaReportes" y usamos el siguiente script para crear la tabla "alumnos":
CREATE TABLE alumnos (
ID bigint(21) NOT NULL,
NOMBRE`varchar(100) NOT NULL,
CLAVE varchar(100) NOT NULL,
PRIMARY KEY (ID)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
después este para las materias:
CREATE TABLE materias (
ID BIGINT(21) NOT NULL,
NOMBRE VARCHAR(100) NOT NULL,
PRIMARY KEY (ID)
) ENGINE=INNODB DEFAULT CHARSET=latin1
y finalmente esta será la tabla intermedia, o tabla de unión de las dos anteriores
(ya que se generará una relación N:M entra ambas):
CREATE TABLE alumnos_materias (
ALUMNO_ID BIGINT(21) NOT NULL,
MATERIA_ID BIGINT(21) NOT NULL,
PRIMARY KEY (ALUMNO_ID, MATERIA_ID),
Ahora que tenemos las tablas usaremos el siguiente script para llenarlas:
INSERT INTO alumnos VALUES (1, 'Alumno 1', '00001');
INSERT INTO alumnos VALUES (2, 'Alumno 2', '00002');
INSERT INTO alumnos VALUES (3, 'Alumno 3', '00003');
INSERT INTO alumnos VALUES (4, 'Alumno 4', '00004');
INSERT INTO alumnos VALUES (5, 'Alumno 5', '00005');
INSERT INTO alumnos VALUES (6, 'Alumno 6', '00006');
INSERT INTO alumnos VALUES (7, 'Alumno 7', '00007');
INSERT INTO alumnos VALUES (8, 'Alumno 8', '00008');
INSERT INTO alumnos VALUES (9, 'Alumno 9', '00009');
INSERT INTO alumnos VALUES (10, 'Alumno 10', '000010');
INSERT INTO alumnos_materias VALUES (2, 1); INSERT INTO alumnos_materias VALUES (8, 1);
INSERT INTO alumnos_materias VALUES (2, 2); INSERT INTO alumnos_materias VALUES (8, 2);
INSERT INTO alumnos_materias VALUES (2, 3); INSERT INTO alumnos_materias VALUES (8, 3);
INSERT INTO alumnos_materias VALUES (3, 2); INSERT INTO alumnos_materias VALUES (9, 2);
INSERT INTO alumnos_materias VALUES (3, 4); INSERT INTO alumnos_materias VALUES (9, 4);
INSERT INTO alumnos_materias VALUES (3, 6); INSERT INTO alumnos_materias VALUES (9, 6);
Ya con los datos listos procedemos a crear el proyecto en NetBeans ("File -> New
Project... -> Java -> Java Application"). Con lo que se creará una clase Main que
aparecerá en nuestro editor.
El paso 2 (en el que empieza el wizard) nos pide dar un nombre al archivo del
reporte y una ubicación. Denle el nombre que gusten (en mi caso
"reporteMaestro.jrxml") y guárdenlo en la carpeta raíz del proyecto de
NetBeans que acabamos de crear.
Presionamos el botón
"Next >". En la siguiente
pantalla debemos darle un
nombre y algunos
parámetros al datasource,
como la dirección del
servidor y el nombre de la
base de datos.
Veremos que en la ventana del paso 3 del "Report Wizard" ahora tenemos un
textarea que nos indica que debemos introducir un query. Pueden usar el query
designer si gustan (haciendo click en el botón "Design Query") para crear la
query que usaremos para obtener todos los datos de la tabla "alumnos" (solo de
esa tabla). Al final la query debe ser más o menos así:
SELECT
alumnos.`ID` AS alumnos_ID,
alumnos.`NOMBRE` AS alumnos_NOMBRE,
alumnos.`CLAVE` AS alumnos_CLAVE
FROM
`alumnos` alumnos
Modificaremos los textos estáticos para que concuerden un poco más con el
tipo de reporte que queremos lograr. También eliminaremos las etiqueta y el
texto que muestran el valor de id ya que, como dijimos hace un momento, no
nos interesa mostrarlo:
Al hacer esto se abrirá la ventana del "Subreport Wizard" que es la que nos
guiará en el proceso de la creación del subreporte:
Presionamos en botón "Siguiente >" para ir al paso 4. En este paso podemos elegir si
queremos crear un grupo, como nosotros no queremos crear ninguno, simplemente
dejamos todo como está y volvemos a presionar el botón "Siguiente >".
En el paso 5 podemos elegir el layout del reporte. Puden seleccionar el que quieran.
En mi caso dejaré la opción por default ("Columnar Layout") y presionamos el botón
"Siguiente >".
Presionamos una vez más el botón "Siguiente >" para ir al ultimo paso.
Modificamos un poco el diseño del reporte para que se vea bien al mostrarlo
dentro del reporte maestro (cambiamos unos textos, eliminamos otros, y
eliminamos la banda "Page Footer", también agregamos una línea en la banda
"Summary" para identificar en el reporte final cuando termine la lista de
materias):
Con esto lograremos que el subreporte se genere solo con las materias que
correspondan al alumno con el id que le indiquemos (lo cual haremos en un
momento y que de hecho es el segundo secreto).
Ahora guardamos el
reporte y cambiamos
a la vista de
"Preview". Ahora
debemos ver algo
como lo siguiente:
exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
exporter.setParameter(JRExporterParameter.OUTPUT_FILE, new
java.io.File("reportePDF.pdf"));
exporter.exportReport();
public Alumno()
{
}
public Materia()
{
}
/**
* @author Alex
*/
public Alumno()
{
}
Jose Alberto Benítez Andrades– jose@indipro.es - @jabenitez88 210
public Alumno(int id, String clave, String nombre)
{
this.id = id;
this.clave = clave;
this.nombre = nombre;
}