miércoles, 3 de marzo de 2010

Dynamic Jasper

El objetivo primordial de este artículo es describir una herramienta que puede resultar bastante útil a la hora de algo tan común como es realizar un informe. Vamos a entrar en aspectos básicos de cara a su rápida utilización y aplicación.

¿Qué es Dynamic Jasper?

Dynamic Jasper es una librería que corre sobre JasperReports y que nos simplifica enormemente la realización de informes. Las posibilidades son enormes (posibilidad de agregar Charts, encadenar reportes, añadir códigos de barras a las columnas de un informe, …) además de usos totalmente básicos. En este artículo nos centraremos en conceptos introductorias que podemos ir combinando para obtener resultados cada vez mejores y más elegantes a la vez de poder sumar aspectos más complejos.

Su funcionamiento básico de DJ se centra en hacer más amigable e intuitivo el uso de JasperReports que para nosotros será una caja negra. Es decir, DJ actuará como un disfraz, aunque realmente seguiremos usando JasperReports, pero ahorrándonos todos los engorrosos pasos que supone usarlo.

La web del proyecto contiene un amplio abanico de documentación y ejemplos que nos pueden ser útiles de cara a realizar elegantes informes.



Entorno de integración

Dynamic Jasper es una librería escrita 100% en Java con lo que es fácilmente integrable en proyectos que empleen el lenguaje Java.

No es necesaria ninguna herramienta adicional o “plug-in” al margen de nuestro entorno de desarrollo (IDE) preferido.

Herramientas necesarias o Dependencias

En la página web de la librería podemos observar las dependencias. Aquí indicaremos que librerías vamos a necesitar integrar en nuestros proyectos para poder usar DJ en nuestro proyecto

  • La librería propia de DJ
  • Las librerías que componen Jasper Reports teniendo en cuenta que desde DJ 3.0.5 se necesita Jasper Reports 3.5.
  • Dependencias: Commons BeanUtils, Commons Collections, Commons Logging, Compilador de Eclipse jdt-core.
  • Para exportar a PDF necesitamos la librería iText
  • Para exportar a Excel necesitamos la librería JExcel API y el conjunto de librerías POI de Apache. Esta última librería no está soportada en su versión beta 3.5, es decir, para que no existan problemas necesitamos la versión 3.2
  • Para exportar a XML necesitamos la librería Commons Digester
  • Luego librerías propias de generación de Charts (JFreeChart , JCommon) o de generación de Barcotes o códigos de barra (barbecue 1.1)

Nuestro primer reporte

Una vez sabemos que tenemos que tener montado en nuestro espacio de trabajo sólo nos queda empezar a desarrollar para empezar a ver los primeros resultados. Vamos a hacer un primer informe para observar los primeros resultados.

Definir esqueleto

La idea de realizar un informe es partir de una especie de esqueleto que iremos rellenando añadiendo cosas.

Este esqueleto se puede definir de varias formas como pueden ser las siguientes:


FastReportBuilder drb = new FastReportBuilder();

DynamicReportBuilder drb = new DynamicReportBuilder();

De este modo ya tenemos el esqueleto en la variable ‘drb’. Ahora procederemos a añadirle cosas. Veremos que las posibilidades que hay y la cantidad de añadidos son bastante interesantes.

Hagámonos a la idea de que si generáramos el informe de estos esqueletos obtendríamos un informe en blanco, sin nada que mostrar. Eso es lo que vamos a ir haciendo ahora, añadir datos.

Añadir Primeros Detalles

DJ nos da la posibilidad de añadir detalles que nos resultarán útiles de cara a facilitar determinada información o añadir aspectos elegantes al informe.

Podemos añadir un título a informe


drb.setTitle("Equipos");
Definición de márgenes en la página
drb.setLeftMargin(margen).setRightMargin(margen).setTopMargin(margen).setBottomMargin(margen);
Definimos la anchura de cabecera del informe y del detalle del informe.
drb.setDetailHeight(anchura).setHeaderHeight(anchura);
Podemos hacer que la página se divida en varias columnas y ahí insertar los datos
//Si optamos por más de una columna podemos definir la separación entre ellas
drb.setColumnsPerPage(columnasPorPagina, separacion);
//Definimos una columna por página
drb.setColumnsPerPage(1);
Podemos añadir autotextos
//Insertamos una Fecha en la cabecera a la izquierda
drb.addAutoText(sdf.format(new Date()), AutoText.POSITION_HEADER, AutoText.ALIGMENT_LEFT);

