JODReports - Mini How to - Más allá de lo que ves

lunes, 15 de noviembre de 2010

JODReports - Mini How to

Después de hacer pruebas con JODReports nos hemos quedado bastante asombrados de lo sencillo que es utilizar documentos ODT como plantillas para generar documentos desde java de forma que con JOOConvertes luego pasamos a pdf, en principio hemos probado casi de todo:

Sustituir variables.
Iteraciones sobre listas de objetos.
Evaluar condiciones para mostrar ciertas partes de código.
Incluir imágenes.
Exportar a pdf.
...

Nos surge un pequeño problema cuando tenemos que anexar documentos pdf dentro del informe generado, esto lo seguiremos con itext, así pues, creo que hemos dado con una solución que optimizará muy mucho el desarrollo de cartas, documentos, informes... en nuestros sistemas.

Os dejo un mini "How to" que me ha pasado un compañero:

1. Requisitos mínimos
Java Runtime Enviroment 5.0 o superior.
Tomcat 4.1 o superior.
Librería jodreports_2.3.0
(Debe ser añadida sólo como libería del proyecto y no como librería de tomcat)
OpenOffice para realizar las plantillas.

2. Sustitución de variablesPara sustituir variables en nuestra plantilla odt, nos bastará con las siguientes líneas de código, utilizando el Map para introducir los valores de sustitución de las variables definidas en nuestras plantillas.

