[ABAP] Datei-Upload

Variante 1 (cl_gui_frontend_services)

DATA: lv_rc TYPE i.
DATA: it_files TYPE filetable.
DATA: lv_action TYPE i.

* FileOpen-Dialog aufrufen
TRY.
        cl_gui_frontend_services=>file_open_dialog( EXPORTING file_filter    = |pdf (*.pdf)\|*.pdf\|{ cl_gui_frontend_services=>filetype_all }|
                                                              multiselection = abap_false
                                                    CHANGING  file_table     = it_files
                                                              rc             = lv_rc
                                                              user_action    = lv_action ).

    IF lv_action = cl_gui_frontend_services=>action_ok.
* wenn Datei ausgewählt wurde
      IF lines( it_files ) > 0.
* ersten Tabelleneintrag lesen
        DATA(lv_filename) = it_files[ 1 ]-filename.

        DATA: lv_filesize TYPE i.
        DATA: it_bin_data TYPE STANDARD TABLE OF raw255.

* Bild auf Appl. Server hochladen (binary)
        cl_gui_frontend_services=>gui_upload( EXPORTING filename   = |{ lv_filename }|
														filetype   = 'BIN'
										      IMPORTING filelength = lv_filesize
										      CHANGING  data_tab   = it_bin_data ).														

        DATA: lv_xstr TYPE xstring.

* RAW (binary) nach xstring
        CALL FUNCTION 'SCMS_BINARY_TO_XSTRING'
          EXPORTING
            input_length = lv_filesize
          IMPORTING
            buffer       = lv_xstr
          TABLES
            binary_tab   = it_bin_data
          EXCEPTIONS
            failed       = 1
            OTHERS       = 2.

        ...
      ENDIF.
    ENDIF.

  CATCH cx_root INTO DATA(e_text).
    MESSAGE e_text->get_text( ) TYPE 'I'.
ENDTRY.

Variante 2 (cl_secxml_helper)

TRY.
    cl_secxml_helper=>file_f4( EXPORTING initial_directory = ''
                                         window_title      = 'Dateiauswahl'
                               IMPORTING filename          = DATA(lv_xfile) ).


    IF lv_xfile IS NOT INITIAL.
      cl_secxml_helper=>upload_file( EXPORTING filename = lv_xfile
                                     IMPORTING bindata  = DATA(lv_data_xstr) ).
      
      ...
    ENDIF.

  CATCH cx_root INTO DATA(e_txt).
    WRITE: / e_txt->get_text( ).
ENDTRY.

[ABAP] DMS: Dateien an Dokumenteninfosätze anhängen (CVAPI_DOC_CREATE)

TYPES: BEGIN OF bin_file,
         name TYPE string,
         size TYPE i,
         data TYPE solix_tab,
       END OF bin_file.

* Dokumentart (TA DC10, Tabelle TDWA)
PARAMETERS: p_type TYPE bapi_doc_aux-doctype OBLIGATORY.
* Teildokument
PARAMETERS: p_part TYPE bapi_doc_aux-docpart OBLIGATORY DEFAULT '000'.
* Dokumentversion
PARAMETERS: p_ver TYPE bapi_doc_aux-docversion OBLIGATORY DEFAULT '00'.
* Beschreibung
PARAMETERS: p_desc TYPE bapi_doc_drat-description DEFAULT 'Test 123'.
* Ablagekategorie (TA OACT, Tabelle SDOKSTCAE, View V_SDOKSTCA)
PARAMETERS: p_stor TYPE bapi_doc_files2-storagecategory OBLIGATORY.
* Logisches Dokument/Workstation Application (TA S_ALR_87008829, Tabelle TDWP, Bild -> JPG)
PARAMETERS: p_appl TYPE bapi_doc_files2-application_id OBLIGATORY DEFAULT 'JPG'.
* Objekttyp (Material -> MARA)
PARAMETERS: p_otype TYPE bapi_doc_drad-objecttype OBLIGATORY DEFAULT 'MARA'.
* Objektkey (Material -> MATNR)
PARAMETERS: p_okey TYPE bapi_doc_drad-objectkey OBLIGATORY DEFAULT '000000001122334455'.

START-OF-SELECTION.
  TRY.
      DATA: lv_rc TYPE i.
      DATA: it_files TYPE filetable.
      DATA: lv_action TYPE i.