//Insertamos “Pagina X/Y” en la cabecera a la derecha
drb.addAutoText(AutoText.AUTOTEXT_PAGE_X_SLASH_Y, AutoText.POSITION_HEADER, AutoText.ALIGMENT_RIGHT);
Como vemos podemos usar más autotextos cuyo tipo será definido en el primer parámetro:

  • AutoText.AUTOTEXT_CREATED_ON : Nos indicará la fecha de creación del reporte
  • AutoText. AUTOTEXT_PAGE_X_SLASH_Y: Página X/Y
  • “Texto cualquiera”
Además de colocarlo donde queramos en la página.

Como hemos comentado con anterioridad, en la página de la librería podemos obtener muchísima más información acerca añadir bastantes más cosas al reporte.


Añadir Columnas


Vamos a comenzar a definir los datos que queremos mostrar en nuestro informe. Supongamos en nuestro ejemplo que tenemos una Collection de objetos de la siguiente clase:

public class Equipo {

private int id;
private String nombre;
private String fundacion;
private String presidente;
private String entrenador;
private LinkedList<Jugador> jugadores;
private String rutaEscudo;
private InputStream escudo;


public Equipo() {
}

public Equipo(int id, String nombre, String fundacion, String presidente, String entrenador, LinkedList<Jugador> jugadores) {
this.id = id;
this.nombre = nombre;
this.fundacion = fundacion;
this.presidente = presidente;
this.entrenador = entrenador;
this.jugadores = jugadores;
}

public InputStream getEscudo() {
return escudo;
}

public String getRutaEscudo() {
return rutaEscudo;
}

public void setRutaEscudo(String rutaEscudo) {
this.rutaEscudo = rutaEscudo;
try {
File fileIn = new File(rutaEscudo);
this.escudo = new FileInputStream(fileIn);
} catch (Exception e){
e.printStackTrace();
}
}

/*resto de Getters and Setters */

Queremos un informe que muestre el listado de datos de esa Collection.

Vamos a definir un informe donde podamos ver los datos en columnas, por tanto, tenemos que definir esas columnas. Veamos como esto nos va a resultar bastante sencillo:


AbstractColumn c1 = ColumnBuilder.getInstance().setColumnProperty("id", Integer.class.getName()).setTitle("ID").setWidth(10).build();

AbstractColumn c2 = ColumnBuilder.getInstance().setColumnProperty("nombre", String.class.getName()).setTitle("Nombre").setWidth(30).build();

AbstractColumn c3 = ColumnBuilder.getInstance().setColumnProperty("fundacion", String.class.getName()).setTitle("Fundacion").setWidth(30).build();

AbstractColumn c4 = ColumnBuilder.getInstance().setColumnProperty("presidente", String.class.getName()).setTitle("Presidente").setWidth(30).build();

//Añadimos las columnas al informe
drb.addColumn(c1);
drb.addColumn(c2);
drb.addColumn(c3);
drb.addColumn(c4);


Para crear las columnas indicamos nombre del atributo, cadena que representa la clase del atributo (class.getName()), el título que queremos mostrar en el informe y la anchura (medida proporcional) de la columna. Existen muchas más opciones que podemos añadir a la columna a la hora de crearla.

También podemos crear las columnas de la siguiente manera


drb.addColumn("TITULO", "id", Integer.class.getName(),10);

Una vez hemos realizado esto tenemos el informe disponible para ser visualizado. Debemos realizar una serie de operaciones antes que veremos en el siguiente apartado.


Generación del Reporte

Una vez hemos formado el informe debemos realizar unas últimas comprobaciones de cara a poder visualizarlo. A parte de estas comprobaciones deberemos indicarle de donde va a sacar los datos para mostrar, es decir, también deberemos indicarle cual es el DataSource origen. Adicionalmente podemos indicar algunas opciones finales antes de realizar estos pasos, por ejemplo:
drb.setUseFullPageWidth(true);
Indicamos que queremos usar todo el ancho de la página a la hora de mostrar el informe.

Ahora realizamos la compilación del esqueleto rellenado para comprobar si hay algún problema y no se puede continuar con el mostrado del informe.


DynamicReport dr = drb.build();

Una vez que se ha realizado el compilado y todo es correcto procedemos a añadirle la Collection que contiene los datos


//Definimos la fuente de datos
JRDataSource ds = new JRBeanCollectionDataSource(l);

//Generamos el informe como JasperPrint con los datos ya añadidos.
JasperPrint jp = DynamicJasperHelper.generateJasperPrint(dr, new ClassicLayoutManager(), ds);

//Podemos también añadir un mapa de parámetros que hayamos definido anteriormente
//JasperPrint jp = DynamicJasperHelper.generateJasperPrint(dr, new ClassicLayoutManager(), ds, map);

Una vez todos estos procesos se han realizado correctamente con el objeto JasperPrint podemos hacer multitud de operaciones: podemos mostrarlo usando la herramienta JasperViewer, podemos exportarlo a otros formatos (apartado 6), ...

JasperViewer es un visor que proporciona la librería que muestra el informe además de permitirnos la exportación de los datos a través de él a PDF, XML, ODT, ...


//Mostramos el reporte mediante el visor JasperViewer. Con el false, indicamos que no
//cierre la aplicación al cerrar el JasperViewer
JasperViewer.viewReport(jp, false);

El resultado debería ser algo parecido a esto:


Reportes con Plantillas

Ya hemos visto que realizar un reporte simple a fin de cuentas no es más que crear un objeto DynamicReportBuilder o FastReportBuilder, añadirle columnas, compilarlo, asociarle un DataSource y mostrarlo. Ahora bien, pongámonos en el caso de que queremos seguir un formato específico de informe o plantilla. Por ejemplo, una ficha de empleado o, como en el caso de ejemplo, una especie de ficha con los datos de los equipos (los que hemos visto en el apartado anterior). Veremos que con DJ es bastante fácil de realizar.

Definir una plantilla

Para definir o crear una plantilla debemos usar alguna herramienta que nos permita la edición de las mismas y la creación de archivos JRXML. Un programa que realiza este tipo de plantillas es el iReport, bastante intuitivo y fácil de manejar. No vamos a entrar en profundidad en el manejo de esta herramienta, sólo describiremos la plantilla que hemos realizado para realizar este elemento.



