Barcodes in einer APEX-Anwendung generieren

Dieser Beitrag dreht sich um das Thema Barcodes und wie man diese in einer Oracle11g-Datenbank aus einer APEX-Anwendung heraus generieren kann. Abbildung 1 zeigt ein Beispiel mit verschiedenen Barcode-Typen. In dieser Form ist der Tipp ist nur in einer Oracle11g-Datenbank getestet und lauffähig.

Achtung: Wenn Sie auf Windows mit einer Datenbank 11.1.0.6 oder 11.1.0.7 arbeiten, funktioniert dieser Tipp nicht. Das Problem ist bekannt (Bug-Eintrag in Metalink "7145719") und wird in Version 11.2. Auf Linux-Plattformen funktioniert der Tipp; das Problem tritt nicht auf.

Barcodes in Application Express

Abbildung 1: Barcodes in Application Express

Vorbereitungen: Java-Bibliothek laden

Zum Generieren der Barcodes dient in diesem Fall die OpenSource Java-Bibliothek Barcode4J. Diese unterlegt der Apache Lizenz 2.0, kann also unter deren Bedingungen frei verwendet werden. Laden Sie also die Datei barcode4j-2.0-bin.zip von der Download-Seite des Barcode4J-Projekts herunter und packen Sie es in ein Verzeichnis Ihrer Wahl aus. Für diesen Tipp wird nur die Bibliothek barcode4j-light.jar benötigt (Abbildung 2).

Nur die Datei "barcode4j-light.jar" wird benötigt

Abbildung 2: Nur die Datei "barcode4j-light.jar" wird benötigt

Diese muss in die Oracle-Datenbank geladen werden. Mit dem folgenden Kommando laden Sie den Java-Code in Ihr Parsing Schema. Ausgangspunkt ist eine Unix-Shell bzw. die "DOS-Box".

$ loadjava -u {APEX-Parsing Schema}/{Passwort} -o -r -v barcode4j-light.jar

arguments: '-u' 'partner/***' '-o' '-r' '-v' 'barcode4j-light.jar' 
creating : resource META-INF/MANIFEST.MF
loading  : resource META-INF/MANIFEST.MF
created  : CREATE$JAVA$LOB$TABLE
creating : resource META-INF/LICENSE
loading  : resource META-INF/LICENSE
creating : resource META-INF/NOTICE
loading  : resource META-INF/NOTICE
creating : class org/krysalis/barcode4j/BarGroup
loading  : class org/krysalis/barcode4j/BarGroup
creating : class org/krysalis/barcode4j/BarcodeClassResolver
:

Es kann sein, dass einige Fehlermeldungen auftreten und das "Resolving" für zwei Java-Klassen der Bibliothek fehlschlägt. Das kann für diesen Tipp ignoriert werden. Die sog. USPS-Mail-Barcodes benötigen wir hier ebensowenig wie die SVG-Unterstützung.

:
The following operations failed
    class org/krysalis/barcode4j/impl/fourstate/USPSIntelligentMail: resolution
    class org/krysalis/barcode4j/output/svg/JDOMSVGCanvasProvider: resolution
exiting  : Failures occurred during processing

Vorbereitungen: PL/SQL-Wrapper einrichten

Wenn die Klassen geladen sind, muss die Funktionalität als nächstes für die SQL- und PL/SQL-Ebene verfügbar gemacht werden. Dazu dient das PL/SQL-Paket BARCODE (Download), welches Sie ebenfalls ins Parsing Schema Ihrer APEX-Anwendung einspielen.

Vorbereitungen: PL/SQL-Prozedur für APEX einrichten

Zum Schluß benötigen Sie noch eine PL/SQL-Prozedur, welche aus APEX heraus aufgerufen wird, um den Barcode (das generierte Bild) anzuzeigen. Spielen Sie den folgenden Code ebenfalls ins Parsing-Schema Ihrer APEX-Anwendung ein und vergeben Sie das EXECUTE-Privileg an PUBLIC.

create or replace procedure get_barcode(
  p_text in varchar2, p_type in varchar2
) is
  v_barcode   blob; 
  V_IMAGETYPE varchar2(100) := 'image/jpeg';
  V_DPI       number        := 150;
  V_FONTPATH  varchar2(100) := 'C:\\WINDOWS\\Fonts';
  V_PIXELSIZE number        := 1;
begin
  barcode.set_dpi(V_DPI);
  barcode.set_font_path(V_FONTPATH);
  if p_type = 'CODE39' then 
    v_barcode := barcode.get_code39(p_text, V_IMAGETYPE, V_PIXELSIZE);
  elsif p_type='CODE128' then 
    v_barcode := barcode.get_code128(p_text, V_IMAGETYPE, V_PIXELSIZE);
  elsif p_type='EAN8' then 
    v_barcode := barcode.get_ean8(p_text, V_IMAGETYPE, V_PIXELSIZE);
  elsif p_type='EAN13' then 
    v_barcode := barcode.get_ean13(p_text, V_IMAGETYPE, V_PIXELSIZE);
  elsif p_type='DATAMATRIX' then
    v_barcode := barcode.get_datamatrix(p_text, V_IMAGETYPE, V_PIXELSIZE);
  elsif p_type='UPCA' then
    v_barcode := barcode.get_upca(p_text, V_IMAGETYPE, V_PIXELSIZE);
  elsif p_type='PDF417' then
    v_barcode := barcode.get_pdf417(p_text, V_IMAGETYPE, V_PIXELSIZE);
  end if;
  owa_util.mime_header(V_IMAGETYPE, false);
  htp.p('Content-Length: ' || dbms_lob.getlength(v_barcode));
  owa_util.http_header_close;
  wpg_docload.download_file(v_barcode);