* FileOpen-Dialog aufrufen
      cl_gui_frontend_services=>file_open_dialog( EXPORTING file_filter = |jpg (*.jpg)\|*.jpg\|{ cl_gui_frontend_services=>filetype_all }|
                                                  CHANGING  file_table  = it_files
                                                            rc          = lv_rc
                                                            user_action = lv_action ).

      IF lv_action = cl_gui_frontend_services=>action_ok.
* wenn Datei ausgewählt wurde
        IF lines( it_files ) > 0.
* Dateien auf den Appl.-Server hochladen
          DATA: lv_file TYPE bin_file.
          cl_gui_frontend_services=>gui_upload( EXPORTING filename   = CONV #( it_files[ 1 ]-filename )
                                                          filetype   = 'BIN'
                                                IMPORTING filelength = lv_file-size
                                                CHANGING  data_tab   = lv_file-data ).

          DATA: lv_xstring TYPE xstring.

* Datei binär zu xstring wandeln
          CALL FUNCTION 'SCMS_BINARY_TO_XSTRING'
            EXPORTING
              input_length = lv_file-size
            IMPORTING
              buffer       = lv_xstring
            TABLES
              binary_tab   = lv_file-data.

* Dokumentinformationssatz
          DATA(lv_draw) = VALUE draw(
                                      dokar = p_type
                                      doktl = p_part
                                      dokvr = p_ver
                                    ).

* DVS: Steuerung für APIS
          DATA(lv_api_control) = VALUE cvapi_api_control(
                                                            no_update_task = abap_true
                                                        ).

* Kurztexte für Dokuinfosätze
          DATA: it_drat TYPE STANDARD TABLE OF dms_db_drat WITH DEFAULT KEY.
          it_drat = VALUE #( (
                                langu = sy-langu
                                dktxt = p_desc
                             )
                           ).

* Verknüpfung Dokument-Objekt
          DATA: it_drad TYPE STANDARD TABLE OF dms_db_drad WITH DEFAULT KEY.

          it_drad = VALUE #( (
                               dokob = p_otype
                               objky = p_okey
                             )
                           ).

* Originale für Dokumente (Dateianhang)
          DATA: it_bin_content TYPE STANDARD TABLE OF drao WITH DEFAULT KEY.

          DATA: lv_data_length TYPE i.
          DATA: it_content_raw TYPE STANDARD TABLE OF orblk WITH DEFAULT KEY.

* xstring --> ORBLK (Binärformat mit Zeilenlänge 2550 Bytes)
          CALL FUNCTION 'SCMS_XSTRING_TO_BINARY'
            EXPORTING
              buffer        = lv_xstring
            IMPORTING
              output_length = lv_data_length
            TABLES
              binary_tab    = it_content_raw.

* Datenaufbereitung
          LOOP AT it_content_raw ASSIGNING FIELD-SYMBOL(<raw>).

            APPEND VALUE #(
                            zaehl = sy-tabix
                            appnr = '1'
                            dokar = p_type
                            orln  = lv_data_length
*                            orbkl = 2550
                            orblk = <raw>
                          ) TO it_bin_content.
          ENDLOOP.

* DVS: Originale zu einem Dokument
          DATA: it_doc_files TYPE STANDARD TABLE OF cvapi_doc_file WITH DEFAULT KEY.

          it_doc_files = VALUE #( ( updateflag  = 'I'
                                    appnr       = '1'
                                    dappl       = p_appl
                                    filename    = it_files[ 1 ]-filename
                                    storage_cat = p_stor
                                    description = p_desc ) ).

          DATA(lv_message) = VALUE messages( ).
          DATA(lv_pfx_dokar) = VALUE draw-dokar( ).
          DATA(lv_pfx_doknr) = VALUE draw-doknr( ).
          DATA(lv_pfx_dokvr) = VALUE draw-dokvr( ).
          DATA(lv_pfx_doktl) = VALUE draw-doktl( ).

* DVS: Dokument anlegen
          CALL FUNCTION 'CVAPI_DOC_CREATE'
            EXPORTING
              ps_draw            = lv_draw
              ps_api_control     = lv_api_control
              pf_content_provide = 'TBL' " Binärdaten des Files als Tabelle übergeben
            IMPORTING
              psx_message        = lv_message
              pfx_dokar          = lv_pfx_dokar
              pfx_doknr          = lv_pfx_doknr
              pfx_dokvr          = lv_pfx_dokvr
              pfx_doktl          = lv_pfx_doktl
            TABLES
              pt_drad_x          = it_drad
              pt_drat_x          = it_drat
              pt_files_x         = it_doc_files
              pt_content         = it_bin_content.

          IF lv_message-msg_type CA 'EA'.