  • Podemos observar que hemos colocado siete elementos en la banda de detalle ('detail'): tres etiquetas o 'label' que son elementos estáticos del informe, tres campos TextField que contendrán tres Fields y un campo Image.
  • Definiciones de Fields de la plantilla. Vemos como hemos definido tres Field de tipo String (nombre, fundación y presidente) y un field de tipo InputStream (escudo). Veremos en el siguiente apartado para que sirven estos Fields.
Nota: En versiones nuevas de iReport se generan las plantillas con un atributo en las bandas que pueden dar problemas. Al seleccionar una banda vemos que posee un atributo llamado 'Split Type' que por defecto tiene el valor 'Strecht'. Para solucionar el problema podemos poner en ese atributo el valor '<Default>'.

Agregar campos y asociar plantilla

Una vez hemos creado la plantilla debemos guardarla con formato JRXML. Lo ideal sería guardarla dentro del proyecto ya que para futuras modificaciones o traslados del proyecto no se nos olvide mover dicha plantilla.

Una vez guardada la plantilla debemos asociarla a nuestro informe para indicarle que debe ajustarse a ella a la hora de mostrar los datos. Asignar una plantilla a un informe es tan fácil como poner la siguiente instrucción:


//Asociamos una plantilla al informe
drb.setTemplateFile("resources/equipos.jrxml");
Ya que le hemos asociado una plantilla debemos crear una 'conexión' entre los datos que tenemos en la aplicación y la plantilla. Como hemos visto anteriormente habíamos creado unos Fields en la plantilla. Ahora crearemos unos campos (Fields) en el informe. Esos campos serán el nombre de los atributos y definiremos su tipo. Vemos como lo hemos realizado en el código.

drb.addField("escudo", InputStream.class.getName());
drb.addField("nombre", String.class.getName());
drb.addField("presidente", String.class.getName());
drb.addField("fundacion", String.class.getName());
A modo de resumen podemos decir que en la plantilla hemos representando gráficamente como mostrar el objeto indicando donde aparecen los atributos y definiendo éstos en la misma. Del mismo modo asociamos esa plantilla al informe y en éste definimos los atributos del objeto.

Generación del Reporte

Una vez hemos realizado estos pasos, sólo nos queda generar el informe. Esta generación es la misma que seguimos en el informe del listado, no existe diferencia alguna. Una vez se ha lanzado el JasperViewer veremos que obtenemos el siguiente informe.


Subreportes

Realizar subreportes con Jasper Reports es bastante confuso y enrevesado. Sin embargo, vamos a ver como realizar subinformes usando la librería DJ es mucho más simple y útil.

Para empezar, vamos a definir la estrategia para realizar este informe.


Paso 1 : Definición Informe

Nuestro objetivo final es definir un informe como subinforme de otro, por tanto, para empezar definiremos dos informes inicialmente independientes. Vamos a crear un informe de tipo plantilla que va a contener un informe de tipo listado (la plantilla contendrá los datos de los equipos y el listado mostrará los jugadores del equipo)

Por tanto, procedemos a definir ambos informes.


