Barcode und QR-Code Generierung in ABAP Cloud

kategorie
ABAP Cloud
Veröffentlicht
autor
Johannes

Barcodes und QR-Codes sind aus modernen Geschaeftsprozessen nicht mehr wegzudenken. Sie beschleunigen die Datenerfassung, reduzieren Fehler und ermoeglichen eine lueckenlose Rueckverfolgbarkeit. In ABAP Cloud gibt es verschiedene Ansaetze, diese Codes zu generieren – von ABAP-nativen Loesungen bis hin zu externen Cloud-Services.

Barcode-Typen im Ueberblick

Je nach Anwendungsfall kommen unterschiedliche Barcode-Formate zum Einsatz:

Barcode-TypDatenkapazitaetAnwendungsbereich
Code128Alphanumerisch, variabelLogistik, Versand, interne Kennzeichnung
EAN-1313 ZiffernEinzelhandel, Konsumgueter
EAN-88 ZiffernKleine Verpackungen
Code39AlphanumerischIndustrie, Automotive
QR-CodeBis 4.296 ZeichenURLs, Kontaktdaten, Rechnungen
DataMatrixBis 2.335 ZeichenPharma, Elektronik, kleine Bauteile

1D vs. 2D Codes

┌─────────────────────────────────────────────────────────────────────┐
│ Barcode-Klassifikation │
│ │
│ ┌────────────────────────────┐ ┌────────────────────────────┐ │
│ │ 1D-Barcodes │ │ 2D-Codes │ │
│ │ │ │ │ │
│ │ ║║█║║█║║║█║█║║█║║ │ │ ▓▓▓▓▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓ │ │
│ │ Code128, EAN, Code39 │ │ ▓ ▓ ▓▓▓ ▓ ▓ │ │
│ │ │ │ ▓ ▓▓▓ ▓ ▓▓ ▓ ▓▓▓ ▓ │ │
│ │ - Linear │ │ ▓ ▓▓▓ ▓ ▓▓ ▓ ▓▓▓ ▓ │ │
│ │ - Nur horizontale Info │ │ ▓ ▓ ▓ ▓ ▓ ▓ │ │
│ │ - Scanner/Lesegeraet │ │ ▓▓▓▓▓▓▓ ▓ ▓ ▓▓▓▓▓▓▓ │ │
│ │ │ │ QR-Code, DataMatrix │ │
│ │ │ │ │ │
│ │ │ │ - Matrix-basiert │ │
│ │ │ │ - Hohe Datenkapazitaet │ │
│ │ │ │ - Kamera/Smartphone │ │
│ └────────────────────────────┘ └────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────┘

Generierungsoptionen in ABAP Cloud

In ABAP Cloud stehen dir mehrere Wege zur Barcode-Generierung zur Verfuegung:

OptionBeschreibungVorteileNachteile
Externe REST-APIsCloud-basierte Barcode-ServicesFlexibel, viele FormateNetzwerkabhaengig, Kosten
ABAP-native GenerierungAlgorithmus in ABAP implementiertKeine AbhaengigkeitenAufwaendig, limitierte Formate
SAP Forms ServiceBarcodes in PDF-TemplatesIntegriertNur fuer PDFs
JavaScript in FioriFrontend-GenerierungSchnell, offlineNur UI-Anzeige

QR-Code Generierung mit externem Service

Die einfachste und flexibelste Methode ist die Nutzung eines externen QR-Code-Services:

HTTP-Client fuer QR-Code API