* Rollback bei Fehler
            CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
          ELSE.
* Daten verbuchen
            CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
              EXPORTING
                wait = abap_true.

            cl_demo_output=>write_data( lv_message ).
            cl_demo_output=>write_data( lv_pfx_dokar ).
            cl_demo_output=>write_data( lv_pfx_doknr ).
            cl_demo_output=>write_data( lv_pfx_dokvr ).
            cl_demo_output=>write_data( lv_pfx_doktl ).

* HTML-Code vom Demo-Output holen
            DATA(lv_html) = cl_demo_output=>get( ).

* Daten im Inline-Browser im SAP-Fenster anzeigen
            cl_abap_browser=>show_html( EXPORTING title       = 'CVAPI_DOC_CREATE'
                                                  html_string = lv_html
                                                  container   = cl_gui_container=>default_screen ).

* cl_gui_container=>default_screen erzwingen
            WRITE: space.
          ENDIF.
        ENDIF.
      ENDIF.
    CATCH cx_root INTO DATA(e_text).
      MESSAGE e_text->get_text( ) TYPE 'S' DISPLAY LIKE 'E'.
  ENDTRY.

[SAP] Archivobjekt anhand seiner ARC_DOC_ID lesen

* Archiv-ID aus Tabelle TOAAR
PARAMETERS: p_arc TYPE toaar-archiv_id.
* ARC_DOC_ID: Beispiel siehe Tabelle TOA01, TOA02, TOA03
PARAMETERS: p_docid TYPE saeardoid DEFAULT '41C0CC07B977349DE10000000A450668'.

START-OF-SELECTION.

  DATA: lv_toa0x TYPE toa01.

* Pr?fen, ob das Archivobjekt in der Tabelle TOA01, TOA02 oder TOA03 abgelegt ist
* Tabelle TOA01
  SELECT SINGLE *
    INTO @lv_toa0x
    FROM toa01
    WHERE arc_doc_id = @p_docid
      AND archiv_id  = @p_arc.

  IF sy-subrc <> 0.
* Tabelle TOA02
    SELECT SINGLE *
      INTO @lv_toa0x
      FROM toa02
      WHERE arc_doc_id = @p_docid
        AND archiv_id  = @p_arc.
  ENDIF.

  IF sy-subrc <> 0.
* Tabelle TOA03
    SELECT SINGLE *
      INTO @lv_toa0x
      FROM toa03
      WHERE arc_doc_id = @p_docid
        AND archiv_id  = @p_arc.
  ENDIF.

  IF sy-subrc = 0.

    WRITE: / lv_toa0x-sap_object.
    WRITE: / lv_toa0x-object_id.
    WRITE: / lv_toa0x-archiv_id.
    WRITE: / lv_toa0x-arc_doc_id.
    WRITE: / lv_toa0x-ar_object.
    WRITE: / lv_toa0x-ar_date.
    WRITE: / lv_toa0x-del_date.
    WRITE: / lv_toa0x-reserve.

    ULINE.

    DATA: lv_url TYPE swk_url.

* CMS:AO API Url für Dokumentzugriff
    CALL FUNCTION 'SCMS_AO_URL_READ'
      EXPORTING
        arc_id = p_arc
        doc_id = p_docid
      IMPORTING
        url    = lv_url
      EXCEPTIONS
        error  = 1
        OTHERS = 2.

    IF sy-subrc = 0.
* URL anzeigen, kann auch im cl_gui_html_viewer direkt angezeigt werden
      WRITE: / lv_url.
*      DATA(o_html) = new cl_gui_html_viewer( parent = cl_gui_container=>default_screen ).
*      o_html->show_url( lv_url ).
      ULINE.
    ELSE.
      WRITE: / 'URL-Error:', sy-subrc.
    ENDIF.

    DATA(lv_length) = 0.
    DATA: it_bin_data TYPE STANDARD TABLE OF tbl1024 WITH DEFAULT KEY.

    DATA: lv_status TYPE char64.
    DATA: lv_doc_type TYPE char64.
    DATA: lv_arch_date TYPE d.
    DATA: lv_arch_time TYPE t.
    DATA: lv_mimetype TYPE char64.
    DATA: it_scms_comps TYPE STANDARD TABLE OF scms_comps WITH DEFAULT KEY.
    DATA: it_scms_compsl TYPE STANDARD TABLE OF scms_compsl WITH DEFAULT KEY.