  • Informe de Plantilla (Equipo)

public static FastReportBuilder initMainReport() throws Exception {
FastReportBuilder report = new FastReportBuilder();

report.setTitle("EQUIPOS");
report.setMargins(margen, margen, margen, margen);

report.setTemplateFile("resources/equipos.jrxml");

report.addField("id", Integer.class.getName());
AbstractColumn c1 = ColumnBuilder.getInstance().setColumnProperty("id", Integer.class.getName()).setTitle("ID").setWidth(10).build();
report.addColumn(c1);

report.addField("nombre", String.class.getName());
report.addField("fundacion", String.class.getName());
report.addField("presidente", String.class.getName());
report.addField("entrenador", String.class.getName());
report.addField("escudo", InputStream.class.getName());

return report;
}


Importante: Podemos observar como hemos definido una columna en el informe a pesar de ser de tipo plantilla. En el siguiente apartado explicaremos la razón.


  • Informe de Listado

public static FastReportBuilder initSubreport() throws Exception {
FastReportBuilder report = new FastReportBuilder();

AbstractColumn c1 = ColumnBuilder.getInstance().setColumnProperty("id", Integer.class.getName()).setTitle("ID").setWidth(10).build();
AbstractColumn c2 = ColumnBuilder.getInstance().setColumnProperty("dorsal", Integer.class.getName()).setTitle("Dorsal").setWidth(30).build();
AbstractColumn c3 = ColumnBuilder.getInstance().setColumnProperty("nombre", String.class.getName()).setTitle("Nombre").setWidth(30).build();
AbstractColumn c4 = ColumnBuilder.getInstance().setColumnProperty("posicion", String.class.getName()).setTitle("Posicion").setWidth(30).build();

report.addColumn(c1);
report.addColumn(c2);
report.addColumn(c3);
report.addColumn(c4);

report.setUseFullPageWidth(true);

return report;
}

Como vemos, nada extraño respecto a lo que explicamos en el apartado de informes de tipo listado

Paso 2 : Agrupación

Definimos sobre que campo queremos agrupar el subinforme.

Bien, hemos visto que se ha creado una columna en el informe de plantilla que realmente no es necesaria pues hemos añadido un Field con ese atributo pero, ¿por qué hacemos esto?.

A la hora de colocar el subinforme debemos indicar un campo significativo para colocar el subinforme, es decir, necesitamos un identificador del objeto para añadir el subinforme. Veamoslo en el ejemplo: Tenemos equipos que poseen un entero llamado 'id' que es el identificador. A la hora de crear el informe para cada valor de ese 'id' se añadirá un subinforme con los datos correspondientes al objeto de ese id.

La agrupación de puede realizar creando un grupo o como veremos en el siguiente apartado


Paso 3 : Asociación

Asociamos un informe como subinforme del otro. Veamos como lo hacemos:

private static DynamicReport definirSubreport(FastReportBuilder report, FastReportBuilder subreport, String atributoColeccion, String claseColeccion) throws Exception {
report.addField(atributoColeccion, claseColeccion);
report.addGroups(1).setGroupLayout(1, GroupLayout.EMPTY);

report.addSubreportInGroupFooter(1, subreport.build(),
new ClassicLayoutManager(), atributoColeccion,
DJConstants.DATA_SOURCE_ORIGIN_FIELD,
DJConstants.DATA_SOURCE_TYPE_COLLECTION);

report.setUseFullPageWidth(true);

return report.build();
}
Para empezar definimos un Campo en el informe 'padre' que no es necesario que sea definido en la plantilla. Ese campo contiene el nombre del atributo del objeto (equipo en nuestro caso) de la colección que mostraremos en el subinforme. Esa colección actuará de DataSource del subinforme.

Definimos el grupo, con la función 'addGroups(1)' donde el parámetro indica el número de columnas que cogeremos para agrupar. En nuestro caso, la primera y única columna definida para el informe con plantilla.

Una vez realizado esto, usamos la función 'addSubreportInGroup(Header|Footer)' para asociar ambos informes. Los parámetros que se pueden observar son: el primero (número 1) es el número del grupo que usamos para agrupar, en este caso el primero; el subreport compilado, es decir, DynamicReport del subinforme; un Layout, nosotro usaremos el clásico; el nombre del atributo de la clase que alimenta a modo de DataSource al subinforme; constante que indica que el DataSource proviene de un campo/field del informe y constante que indica que el tipo del DataSource es una colección.

Una vez realizado esto compilamos el informe y realizamos la generación del informe y obtendremos los siguiente:


Formas de Mostrar un reporte

La herramienta JasperViewer es bastante útil de cara a realizar una especie de previsualizado y desde ella realizar una exportación. Muchas veces nos interesa exportar directamente informes en nuestro máquina o en la máquina del cliente, por ejemplo, si generamos informes masivamente y queremos exportarlos a varios ficheros ya que sería bastante engorroso que JasperViewer nos mostrara todos los informes y nosotros los exportaramos.

Exportación PDF, HTML, XML

DJ proporciona métodos para exportar nuestros informes a formatos conocidos y comunes. Tenemos la posibilidad de exportar a PDF, HTML y XML, entre otros.

La ventaja que proporciona DJ es que exportar a cualquiera de estos formatos nos cuesta una sóla línea. Simplemente, en lugar de notificar a JasperViewer lo que queremos mostrar usaremos una clase llamada 'JasperExportManager' que nos proporcionará soluciones de cara a las exportaciones. Vemos que métodos podemos usar:


