prog:oracle_apex_jasper_reports
Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
Beide Seiten der vorigen RevisionVorhergehende Überarbeitung | |||
prog:oracle_apex_jasper_reports [2016/07/07 09:59] – [Quellen] gpipperr | prog:oracle_apex_jasper_reports [2016/07/11 22:30] (aktuell) – [Quellen] gpipperr | ||
---|---|---|---|
Zeile 1: | Zeile 1: | ||
+ | =====Oracle APEX 5 und Jasper Reports 6 zusammen installieren und nützen===== | ||
+ | Aus HTML Anwendungen ist das Drucken meist eine Herausforderung, | ||
+ | |||
+ | Eine Möglichkeit ist das Erstellen eines Berichts als PDF, der dann ausgedruckt werden kann. | ||
+ | |||
+ | Ein hervorragendes, | ||
+ | |||
+ | Steht dieser nicht zur Verfügung ist es eine Alternative ein Open Source Produkt wie [[http:// | ||
+ | |||
+ | Eine sehr gute Anleitung + Software dazu bzgl. einer tiefen Apex Integration findet sich hier => http:// | ||
+ | |||
+ | Im ersten Schritt versuche ich das aber mal mit dem derzeitigen APEX 5 und PL/SQL in der 12c Board Mitteln zu lösen. | ||
+ | |||
+ | |||
+ | ---- | ||
+ | |||
+ | ==== Aufsetzen einer Jasper Reports Umgebung==== | ||
+ | |||
+ | Voraussetzung: | ||
+ | |||
+ | Eine Umgebung mit Tomcat und den ORDS für Oracle Apex ist bereits installiert, | ||
+ | |||
+ | Leider lässt sich adhoc das Repository von Jasper NICHT in der Oracle Datenbank anlegen. | ||
+ | |||
+ | |||
+ | Auf diese existierenden Umgebung wird nun eine Community Jasper Report 6.2 Applikation aufgesetzt. | ||
+ | |||
+ | |||
+ | Download der Software über http:// | ||
+ | |||
+ | * JasperReports® Server | ||
+ | * JasperReports | ||
+ | * Jaspersoft® Studio | ||
+ | |||
+ | Dazu ist einen Community Mitgliedschaft notwendig. | ||
+ | |||
+ | ==== Standalone Jasper Umgebung==== | ||
+ | |||
+ | Ziel ist es das alles unter Oracle läuft, leider wird das aber nativ nicht unterstütz . | ||
+ | |||
+ | Daher im ersten Schritt auf einer Testmaschine über den Windows Installer " | ||
+ | |||
+ | * Exe starten next - next | ||
+ | * Lizenzbedingungen akzeptieren | ||
+ | * Custom install auswählen - next | ||
+ | * Programm Verzeichnis auswählen wie d: | ||
+ | * "I want to use an existing Tomcat" | ||
+ | * "I want to use the bundled PostgreSQL database" | ||
+ | * Tomcat Server Port angeben,in unsere Fall 8081 - next | ||
+ | * Wenn Tomcat noch läuft diesen erst stoppen? hilft nicht daher jetzt oben 8081 angeben Bug? | ||
+ | * Port muss unterschiedlich sein, ist aber ein Bug im Installer! | ||
+ | * Database Server Port angeben 5432 - next | ||
+ | * Tomcat Verzeichnis auswählen - in unseren Fall D: | ||
+ | * Samples mit installieren - Next | ||
+ | * Installation starten mit Next | ||
+ | * Installation läuft ca. 5min | ||
+ | * Finish | ||
+ | |||
+ | Nun den Tomcat wieder starten, Jasper wird deployed, leider klappt es aber gar nicht .... | ||
+ | |||
+ | Jetzt heißt es den Fehler suchen.... | ||
+ | |||
+ | < | ||
+ | 09-Jun-2016 22: | ||
+ | | ||
+ | </ | ||
+ | |||
+ | =>> postgresql war nicht gestartet! | ||
+ | |||
+ | Siehe dazu auch zur Installation => http:// | ||
+ | |||
+ | |||
+ | Das wir in unserer Umgebung den [[prog: | ||
+ | |||
+ | apex.conf: | ||
+ | <code apache> | ||
+ | .. | ||
+ | JKMount / | ||
+ | .. | ||
+ | </ | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | === Login in den Jasper Report Server === | ||
+ | |||
+ | Login mit dem User jasperadmin / pwd jasperadmin , diese SOFORT anpassen! | ||
+ | |||
+ | Local Test mit < | ||
+ | Produktiv aufrufen mit < | ||
+ | |||
+ | Nun noch eine Datasource für die Oracle Datenbank anlegen, unter "Data Source" | ||
+ | |||
+ | Als erstes über " | ||
+ | |||
+ | |||
+ | === Repository nach Oracle verschieben === | ||
+ | |||
+ | Aus den Sourcen lässt sich das SQL für das Repository ermitteln, evtl. lässt sich daraus eine Oracle Version " | ||
+ | |||
+ | Dazu die Datei " | ||
+ | |||
+ | Diese müssen nun auf die Oracle Syntax angepasst werden. | ||
+ | |||
+ | Alles wird nun in der Oracle gleich wie in der Postgresql | ||
+ | |||
+ | Mal sehen ob das so einfach dann klappt. | ||
+ | |||
+ | demnächst mehr | ||
+ | |||
+ | |||
+ | ---- | ||
+ | |||
+ | ==== Report Designer starten==== | ||
+ | |||
+ | Die Datei " | ||
+ | |||
+ | |||
+ | Über " | ||
+ | |||
+ | Als erstes wird ein Data Adapter benötigt, dazu muss aber zuvor der Pfad zu den JDBC Jars von Oracle definiert werden. | ||
+ | |||
+ | * {{ : | ||
+ | * {{ : | ||
+ | |||
+ | |||
+ | Nun kann über " | ||
+ | |||
+ | Nach dem ersten Report diesen auf den Server hochladen, dazu im Studio eine Server Verbindung anlegen und dort den Bericht hochladen. | ||
+ | |||
+ | ---- | ||
+ | |||
+ | ===== Integration in Apex ===== | ||
+ | |||
+ | Die einfachste Integration ist das Weiterleiten der URL an den Report Server von Jasper. | ||
+ | |||
+ | Allerdings ist dann das Ganze nicht direkt integriert, mit den Benutzerrechten und dem Passwort dazu ist das nicht so einfach. | ||
+ | |||
+ | Besser ist eine tiefe Integration und der Aufruf des Berichts über die [[http:// | ||
+ | |||
+ | Dies kann nun per JavaScript in der Oberfläche erfolgen oder per UTL_HTTP über PL/SQL in der Datenbank. | ||
+ | |||
+ | |||
+ | Als erstes mit einem Rest Tool wie http:// | ||
+ | restclient-ui-3.5-jar-with-dependencies.jar herunterladen und testen. | ||
+ | |||
+ | |||
+ | === JavaScript === | ||
+ | => <fc # | ||
+ | ==Visualize.js== | ||
+ | |||
+ | * http:// | ||
+ | * http:// | ||
+ | |||
+ | |||
+ | |||
+ | ==== APEX - PL/SQL ==== | ||
+ | |||
+ | Die Integration in Apex erfolgt dadruch, das im Backend, d.h. in der Datenbank ein REST Call an den Jasper Server versandt wird, dies Call liefert den Bericht im gewünschten Format zurück, Diese Bericht wird dann in einer BLOB Variable gespeichert, | ||
+ | |||
+ | |||
+ | {{ : | ||
+ | |||
+ | |||
+ | |||
+ | ===APEX_WEB_SERVICE verwenden=== | ||
+ | |||
+ | siehe https:// | ||
+ | |||
+ | Mit Hilfe von " | ||
+ | |||
+ | |||
+ | Zuvor eine ACL hinterlegen, | ||
+ | |||
+ | ACL: | ||
+ | <code sql> | ||
+ | | ||
+ | v_apex_server VARCHAR2(256): | ||
+ | BEGIN | ||
+ | DBMS_NETWORK_ACL_ADMIN.APPEND_HOST_ACE( | ||
+ | | ||
+ | , lower_port => 80 | ||
+ | , upper_port => 80 | ||
+ | , ace => xs$ace_type(privilege_list => xs$name_list(' | ||
+ | | ||
+ | | ||
+ | ); | ||
+ | END; | ||
+ | / | ||
+ | </ | ||
+ | |||
+ | |||
+ | Ein erster Test, der aber leider für diesen Einsatzzweck nicht erfolgreich ist, das Dokument wird als CLOB zurückgeben, | ||
+ | <code plsql> | ||
+ | DECLARE | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | -- use this to get resource infos for this report | ||
+ | | ||
+ | -- get the report | ||
+ | | ||
+ | -- Which Report | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | -- read the clob | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | -- set the data | ||
+ | | ||
+ | BEGIN | ||
+ | -- create the URL | ||
+ | | ||
+ | |||
+ | | ||
+ | |||
+ | | ||
+ | , p_http_method => ' | ||
+ | , p_parm_name | ||
+ | , p_parm_value | ||
+ | , p_username | ||
+ | , p_password | ||
+ | |||
+ | | ||
+ | | ||
+ | |||
+ | -- create blob | ||
+ | | ||
+ | |||
+ | -- read the file | ||
+ | -- alternativ | ||
+ | | ||
+ | | ||
+ | BEGIN | ||
+ | LOOP | ||
+ | -- read as clob | ||
+ | | ||
+ | | ||
+ | -- convert to blob | ||
+ | | ||
+ | | ||
+ | -- next loop | ||
+ | | ||
+ | | ||
+ | END LOOP; | ||
+ | | ||
+ | WHEN NO_DATA_FOUND THEN | ||
+ | NULL; | ||
+ | END; | ||
+ | | ||
+ | | ||
+ | BEGIN | ||
+ | --send the file via APEX | ||
+ | OWA_UTIL.mime_header (NVL (v_mime_type, | ||
+ | HTP.p (' | ||
+ | htp.p(' | ||
+ | owa_util.http_header_close; | ||
+ | wpg_docload.download_file (v_blob); | ||
+ | apex_application.stop_apex_engine; | ||
+ | EXCEPTION WHEN OTHERS THEN | ||
+ | htp.prn(' | ||
+ | apex_application.stop_apex_engine; | ||
+ | END; | ||
+ | END; | ||
+ | / | ||
+ | </ | ||
+ | |||
+ | Der Bericht kann nun über SQL*Plus testweise aufgerufen werden! | ||
+ | |||
+ | Für HTTPS muss allerdings noch eine Wallet hinterlegt werden! | ||
+ | |||
+ | |||
+ | Jetzt muss das nur noch in Apex eingebunden werden. | ||
+ | |||
+ | Auf die Schnelle in einer neuen leeren Apex Seite im Pre-Rendering Bereich im Before Header als Prozesse obigen Code hinterlegt, leider gibt das noch Bruch, wie befürchtet, | ||
+ | |||
+ | <fc # | ||
+ | |||
+ | |||
+ | === Lösung mit UTL_HTTP === | ||
+ | |||
+ | Um nun ein BLOB als Ergebniss zu erhalten, muss mit UTL_HTTP gearbeitet werden. | ||
+ | |||
+ | ACL auf dem APEX Schema Owner setzen! | ||
+ | <code sql> | ||
+ | | ||
+ | v_apex_server VARCHAR2(256): | ||
+ | BEGIN | ||
+ | DBMS_NETWORK_ACL_ADMIN.APPEND_HOST_ACE( | ||
+ | | ||
+ | , lower_port => 80 | ||
+ | , upper_port => 80 | ||
+ | , ace => xs$ace_type(privilege_list => xs$name_list(' | ||
+ | | ||
+ | | ||
+ | ); | ||
+ | END; | ||
+ | / | ||
+ | </ | ||
+ | |||
+ | |||
+ | |||
+ | So gehts, sehr grob, aber muss jetzt Abend essen kochen: | ||
+ | |||
+ | <code plsql> | ||
+ | declare | ||
+ | -- URL to call | ||
+ | v_url varchar2(2000): | ||
+ | |||
+ | -- Login data | ||
+ | v_username varchar2(2000): | ||
+ | v_password varchar2(2000): | ||
+ | v_realm | ||
+ | v_scheme | ||
+ | |||
+ | -- get the URL Data | ||
+ | v_req utl_http.req; | ||
+ | v_resp | ||
+ | v_blob | ||
+ | v_buf_blob blob; | ||
+ | | ||
+ | v_file_length pls_integer :=0; | ||
+ | v_mime_type varchar2(34) | ||
+ | v_report_name varchar2(45): | ||
+ | v_error_log | ||
+ | v_error | ||
+ | begin | ||
+ | |||
+ | -- Handle the http return code in this script | ||
+ | utl_http.set_response_error_check(false); | ||
+ | | ||
+ | -- Start the http request | ||
+ | v_req := utl_http.begin_request(v_url); | ||
+ | -- use in this example http basic authen. scheme | ||
+ | utl_http.set_authentication(v_req, | ||
+ | | ||
+ | -- do the request | ||
+ | v_resp := utl_http.get_response(v_req); | ||
+ | | ||
+ | -- check if the login was sucessfull | ||
+ | if (v_resp.status_code = utl_http.http_unauthorized) then | ||
+ | -- check the answer of the server | ||
+ | utl_http.get_authentication(v_resp, | ||
+ | v_error_log: | ||
+ | v_error_log: | ||
+ | -- end the request | ||
+ | utl_http.end_response(v_resp); | ||
+ | v_error: | ||
+ | elsif (v_resp.status_code = utl_http.http_proxy_auth_required) then | ||
+ | utl_http.get_authentication(v_resp, | ||
+ | v_error_log: | ||
+ | v_error_log: | ||
+ | -- end the request | ||
+ | utl_http.end_response(v_resp); | ||
+ | v_error: | ||
+ | elsif (v_resp.status_code = utl_http.HTTP_NOT_FOUND ) then | ||
+ | utl_http.end_response(v_resp); | ||
+ | v_error_log: | ||
+ | v_error: | ||
+ | elsif (v_resp.status_code > 299 ) then | ||
+ | utl_http.end_response(v_resp); | ||
+ | v_error_log: | ||
+ | v_error: | ||
+ | else | ||
+ | v_error: | ||
+ | end if; | ||
+ | | ||
+ | -- create the blob to hold the result of the request | ||
+ | dbms_lob.createtemporary( v_blob, true ); | ||
+ | -- readhe responmse | ||
+ | -- | ||
+ | begin | ||
+ | loop | ||
+ | | ||
+ | | ||
+ | end loop; | ||
+ | | ||
+ | when utl_http.end_of_body | ||
+ | then | ||
+ | null; | ||
+ | end; | ||
+ | -- close the response | ||
+ | utl_http.end_response(v_resp); | ||
+ | |||
+ | -- send the data | ||
+ | v_file_length: | ||
+ | v_error_log: | ||
+ | | ||
+ | -- if no error send the blob as pdf | ||
+ | if | ||
+ | begin | ||
+ | | ||
+ | htp.p (' | ||
+ | htp.p(' | ||
+ | owa_util.http_header_close; | ||
+ | wpg_docload.download_file (v_blob); | ||
+ | exception when others then | ||
+ | v_error_log: | ||
+ | v_error: | ||
+ | end; | ||
+ | end if; | ||
+ | if v_error = true then | ||
+ | owa_util.mime_header (' | ||
+ | owa_util.http_header_close; | ||
+ | v_error_log: | ||
+ | htp.p(v_error_log); | ||
+ | -- to debug strange results | ||
+ | --if v_blob is not null then | ||
+ | -- wpg_docload.download_file (v_blob); | ||
+ | --end if; | ||
+ | end if; | ||
+ | -- end the apex process | ||
+ | | ||
+ | |||
+ | exception when others then | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | end; | ||
+ | </ | ||
+ | |||
+ | Die Authorisierung finden Sie hier => Handling HTTP Authentication mit UTL_HTTP https:// | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | **Schlussfolgerung: | ||
+ | |||
+ | D.h. wir können mit " | ||
+ | |||
+ | |||
+ | Synchron: | ||
+ | |||
+ | * Dann können wir gleich synchron mit UTL_HTTP den Bericht rufen und aus der DB verwenden. | ||
+ | |||
+ | Asynchron: | ||
+ | * Hier können wir wieder mit apex_web_service alles vorbereiten und dann den eigentliche Bericht mit UTL_HTTP abholen | ||
+ | |||
+ | |||
+ | Jetzt nähern wir uns stark der Lösung von Dietmar mit UTL_HTTP, eine einfache Umsetzen mit APEX_WEB_SERVICE sehe ich hier auf die schnelle nicht, da es anscheinend keine Möglichkeit gibt, den Return einer Rest Calls als BLOB zu erhalten, jeder Verarbeitung eines CLOB führt aber zu Zeichensatzprobleme und zerstöret damit die Stuktur einer PDF Daten. | ||
+ | |||
+ | |||
+ | ---- | ||
+ | |||
+ | ==== Quellen ==== | ||
+ | |||
+ | PLSQL | ||
+ | |||
+ | * https:// | ||
+ | * https:// | ||
+ | * http:// | ||
+ | * http:// | ||
+ | |||
+ | Apex Integration: | ||
+ | |||
+ | * http:// | ||
+ | * http:// | ||
+ | * http:// | ||
+ | |||
+ | |||
+ | * http:// | ||
+ | * http:// | ||
+ | |||
+ | |||
+ | |||
+ | Jasper Allgemein | ||
+ | |||
+ | |||
+ | User: | ||
+ | |||
+ | * http:// | ||
+ | |||
+ | Integration | ||
+ | |||
+ | * http:// | ||
+ | * http:// | ||
+ | |||
+ | * http:// | ||
+ | |||
+ | Oracle als Repostitory verwenden | ||
+ | |||
+ | * http:// | ||
+ | * http:// | ||
+ | * https:// | ||
+ | |||
+ | Apex Allgemein: | ||
+ | * http:// |
prog/oracle_apex_jasper_reports.txt · Zuletzt geändert: 2016/07/11 22:30 von gpipperr