* Status des AO lesen
* CMS: AO API Statusabfrage
    CALL FUNCTION 'SCMS_AO_STATUS'
      EXPORTING
        arc_id       = p_arc
        doc_id       = p_docid
      IMPORTING
        status       = lv_status
        doc_type     = lv_doc_type
        arch_date    = lv_arch_date
        arch_time    = lv_arch_time
        mimetype     = lv_mimetype
      TABLES
        comps        = it_scms_comps
        compsl       = it_scms_compsl
      EXCEPTIONS
        error_http   = 1
        error_kernel = 2
        error_archiv = 3
        error_config = 4
        OTHERS       = 5.
    IF sy-subrc = 0.
      LOOP AT it_scms_comps ASSIGNING FIELD-SYMBOL(<c>).
        WRITE: / <c>-compid, <c>-mimetype, <c>-compsize, <c>-compdatec, <c>-comptimec, <c>-compdatem, <c>-comptimem, <c>-status.
      ENDLOOP.
    ELSE.
      WRITE: / 'Status-Error:', sy-subrc.
    ENDIF.

    ULINE.

* Bin?rdaten des AO lesen
* CMS: AO API Dokument bereitstellen Tabelle
    CALL FUNCTION 'SCMS_AO_TABLE_GET'
      EXPORTING
        arc_id       = p_arc
        doc_id       = p_docid
      IMPORTING
        length       = lv_length
      TABLES
        data         = it_bin_data
      EXCEPTIONS
        error_http   = 1
        error_archiv = 2
        error_kernel = 3
        error_config = 4
        OTHERS       = 5.

    IF sy-subrc = 0.
      DATA: lv_xstring TYPE xstring.

* Bin?rdaten in xstring konvertieren
      CALL FUNCTION 'SCMS_BINARY_TO_XSTRING'
        EXPORTING
          input_length = CONV i( lv_length )
        IMPORTING
          buffer       = lv_xstring
        TABLES
          binary_tab   = it_bin_data
        EXCEPTIONS
          failed       = 1
          OTHERS       = 2.

      IF sy-subrc = 0.
        ...
      ENDIF.
    ELSE.
      WRITE: / 'Error getting AO-data:', sy-subrc.
    ENDIF.
  ELSE.
    WRITE: / 'ARC_DOC_ID not found:', sy-subrc.
  ENDIF.

[ABAP] Archivobjekte lesen

* Archiv-ID aus Tabelle TOAAR
PARAMETERS: p_arc TYPE toaar-archiv_id.
* Dokumentart, in TOADV (SM30) gepflegt
PARAMETERS: p_aro TYPE toadv-ar_object DEFAULT 'SDOINVOICE'.
* Dateinamenerweiterung
PARAMETERS: p_dtype TYPE toaom-doc_type DEFAULT 'PDF'.
* SAP ArchiveLink: Objekt-Id (Objektidentifikator)
* SAP Objekt-Ident
* bei VBRK       - '0070000000                    0000000100'
* bei BUS1001006 - '0000000011000011111'
* Beispiele in TOA01, TOA02 oder TOA03
PARAMETERS: p_oid TYPE saeobjid DEFAULT '0070000000                    0000000100'.
* SAP ArchiveLink: Objekttyp des Business Objekts
* VBRK       - Kundeneinzelfaktura
* BUS1001006 - Standard Material
PARAMETERS: p_sobj TYPE tojtb-name DEFAULT 'VBRK'.

START-OF-SELECTION.

  DATA: it_connect_info TYPE STANDARD TABLE OF toav0 WITH DEFAULT KEY.

* Alle verkn?pften Archivobjekte zum Objekt anhand der Selektionskriterien ermitteln
* SAP ArchiveLink: Ermitteln von Ablage-Id und Dok.-Id zu Anwendungsobject
  CALL FUNCTION 'ARCHIV_CONNECTINFO_GET_META'
    EXPORTING
      archiv_id             = p_arc
      ar_object             = p_aro
      doc_type              = p_dtype
      object_id             = p_oid
      sap_object            = p_sobj
    TABLES
      connect_info          = it_connect_info
    EXCEPTIONS
      error_connectiontable = 1
      OTHERS                = 2.

  IF sy-subrc = 0.

