API REST + BIRT: Crea PDFs y PPTs con Imágenes personalizadas

En este tutorial veremos cómo usar BIRT para generar informes en formato PPTX o PDF con imágenes dinámicas consumidas desde un API REST
Generando informes insertando imágenes con BIRT

En este artículo vamos a hablar sobre cómo insertar dinámicamente una imagen después de consumir una API REST desde BIRT.

Índice de contenidos

1. Introducción

La motivación de este tutorial surgió al intentar encontrar una manera de mejorar las gráficas de ofrece por defecto BIRT. BIRT es una herramienta similar a Jasper Report de código abierto promovida por Eclipse.

Las principales ventajas de BIRT son:

  • Admite diferentes datasource y tipo de datos para generar informes.
  • Permite diferentes formatos de salida usando un mismo informe como plantilla (PDF, PPTX, DOCX, etc).
  • Tiene una gran integración con Java.

Las principales desventajas de BIRT son:

  • La falta de documentación en la web sobre él y la que hay es muy antigua o está desactualizada.
  • El look & feel de las gráficas que se propone desde el asistente por defecto de la herramienta tiene un diseño algo antiguo. En este tutorial vamos a dar una alternativa para mejorar en algo esta última desventaja.

2. Entorno

El tutorial está escrito usando el siguiente entorno:

  • Hardware: Portátil Apple M1 Pro 16′ (M1, 32 GB).
  • Sistema Operativo: Mac OS Sonoma 14.4.1
  • BIRT report-designer-all-in-one 4.15.0-202403270652 macosx.cocoa.x86_64.tar.gz.sha512

3. Preparando el entorno

Para ejecutar la última versión de BIRT desde un M1 debemos seguir los siguientes pasos:

  • Para ejecutar BIRT desde un M1 hay que ejecutar el siguiente comando:

Text
<pre class="lang:xml"> $> sudo xattr -rd com.apple.quarantine ./eclipse.app

Text
<pre class="lang:xml"> $> open ./eclipse.app

Este comando sirve para sacar de la cuarentena de Apple el ejecutable. Es el equivalente a permitir la ejecución de un desarrollador no identificado o de la Apple Store.

NOTA: Si no crees que lo has descargado de la fuente oficial o tienes dudas sobre la seguridad, no lo ejecutes pero solo he sido capaz de abrir BIRT después de ejecutarlo. Si no me salia el siguiente mensaje al ejecutar el open:

3.1. Una API REST Mock que consumir

En un ejemplo real utilizaremos una API REST que dado un identificador y tipo de gráfico nos devuelva la imagen de la gráfica generado con Chart Js por ejemplo. Pero para probar la inserción dinámica de imágenes en BIRT con vale con una API Mockedada como las que ofrece la página https://dummyjson.com, la qual nos devuelve un JSON como este:


Text
<pre class="lang:xml"> {
"id": 1,
"title": "iPhone 9",
"description": "An apple mobile which is nothing like apple",
"price": 549,
"discountPercentage": 12.96,
"rating": 4.69,
"stock": 94,
"brand": "Apple",
"category": "smartphones",
"thumbnail": "https://cdn.dummyjson.com/product-images/1/thumbnail.jpg",
"images": [
"https://cdn.dummyjson.com/product-images/1/1.jpg",
"https://cdn.dummyjson.com/product-images/1/2.jpg",
"https://cdn.dummyjson.com/product-images/1/3.jpg",
"https://cdn.dummyjson.com/product-images/1/4.jpg",
"https://cdn.dummyjson.com/product-images/1/thumbnail.jpg"
]
}

Para el ejemplo consumiremos los campos id, title y la primera de imágenes.

3.2. Explorando BIRT

Como primer elemento que vemos en BIRT tenemos el menú «Data Explorer» que nos da una visión por paquetes de las diferentes partes referente a Datos que podemos usar para generar el informe (Data Source, Data Set, Variables, etc).

Nosotros nos centraremos en estos componentes para nuestro ejemplo. Para empezar a construirlo añadiremos:

  • En el layout hay un componente de tipo imagen.
  • En el paquete DataSource un nuevo datasource script.
  • En las variables declarar
    • HTMLJSON (variable de tipo informe). En esta variable se almacenará la respuesta al API Rest moqueada en formato Json.
    • recNum (variable de tipo informe y con valor 0). En esta variable almacenaremos los elementos recorridos (o leídos) por el datasource.
    • len (variable de tipo informe y con valor 1). En esta variable almacenaremos el número de registros totales que tiene la respuesta. Como no es un array y solo es un elemento, lo fijamos directamente en 1.
    • En el layout, tenemos que insertar un elemento de tipo Image. Si navegamos por los diferentes elementos del «Data Explorer» como el DataSource Script podemos ver tres partes importantes:
      • Selector Script: Selector en los que puedes introducir lógica en forma de script para ese elemento.
      • Pestaña Script: Parte donde aparece el editor donde introducir el script.
      • Pestaña Layout: Parte donde vuelves a ver cómo están dispuestos cada componente de nuestro informe.

Para consumir el api desde el data source en la pestaña Script y el selector open con el siguiente código:


Text
<pre class="lang:xml">// Lectura de la respuesta al api rest

importPackage(Packages.java.io);
importPackage(Packages.java.net);

var inStream = new URL("https://dummyjson.com/products/1").openStream();
var inStreamReader = new InputStreamReader(inStream);
var bufferedReader = new BufferedReader(inStreamReader);
var line;
var result = "";