 //Exportación a formato HTML
JasperExportManager.exportReportToHtmlFile(jp, EXPORT_PATH + "exportacionHTML.html");
//Exportación a formato PDF
JasperExportManager.exportReportToPdfFile(jp, EXPORT_PATH + "exportacionPDF.pdf");
//Exportación a formato XML, sin embeber imágenes
JasperExportManager.exportReportToXmlFile(jp, EXPORT_PATH + "exportacionXML.1.xml", false);
//Exportación a formato XML, embebiendo imágenes
JasperExportManager.exportReportToXmlFile(jp, EXPORT_PATH + "exportacionXML.2.xml", true);

Como vemos la exportación es bastante simple, una sóla línea nos proporciona un fichero o la información del informe.

Exportación a Excel

La exportación a Excel es ligeramente más compleja que las que hemos visto anteriormente ya que realmente no existe una mecanización por parte de DJ de exportación a este tipo de archivo. La documentación de DJ si que nos da información acerca de como exportar un informe a XLS.

Vamos a incluir un ejemplo de método para exportar un objeto JasperPrint (el jp que hemos mostrado anteriormente) a un archivo Excel.


private static void exportToExcel(JasperPrint jp) throws Exception {

//Creamos una instancia del objeto JRXlsExplorer que se encuentra en la librería jasperreports-X.X.X.jar
JRXlsExporter exporter = new JRXlsExporter();
//Si queremos definir varios Sheet lo hacemos en un array de cadenas que posteriormente la añadiremos por parámetros.
String[] sheetNames = {"Hoja 1"};

//Creamos el fichero de salida donde exportaremos el informe a Excel
File outputFile = new File(EXPORT_PATH + "exportacionEXCEL.xls");
FileOutputStream fos = new FileOutputStream(outputFile);

//Empezamos a definir los parámetros de la exportacion
//Indicamos el objeto JasperPrint que deseamos exportar
exporter.setParameter(JRExporterParameter.JASPER_PRINT, jp);
//Indicamos el fichero donde vamos a exportar el informe
exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, fos); //and output stream

//Excel specific parameter
//Indicamos si queremos una página por Sheet
exporter.setParameter(JRXlsExporterParameter.IS_ONE_PAGE_PER_SHEET, Boolean.FALSE);
//Indicamos si deseamos eliminar los espacios vacíos entre filas
exporter.setParameter(JRXlsExporterParameter.IS_REMOVE_EMPTY_SPACE_BETWEEN_ROWS, Boolean.TRUE);
//Indicamos si quremos mostrar una página en blanco como fondo
exporter.setParameter(JRXlsExporterParameter.IS_WHITE_PAGE_BACKGROUND, Boolean.FALSE);

//Definimos los nombres de los Sheet que es el Array de String que definimos arriba
exporter.setParameter(JRXlsExporterParameter.SHEET_NAMES, sheetNames );

//Usamos la función exportReport para crear el nuevo Excel.
exporter.exportReport();
}

