[ABAP] Excel-Datei (*.xlsx) in interne Tabelle laden (cl_fdt_xl_spreadsheet)

* Mit Hilfe der Klasse cl_fdt_xl_spreadsheet können über XML-Transformationen
* aus XLSX-Dateien Daten extrahiert und in eine interne Tabelle konvertiert werden
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 = |xlsx (*.xlsx)\|*.xlsx\|{ 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.
* ersten Tabelleneintrag lesen
        DATA: lv_filesize TYPE w3param-cont_len.
        DATA: lv_filetype TYPE w3param-cont_type.
        DATA: it_bin_data TYPE w3mimetabtype.

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

* solix -> xstring
        DATA(lv_bin_data) = cl_bcs_convert=>solix_to_xstring( it_solix = it_bin_data ).

* Excel (itab) -> XML -> Ref-Objekt
* Achtung: Speicherintensiv und rel. langsam! Es sollten keine großen Datenmengen verarbeitet werden.
        DATA(o_excel) = NEW cl_fdt_xl_spreadsheet( document_name = CONV #( it_files[ 1 ]-filename )
                                                   xdocument     = lv_bin_data ).

        DATA: it_worksheet_names TYPE if_fdt_doc_spreadsheet=>t_worksheet_names.

* Worksheetnamen ermitteln
        o_excel->if_fdt_doc_spreadsheet~get_worksheet_names( IMPORTING worksheet_names = it_worksheet_names ).

        IF lines( it_worksheet_names ) > 0.
* erste Worksheet -> REF to itab
          DATA(o_sheet_itab) = o_excel->if_fdt_doc_spreadsheet~get_itab_from_worksheet( it_worksheet_names[ 1 ] ).

          FIELD-SYMBOLS: <sheet> TYPE table.
          ASSIGN o_sheet_itab->* TO <sheet>.

          cl_demo_output=>write_data( <sheet> ).

* HTML-Daten aus itab generieren
          DATA(lv_html) = cl_demo_output=>get( ).

* Daten im Inline-Browser im SAP-Fenster anzeigen
          cl_abap_browser=>show_html( EXPORTING
                                        title        = 'Excel-Worksheet'
                                        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.

[ABAP] PDFs mittels Klasse CL_RSPO_PDF_MERGE zusammenfügen (mergen)

* benötigt KEIN ADS (Adobe Document Service)
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    = |pdf (*.pdf)\|*.pdf\|{ cl_gui_frontend_services=>filetype_all }|
                                                  multiselection = abap_true
                                                CHANGING
                                                  file_table  = it_files
                                                  rc          = lv_rc
                                                  user_action = lv_action ).

    IF lv_action = cl_gui_frontend_services=>action_ok.
* wenn mind. zwei Dateien ausgewählt worden sind
      IF lines( it_files ) > 1.
* PDF-Merge Objekt
        DATA(o_pdf_merger) = NEW cl_rspo_pdf_merge( ).

* Dateiliste durchgehen
        LOOP AT it_files ASSIGNING FIELD-SYMBOL(<f>).

          DATA(lv_filesize) = CONV w3param-cont_len( '0' ).
          DATA(it_bin_data) = VALUE w3mimetabtype( ).

* Datei auf Appl. Server hochladen (binary)
          cl_gui_frontend_services=>gui_upload( EXPORTING
                                                  filename   = |{ it_files[ sy-tabix ]-filename }|
                                                  filetype   = 'BIN'
                                                IMPORTING
                                                  filelength = lv_filesize
                                                CHANGING
                                                  data_tab   = it_bin_data ).

* solix -> xstring
          DATA(lv_bin_data) = cl_bcs_convert=>solix_to_xstring( it_solix = it_bin_data ).

* Binärdaten der PDF-Datei als xstring zum Merger-Objekt hinzufügen
          o_pdf_merger->add_document( lv_bin_data ).

          WRITE: / |Hinzugefügt: { it_files[ sy-tabix ]-filename } ({ lv_filesize } Bytes)|.
        ENDLOOP.

* PDF-Dokumente mergen
        o_pdf_merger->merge_documents( IMPORTING merged_document = DATA(lv_merged_pdf)
                                                 rc              = lv_rc ).

        IF lv_rc = 0.
          DATA: lv_filename TYPE string.
          DATA: lv_fullpath TYPE string.
          DATA: lv_path TYPE string.

* SaveDialog
          cl_gui_frontend_services=>file_save_dialog( EXPORTING
                                                        default_extension   = 'pdf'
                                                        default_file_name   = 'merged.pdf'
                                                        file_filter         = |pdf (*.pdf)\|*.pdf\|{ cl_gui_frontend_services=>filetype_all }|
                                                        prompt_on_overwrite = abap_true
                                                      CHANGING
                                                        filename          = lv_filename     " Dateiname
                                                        path              = lv_path         " Pfad
                                                        fullpath          = lv_fullpath     " Pfad + Dateiname
                                                        user_action       = lv_action ).    " Benutzeraktion

          IF lv_action EQ cl_gui_frontend_services=>action_ok.
* xstring -> solix
            DATA(it_bin_data_merged) = cl_bcs_convert=>xstring_to_solix( lv_merged_pdf ).

            DATA(lv_size_merged) = xstrlen( lv_merged_pdf ).

* Datei lokal speichern
            cl_gui_frontend_services=>gui_download( EXPORTING
                                                      filename                = lv_fullpath
                                                      filetype                = 'BIN'
                                                      bin_filesize            = lv_size_merged
                                                    CHANGING
                                                      data_tab                = it_bin_data_merged ).

            WRITE: / |Gespeichert: { lv_fullpath } ({ lv_size_merged } Bytes)|.

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

[ABAP] PDF-Dokument per ADS (Adobe Document Service) in XML konvertieren

* https://www.berater-wiki.de/XML_aus_PDF_extrahieren_mit_Testprogramm_FP_PDF_TEST_03
* http://sapfirst.blogspot.com/2014/05/inbound-abap-proxy-with-pdf-attachment.html
* Paket:     SAFP
* Programme: FP_PDF_TEST_01 (PDF erzeugen)
*            FP_PDF_TEST_03 (Datenextraktion)
* XFD (XML Form Data): https://www.berater-wiki.de/XFD-Datei_(Values_of_PDF_form_fields_in_XML)
* XFT (XML Form Template)
* XDC (XML Printer Definitions)

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    = |pdf (*.pdf)\|*.pdf\|{ 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 mind. zwei Dateien ausgewählt worden sind
      IF lines( it_files ) > 0.
        DATA(lv_filesize) = CONV w3param-cont_len( '0' ).
        DATA(it_bin_data) = VALUE w3mimetabtype( ).

* Datei auf Appl. Server hochladen (binary)
        cl_gui_frontend_services=>gui_upload( EXPORTING
                                                filename   = |{ it_files[ 1 ]-filename }|
                                                filetype   = 'BIN'
                                              IMPORTING
                                                filelength = lv_filesize
                                              CHANGING
                                                data_tab   = it_bin_data ).

* solix -> xstring
        DATA(lv_bin_data) = cl_bcs_convert=>solix_to_xstring( it_solix = it_bin_data ).

* Form Processor erzeugen
        DATA(o_form_processor) = cl_fp=>get_reference( ).
* PDF-Objekt erzeugen
        DATA(o_pdf) = o_form_processor->create_pdf_object( ).
* Binärdaten an PDF-Objekt übergeben
        o_pdf->set_document( pdfdata = lv_bin_data ).
* PDF-Daten extrahieren
        o_pdf->set_extractdata( ).
* ADS-Server rufen
        o_pdf->execute( ).
* extrahierte Daten holen (xstring)
        o_pdf->get_data( IMPORTING formdata = DATA(lv_pdf_formdata) ).

* xstring (binary) -> XML-string (UTF-8)
        DATA(lv_pdf_xml_str) = ||.
        DATA(o_conv) = cl_abap_conv_in_ce=>create( input    = lv_pdf_formdata
                                                   encoding = 'UTF-8' ).
        o_conv->read( IMPORTING data = lv_pdf_xml_str ).

* XML-Zugriff
        DATA(o_ixml) = cl_ixml=>create( ).

        DATA(o_sf) = o_ixml->create_stream_factory( ).
        DATA(o_doc) = o_ixml->create_document( ).
        DATA(o_stream) = o_sf->create_istream_string( lv_pdf_xml_str ).

* XML-Parser
        DATA(o_parser) = o_ixml->create_parser( stream_factory = o_sf
                                                istream        = o_stream
                                                document       = o_doc ).

* XML parsen
        IF o_parser->parse( ) = 0.

          DATA(o_root) = o_doc->get_root_element( ).

          ...

        ELSE.
* Fehlerauswertung
          DO o_parser->num_errors( ) TIMES.
            DATA(o_err) = o_parser->get_error( index = sy-index - 1 ).
            IF o_err IS BOUND.
              WRITE: / o_err->get_column( ), o_err->get_line( ), o_err->get_reason( ).
            ENDIF.
          ENDDO.
        ENDIF.

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

[ABAP] Mit Hilfe der Klasse cl_fxs_image_processor Infos zu einem Bild auslesen, Größe verändern (Resize) und Bildformat konvertieren (Convert)

* Im Beispiel wird das Eingabebild (PNG) nach JPG konvertiert und auf 800x600px in der Größe verändert

* Dateiname der Bilddatei zum hochladen
PARAMETERS: p_fname TYPE file_table-filename OBLIGATORY.
PARAMETERS: p_width TYPE i DEFAULT 800.
PARAMETERS: p_height TYPE i DEFAULT 600.

* wenn die F4-Hilfe für den Dateinamen aufgerufen wird
AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_fname.

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

* File-Tabelle leeren, da hier noch alte Einträge von vorherigen Aufrufen drin stehen können
  CLEAR it_files.

* FileOpen-Dialog aufrufen
  TRY.
      cl_gui_frontend_services=>file_open_dialog( EXPORTING
                                                    file_filter = |png (*.png)\|*.png\|{ 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.
* ersten Tabelleneintrag lesen
          p_fname = it_files[ 1 ]-filename.
        ENDIF.
      ENDIF.

    CATCH cx_root INTO DATA(e_text).
      MESSAGE e_text->get_text( ) TYPE 'S' DISPLAY LIKE 'E'.
  ENDTRY.

START-OF-SELECTION.

  TRY.
      DATA: lv_filesize TYPE w3param-cont_len.
      DATA: lv_filetype TYPE w3param-cont_type.
      DATA: it_bin_data TYPE w3mimetabtype.

      WRITE: / p_fname.

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

* solix -> xstring
      DATA(lv_img_data) = cl_bcs_convert=>solix_to_xstring( it_solix = it_bin_data ).

* FXS-Objekt holen
      DATA(o_ip) = NEW cl_fxs_image_processor( ).

* Bild zum Konverter hinzufügen
      DATA(lv_hndl) = o_ip->add_image( iv_data = lv_img_data ).

      DATA: lv_mimetype	TYPE string.
      DATA: lv_xres	TYPE i.
      DATA: lv_yres	TYPE i.
      DATA: lv_xdpi	TYPE i.
      DATA: lv_ydpi	TYPE i.
      DATA: lv_bitdepth	TYPE i.

* Infos holen
      o_ip->get_info( EXPORTING
                        iv_handle   = lv_hndl
                      IMPORTING
                        ev_mimetype = lv_mimetype
                        ev_xres     = lv_xres
                        ev_yres     = lv_yres
                        ev_xdpi     = lv_xdpi
                        ev_ydpi     = lv_ydpi
                        ev_bitdepth = lv_bitdepth ).

* Infos ausgeben
      WRITE: / 'MIME-Type:', lv_mimetype.
      WRITE: / '        X:', lv_xres.
      WRITE: / '        Y:', lv_yres.
      WRITE: / '    X-DPI:', lv_xdpi.
      WRITE: / '    Y-DPI:', lv_ydpi.
      WRITE: / '      Bit:', lv_bitdepth.

* Größe ändern (Resize)
      o_ip->resize( EXPORTING
                      iv_handle = lv_hndl
                      iv_xres   = p_width
                      iv_yres   = p_height ).

* Konvertierung (Convert) nach JPG
* Zielformate können nur sein (andernfalls gibt es eine Exception vom Typ cx_sy_range_out_of_bounds):
*   cl_fxs_mime_types=>co_image_bitmap
*   cl_fxs_mime_types=>co_image_png
*   cl_fxs_mime_types=>co_image_jpeg
      o_ip->convert( EXPORTING
                      iv_handle = lv_hndl
                      iv_format = cl_fxs_mime_types=>co_image_jpeg ).

* Infos holen
      o_ip->get_info( EXPORTING
                        iv_handle   = lv_hndl
                      IMPORTING
                        ev_mimetype = lv_mimetype
                        ev_xres     = lv_xres
                        ev_yres     = lv_yres
                        ev_xdpi     = lv_xdpi
                        ev_ydpi     = lv_ydpi
                        ev_bitdepth = lv_bitdepth ).

* Infos ausgeben
      WRITE: / 'MIME-Type:', lv_mimetype.
      WRITE: / '        X:', lv_xres.
      WRITE: / '        Y:', lv_yres.
      WRITE: / '    X-DPI:', lv_xdpi.
      WRITE: / '    Y-DPI:', lv_ydpi.
      WRITE: / '      Bit:', lv_bitdepth.

* Binärdaten (xstring) des Bildes holen
      DATA(lv_img_conv_data) = o_ip->get_image( EXPORTING iv_handle = lv_hndl ).

* xstring -> solix
      DATA(it_img_conv_data) = cl_bcs_convert=>xstring_to_solix( iv_xstring = lv_img_conv_data ).

      WRITE: / |{ p_fname }.jpg|.

* Image lokal speichern
      cl_gui_frontend_services=>gui_download( EXPORTING
                                                filename     = |{ p_fname }.jpg|
                                                filetype     = 'BIN'
                                                bin_filesize = xstrlen( lv_img_conv_data )
                                              CHANGING
                                                data_tab     = it_img_conv_data ).

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

[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).