CLASS zcl_qr_code_generator DEFINITION
PUBLIC
FINAL
CREATE PUBLIC.
PUBLIC SECTION.
TYPES: BEGIN OF ty_qr_result,
image_base64 TYPE string,
content_type TYPE string,
success TYPE abap_bool,
message TYPE string,
END OF ty_qr_result.
METHODS generate_qr_code
IMPORTING
iv_content TYPE string
iv_size TYPE i DEFAULT 200
iv_format TYPE string DEFAULT 'PNG'
RETURNING
VALUE(rs_result) TYPE ty_qr_result.
PRIVATE SECTION.
METHODS get_http_client
RETURNING
VALUE(ro_client) TYPE REF TO if_web_http_client.
ENDCLASS.
CLASS zcl_qr_code_generator IMPLEMENTATION.
METHOD generate_qr_code.
DATA: lo_client TYPE REF TO if_web_http_client,
lo_response TYPE REF TO if_web_http_response,
lv_url TYPE string.
TRY.
" URL mit Parametern aufbauen
" Beispiel mit goqr.me API (kostenlos)
lv_url = |https://api.qrserver.com/v1/create-qr-code/| &&
|?data={ cl_web_utility=>escape_url( iv_content ) }| &&
|&size={ iv_size }x{ iv_size }| &&
|&format={ iv_format }|.
" HTTP-Client erstellen
lo_client = cl_web_http_client_manager=>create_by_http_destination(
i_destination = cl_http_destination_provider=>create_by_url( lv_url )
).
" Request senden
lo_response = lo_client->execute( if_web_http_client=>get ).
" Antwort auswerten
IF lo_response->get_status( )-code = 200.
rs_result-image_base64 = cl_web_utility=>encode_base64(
lo_response->get_binary( )
).
rs_result-content_type = |image/{ to_lower( iv_format ) }|.
rs_result-success = abap_true.
ELSE.
rs_result-success = abap_false.
rs_result-message = |HTTP Error: { lo_response->get_status( )-code }|.
ENDIF.
lo_client->close( ).
CATCH cx_web_http_client_error INTO DATA(lx_http).
rs_result-success = abap_false.
rs_result-message = lx_http->get_text( ).
CATCH cx_root INTO DATA(lx_error).
rs_result-success = abap_false.
rs_result-message = lx_error->get_text( ).
ENDTRY.
ENDMETHOD.
METHOD get_http_client.
" Alternative: Destination aus Communication Arrangement nutzen
ro_client = cl_web_http_client_manager=>create_by_http_destination(
i_destination = cl_http_destination_provider=>create_by_comm_arrangement(
comm_scenario = 'Z_QR_CODE_SERVICE'
service_id = 'Z_QR_CODE_OUTBOUND'
)
).
ENDMETHOD.
ENDCLASS.

Communication Arrangement einrichten

Fuer produktive Systeme solltest du eine Destination verwenden:

1. Communication System anlegen (SAP BTP Cockpit)
- Name: QR_CODE_SERVICE
- Host: api.qrserver.com
- Port: 443
- Protocol: HTTPS
2. Communication Arrangement erstellen
- Scenario: Z_QR_CODE_SERVICE
- Outbound Service: Z_QR_CODE_OUTBOUND
- Authentication: None (oeffentliche API)
3. Outbound Service Definition (ABAP)
" Service Consumption Model (ABAP)
@EndUserText.label: 'QR Code Service'
define service ZS_QR_CODE_SERVICE {
expose zcl_qr_code_generator as QRCodeGenerator;
}

Barcode Generierung (Code128)

Code128 ist ein weit verbreiteter 1D-Barcode fuer Logistik und Versand:

Algorithmus fuer Code128

