Comment afficher les pièces jointes dans les rapports BIRT pour IBM Maximo Application Suite (MAS 9)


Dans notre blog précédent, nous avons expliqué comment afficher les images jointes par les techniciens de terrain directement dans les rapports BIRT d'IBM Maximo 7.6. Cette approche fonctionnait en lisant les fichiers image directement à partir du système de fichiers du serveur à l'aide d'un chemin de fichier local stocké dans Nom d'URL domaine du docinfo objet.
Avec le passage à IBM Maximo Application Suite (MAS 9), cette méthode ne fonctionne plus. MARS 9 est une plate-forme native du cloud, et les pièces jointes ne sont plus stockées sur un système de fichiers local, elles sont stockées dans Stockage d'objets dans le cloud (COS), qui est compatible S3. Le Nom d'URL Le champ contient désormais une référence COS (par exemple cos:doclinks/your-file.jpg) plutôt qu'un chemin local, de sorte que l'ancienne approche File () échoue complètement.
Ce blog détaille l'approche mise à jour pour récupérer et rendre ces images depuis S3/COS dans vos rapports BIRT sur MAS 9.
Dans Maximo 7.6, la valeur URLName pointait directement vers un fichier sur le disque, par exemple :
/opt/IBM/SMP/maximo/doclinks/Attachments/image.jpg
Le script lit simplement ce fichier à l'aide de java.io.File et transmet les octets à l'élément d'image dynamique BIRT, ce qui est simple pour un déploiement sur site.
Dans MARS 9, le même champ contient désormais un URI COS tel que :
cos:doclinks/image.jpg
Il n'y a aucun fichier local à lire. L'image se trouve dans un compartiment S3 et vous devez vous authentifier à l'aide d'informations d'identification AWS et télécharger l'objet lors de l'exécution du rapport. La mise en page du rapport BIRT elle-même (image dynamique dans une cellule de tableau) reste exactement la même. Seuls les scripts doivent être modifiés.
La solution implique deux zones de script dans le concepteur de rapports BIRT :
Les étapes de mise en page du rapport (création d'un jeu de données à partir de docinfo, en le liant à un tableau, en insérant un élément d'image dynamique) restent les mêmes que ceux décrits dans le blog d'origine. Si vous n'avez pas encore terminé ces étapes, reportez-vous aux étapes 1 à 3 du guide original premier.
Comme précédemment, créez un ensemble de données qui récupère les Nom d'URL à partir du docinfo objet, filtré selon vos critères (par exemple, question d'inspection spécifique ou type de document). Le Nom d'URL colonne est celle que les scripts utiliseront pour localiser l'image dans S3.
Construisez votre tableau, liez-le à l'ensemble de données et placez un élément d'image dans la cellule appropriée. Définissez le type de source d'image sur « Image dynamique » — cette valeur est inchangée par rapport à Maximo 7.6.
Dans le rapport Initialiser section de script, ajoutez ce qui suit. Cela s'exécute une fois au démarrage du rapport, lit les informations d'identification COS dans les propriétés du système Maximo et crée un client S3 partagé :

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();
Remarque : Les informations d'identification (mxe.cosaccesskey, mxe.cossecretkey, mxe.cossysbucket) sont lues directement à partir des propriétés système de Maximo. Il n'est donc pas nécessaire de coder en dur les valeurs sensibles dans le rapport.
Dans l'élément Dynamic Image sur Create script, ajoutez ce qui suit. Cela se déclenche pour chaque ligne, analyse l'URI COS, télécharge l'image, gère la conversion des formats, applique la compression JPEG et définit les dimensions d'affichage :
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();
}
}
Prévisualisez le rapport dans BIRT Designer pour vérifier que les images s'affichent correctement. Une fois vérifié, importez le rapport dans MAS et testez-le en générant un PDF par rapport à un bon de travail ou à une inspection contenant des photos en pièce jointe.

La migration de Maximo 7.6 vers MARS 9 introduit un changement fondamental dans la manière dont les pièces jointes sont stockées et consultées. En passant d'une approche basée sur des fichiers locaux à une extraction basée sur S3/COS, les scripts qui génèrent des images dynamiques dans les rapports BIRT doivent être mis à jour en conséquence.
Grâce au script d'initialisation qui gère l'authentification S3 et au script OnCreate qui gère le téléchargement des objets et le traitement des images, vous pouvez continuer à fournir des rapports riches et améliorés avec des images dans MAS 9 tout aussi efficacement que dans la version 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.