while ((line = bufferedReader.readLine()) != null)
result += line;
inStream.close();

// Convertimos la respuesta a JSON
var json = JSON.parse(result);

// Almacenamos el JSON en la variable HTMLJSON
vars["HTMLJSON"] = json;

Para leer la respuesta y poder usarla dentro del componente Image, tenemos que incluir un nuevo dataset con los siguientes campos:

Aunque en el ejemplo solo utilizaremos los campos imageUrl y imageLogo para el ejemplo de imagen dinámica, se podría inserta tanto el campo id como title en el report.

Para recorrer la respuesta y almacenarla en el dataset, tenemos que introducir el siguiente código en la pestaña de script en el selector fetch.


Text
<pre class="lang:xml">importPackage(Packages.java.io);
importPackage(Packages.java.lang);
importPackage(Packages.java.net);

// Incluir dependencia en la carpeta plugins
importPackage(Packages.javax.imageio);

// Condición de parada para dejar de recorrer el dataset
if (vars["recNum"] >= vars["len"])
    return false;

// Lectura de las variables de tipo String
row["id"] = vars["HTMLJSON"].id;
row["title"] = vars["HTMLJSON"].title;
row["imageUrl"] = vars["HTMLJSON"].images[0];

// Convertir imageUrl en un tipo Blod capaz de renderizar
var myUrl = new Packages.java.net.URL(row["imageUrl"]);
var img = ImageIO.read(myUrl)
var bas = new ByteArrayOutputStream();
ImageIO.write(img, "jpg", bas);
row["imageLogo"] = bas.toByteArray();

NOTA: Habría que incluir el jar commons-io-2.16.1.jar de esta página e incluirlo en la siguiente ruta para que pueda ser importada desde el script.


Text
<pre class="lang:xml"> $> open /Users/ddelcastillo/Desktop/eclipse.app/Contents/Eclipse/plugins

Para poder hacer una prueba integrada de que el data source lee la api y el dataset es capaz de procesar la respuesta deberíamos ver esto en al Edit > Preview Results. Se debería ver algo parecido a esto:

NOTA: En ejemplo vemos como el código sólo carga un registro, ya que la respuesta del mock no es un array y solo tiene un producto, pero se podría cargar el dataset con más registros.

3.3. Generando documentos

Después de comprobar que somos capaces de consumir el API REST y cargar el dataset, podemos insertar la fila del dataset que contiene la imagen como Blob de la siguiente manera:

Si vamos a la pestaña del layout, podemos un aspa roja como que la imagen no se ha cargado. Esto es porque la imagen se renderiza en el momento de generar el documento y no en la preview.

Con todo listo, si vamos al menú Run > View Report > In web Viewer (o cualquier otro documento PPTX, PDF, etc). Y vemos como la imagen consumida desde la API se carga correctamente:

También podemos exportar a diferentes documentos desde el visor web.

4. Conclusiones

Este tutorial se originó para intentar actualizar las gráficas en los informes de un cliente. Y aunque esperamos opciones más modernas como ChartJS con PPTXGen, el cliente perdía la posibilidad de insertar imágenes en tablas. Ya que el nuevo stack propuesto para generar informes no lo permitía.

Por eso, decidimos explorar la posibilidad de integrar una API REST a su sistema de generación de informes para que el cliente no perdiera ninguna funcionalidad de los informes actuales sin dejar de actualizar el stack usando cualquier tecnología más actual para generar gráficas. A veces es mejor trabajar en una integración mejorando un poco la solución que ya tenemos a empezar con una tecnología diferente desde cero.

Os dejo el proyecto de ejemplo de tutorial por si os es útil.

5. Referencias

  • Como consumir una API REST desde BIRT : .
  • Plugin Da Vinci Chart para BIRT:

Comentarios

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

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

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

  • Responsable: IZERTIS S.A.
  • Finalidad: Envío información de carácter administrativa, técnica, organizativa y/o comercial sobre los productos y servicios sobre los que se nos consulta.
  • Legitimación: Consentimiento del interesado
  • Destinatarios: Otras empresas del Grupo IZERTIS. Encargados del tratamiento.
  • Derechos: Acceso, rectificación, supresión, cancelación, limitación y portabilidad de los datos.
  • Más información: Puedes ampliar información acerca de la protección de datos en el siguiente enlace:política de privacidad

Consultor Tecnológico de desarrollo de proyectos informáticos. Ingeniero Técnico en Informática de Sistemas por la Universidad Politécnica de Madrid Puedes encontrarme en Autentia: Ofrecemos servicios de soporte a desarrollo, factoría y formación. Somos expertos en Java/Java EE

¿Quieres publicar en Adictos al trabajo?

Te puede interesar

Aprende cómo migrar tu sitio Joomla 3 a Joomla 5 de forma segura, manteniendo el diseño, la funcionalidad y compatibilidad con extensiones. Una guía paso a paso con recomendaciones, imágenes y buenas prácticas para actualizar sin sorpresas.
Descubre qué es Yocto Project, sus ventajas, usos reales en Izertis y cómo crear tu propia distribución Linux para Raspberry Pi paso a paso, de forma sencilla y flexible.
¿Trabajas con Drupal y SonarQube 9.9? En este artículo exploramos cómo adaptar el análisis estático para evitar falsos positivos, desactivar reglas conflictivas del Quality Profile y delegar el estilo a PHP CodeSniffer. Una guía práctica para mejorar la integración sin depender aún de SonarQube 10.