DocumentTemplateFactory documentTemplateFactory =
new DocumentTemplateFactory();
DocumentTemplate template =
documentTemplateFactory.getTemplate(new File(ruta_fisica_plantilla/nombreFichero.odt));
Map data = new HashMap();
data.put("nombre_variable", "valor_variable");
// añadir todas las variables a cambiar
// ...
template.createDocument(data,
new FileOutputStream(ruta_fisica_fichero_guardar//nombreFichero-final.odt));

Las variables se introducirán en la plantilla con la siguiente sintaxis.
${nombre_variable}

3. Rellenar una tabla
Para insertar registros sobre una tabla, nos bastará con el código anterior, con la salvedad de que en lugar de insertar un valor a la variable, se le asignará un list.

La forma de introducir las variables en la plantilla será la siguiente:

3.1. Insertaremos una tabla en nuestra plantilla, con 2 filas si tenemos cabecera o 1 si no la tenemos.
3.2. En la primera fila, posterior a nuestra cabecera si existe, insertaremos las nombres de variables que necesitemos y queramos mostrar en cada celda.
3.3. Cerraremos nuestra plantilla
3.4. Abriremos el documento odt con winrar y extraemos el fichero content.xml para realizar unas pequeñas modificaciones.
3.5. Buscamos la tabla en el fichero content.xml y en antes de definir el table-row donde se encuentran las variables definidas por nosotros, añadimos las siguiente sentencia:
[#list nombre_list_varable as variable]3.6 Cuando acaba la definición del table-row, cerramos nuestra sentencia list, con:
[/#list]
3.7. Aplicarmos los cambios y sustituimos el content.xml del odt, por el que hemos modificado.

4. Sustituir imágenes
Para sustituir imágenes en nuestra plantilla odt, debemos definir un ImageSource en nuestra clase y añadirlo a nuestro map de sustitución con el nombre de la variable definida en nuestra plantilla. Un ImageSource se puede definir de las siguientes maneras:
ImageSource imagen =
new RenderedImageSource(ImageIO.read(new File(ruta_fisica_imagen)));
ImageSource imagen =
new FileImageSource(ruta_fisica_imagen);
ImageSource imagen =
new ClasspathImageSource(ruta_fisica_imagen);

Una vez insertada una imagen en nuestra plantilla (para luego ser sustituida), debemos editar su nombre por: jooscript.image(nombre_variable)

5. Sentencia if / if-elseEstas nos permitirán sobre todo mostrar o ocultar texto de la plantilla en función de determinadas condiciones. La sintaxis es la siguiente:

[#if valor1 = valor2]
bloque de informacion
[#/if]
[#if valor1 = valor2]
bloque de informacion
[#else]bloque de información
[#/if]

Saludos reportiaaaaaaaaaaaanos !!

Texto del mini how to: Roger Moore

Actualización del 13 de Mayo de 2013

Os dejamos un nuevo tutorial avanzado con insercción de imágenes dinámicas, tablas....

JODReports - Tutorial práctico

12 comentarios:

  1. Buenas tardes,
    Llevo dos días viendo como funciona jodReports y jodRevert, y gracias a este artículo, se ve claramente cómo se puede usar. Pero aún así tengo un par de dudas, una es que estoy generando un listado de objetos, y me gustaría recorrer la lista de los objetos mostrando sus atributos, pero un objeto por página. Ha visto algo similar, he estado buscando y no se como puedo incluir este salto de página.
    Muchas gracias.

    ResponderEliminar
  2. Buenas tardes Susana,
    Para realizar lo que necesitas, puedes incluir dentro de la sentencia [#list ...] la página o páginas que necesitas repetir.

    [#list objeto_list as objeto]
    página que necesitas repetir
    [#/list]

    ResponderEliminar
  3. Hola Susana !!

    Te sirvió lo que Roge te comentó?

    En principio ese caso que nos plantéas lo hemos desarrollado nosotros y es muy sencillo no tienes más que meter un salto de página justo antes del código [#list objeto_list as objeto]

    Espero que te haya servido para solventar tus dudas el artículo y nuestros comentarios.

    ResponderEliminar
  4. Buenos días!
    Lo que al final he hecho es, recorrer la lista y si existe elemento incluyo:

    text:p text:style-name="P$[x_index+1"
    De esta forma me incluye el salto de página, no se si es exactamente como lo habeis desarrollado ustedes, pero si que me ha servido el artículo.

    Ahora, me estoy peleando con jodconverter y también con el content.xml para crear la plantilla, estoy pasándole una lista de objetos, y uno de los atributos de ese objeto es de tipo List, es lo que no me lee,... espero tener suerte.

    Gracias!

    ResponderEliminar
  5. Aqui estoy de nuevo, a ve si me podeis ayudar, estoy pasándole a la plantilla una lista de objetos, con los atributos de ese objeto que son de tipo String no tengo problema para pasarlos a content.xml, pero uno de esos atributos es de tipo List, ¿hay alguna forma de iterar dentro del content.xml, para obtener los datos de esa lista?
    Espero haberme explicado bien, Gracias :)

    ResponderEliminar
  6. Hola Miguelón.

    Me alegra que pueda servir de algo

    ResponderEliminar
  7. Buenas tardes de Dios... disculpen pero tengo una gran duda y realmente necesito resolver este problema.. tengo una aplicación que genera reportes persistiendo en una base de datos.. los reportes los imprimo con JODReports en una hoja de calculo sin ningun problema, pero lo que sucede sq los campos ya sean numéricos o no, los imprime como tal, con un apóstrofe delante y realmente necesito que se impriman como números para poder verificar algunos resultados del reporte. Alguien me podría ayudar??

    ResponderEliminar
  8. Buenos días Miguel Angel. El problema es el siguiente, cuando preparamos la plantilla y colocamos nuestras variables ${valor} para que posteriormente sean remplazadas y aunque le indiquemos que el formato de esta celda es númerico, el OpenOffice al guardar el documento lo guarda como tipo "string" ya que nuestra variable en definitiva es un "string" (aunque le demos a formato y muestre numérico).
    Para solucionar esto puedes hacer lo siguiente: una vez tengas el documento preparado con todos los valores a sustituir indicadas guarda el documento y ábrelo con WinRar y edita el archivo content.xml.
    Has una busqueda por el nombre de tus variables numéricas. Veras que están en una celda de tipo "string"
    <table:table-cell table:style-name="ce2" office:value-type="string">
    <text:p>${valor}</text:p>
    </table:table-cell>
    Para que sean numéricas sustituye el tipo de "string" a "float" y añade la siguiente propiedad office:value="" cuyo valor es nuestra variable para que quede de la siguiente manera:
    <table:table-cell table:style-name="ce2" office:value-type="float" office:value="${valor}">
    <text:p>${valor}</text:p>
    </table:table-cell>

    Guarda el content.xml dentro del ods que abriste con Winrar y utiliza tu plantilla veras como ya te aparecen sin el apóstrofe y te lo interpreta como números.

    NOTA: El apóstrofe lo coloca el OpenOffice a los números en celdas de tipo "string", el apóstrofe no se almacena ni se inserta.
    Salu2 y espero que te sirva, ya nos contarás.

    ResponderEliminar
  9. Muy buen tutorial :). Quisiera saber si se puede programáticamente, insertar el contenido de un ODT dentro de otro. Desde el LibreOffice puedo hacerlo por la opción Insertar>Documento, pero necesito hacerlo dinámicamente.

    Saludos y gracias :)

    ResponderEliminar
  10. Buenas, la opción que se suele utilizar es generar dinámicamente los distintos ODTs y una vez generados correctamente anexarlos.

    ResponderEliminar