CLASS zcl_code128_generator DEFINITION
PUBLIC
FINAL
CREATE PUBLIC.
PUBLIC SECTION.
TYPES: BEGIN OF ty_barcode_result,
barcode_string TYPE string,
check_digit TYPE i,
success TYPE abap_bool,
message TYPE string,
END OF ty_barcode_result.
METHODS generate_code128b
IMPORTING
iv_data TYPE string
RETURNING
VALUE(rs_result) TYPE ty_barcode_result.
METHODS generate_barcode_image
IMPORTING
iv_data TYPE string
iv_width TYPE i DEFAULT 300
iv_height TYPE i DEFAULT 100
RETURNING
VALUE(rv_base64) TYPE string.
PRIVATE SECTION.
CONSTANTS: BEGIN OF gc_code128b,
start_code TYPE i VALUE 104,
stop_code TYPE i VALUE 106,
END OF gc_code128b.
CLASS-DATA: gt_code128_patterns TYPE STANDARD TABLE OF string WITH EMPTY KEY.
CLASS-METHODS class_constructor.
METHODS calculate_check_digit
IMPORTING
iv_data TYPE string
RETURNING
VALUE(rv_checksum) TYPE i.
ENDCLASS.
CLASS zcl_code128_generator IMPLEMENTATION.
METHOD class_constructor.
" Code128 Barcode-Muster initialisieren
" Jedes Muster besteht aus 6 Balken/Luecken
gt_code128_patterns = VALUE #(
( |11011001100| ) " 0
( |11001101100| ) " 1
( |11001100110| ) " 2
" ... weitere Muster
).
ENDMETHOD.
METHOD generate_code128b.
DATA: lv_checksum TYPE i,
lv_index TYPE i.
" Validierung
IF strlen( iv_data ) = 0.
rs_result-success = abap_false.
rs_result-message = 'Keine Daten angegeben'.
RETURN.
ENDIF.
" Pruefsumme berechnen
lv_checksum = calculate_check_digit( iv_data ).
rs_result-check_digit = lv_checksum.
rs_result-success = abap_true.
" Barcode-String zusammenbauen (vereinfacht)
rs_result-barcode_string = |{ gc_code128b-start_code }|.
DO strlen( iv_data ) TIMES.
lv_index = sy-index - 1.
rs_result-barcode_string = rs_result-barcode_string &&
cl_abap_conv_codepage=>convert_to(
source = substring( val = iv_data off = lv_index len = 1 )
).
ENDDO.
rs_result-barcode_string = rs_result-barcode_string &&
|{ lv_checksum }{ gc_code128b-stop_code }|.
ENDMETHOD.
METHOD calculate_check_digit.
DATA: lv_sum TYPE i,
lv_char TYPE c LENGTH 1,
lv_value TYPE i.
" Start mit Start-Code
lv_sum = gc_code128b-start_code.
" Jeden Buchstaben gewichtet addieren
DO strlen( iv_data ) TIMES.
lv_char = iv_data+( sy-index - 1 )(1).
" ASCII-Wert - 32 ergibt Code128B-Wert
lv_value = cl_abap_conv_codepage=>convert_to(
source = CONV string( lv_char )
)-1 - 32.
lv_sum = lv_sum + ( lv_value * sy-index ).
ENDDO.
" Modulo 103
rv_checksum = lv_sum MOD 103.
ENDMETHOD.
METHOD generate_barcode_image.
" Fuer Bildgenerierung externen Service nutzen
DATA(lo_qr_gen) = NEW zcl_qr_code_generator( ).
" Barcode-Service URL (Beispiel mit barcodeapi.org)
DATA(lv_url) = |https://barcodeapi.org/api/128/{ cl_web_utility=>escape_url( iv_data ) }|.
TRY.
DATA(lo_client) = cl_web_http_client_manager=>create_by_http_destination(
i_destination = cl_http_destination_provider=>create_by_url( lv_url )
).
DATA(lo_response) = lo_client->execute( if_web_http_client=>get ).
IF lo_response->get_status( )-code = 200.
rv_base64 = cl_web_utility=>encode_base64(
lo_response->get_binary( )
).
ENDIF.
lo_client->close( ).
CATCH cx_root.
CLEAR rv_base64.
ENDTRY.
ENDMETHOD.
ENDCLASS.

Integration in PDF-Dokumente

Barcodes werden haeufig in PDFs wie Lieferscheinen oder Rechnungen benoetigt:

XSL-FO Template mit eingebettetem Barcode

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:template match="/">
<fo:root>
<fo:layout-master-set>
<fo:simple-page-master master-name="delivery-note"
page-height="297mm" page-width="210mm"
margin-top="20mm" margin-bottom="20mm"
margin-left="20mm" margin-right="20mm">
<fo:region-body/>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="delivery-note">
<fo:flow flow-name="xsl-region-body">
<!-- Kopfbereich mit Barcode -->
<fo:block-container position="absolute" top="0mm" right="0mm">
<fo:block>
<!-- Barcode als Base64-Bild -->
<fo:external-graphic
src="url('data:image/png;base64,{/document/barcode_image}')"
content-height="15mm"
scaling="uniform"/>
</fo:block>
<fo:block font-size="8pt" text-align="center">
<xsl:value-of select="/document/delivery_number"/>
</fo:block>
</fo:block-container>
<!-- QR-Code fuer Tracking-URL -->
<fo:block-container position="absolute" top="50mm" right="0mm">
<fo:block>
<fo:external-graphic
src="url('data:image/png;base64,{/document/qr_code_image}')"
content-height="25mm"
scaling="uniform"/>
</fo:block>
<fo:block font-size="7pt" text-align="center">
Scan fuer Tracking
</fo:block>
</fo:block-container>
<!-- Dokumentinhalt -->
<fo:block font-size="18pt" font-weight="bold" margin-bottom="10mm">
Lieferschein
</fo:block>
<!-- Weitere Inhalte... -->
</fo:flow>
</fo:page-sequence>
</fo:root>
</xsl:stylesheet>

PDF-Generierung mit Barcode