* Liste der Verkn?fpungen durchgehen und Bin?rdaten aus Archiv holen
    LOOP AT it_connect_info ASSIGNING FIELD-SYMBOL(<ci>).

      WRITE: / <ci>-archiv_id, <ci>-sap_object, <ci>-object_id, <ci>-arc_doc_id, <ci>-reserve.

      DATA(lv_length) = 0.
      DATA: it_bin_data TYPE STANDARD TABLE OF tbl1024 WITH DEFAULT KEY.

      CLEAR: it_bin_data.

* Bin?rdaten des AO lesen
* CMS: AO API Dokument bereitstellen Tabelle
      CALL FUNCTION 'SCMS_AO_TABLE_GET'
        EXPORTING
          arc_id       = <ci>-archiv_id
          doc_id       = <ci>-arc_doc_id
        IMPORTING
          length       = lv_length
        TABLES
          data         = it_bin_data
        EXCEPTIONS
          error_http   = 1
          error_archiv = 2
          error_kernel = 3
          error_config = 4
          OTHERS       = 5.

      IF sy-subrc = 0.
        DATA: lv_xstring TYPE xstring.

* Bin?rdaten in xstring konvertieren
        CALL FUNCTION 'SCMS_BINARY_TO_XSTRING'
          EXPORTING
            input_length = CONV i( lv_length )
          IMPORTING
            buffer       = lv_xstring
          TABLES
            binary_tab   = it_bin_data
          EXCEPTIONS
            failed       = 1
            OTHERS       = 2.

        IF sy-subrc = 0.
          ...
        ENDIF.
      ELSE.
        WRITE: / 'Error:', sy-subrc.
      ENDIF.
    ENDLOOP.
  ELSE.
    WRITE: / 'Verbindungsdaten nicht gefunden:', sy-subrc.
  ENDIF.

[ABAP] SAP Gateway File-Download über DEFINE und GET_STREAM

SE80: DDIC-Typ anlegen “ZFILESTREAM”

Feldname    Name im Gateway   ABAP-Typ     Bemerkung
------------------------------------------------------------------------------------------------------------------
FILEKEY     FileKey           beliebig     eindeutige Referenz (Key) zur späteren Ermittelung der Datei im Backend
MIME_TYPE   MimeType          CHAR100      Platzhalter für MimeType der Datei
VALUE       Value             XSTRINGVAL   Platzhalter für Binärdaten

SEGW: neuer Entitätstyp zum Lesen der Datei

  • Name: “FileStream”, DDIC-Typ “ZFILESTREAM” importieren
Name      Schlüssel   EDM-Coretyp   Bezeichner        ABAP-Feldname
-------------------------------------------------------------------
FileKey   ja          Edm.String    FileId            FILEKEY
MimeType  nein        Edm.String    Mimetyp           MIME_TYPE
Value     nein        Edm.Binary    Media Ressource   VALUE
  • Haken bei Medium setzen

SE80: ZCL_…_MPC_EXT~DEFINE redefinieren

METHOD define.
  DATA: lo_entity   TYPE REF TO /iwbep/if_mgw_odata_entity_typ.
  DATA: lo_property TYPE REF TO /iwbep/if_mgw_odata_property.

* Aufruf Basisklasse
  super->define( ).

* Entität "FileStream" holen
  lo_entity = model->get_entity_type( iv_entity_name = zcl_..._mpc=>gc_filestream ).

  IF lo_entity IS BOUND.

* Feld für MimeType (==MIME_TYPE) als ContentType setzen
    lo_property = lo_entity->get_property( iv_property_name = 'MimeType' ).
    lo_property->set_as_content_type( ).

  ENDIF.
ENDMETHOD.

SE80: /IWBEP/IF_MGW_APPL_SRV_RUNTIME~GET_STREAM redefinieren

METHOD /iwbep/if_mgw_appl_srv_runtime~get_stream.
  DATA: lv_file        TYPE zcl_..._mpc=>ts_filestream.
  DATA: lv_stream      TYPE ty_s_media_resource.

* Welche Entität?
  CASE io_tech_request_context->get_entity_type_name( ).
    WHEN zcl_..._mpc=>gc_filestream.
* Schlüssel ("FILEKEY") ermitteln
      io_tech_request_context->get_converted_keys( IMPORTING es_key_values = lv_file ).

* gewünschte Binärdaten anhand des Schlüssels aus SAP lesen
      DATA: it_bin_data TYPE STANDARD TABLE OF raw255.
      
      it_bin_data = ...

