Komplexe Excel-Berichte mit APEX und jXLS erstellen

Transcription

Komplexe Excel-Berichte mit APEX und jXLS erstellen
Komplexe Excel-Berichte mit APEX und jXLS
erstellen
Dietmar Aust
Opal-Consulting
Köln
Schlüsselworte:
Oracle APEX, MS Excel, jXLS, Bericht, Template, Open Source
Einleitung
In fast jeder Webapplikation wird in der einen oder anderen Form ein Export der Daten nach
MS Excel benötigt, wobei die Anwendungsfälle sehr unterschiedlich sein können. Am
häufigsten wird ein einfacher Export der Daten benötigt, um diese in MS Excel weiter zu
verarbeiten.
In anderen Fällen wird jedoch eine MS Excel Arbeitsmappe mit mehreren Arbeitsblättern
oder mit einer ganz bestimmten Formatierung benötigt, weil dieses Format zwischen den
Abteilungen abgestimmt wurde oder weil die Datei durch Makros automatisch weiter
verarbeitet wird.
Die verschiedenen Wege von APEX zu MS Excel
Welche Möglichkeiten haben wir, aus einer APEX Applikation einen Export zu MS Excel zu
erstellen?
APEX CSV Export
Oracle APEX bietet eine einfache Möglichkeit, jeden Bericht im CSV Format zu exportieren.
Dazu aktivieren den Export deklarativ in den Einstellungen zu diesem Bericht. Damit werden
die Daten exportiert und über den Browser MS Excel gestartet. Durch dieses Verfahren
bekommen wir jedoch nur die reinen Daten, ohne Formatierungen, Logos oder Makros. Wir
können in dieser MS Excel Arbeitsmappe auch nur Daten aus einer Abfrage exportieren, nicht
aus mehreren. Außerdem ist es immer wieder ein Problem, dass MS Excel versucht, die Daten
intelligent zu interpretieren. Dabei finden dann Datentypkonvertierungen statt, die wir nicht
beabsichtigen.
Oracle BI-Publisher
Der Oracle BI-Publisher bietet zwei unterschiedliche Möglichkeiten, MS Excel
Arbeitsmappen zu erzeugen. Der erste basiert auf dem bekannten Ansatz, mit MS Word eine
Vorlage erstellen, in die wir die Daten integrieren können. Diese Vorlage kann dann in den
verschiedenen Formaten (MS Word, XML, MS Excel) exportiert werden.
Generell hat dieser Ansatz seine Grenzen. Dies gilt jedoch nicht nur für die Generierung
durch den BI-Publisher sondern generell für alle Berichtsgeneratoren (BIRT, JasperReports,
Oracle Reports, Crystal Reports, etc.), die ein Seitenlayout verwenden und den resultierenden
Bericht einfach nur in verschiedenen Formaten exportieren können. So müssen wir einerseits
viel Aufwand investieren, damit wir im Berichtsgenerator eine Vorlage erstellen, die dem
Endergebnis ähnlich ist. Außerdem können wir keine speziellen Funktionen des Zielformates
nutzen, z.B. native Funktionen von MS Excel.
Der BI-Publisher unterstützt dazu einen alternativen Ansatz, bei dem MS Excel für die
Erstellung der Vorlage verwendet wird. Der BI-Publisher stellt ein Plugin für MS Excel
bereit, welches in einer MS Excel Arbeitsmappe Platzhalter einbetten kann. Wir speichern das
Dokument im XML Format und legen es im J2EE Container ab. Zur Laufzeit wird dann aus
dieser Vorlage der fertige MS Excel Bericht generiert. Diese Integration mit APEX müssen
wir jedoch selbst programmieren.
HTP.P basierte Ansätze
Bei den sogenannten HTP.P Ansätzen geben wir mittels der Funktion htp.p aus dem
OWA_TOOLKIT die Daten direkt an den Browser zurück.
BEGIN
OWA_UTIL.mime_header('application/vnd.ms-excel', False);
HTP.p ('Content-Disposition: attachment; filename="emp.csv"');
OWA_UTIL.http_header_close;
FOR x IN (SELECT e.ename, e.empno, d.dname
FROM emp e, dept d
WHERE e.deptno = d.deptno AND e.deptno LIKE :p1_deptno)
LOOP
HTP.prn (x.ename || ',' || x.empno || ',' || x.dname || CHR (13));
END LOOP;
APEX_APPLICATION.g_unrecoverable_error := TRUE;
END;
Dabei können wir sowohl CSV Daten exportieren wie auch das ab MS Excel 2003 verfügbare
XML Format. Darüber haben wir die Möglichkeit, mit mehreren Datenblättern zu arbeiten
oder auch Formatierungen einzubeziehen.
Ein weiterer Workaround ist die Generierung von formatierten HTML und dem Setzen des
Mime-Typen für MS Excel. Dadurch wird MS Excel geöffnet und konvertiert das HTML
Dokument selbst. Dies ist ein praktisches Vorgehen, wenn wir nur ein wenig Formatierung
benötigen.
jXLS
Das Open Source Projekt jXLS (http://jxls.sourceforge.net/) ist eine kleine und
einfach zu verwendende Java Bibliothek, um native MS Excel Dateien (z.B.
umsätze_2010.xls) auf Basis von Vorlagen zu generieren. Wir können eine normale MS
Excel Datei als Vorlage verwenden und dort unsere Platzhalter integrieren. Zur Laufzeit wird
dann diese Vorlage analysiert und die Daten werden integriert.
jXLS basiert auf einem anderen Open Source Projekt namens Apache POI
(http://poi.apache.org/), dieses realisiert in Java die Low-Level Funktionen, um die MS
Office Formate in ihrer Binärform zu lesen und zu schreiben. Somit werden auch ältere Office
Versionen (beginnend ab Office 97) unterstützt.
jXLS unterstützt bietet eine Templating Sprache, mit deren Hilfe wir Anweisungen direkt in
die MS Excel Datei einbetten können. So können wir Schleifen, Bedingungen und auch
Ausdrücke (über JEXL) verwenden, um darin entsprechende Logik zu programmieren. Wir
können mehre Abfragen innerhalb einer Arbeitsmappe verwenden, auch innerhalb eines
Arbeitsblattes. Genauso gut können wir auch dieselbe Abfrage auf mehreren Arbeitsblättern
verwenden.
Integration in APEX
Wie können wir nun dieses Framework in unseren APEX Applikation verwenden? Wir haben
bereits eine Integration in Java geschrieben, die eine Schnittstelle zu PL/SQL zur Verfügung
stellt. Diese Integration verwendet Java in der Datenbank und wird mittels loadjava
installiert.
Vom Ablauf her benötigen wir zuerst eine
Vorlage im MS Excel Format. Diese können wir
über die üblichen Wege als BLOB in der
Datenbank zugänglich machen. So können wir
z.B. den Upload über APEX nutzen, die Vorlage
im Builder unter Gemeinsamen Komponenten
hochladen, aus dem Dateisystem über BFILEs
zugänglich machen, etc.
Dann spezifizieren wir nur noch die entsprechenden Abfragen als SQL Statements und rufen
die API zusammen mit der Vorlage als BLOB auf.
CREATE PROCEDURE XLIB.generate_template (p_fil_id IN NUMBER)
is
l_blob
BLOB;
l_out_blob
BLOB;
l_maps
xlib_vc2_array_t := xlib_vc2_array_t ();
l_queries
xlib_vc2_array_t := xlib_vc2_array_t ();
BEGIN
SELECT fil_blob_content
INTO l_blob
FROM xlib_cms_files
WHERE fil_id = p_fil_id;
l_maps.EXTEND
l_maps
(1)
l_queries (1)
l_out_blob :=
(); l_queries.EXTEND ();
:= 'user_objects';
:= 'select object_name from user_objects';
xlib_xls.render_template (p_maps
=> l_maps,
p_queries
=> l_queries,
p_template
=> l_blob
);
OWA_UTIL.mime_header ('application/vnd.ms-excel', FALSE);
--htp.print('ContentDisposition:attachment;filename="'||v_report_title||'.xls"');
OWA_UTIL.http_header_close;
WPG_DOCLOAD.download_file (p_blob => l_out_blob);
END;
Da wir im Ergebnis wieder ein BLOB erhalten, können wir dieses dann direkt im Browser zur
Anzeige bringen (WPG_DOCLOAD.download_file (p_blob => l_out_blob);), in einer
Tabelle speichern oder per Email als Attachement versenden.
Obwohl jXLS viele Möglichkeiten über die Templating Sprache anbietet, verwenden wir in
unseren Projekten meist den einfachen Weg, Daten über Platzhalter zu integrieren. Dabei
liefern wir entweder nur viele einzelne Spalten innerhalb eines Datensatzes
(${shdb_standorte.sta_strasse}, ${shdb_standorte.sta_plz}) oder wir liefern eine
Liste, die wir in der MS Excel Arbeitsmappe dann referenzieren.
Dies sind die häufigsten Formen, wie wir das Framework in unseren Projekten einsetzen.
Fazit
Der Vortrag beschreibt die Integration der Open Source Java Bibliothek jXLS mit Oracle
APEX. jXLS ist eine kleine und einfach zu verwendende Java Bibliothek, um MS Excel
Arbeitsmappen mit Hilfe eines Template-Ansatzes zu erstellen.
Dies ist eine sehr elegante Methode (vergleichbar mit dem MS Excel Plugin des Oracle BIPublishers) bei der, ausgehend von einer nativen MS Excel Arbeitsmappe, Platzhalter
verwendet werden, um diese dann anschließend dynamisch mit den konkreten Werten zu
befüllen. Auf diesem Wege können wir die bereits vorhandenen MS Excel Arbeitsmappen der
Fachabteilung nutzen (inkl. der Logos, Diagramme, komplexer Berechnungen, etc.) und diese
dann befüllen, indem wir die entsprechenden Platzhalter in einer einfachen Template Sprache
direkt in der Arbeitsmappe integrieren.
Allgemeiner betrachtet ist dies ein Ansatz, um den gesamten Java Stack (inkl. aller
verfügbaren Open Source Bibliotheken) in APEX Applikationen zu nutzen. Damit können
selbst komplexere Kundenanforderungen elegant umgesetzt werden, die APEX
standardmäßig nicht unterstützt.
Bitte wenden Sie sich an den Autor für einen Download der Integration mit jXLS.
Kontaktadresse:
Dietmar Aust
Zum Tilmeshof 11
D-50859 Köln
Telefon:
Fax:
E-Mail
Internet:
+49(0)221-17099459
+49(0)221-17099759
dietmar.aust@opal-consulting.de
http://www.opal-consulting.de