Eine wichtige Anforderung bei der Erstellung von Berichten mit Jaspersoft ist die Darstellung von Datensätzen in leicht verständlicher Form. Grafische Darstellungen sind hierzu oft gut geeignet; so bietet Jaspersoft beispielsweise die automatische Generierung von (HTML5-)Charts an. Je nach Berichtsanforderung kann es aber sein, dass sich eine Text- und Grafikdarstellung vermischen sollen, z.B. in Form von unterschiedlich großen Balken pro Zeile wie in folgendem Beispielbericht über die Beliebtheit einzelner Farben beim Autokauf:

Ein Bericht mit dynamisch wachsenden Balken pro Zeile

Eine derartige Anforderung lässt sich nicht trivial über die Verwendung eines Charts abbilden. Ebenso ist die klassische Variante, Bilder über eine Datei in einen Bericht einzubinden, so wie es im Beispiel beim Firmenlogo der Fall ist, hier ungeeignet:

Einbinden eines Bildes in den Report durch Angabe des Dateipfads

Da der angezeigte Balken pro Zeile je nach Parameterauswahl (z.B. das Jahr der Umfrage) unterschiedlich groß wird und auch in jeder Zeile unterschiedlich eingefärbt werden soll, können keine vorab erstellten Grafiken eingebunden werden.

Wie lassen sich kombinierte Text- und Grafikdarstellungen mit Jaspersoft umsetzen?

Sehen wir uns hierzu einmal unser vorliegendes Datenset an:

Datenset für den Bericht. Enthalten sind Name der Farbe, Anteil und der Hex-Code der Farbe.

Zu jeder anzuzeigenden Zeile kennen wir den Beliebtheitsanteil. Dieser lässt sich (bei bekannter Maximalbreite) in die Breite des jeweiligen Balkens umrechnen. Außerdem kennen wir zu jeder anzuzeigenden Farbe ihre hexadezimale Darstellung. Die beiden Informationen über die Balken, die sich dynamisch ändern können, sind uns also bekannt.

Sollte man schon etwas Erfahrung im Erstellen von JasperReports mitbringen, so wird man vermutlich bemerkt haben, dass das Image Element von Jaspersoft verschiedene Dateiformate verarbeiten kann. So ist es möglich, neben pixelbasierten Formaten wie JPEG und PNG auch Vektorgrafiken in Form von SVGs einzubinden. Da das Format SVG auf XML basiert, sind Detailänderungen an den Bildern leicht durch Anpassungen im Quellcode zu realisieren. Die Balken lassen sich also dynamisch erstellen, wenn wir immer ein angepasstes SVG laden können.

SVG-Bildinformationen aus byte Arrays lesen – mit dem SimpleDataRenderer

Zum Laden von Bildinformation enthält die JasperReports Library mit dem SimpleDataRenderer eine Klasse, mit der wir Bilder nicht nur aus Dateien lesen können, sondern auch aus byte Arrays. Ein solches byte Array können wir im Jasperbericht für jede Zeile aus dem Datenset zur Laufzeit erzeugen, z.B. durch Konvertieren eines Strings.

Und damit schließt sich der Kreis: In einem String können wir nämlich ein komplettes SVG unterbringen, für welches wir den Quellcode dynamisch zusammensetzen. Bei unseren Balken sieht das wie folgt aus:

Quellcode für eine Berichtsvariable, welche dynamisch generierten SVG Code enthalten soll

Über das Feld color_code setzen wir jeweils die Farbe des Balkens und über die Variable current_bar_width die zuvor berechnete Balkenbreite. Mit den verschiedenen anderen Parametern speichern wir auf Reportebene bestimmte Maße ab, mit denen wir statische Eigenschaften der Balken manipulieren können. Den so erzeugten und als Variable abgespeicherten String können wir nun in einem Image Objekt nutzen, um unsere Balken in das Report Design einzubinden:

Image Expression im Bericht, die die SVG Variable und den SimpleDataRenderer nutzt

Damit haben wir unser Ziel erreicht und nutzen einen dynamisch pro Zeile erstellten Balken in unserem Report. Auch andere Anwendungen, wie eine wechselnde Anzahl abgegebener Sterne bei Bewertungen oder Kreise mit unterschiedlichen Radii, sind durch die Erzeugung von SVGs im Bericht möglich.

Darüber hinaus eignet sich der SimpleDataRenderer aber auch, um direkt im jrxml oder in der Datenbank hinterlegte codierte Pixelgrafiken darzustellen, sodass diese nicht als eigene Dateien abgelegt werden müssen. Der SimpleDataRenderer ist somit ein mächtiges Werkzeug für jeden JasperReports-Entwickler.