Cómo mostrar los archivos adjuntos en los informes BIRT para IBM Maximo Application Suite (MAS 9)
Ver Bolisetti
April 29, 2026


En nuestro blog anterior, explicamos cómo mostrar las imágenes adjuntas por los técnicos de campo directamente en los informes BIRT en IBM Maximo 7.6. Este enfoque consistía en leer los archivos de imagen directamente desde el sistema de archivos del servidor mediante una ruta de archivo local almacenada en Nombre de URL campo de la docinfo objeto.
Con el cambio a IBM Maximo Application Suite (MAS 9), ese método ya no funciona. MARZO 9 es una plataforma nativa de la nube y los archivos adjuntos ya no se almacenan en un sistema de archivos local, sino en Almacenamiento de objetos en la nube (COS), que es compatible con S3. El Nombre de URL El campo ahora contiene una referencia COS (por ejemplo, cos:doclinks/your-file.jpg) en lugar de una ruta local, por lo que el enfoque anterior de File () falla por completo.
Este blog detalla el enfoque actualizado para obtener y renderizar esas imágenes de S3/COS en sus informes BIRT en MAS 9.
En Maximo 7.6, el valor de URLName apuntaba directamente a un archivo en el disco, por ejemplo:
/opt/IBM/SMP/maximo/doclinks/Attachments/image.jpg
El script simplemente leía ese archivo con java.io.File y pasaba los bytes al elemento de imagen dinámica BIRT, algo sencillo para una implementación local.
En MARZO 9, el mismo campo ahora contiene una URI COS como:
cos:doclinks/image.jpg
No hay ningún archivo local que leer. La imagen se encuentra en un bucket de S3 y debe autenticarse con las credenciales de AWS y descargar el objeto durante el tiempo de ejecución del informe. El diseño del informe BIRT en sí mismo (imagen dinámica en una celda de la tabla) sigue siendo exactamente el mismo. Solo es necesario cambiar los guiones.
La solución incluye dos áreas de secuencias de comandos en el diseñador de informes BIRT:
Los pasos de diseño del informe (crear un conjunto de datos a partir de docinfo, vincularlo a una tabla, insertar un elemento de imagen dinámica) siguen siendo los mismos que se describen en el blog original. Si aún no ha completado esos pasos, consulte los pasos 1 a 3 del guía original primero.
Al igual que antes, cree un conjunto de datos que obtenga el Nombre de URL de la docinfo objeto, filtrado según sus criterios (por ejemplo, pregunta de inspección específica o tipo de documento). El Nombre de URL La columna es lo que usarán los scripts para localizar la imagen en S3.
Crea tu tabla, vincúlala al conjunto de datos y coloca un elemento de imagen dentro de la celda correspondiente. Establezca el tipo de fuente de la imagen en «Imagen dinámica» — esto no ha cambiado con respecto a Maximo 7.6.
En el informe Inicializar sección de script, añada lo siguiente. Se ejecuta una vez al iniciar el informe, lee las credenciales de COS de las propiedades del sistema Maximo y crea un cliente S3 compartido:

importPackage(Packages.com.ibm.tivoli.maximo.report.script);
importPackage(Packages.com.amazonaws.auth);
importPackage(Packages.com.amazonaws.services.s3);
importPackage(Packages.com.amazonaws.services.s3.model);
importPackage(Packages.psdi.server);
var accessKey = MXServer.getMXServer().getProperty("mxe.cosaccesskey");
var secretKey = MXServer.getMXServer().getProperty("mxe.cossecretkey");
var bucketName = MXServer.getMXServer().getProperty("mxe.cossysbucket");
// Set up AWS credentials and S3 client
var credentials = new BasicAWSCredentials(accessKey, secretKey);
var s3Client = new AmazonS3Client(credentials);
mxReportScriptContext = MXReportScriptContext.initialize(reportContext);
mxReportScriptContext.setDefaultLogLevel("DEBUG");
mxReportScriptContext.setDefaultLogFile("servicereport.log");
scriptLogger = mxReportScriptContext.getReportScriptLogger();
Nota: Las credenciales (mxe.cosaccesskey, mxe.cossecretkey, mxe.cossysbucket) se leen directamente desde las propiedades del sistema de Maximo, por lo que no es necesario codificar valores confidenciales en el informe.
En el elemento Dynamic Image OnCreate script, añada lo siguiente. Esto se activa para cada fila, analiza la URI del COS, descarga la imagen, gestiona la conversión de formato, aplica la compresión JPEG y establece las dimensiones de la pantalla:
importPackage(Packages.javax.imageio);
importPackage(Packages.javax.imageio.stream);
importPackage(Packages.java.io);
importPackage(Packages.java.lang);
importPackage(Packages.java.awt.image);
importPackage(Packages.java.awt);
importPackage(Packages.java.net);
importPackage(Packages.com.amazonaws.auth);
importPackage(Packages.com.amazonaws.services.s3);
importPackage(Packages.com.amazonaws.services.s3.model);
if (row["urlName"] != null) {
var fullUrl = String(row["urlName"]);
var prefix = "cos:doclinks/";
var cleanFileName = fullUrl;
var fileName = "";
var fileExtension = "";
if (fullUrl != null) {
if (fullUrl.startsWith(prefix)) {
cleanFileName = fullUrl.substring(prefix.length);
}
var lastSlashIndex = cleanFileName.lastIndexOf("/");
fileName = (lastSlashIndex >= 0)
? cleanFileName.substring(lastSlashIndex + 1) : cleanFileName;
var lastDotIndex = fileName.lastIndexOf(".");
if (lastDotIndex >= 0 && lastDotIndex < fileName.length - 1) {
fileExtension = String(fileName.substring(lastDotIndex + 1).toLowerCase());
}
}
var s3Object = null; var inputStream = null;
var img = null; var bas = null;
var ios = null; var writer = null;
try {
s3Object = s3Client.getObject(new GetObjectRequest(bucketName, cleanFileName));
inputStream = s3Object.getObjectContent();
img = ImageIO.read(inputStream);
if (img == null) {
throw new Error("Failed to read image from S3: " + fileName);
}
// Convert to RGB if needed
if (img.getType() !== BufferedImage.TYPE_INT_RGB) {
var rgbImage = new BufferedImage(
img.getWidth(), img.getHeight(), BufferedImage.TYPE_INT_RGB);
var g = rgbImage.createGraphics();
g.drawImage(img, 0, 0, Color.WHITE, null);
g.dispose();
img = rgbImage;
}
bas = new ByteArrayOutputStream();
var format = (["jpeg","jpg","png","bmp"].indexOf(fileExtension) >= 0)
? fileExtension : "jpeg";
if (format === "jpeg" || format === "jpg") {
var writers = ImageIO.getImageWritersByFormatName("jpeg");
if (!writers.hasNext()) throw new Error("No JPEG writer available");
writer = writers.next();
ios = ImageIO.createImageOutputStream(bas);
writer.setOutput(ios);
var param = writer.getDefaultWriteParam();
if (param.canWriteCompressed()) {
param.setCompressionMode(
javax.imageio.ImageWriteParam.MODE_EXPLICIT);
param.setCompressionQuality(0.3);
}
writer.write(null,
new javax.imageio.IIOImage(img, null, null), param);
} else {
if (!ImageIO.write(img, format, bas)) {
throw new Error("Failed to write image: " + format);
}
}
this.data = bas.toByteArray();
var picWidth = img.getWidth();
if (picWidth > 300) {
var aspectRatio = img.getHeight() / picWidth;
this.width = '300px';
this.height = Math.round(300 * aspectRatio) + 'px';
} else {
this.width = null; this.height = null;
}
} catch (e) {
throw new Error("Error processing '" + fileName + "': " + e.message);
} finally {
if (writer != null) writer.dispose();
if (ios != null) ios.close();
if (bas != null) bas.close();
if (inputStream != null) inputStream.close();
if (s3Object != null) s3Object.close();
}
}
Obtenga una vista previa del informe en BIRT Designer para confirmar que las imágenes se representan correctamente. Una vez verificado, importe el informe a MAS y pruébelo generando un PDF comparándolo con una orden de trabajo o inspección que contenga fotos adjuntas.

La migración de Maximo 7.6 a MARZO 9 introduce un cambio fundamental en la forma en que se almacenan los archivos adjuntos y se accede a ellos. Al pasar de un enfoque basado en archivos locales a una recuperación basada en S3/COS, los scripts que utilizan las imágenes dinámicas en los informes del BIRT deben actualizarse en consecuencia.
Con el script Initialize que gestiona la autenticación de S3 y el script OnCreate que gestiona la descarga de objetos y el procesamiento de imágenes, puede seguir entregando informes enriquecidos y mejorados con imágenes en MAS 9 con la misma eficacia que en 7.6.
Discover everything you need to know to modernize your asset management strategy.
Inside, you’ll learn:

ActiveG, BPD Zenith, EAM Swiss, InterPro Solutions, Lexco, Peacock Engineering, Projetech, Sharptree, and ZNAPZ have united under one brand: Naviam.
You’ll be redirected to the most relevant page at Naviam.io in a few seconds — or you can
go now.