CLASS zcl_delivery_note_pdf DEFINITION
PUBLIC
FINAL
CREATE PUBLIC.
PUBLIC SECTION.
METHODS generate_delivery_note
IMPORTING
is_delivery TYPE zdelivery_data
RETURNING
VALUE(rv_pdf) TYPE xstring
RAISING
cx_transformation_error.
PRIVATE SECTION.
METHODS prepare_xml_data
IMPORTING
is_delivery TYPE zdelivery_data
RETURNING
VALUE(rv_xml) TYPE string.
METHODS add_barcode_images
IMPORTING
is_delivery TYPE zdelivery_data
EXPORTING
ev_barcode_b64 TYPE string
ev_qrcode_b64 TYPE string.
ENDCLASS.
CLASS zcl_delivery_note_pdf IMPLEMENTATION.
METHOD generate_delivery_note.
DATA: lv_xml TYPE string,
lv_barcode_b64 TYPE string,
lv_qrcode_b64 TYPE string,
lv_xslfo TYPE string,
lv_pdf TYPE xstring.
" Barcodes generieren
add_barcode_images(
EXPORTING
is_delivery = is_delivery
IMPORTING
ev_barcode_b64 = lv_barcode_b64
ev_qrcode_b64 = lv_qrcode_b64
).
" XML-Daten vorbereiten
lv_xml = prepare_xml_data( is_delivery ).
" Barcode-Bilder in XML einsetzen
REPLACE ALL OCCURRENCES OF '{BARCODE_IMAGE}' IN lv_xml
WITH lv_barcode_b64.
REPLACE ALL OCCURRENCES OF '{QRCODE_IMAGE}' IN lv_xml
WITH lv_qrcode_b64.
" XSL-FO Transformation
CALL TRANSFORMATION z_delivery_note_xslfo
SOURCE XML lv_xml
RESULT XML lv_xslfo.
" XSL-FO zu PDF konvertieren
" (erfordert FOP-Service oder externen PDF-Renderer)
rv_pdf = zcl_pdf_renderer=>render_xslfo( lv_xslfo ).
ENDMETHOD.
METHOD add_barcode_images.
DATA(lo_barcode_gen) = NEW zcl_code128_generator( ).
DATA(lo_qr_gen) = NEW zcl_qr_code_generator( ).
" Code128 Barcode fuer Lieferscheinnummer
ev_barcode_b64 = lo_barcode_gen->generate_barcode_image(
iv_data = is_delivery-delivery_number
iv_width = 300
iv_height = 80
).
" QR-Code mit Tracking-URL
DATA(lv_tracking_url) = |https://tracking.example.com/{ is_delivery-delivery_number }|.
DATA(ls_qr_result) = lo_qr_gen->generate_qr_code(
iv_content = lv_tracking_url
iv_size = 200
).
IF ls_qr_result-success = abap_true.
ev_qrcode_b64 = ls_qr_result-image_base64.
ENDIF.
ENDMETHOD.
METHOD prepare_xml_data.
" XML-Struktur fuer das PDF aufbauen
rv_xml = |<?xml version="1.0" encoding="UTF-8"?>| &&
|<document>| &&
| <delivery_number>{ is_delivery-delivery_number }</delivery_number>| &&
| <customer_name>{ is_delivery-customer_name }</customer_name>| &&
| <barcode_image>{BARCODE_IMAGE}</barcode_image>| &&
| <qr_code_image>{QRCODE_IMAGE}</qr_code_image>| &&
| <items>|.
LOOP AT is_delivery-items INTO DATA(ls_item).
rv_xml = rv_xml &&
| <item>| &&
| <material>{ ls_item-material }</material>| &&
| <quantity>{ ls_item-quantity }</quantity>| &&
| </item>|.
ENDLOOP.
rv_xml = rv_xml &&
| </items>| &&
|</document>|.
ENDMETHOD.
ENDCLASS.

Anzeige in Fiori App

Fuer die Anzeige von Barcodes in Fiori Apps gibt es zwei Ansaetze:

Backend-generierte Bilder

Der Barcode wird im Backend generiert und als Base64-String zum Frontend gesendet:

" RAP Action fuer Barcode-Generierung
managed implementation in class zbp_i_product unique;
strict ( 2 );
define behavior for ZI_Product alias Product
{
// Action zum Generieren des Produkt-Barcodes
action generateBarcode result [1] $self;
// Virtuelles Feld fuer Barcode-Bild
field ( readonly ) BarcodeImage;
}
CLASS zbp_i_product DEFINITION LOCAL.
PRIVATE SECTION.
METHODS generateBarcode FOR MODIFY
IMPORTING keys FOR ACTION Product~generateBarcode RESULT result.
ENDCLASS.
CLASS zbp_i_product IMPLEMENTATION.
METHOD generateBarcode.
" Produkte lesen
READ ENTITIES OF zi_product IN LOCAL MODE
ENTITY Product
FIELDS ( ProductId ProductName )
WITH CORRESPONDING #( keys )
RESULT DATA(lt_products).
LOOP AT lt_products ASSIGNING FIELD-SYMBOL(<ls_product>).
" Barcode generieren
DATA(lo_barcode) = NEW zcl_code128_generator( ).
DATA(lv_barcode_b64) = lo_barcode->generate_barcode_image(
iv_data = CONV string( <ls_product>-ProductId )
).
" Produkt mit Barcode-Bild aktualisieren
MODIFY ENTITIES OF zi_product IN LOCAL MODE
ENTITY Product
UPDATE FIELDS ( BarcodeImage )
WITH VALUE #( (
%tky = <ls_product>-%tky
BarcodeImage = lv_barcode_b64
) ).
ENDLOOP.
" Ergebnis zurueckgeben
READ ENTITIES OF zi_product IN LOCAL MODE
ENTITY Product
ALL FIELDS
WITH CORRESPONDING #( keys )
RESULT DATA(lt_result).
result = VALUE #( FOR ls_prod IN lt_result (
%tky = ls_prod-%tky
%param = ls_prod
) ).
ENDMETHOD.
ENDCLASS.

CDS View mit Barcode-Feld

@EndUserText.label: 'Produkt mit Barcode'
@Metadata.allowExtensions: true
define view entity ZC_Product
as projection on ZI_Product
{
@UI: {
lineItem: [{ position: 10 }],
identification: [{ position: 10 }]
}
key ProductId,
@UI: {
lineItem: [{ position: 20 }],
identification: [{ position: 20 }]
}
ProductName,
@UI: {
identification: [{
position: 30,
label: 'Barcode'
}]
}
@UI.dataPoint: {
visualization: #STANDARD
}
@Semantics.imageUrl: true
BarcodeImageUrl,
@UI.hidden: true
BarcodeImage
}

Berechnung der Barcode-URL

define view entity ZI_Product
as select from zproduct
{
key product_id as ProductId,
product_name as ProductName,
-- URL fuer Barcode-API
concat(
'https://barcodeapi.org/api/128/',
product_id
) as BarcodeImageUrl,
-- Placeholder fuer generiertes Bild
cast( '' as abap.string ) as BarcodeImage
}

Externe Services vs. ABAP-native Loesungen

Vergleich der Ansaetze

KriteriumExterne ServicesABAP-native
Setup-AufwandGeringHoch
Unterstuetzte FormateVieleBegrenzt
PerformanceNetzwerklatenzSchnell
Offline-FaehigkeitNeinJa
KostenGgf. API-KostenKeine
WartungBeim AnbieterEigenverantwortlich

Empfehlung nach Anwendungsfall

┌─────────────────────────────────────────────────────────────────────┐
│ Entscheidungsbaum │
│ │
│ Benoetigst du viele Barcode-Formate? │
│ │ │
│ ├── Ja ──► Externer Service (z.B. barcodeapi.org) │
│ │ │
│ └── Nein │
│ │ │
│ └── Ist Offline-Faehigkeit wichtig? │
│ │ │
│ ├── Ja ──► ABAP-native Implementierung │
│ │ │
│ └── Nein │
│ │ │
│ └── Hohe Volumina (>1000/Minute)? │
│ │ │
│ ├── Ja ──► ABAP-native oder Self-hosted │
│ │ │
│ └── Nein ──► Externer Service │
└─────────────────────────────────────────────────────────────────────┘

Beliebte externe Barcode-APIs

ServiceURLKostenmodell
goQR.meapi.qrserver.comKostenlos
Barcode APIbarcodeapi.orgKostenlos
Zxingzxing.orgOpen Source
QRCode Monkeyqrcode-monkey.comFreemium

Best Practices

Performance-Optimierung

