[ABAP] CONVERT_OTF: OTF-Format als PDF speichern und anzeigen (Beispiel Smart Forms-Formular)

* https://www.tutorialspoint.com/sap_smart_forms/
* https://www.berater-wiki.de/Smart_Forms_Generierter_Funktionsbaustein
* https://mind-forms.de/sap-formulartechnologien/sapscript/sapscript-formulare-in-pdf-umwandeln/

* Tabelle STXFADM

PARAMETERS: p_form TYPE stxfadm-formname DEFAULT 'SF_EXAMPLE_01'.
PARAMETERS: p_open TYPE abap_bool DEFAULT abap_true.

START-OF-SELECTION.
  DATA(lv_control_parameters) = VALUE ssfctrlop( no_dialog = abap_true
                                                 preview   = space
                                                 getotf    = abap_true
                                                 langu     = sy-langu ).

  DATA: lv_devtype TYPE rspoptype.

* Smart Forms: Gerätetyp nach Sprache ermitteln
  CALL FUNCTION 'SSF_GET_DEVICE_TYPE'
    EXPORTING
      i_language             = lv_control_parameters-langu
    IMPORTING
      e_devtype              = lv_devtype
    EXCEPTIONS
      no_language            = 1
      language_not_installed = 2
      no_devtype_found       = 3
      system_error           = 4
      OTHERS                 = 5.

  IF sy-subrc = 0.
    DATA(lv_output_options) = VALUE ssfcompop( tddest    = 'LOCL'
                                               tdprinter = lv_devtype ).

* FuBa Name ermitteln
    DATA: lv_fm_name TYPE rs38l_fnam.

* Smart Forms: Name des Funktionsbausteins bestimmen
    CALL FUNCTION 'SSF_FUNCTION_MODULE_NAME'
      EXPORTING
        formname           = p_form
      IMPORTING
        fm_name            = lv_fm_name
      EXCEPTIONS
        no_form            = 1
        no_function_module = 2
        OTHERS             = 3.

    IF sy-subrc = 0.

      DATA: lv_document_output_info TYPE ssfcrespd.
      DATA: lv_job_output_info TYPE ssfcrescl.
      DATA: lv_job_output_options TYPE ssfcresop.

* Zusatzparameter für Fuba für Formular 'SF_EXAMPLE_01'
      DATA: lv_customer TYPE scustom.
      DATA: it_bookings TYPE ty_bookings.
      DATA: it_connections TYPE ty_connections.

* FuBa der Form aufrufen und OTF-Daten erzeugen
      CALL FUNCTION lv_fm_name
        EXPORTING
          control_parameters   = lv_control_parameters
          output_options       = lv_output_options
          user_settings        = space
          customer             = lv_customer
          bookings             = it_bookings
          connections          = it_connections
        IMPORTING
          document_output_info = lv_document_output_info
          job_output_info      = lv_job_output_info
          job_output_options   = lv_job_output_options
        EXCEPTIONS
          formatting_error     = 1
          internal_error       = 2
          send_error           = 3
          user_canceled        = 4
          OTHERS               = 5.

      IF sy-subrc = 0.

        DATA(lv_bin_filesize) = 0.

        DATA: lv_pdf_xstring TYPE xstring.
        DATA: it_lines TYPE tline_t.

* Konvertieren von OTF-Format in verschiedene Formate (TLINE Tabelle)
        CALL FUNCTION 'CONVERT_OTF'
          EXPORTING
            format                = 'PDF' " ASCII, PDF
          IMPORTING
            bin_filesize          = lv_bin_filesize
*           bin_file              = lv_pdf_xstring             " PDF Binärdaten -> einkommentieren, wenn benötigt, sonst it_lines leer!
          TABLES
            otf                   = lv_job_output_info-otfdata " Input OTF
            lines                 = it_lines                   " Output
          EXCEPTIONS
            err_max_linewidth     = 1
            err_format            = 2
            err_conv_not_possible = 3
            err_bad_otf           = 4
            OTHERS                = 5.

        IF sy-subrc = 0.

          DATA: lv_action TYPE i.
          DATA: lv_filename TYPE string.
          DATA: lv_fullpath TYPE string.
          DATA: lv_path TYPE string.

          TRY.
* Speichern-Dialog
              cl_gui_frontend_services=>file_save_dialog( EXPORTING
                                                            default_file_name = |{ p_form }.pdf|
                                                            default_extension = 'pdf'
                                                            file_filter       = '(*.pdf)|*.pdf|'
                                                          CHANGING
                                                            filename          = lv_filename
                                                            path              = lv_path
                                                            fullpath          = lv_fullpath
                                                            user_action       = lv_action ).

              IF lv_action EQ cl_gui_frontend_services=>action_ok.
* Daten lokal speichern
                cl_gui_frontend_services=>gui_download( EXPORTING
                                                          bin_filesize = lv_bin_filesize
                                                          filename     = lv_fullpath
                                                          filetype     = 'BIN'
                                                        CHANGING
                                                          data_tab     = it_lines ).

                WRITE: / |Datei erfolgreich unter { lv_fullpath } gespeichert.|.

                IF abap_true = p_open.
* Datei anzeigen
                  cl_gui_frontend_services=>execute( document = lv_fullpath ).
                ENDIF.
              ENDIF.

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

        DATA: it_sf_errors TYPE tsferror.

* Smart Forms: Lesen der Fehlertabelle nach Aufruf
        CALL FUNCTION 'SSF_READ_ERRORS'
          IMPORTING
            errortab = it_sf_errors.

        cl_demo_output=>display( it_sf_errors ).
      ENDIF.

    ELSE.
      MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
    ENDIF.

  ELSE.
    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  ENDIF.