end;
/

grant execute on get_barcode to public
/

Zu Beginn der Prozedur werden einige Konstanten definiert. Wichtig ist die Variable V_FONTPATH und der korrespondierende Aufruf von BARCODE.SET_FONT_PATH. In der Variable muss ein Verzeichnis mit TTF-Dateien ("TrueType Fonts") für die gängigen Fonts stehen. Auf Windows-Systemen ist das typischerweise C:\WINDOWS\Fonts. Passen Sie diesen Pfad ggfs. an Ihr System an.

Damit Sie diesen "Font-Pfad" in der Java-Engine der Datenbank setzen können, benötigen Sie ein entsprechendes Java-Privileg, welches Ihnen der Datenbankadministrator wie folgt einrichten kann.

call dbms_java.grant_permission( 
  '[APEX Parsing Schema]',
  'SYS:java.util.PropertyPermission', 
  'sun.java2d.fontpath', 
  'read,write' 
);

Sie erkennen die Fontdateien normalerweise am Suffix .ttf. Achten Sie (speziell unter Linux/UNIX) weiterhin darauf, dass die im diesem Verzeichnis liegenden TTF-Dateien vom Betriebssystem-User "oracle" gelesen werden können - die Rechte sollten typischerweise so aussehen:

:
-rw-r--r--  1 root root    55220 2004-03-19 09:27 SUSESerif-Roman.ttf
-rw-r--r--  1 root root    53564 2004-03-19 09:27 SUSESerif-Bold.ttf
-rw-r--r--  1 root root    56708 2004-03-19 09:27 SUSESans-Roman.ttf
-rw-r--r--  1 root root    58804 2004-03-19 09:27 SUSESans-Oblique.ttf
-rw-r--r--  1 root root    44848 2004-03-19 09:27 SUSESansMono-Roman.ttf
:

Beachten Sie noch eine Besonderheit, wenn Sie mit dem PL/SQL Embedded Gateway arbeiten. Der direkte Aufruf der Prozedur per URL muss eigens gestattet werden - wie das geht, ist im Community Tipp Der Webserver von Application Express: PL/SQL Embedded Gateway oder Apache im Abschnitt Eigene PL/SQL Prozeduren direkt per URL aufrufen beschrieben.

Barcodes in einem APEX-Bericht nutzen

Nun sind alle Vorbereitungen gemacht - die Barcodes können (bspw. in einem Bericht) genutzt werden. Erzeugen Sie dazu einen normalen SQL-Bericht in Ihrer Anwendung mit folgender Abfrage:

select 
  empno,
  ename,
  empno barcode1,
  empno barcode2
from emp

In den Spalten BARCODE1 und BARCODE2 werden die Barcodes dargestellt. Navigieren Sie dazu zu den Berichtsattributen und dann zunächst zu den Eigenschaften der Spalte BARCODE1. Als HTML-Ausdruck tragen Sie dann folgendes ein:

<img src="#OWNER#.GET_BARCODE?P_TEXT=#EMPNO#&P_TYPE=CODE39" alt="#EMPNO#" title="#EMPNO#">
HTML-Ausdruck für Spalte "BARCODE1" eintragen

Abbildung 3: HTML-Ausdruck für Spalte "BARCODE1" eintragen

Generieren Sie den zweiten Barcode analog dazu als "Datamatrix" mit folgendem HTML-Ausdruck.

<img src="#OWNER#.GET_BARCODE?P_TEXT=#EMPNO#&P_TYPE=DATAMATRIX" alt="#EMPNO#" title="#EMPNO#">

Das Ergebnis sollte dann wie in Abbildung 4 aussehen.

Das Ergebnis: Bericht mit Barcodes

Abbildung 4: Das Ergebnis: Bericht mit Barcodes

Sie können in der Prozedur GET_BARCODE erkennen, welche Barcodes Ihnen zur Verfügung stehen:

  • CODE39
  • CODE128
  • DATAMATRIX
  • PDF417
  • EAN8
  • EAN13
  • UPC-A

Achten Sie bei den letzten drei Typen ( EAN8, EAN13 und UPC-A) darauf, dass die Java-Bibliothek die Prüfziffern der übergebenen Texte kontrolliert und im Fehlerfall Exceptions auslöst. Es kann also hilfreich sein, die Prozedur GET_BARCODE um ein Exception Handling zu erweitern. So wird ein EAN13-Barcode nur dann korrekt generiert, wenn entweder eine 12-Stellige (ggfs. mit der LDAD-Funktion auffüllen) oder eine 13-Stellige Zahl mit korrekter Prüfsumme übergeben wird. Andernfalls wird eine Exception ausgelöst, die sich dann im Apache Error Logfile oder im Tracefile des Embedded Gateway wiederfindet.

Wenn Sie sich mit Java auskennen und die Bibliothek Barcode4J näher ansehen, so bieten sich Ihnen noch zahlreiche Möglichkeiten, die Barcodes zu konfigurieren. Dieser Tipp fokussiert sich lediglich darauf, das Generieren von Barcodes überhaupt zu ermöglichen. Kombiniert man dies mit dem Community-Tipp PDF-Ausgabe mit dynamischen Bildern, so lassen sich die Barcodes mit Hilfe des Oracle BI Publisher auch als PDF- oder andere Formate ausgeben.

Zurück zur Community-Seite