* Dateinamen ermitteln        
      DATA: lv_filename TYPE skwf_filnm.
      
      lv_filename = ...

* Für die Umwandlung die Dateigröße der Binärdaten berechnen
      DATA(lv_size) = lines( it_bin_data ).
      DATA: lv_line LIKE LINE OF it_bin_data.
      DATA(lv_length) = 0.
* für Unicode-Kompatibilität IN BYTE MODE
      DESCRIBE FIELD lv_line LENGTH lv_length IN BYTE MODE.
      lv_size = lv_size * lv_length.

* Binärdaten in xstring für die Rückgabe konvertieren        
      CALL FUNCTION 'SCMS_BINARY_TO_XSTRING'
        EXPORTING
          input_length = lv_size
        IMPORTING
          buffer       = lv_stream-value
        TABLES
          binary_tab   = it_bin_data
        EXCEPTIONS
          failed       = 1
          OTHERS       = 2.

      IF sy-subrc = 0.        
* MIME-Typen der Datei ermitteln und an das Frontend übergeben
        DATA: lv_mimetype TYPE skwf_mime.
              
* aus Dateinamen den MIME-Typen ermitteln
        CALL FUNCTION 'SKWF_MIMETYPE_OF_FILE_GET'
          EXPORTING
            filename = lv_filename
          IMPORTING
            mimetype = lv_mimetype.
                
        lv_stream-mime_type = lv_mimetype.

* HTTP-Header-Infos setzen (Dateiname usw.)
        DATA(lv_lheader) = VALUE ihttpnvp( name  = 'Content-Disposition'
                                           value = |inline; filename="{ escape( val = lv_filename format = cl_abap_format=>e_url ) }";| ). " Datei im Tab inline (Plugin) öffnen
*                                           value = |outline; filename="{ escape( val = lv_filename format = cl_abap_format=>e_url ) }";| ). " Datei zum direkten Herunterladen / Öffnen anbieten

        set_header( is_header = lv_lheader ).

* alle Daten zum Frontend schicken
        me->copy_data_to_ref( EXPORTING is_data = lv_stream
                              CHANGING cr_data  = er_stream ).
      ENDIF.

    WHEN OTHERS.
* andere Entitäten standardmäßig behandeln
      super->/iwbep/if_mgw_appl_srv_runtime~get_stream(
        EXPORTING
          iv_entity_name          = iv_entity_name
          iv_entity_set_name      = iv_entity_set_name
          iv_source_name          = iv_source_name
          it_key_tab              = it_key_tab
          it_navigation_path      = it_navigation_path
          io_tech_request_context = io_tech_request_context
          IMPORTING
            er_stream             = er_stream
            es_response_context   = es_response_context ).
  ENDCASE.
ENDMETHOD.

Weiterführende Infos: SAP Fiori tricks: Get rid of $value in PDF display/downloads

[ABAP] MIME-Objekt aus dem Repository laden

* Objekt-ID des Mime-Objekts
DATA: lv_object_id TYPE char32 VALUE 'EE3ECB43B3E70B43E10000000A15509A'.

DATA: lv_desc TYPE skwf_desc.
DATA: lv_docname TYPE skwf_urlp.
DATA: lv_filename TYPE string.
DATA: lv_filesize TYPE i.
DATA: lv_mimetype TYPE mr_mimtype.
DATA: lv_langu TYPE sy-langu.

DATA: it_bin_data TYPE sdokcntbins. " RAW1022

DATA(lv_io) = VALUE skwf_io( objtype = 'L' " Unbestimmt (= alle), F Verzeichnis, L Loio, P Phio, R Relation
                             class = 'M_IMAGE_L'
                             objid = lv_object_id ).

* Sprachvorgabe
lv_langu = 'D'.

* MIME-Objekt laden
cl_wb_mime_repository=>load_mime( EXPORTING
                                    io              = lv_io
                                  IMPORTING
                                    docname         = lv_docname
                                    description     = lv_desc
                                    filename        = lv_filename
                                    filesize        = lv_filesize
                                    bin_data        = it_bin_data
                                    mimetype        = lv_mimetype
                                  CHANGING
                                    language        = lv_langu ).

WRITE: / lv_docname.
WRITE: / lv_desc.
WRITE: / lv_filename.
WRITE: / lv_filesize.
WRITE: / lv_mimetype.
WRITE: / lv_langu.

DATA: lv_xstr_line TYPE xstring.
DATA: lv_xstr_result TYPE xstring.