Todos estos atributos los podemos ver en la documentación de Jasper Reports, o podemos verlo en el Javadoc que podemos encontrar en la red.

Nota: Indicar que para que podamos realizar la exportación a EXCEL las últimas versiones de DJ no soportan la exportación con las librerías del POI de Apache 3.5, ya que según el equipo de desarrollo de DJ hasta que no dejara de estar POI 3.5 en fase beta no se adaptaría DJ a dicha librería.

Enlaces


21 comentarios:

  1. Muchas gracias por este artículo. Entre los infinitos manuales que hay sobre este tema, el tuyo ha sido el único que, por lo directo que es, me ha ayudado de verdad.

    Solo dos cosas:

    1ª Creo que el paso 3 no acaba de quedar claro:

    report.addField(atributoColeccion, claseColeccion);

    ¿atributoColeccion?: ¿cual sería, el id que hemos puesto en el 'padre'? ¿el data source del subreporte es un field? ¿y en ese caso como se montaria eso?

    2ª Ya para rematar la faena, sería genial si además añadieras el código para descarga. Y ya puestos a pedir, en forma de proyecto de eclipse, jeje

    Bueno, peticiones aparte, lo dicho, que muchas gracias por el curro y por ayudar a gente que como yo, anda un poco perdida.

    ResponderEliminar
  2. Buneas noches Jrgamez gracias por tus tutorila estan buenisimo y en verdad espero em ayuden, actualmente estoy desarrollanod un programa para la universidad con gambas y repòrtes en ireport y no he lo grado levantar los reportes desde gambas tendras alguna idea de como hacerlo ?

    ResponderEliminar
  3. Buenas Javier,

    - atributoColeccion es el listado que vamos a mostrar como subreport, es decir, el atributo (field) de la clase padre que contiene el listado (u otro tipo Collection) sobre el que mostraremos los datos en el subreport.

    - Acabo de poner el código fuente del proyecto Netbeans donde hice los ejemplos. Espero que te sirvan.

    Jonathan:

    - La verdad es que no conozco gambas y, siendo sincero, poco te puedo ayudar. Mira bien lo que te proporciona gambas para hacer las llamadas a informes porque iReport si no estoy equivocado te sirve para crearte las plantillas.

    Saludos a los dos y perdonad la tardanza

    ResponderEliminar
  4. Se me olvidaba comentar:

    Cuidado con las versiones de librerías porque ya lo he sufrido en mis carnes.

    Al intentar asociar varios subreports a un report 'padre' podemos tener problemas en versiones de DynamicJasper.jar 2.0.8, porque pueden aparecer pisados.

    Recomiendo actualizar, no a la última, que da problemas de compatibilidad con otras librerías, sino a la 3.0.16 p.ej. actualizando para esta versión el jasperreports.jar a 3.5.1 y actualizar xercesImpl.jar que requiere jasperreports.

    ResponderEliminar
  5. Hola, yo quisiera saber como armar un reporte con dos subreportes, pero estos subreportes son muy diferentes y ademas se deben generar segun algunas condiciones.
    El tipo de reporte puede ser listado completo o resumen (+ grafica), si desde el front end selecciono 'Listado' me realiza el listado si selecciono 'Resumen' me realiza solo el resumen, si selecciono ambas opciones me realizaria todo en un mismo reporte, ademas si se seleccionaron ambas opciones despues del primer subreporte tiene que meter un 'Page Break' para separar el listado completo del resumen (esto es para el caso de informacion en empresas, puede requerirse un listado + resumen para archivar en carpeta, listado solo para enviar a call center o resumen para informacion de la parte gerencial solamente).
    Tomando en cuenta el ejemplo 'LaunchReportEquiposPlantilla' habria que definir dos subreportes ¿como se asocian al reporte principal?, seria algo asi?:
    report.addSubreportInGroupDetail(1, subreport1.build(),[...]
    report.addSubreportInGroupDetail(1, subreport2.build(),[...]
    ¿o tambien cambiaria el primer dato?
    report.addSubreportInGroupDetail(1, subreport1.build(),[...]
    report.addSubreportInGroupDetail(2, subreport2.build(),[...]
    Seria muy importante que me digas si esto se puede hacer y como seria con el 'Page Break'.
    Desde ya muchas gracias, una vez que pueda solucionar este tipo de cosas, con gusto te pasaria articulos con ejemplos de situaciones plateadas en la realidad y que pude resolver no habiendo encontrado informacion al respecto.
    Saludos cordiales.
    Joaquin.

    ResponderEliminar
  6. Buenas Joaquín,

    Prueba a usar el addConcatenatedReport para meter los subreportes. Es otra vía que puedes estudiar.

    Perdona que no ahonde en la solución, pero es que en estos momentos no puedo. Esta tarde si tengo un rato, te intento poner algo más completo.

    Saludos

    ResponderEliminar
  7. hola juan, gracias por la respuesta. Se me hace muy dificil hacerme una idea de como funciona dado que siempre encuentro informacion en ingles (incluso la del autor siendo argentino), he intentado entender el funcionamiento basico para ir viendo como agregar cosas paso a paso, bajandome el codigo que brindas y probandolo... funciona, bajandome los ejemplos de dynamic... funciona.
    Me surgieron dudas con todo esto, tales como las siguientes:
    Cual es la diferencia entre FastReportBuilder y DynamicReportBuilder? que hace cada una de ellas? he podido interpretar cual es la diferencia pero al probar de crear un reporte vacio (para ver el funcionamiento en un paso a paso) me ha tirado el siguiente error: net.sf.jasperreports.engine.JRException: Error compiling report java source files : D:\programacion\java\proyectos\prueba\build\classes\DynamicReport_1315853688573_267641.java
    a que se debe esto? estoy usando DynamicJasper-3.1.9 con jasperreports-4.0.2
    El codigo de prueba fue el siguiente:

    FastReportBuilder drb = new FastReportBuilder();
    DynamicReport dr = drb
    .setTitle("November 2006 sales report")
    .setSubtitle("This report was generated at " + new Date())
    .setPrintBackgroundOnOddRows(true)
    .setUseFullPageWidth(true)
    .build();

    JasperPrint jp = null;
    try {
    jp = DynamicJasperHelper.generateJasperPrint(dr, new ClassicLayoutManager(), parametro);
    } catch (JRException ex) {
    ....
    }
    JasperViewer.viewReport(jp); //finally display the report report

    Si puedes contestame a mi mail, asi te puedo explicar mejor que es lo que quiero hacer, una vez que pueda entender todo esto, creo que haré un blog exclusivo para dynamicJasper y jasper report con toda la informacion en español, necesito hacer reportes, con sub reportes, subreportes con consultas dinamicas y otras cosas mas.
    Disculpa la molestia, quizas debas estar muy ocupado, pero ademas de que la necesidad me urge, quiero aprender para poder aportar informacion que el dia de mañana pueda llegar a servirle a todos.
    Saludos cordiales.
    Joaquin

    ResponderEliminar
  8. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
  9. Hola, muchas gracias por tu aporte.
    En mi aplicación necesito agregar mensajes a cada barras en los graficos.. Como puedo hacerlo?

    ResponderEliminar
  10. Saludos y buen post!
    Quería preguntar:

    En tu ejemplo al usar una template, Colocas 3 campos field (nombre, fundacion, presidente) en la barra Detail del template, y desde java los enlazas con drb.addField(nombre, String.calss.getName()).

    En la sección de How To de DynamicJasper dice que la barra detail debe estar limpia, caso contrario la información ahí será eliminada.

    Cómo puedo hacer para yo poder definir en la plantilla dónde deseo que salgan los campos de mi colección?

    ResponderEliminar
  11. Hola Miguel,

    La parte de Detail debe estar vacía si deseas generar un informe en listado por columnas. No añades nada porque con los addColumn ya estás definiendo el informe como el que dice.

    Si haces un informe template, no añades columnas, y para que se muestren los datos debes indicarselo a través del addField. Si ese Field lo colocas en el Detail de la plantilla te aseguras que cada vez que DJ itere sobre la colección a mostrar en el informe, incluirá los datos en los Field que has colocado en Detail.

    Digamos que es como una personalización del informe por columnas simple que nos proporciona DJ por defecto.

    Espero haberte ayudado y haberme explicado correctamente

    Saludos

    ResponderEliminar
  12. chévere tu respuesta juanra, muchas gracias...

    Sí lo he probado de esa forma, solo con .addField (sin setear las columnas)y en la plantilla colocando los $F{fieldn} pero no me funcionaba... voy a chequear un poco más desde tu código de ejemplo y lo comento...

    Buen post acerca de DynamicJasper, para noobies :D Con los subreportes aún no empiezo, si no me salen, igual te pregunto por este medio... gracias!

    ResponderEliminar
  13. Muy buen post! tengo una consulta...estoy intentando hacer un reporte y los objetos de los cuales obtengo los datos no tienen todos los getters y setters, por ahora usando jasper reports habia pasado al template como parametro los objetos y despues con un scriptlet obtenia los valores para mostrar...como hago para definir utilizando DynamicJasper parametros del reporte?
    Desde ya muchas gracias!

    ResponderEliminar
  14. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
  15. hola, sabes si hay algún problema con dynamic report 5 00 y jasper report 5 2 0 ? al tener un field en mi archivo jrxml no me muestra su valor, solo me muestra el subreporte. Pero al cambiar a las librerías que tienes dynamic jasper 3 0 9 y jasper report 3 5 1 sí me muestra los valores del sub reporte junto con los que se le pasan al field del archivo jrxml. Tienes conocimiento de la correspondencia adecuada entre las librerías o si es un bug? Gracias, el tuto está excelente

    ResponderEliminar
    Respuestas
    1. Sinceramente, nunca me ha visto obligado a subir la versión de las librerías, así que no he experimentado los problemas que comentas, únicamente con versiones del editor iReport que en versiones nuevas añade unos parámetros en los jrxml que DynamicJasper no reconoce.

      Siento no poder ayudarte y perdona la tardanza al contestarte.

      Eliminar
  16. A la hora de visualizar el reporte, solo se muestra una sola vez el reporte principal. Que pudiera ocacionar esto. A alguien le he dado este problema...

    ResponderEliminar
  17. Saludos a todos, siempre he diseñado con ireport pero esta vez los necesito hacer dinamicos o sea desde mi app, buscando en internet me encuentro con este blob y el uso de Dynamic Jasper, alguin me podria decir cuales librerias son la que tengo que agregar a mi proyecto porque realmente no he podido hacer hacer ningun ejemplo ni el de este blog ni el del sitio oficial, espero alguin me pueda ayudar, un saludo

    ResponderEliminar
  18. Saludos, muy buena explicacion, pero en mi caso estoy haciendo el reporte de un tableview de javafx en donde el ususario puede escoger las columnas que desee mostrar, todos los ejemplos que he visto ya vienen predefinisdas las colummnas en base una entidad o algo asi, alquien me puede dar alguna idea de como puedo hacer mi reporte, saludos

    ResponderEliminar
  19. Hola alguno sabe si se pueden generar grupos por mas de 1 columna?

    ResponderEliminar
  20. alguien tendra el codigo fuente el enlace esta roto por favor

    ResponderEliminar