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