* RAW (binary) -> xstring
CALL FUNCTION 'SCMS_BINARY_TO_XSTRING'
  EXPORTING
    input_length = lv_filesize
  IMPORTING
    buffer       = lv_xstr_result
  TABLES
    binary_tab   = it_bin_data
  EXCEPTIONS
    failed       = 1
    OTHERS       = 2.

IF sy-subrc NE 0.
  MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.

[ABAP] RAW (binary) nach xstring wandeln

Variante 1 (SCMS_BINARY_TO_XSTRING)

DATA: it_bin_data TYPE STANDARD TABLE OF raw255. " iTab mit Binärdaten
DATA: lv_bytes TYPE i.                           " reale Länge der Daten in Bytes
DATA: lv_xstr_result TYPE xstring.

...

CALL FUNCTION 'SCMS_BINARY_TO_XSTRING'
  EXPORTING
    input_length = lv_bytes
  IMPORTING
    buffer       = lv_xstr_result
  TABLES
    binary_tab   = it_bin_data
  EXCEPTIONS
    failed       = 1
    OTHERS       = 2.

IF sy-subrc NE 0.
  MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.

Variante 2 (cl_swf_utl_convert_xstring)

DATA: lv_size TYPE i.
DATA: it_raw_data TYPE STANDARD TABLE OF raw255.

cl_gui_frontend_services=>gui_upload( EXPORTING
                                        filename     = 'c:\temp\binaryfile.dat'
                                        filetype     = 'BIN'
                                        read_by_line = space
                                      IMPORTING
                                        filelength   = lv_size
                                      CHANGING
                                        data_tab     = it_raw_data ).

DATA(lv_xlsx_str) = cl_swf_utl_convert_xstring=>table_to_xstring( i_table = it_raw_data
                                                                  i_size  = lv_size ).

Variante 3 (cl_scp_change_db)

DATA: lv_size TYPE i.
DATA: it_raw_data TYPE STANDARD TABLE OF raw255.
DATA: lv_xstr_result TYPE xstring.

cl_gui_frontend_services=>gui_upload( EXPORTING
                                        filename     = 'c:\temp\binaryfile.dat'
                                        filetype     = 'BIN'
                                        read_by_line = space
                                      IMPORTING
                                        filelength   = lv_size
                                      CHANGING
                                        data_tab     = it_raw_data ).
                                        
cl_scp_change_db=>xtab_to_xstr( EXPORTING
                                  im_xtab    = it_raw_data
                                  im_size    = lv_size
                                IMPORTING
                                  ex_xstring = lv_xstr_result ).

Variante 4 (cl_bcs_convert)

* solix -> xstring
DATA: lv_size TYPE i.
DATA: it_raw_data TYPE solix_tab.

cl_gui_frontend_services=>gui_upload( EXPORTING
                                        filename     = 'c:\temp\binaryfile.dat'
                                        filetype     = 'BIN'
                                        read_by_line = space
                                      IMPORTING
                                        filelength   = lv_size
                                      CHANGING
                                        data_tab     = it_raw_data ).

DATA(lv_xstr_result) = cl_bcs_convert=>solix_to_xstring( it_solix = it_raw_data ).

Variante 5 (cl_abap_conv_obj)

DATA: it_bin_data TYPE raw255. " iTab mit Binärdaten
DATA: lv_bytes TYPE i.         " reale Länge der Daten in Bytes

...

DATA: lv_xstr_line TYPE xstring.
DATA: lv_xstr_result TYPE xstring.

* RAW (binary) -> xstring
DATA(o_conv) = NEW cl_abap_conv_obj( ).

LOOP AT it_bin_data ASSIGNING FIELD-SYMBOL(<l>).
* Zeile konvertieren
  o_conv->convert( EXPORTING
                     inbuff = <l>
                     outbufflg = 65535 " max. Zeilenlänge in it_bin_data
                   IMPORTING
                     outbuff = lv_xstr_line ).

* Zeilen zusammenbauen
  CONCATENATE lv_xstr_result lv_xstr_line INTO lv_xstr_result IN BYTE MODE.
ENDLOOP.

* evtl. Rest von xstring abschneiden, für reale Länge der Daten
lv_xstr_result = lv_xstr_result(lv_bytes).

[ABAP] Beliebige Dateien zu einer Zipdatei hinzufügen