" Barcode-Generierung cachen
CLASS zcl_barcode_cache DEFINITION
PUBLIC
FINAL
CREATE PRIVATE.
PUBLIC SECTION.
CLASS-METHODS get_instance
RETURNING
VALUE(ro_instance) TYPE REF TO zcl_barcode_cache.
METHODS get_barcode
IMPORTING
iv_content TYPE string
iv_type TYPE string DEFAULT 'QR'
RETURNING
VALUE(rv_base64) TYPE string.
PRIVATE SECTION.
CLASS-DATA: go_instance TYPE REF TO zcl_barcode_cache.
TYPES: BEGIN OF ty_cache_entry,
content TYPE string,
type TYPE string,
image TYPE string,
created TYPE timestamp,
END OF ty_cache_entry.
DATA: mt_cache TYPE HASHED TABLE OF ty_cache_entry
WITH UNIQUE KEY content type.
CONSTANTS: gc_cache_ttl_sec TYPE i VALUE 3600. " 1 Stunde
ENDCLASS.
CLASS zcl_barcode_cache IMPLEMENTATION.
METHOD get_instance.
IF go_instance IS NOT BOUND.
go_instance = NEW #( ).
ENDIF.
ro_instance = go_instance.
ENDMETHOD.
METHOD get_barcode.
DATA: ls_cache TYPE ty_cache_entry,
lv_now TYPE timestamp.
GET TIME STAMP FIELD lv_now.
" Im Cache suchen
READ TABLE mt_cache INTO ls_cache
WITH KEY content = iv_content
type = iv_type.
IF sy-subrc = 0.
" Pruefen ob noch gueltig
IF lv_now - ls_cache-created < gc_cache_ttl_sec.
rv_base64 = ls_cache-image.
RETURN.
ELSE.
" Abgelaufen - aus Cache entfernen
DELETE mt_cache WHERE content = iv_content AND type = iv_type.
ENDIF.
ENDIF.
" Neu generieren
CASE iv_type.
WHEN 'QR'.
DATA(lo_qr) = NEW zcl_qr_code_generator( ).
DATA(ls_result) = lo_qr->generate_qr_code( iv_content ).
IF ls_result-success = abap_true.
rv_base64 = ls_result-image_base64.
ENDIF.
WHEN 'CODE128'.
DATA(lo_barcode) = NEW zcl_code128_generator( ).
rv_base64 = lo_barcode->generate_barcode_image( iv_content ).
ENDCASE.
" In Cache speichern
IF rv_base64 IS NOT INITIAL.
INSERT VALUE #(
content = iv_content
type = iv_type
image = rv_base64
created = lv_now
) INTO TABLE mt_cache.
ENDIF.
ENDMETHOD.
ENDCLASS.

Fehlerbehandlung

" Robuste Barcode-Generierung mit Fallback
METHODS generate_with_fallback
IMPORTING
iv_content TYPE string
RETURNING
VALUE(rv_base64) TYPE string.
METHOD generate_with_fallback.
" Primaerer Service versuchen
TRY.
DATA(lo_qr) = NEW zcl_qr_code_generator( ).
DATA(ls_result) = lo_qr->generate_qr_code( iv_content ).
IF ls_result-success = abap_true.
rv_base64 = ls_result-image_base64.
RETURN.
ENDIF.
CATCH cx_root INTO DATA(lx_error).
" Fehler loggen
zcl_logger=>log_error(
iv_message = |QR-Generierung fehlgeschlagen: { lx_error->get_text( ) }|
).
ENDTRY.
" Fallback: Alternativer Service
TRY.
rv_base64 = zcl_barcode_fallback=>generate( iv_content ).
CATCH cx_root.
" Letzter Fallback: Platzhalter-Bild
rv_base64 = zcl_barcode_fallback=>get_placeholder( ).
ENDTRY.
ENDMETHOD.

Zusammenfassung

AspektEmpfehlung
QR-CodesExterne API (goQR.me) fuer einfache Integration
1D-BarcodesExterne API oder ABAP-native fuer Code128
PDF-IntegrationBase64-kodierte Bilder in XSL-FO
Fiori-AnzeigeBackend-Generierung mit @Semantics.imageUrl
PerformanceCaching bei wiederholten Aufrufen
FehlertoleranzFallback-Mechanismen implementieren

Die Wahl zwischen externen Services und ABAP-nativen Loesungen haengt von deinen Anforderungen ab. Fuer die meisten Anwendungsfaelle bieten externe APIs die beste Balance aus Funktionalitaet und Implementierungsaufwand.

Verwandte Themen