TYPES: BEGIN OF bin_file,                          " Typ für Binärdatei mit Meta-Infos für das Zipfile
         name TYPE string,
         size TYPE i,
         data TYPE solix_tab,
       END OF bin_file.

DATA: lv_filename TYPE string.                     " Dateiname für FileOpen/FileSave
DATA: wa_file TYPE bin_file.                       " Binärdatei mit Meta-Infos für das Zipfile
DATA: it_binfiles TYPE STANDARD TABLE OF bin_file. " unkomprimierter Stream (Tabelle mit Dateien zum Zippen)
DATA: lv_path TYPE string.

START-OF-SELECTION.
* ZIP-Objekt erzeugen
  DATA(o_zip) = NEW cl_abap_zip( ).

  DATA: it_sel_filetab TYPE filetable.
  DATA: ret_code TYPE i.
  DATA: lv_action TYPE i.
* FileOpen-Dialog für Dateiauswahl anzeigen
* Mehrfachselektion möglich
  cl_gui_frontend_services=>file_open_dialog( EXPORTING
                                                window_title   = 'Dateien zum Komprimieren auswählen'
                                                multiselection = abap_true
                                              CHANGING
                                                file_table     = it_sel_filetab
                                                rc             = ret_code    " Anzahl ausgewählte Dateien, -1 bei Fehler
                                                user_action    = lv_action ).

  IF lv_action = cl_gui_frontend_services=>action_ok.

* Ausgewählte Dateien durchgehen
    LOOP AT it_sel_filetab INTO DATA(wa_sel_file).

      WRITE: / |Datei hinzugefügt: { wa_sel_file-filename }|.

* Dateien auf den Appl.-Server hochladen
      cl_gui_frontend_services=>gui_upload( EXPORTING
                                              filename   = |{ wa_sel_file-filename }|
                                              filetype   = 'BIN'
                                            IMPORTING
                                              filelength = wa_file-size
                                            CHANGING
                                              data_tab   = wa_file-data ).

* Pfad + Dateinamen aufsplitten
      CALL FUNCTION 'SO_SPLIT_FILE_AND_PATH'
        EXPORTING
          full_name     = wa_sel_file-filename
        IMPORTING
          file_path     = lv_path
          stripped_name = wa_file-name
        EXCEPTIONS
          x_error       = 1
          OTHERS        = 2.

* Datei zum Stream hinzufügen
      APPEND wa_file TO it_binfiles.

    ENDLOOP.

    ULINE.

    DATA: lv_xstring TYPE xstring.
* unkomprimierte Daten zum Zip-File hinzufügen
    LOOP AT it_binfiles INTO wa_file.

* jeden Datei-Stream binär zu xstring wandeln
      CALL FUNCTION 'SCMS_BINARY_TO_XSTRING'
        EXPORTING
          input_length = wa_file-size
        IMPORTING
          buffer       = lv_xstring
        TABLES
          binary_tab   = wa_file-data.

      o_zip->add( name    = wa_file-name
                  content = lv_xstring ).

    ENDLOOP.

* Daten komprimieren
    DATA(lv_zip) = o_zip->save( ).

    DATA: lv_zip_size TYPE i.
    DATA: it_zip_bin_data TYPE STANDARD TABLE OF raw255.

* xstring mit Zip-Daten zu binär rückwandeln
    CALL FUNCTION 'SCMS_XSTRING_TO_BINARY'
      EXPORTING
        buffer        = lv_zip
      IMPORTING
        output_length = lv_zip_size
      TABLES
        binary_tab    = it_zip_bin_data.

    DATA: lv_dest_filepath TYPE string.

* SaveFile-Dialog aufrufen
    cl_gui_frontend_services=>file_save_dialog( EXPORTING
                                                  window_title         = 'Zipdatei speichern'
                                                  file_filter          = '(*.zip)|*.zip|'
                                                CHANGING
                                                  filename             = lv_filename
                                                  path                 = lv_path
                                                  fullpath             = lv_dest_filepath ).

* Zipdatei vom Appl-Server auf den lokalen Pfad speichern
    cl_gui_frontend_services=>gui_download( EXPORTING
                                              filename                = lv_dest_filepath
                                              filetype                = 'BIN'
                                              bin_filesize            = lv_zip_size
                                            CHANGING
                                              data_tab                = it_zip_bin_data ).

    IF sy-subrc <> 0.
      MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
    ELSE.
      WRITE: / |Zipdatei erfolgreich unter { lv_dest_filepath } gespeichert.|.
    ENDIF.
  ENDIF.