SAP 上传PDF文件进行传输

2023-10-13 15:03:45 浏览数 (2)

记录一次PDF文件在SAP系统内的转换(结尾附Restful接口调用) : 表结构如下:

源代码如下:

代码语言:javascript复制
*&---------------------------------------------------------------------*
*& Report ZPDF_DEMO.
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT zpdf_demo.

CLASS lcl_event_receiver DEFINITION.

  PUBLIC SECTION.
    METHODS:
      handle_button_click
        FOR EVENT button_click OF cl_gui_alv_grid
        IMPORTING es_col_id es_row_no.

ENDCLASS.

CLASS lcl_event_receiver IMPLEMENTATION.

  METHOD handle_button_click.
    PERFORM button_click USING es_col_id es_row_no.
  ENDMETHOD.

ENDCLASS.

CONSTANTS:gc_status  TYPE slis_formname VALUE 'FRM_STATUS',
          gc_command TYPE slis_formname VALUE 'FRM_COMMAND'.

DATA:BEGIN OF gs_data.
       :   INCLUDE TYPE zbct_app_pdf."定义结构
DATA:  icon      TYPE c LENGTH 10,
       box,
       cellstyle TYPE lvc_t_styl.     "单元格编辑
DATA:END OF gs_data,
  gt_data     LIKE TABLE OF gs_data,
  gv_file_cat TYPE zbct_app_pdf-file_cat VALUE 'HELP'.

DATA:gv_title TYPE text100. "标题
DATA:gs_lay TYPE lvc_s_layo.
DATA:gt_fieldcat TYPE lvc_t_fcat,
     gs_fieldcat TYPE lvc_s_fcat.
DATA:gt_event TYPE slis_t_event,
     gs_event LIKE LINE OF gt_event.
DATA:gs_sort_lvc TYPE lvc_s_sort,
     gt_sort_lvc TYPE lvc_t_sort.
DATA gv_grid TYPE REF TO cl_gui_alv_grid.
DATA gv_event_receiver TYPE REF TO lcl_event_receiver.

START-OF-SELECTION.
  PERFORM frm_data_get.    "数据读取

END-OF-SELECTION.
  PERFORM frm_alv_dis.     "alv展示

*&---------------------------------------------------------------------*
*& Form FRM_DATA_GET
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM frm_data_get.

  DATA:lv_stylerow TYPE lvc_s_styl,
       lv_icon     TYPE icons-text.

  SELECT *
    INTO CORRESPONDING FIELDS OF TABLE gt_data
    FROM zbct_app_pdf
   WHERE file_cat = gv_file_cat.

  " 创建按钮图标
  CALL FUNCTION 'ICON_CREATE'
    EXPORTING
      name                  = 'ICON_ICON_LIST'
      text                  = '展示'
      info                  = 'PDF展示'
      add_stdinf            = 'X'
    IMPORTING
      result                = lv_icon
    EXCEPTIONS
      icon_not_found        = 1
      outputfield_too_short = 2
      OTHERS                = 3.

  " 增加按钮
  LOOP AT gt_data INTO gs_data.
    lv_stylerow-fieldname = 'ICON'.
    lv_stylerow-style = cl_gui_alv_grid=>mc_style_button.
    APPEND lv_stylerow TO gs_data-cellstyle.
    gs_data-icon = lv_icon.
    MODIFY gt_data FROM gs_data.
  ENDLOOP.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_ALV_DIS
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM frm_alv_dis .

  PERFORM frm_layout_set.
  PERFORM frm_field_set .

  CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY_LVC'
    EXPORTING
      i_callback_program       = sy-repid
      i_callback_pf_status_set = gc_status
      i_callback_user_command  = gc_command
      is_layout_lvc            = gs_lay
      it_fieldcat_lvc          = gt_fieldcat[]
      it_sort_lvc              = gt_sort_lvc[]
      i_save                   = 'A'
      it_events                = gt_event
    TABLES
      t_outtab                 = gt_data[]
    EXCEPTIONS
      program_error            = 1
      OTHERS                   = 2.

  IF sy-subrc <> 0.
* IMPLEMENT SUITABLE ERROR HANDLING HERE
  ENDIF.

ENDFORM.
*&---------------------------------------------------------------------*
*& FORM FRM_LAYOUT_SET
*&---------------------------------------------------------------------*
*& TEXT
*&---------------------------------------------------------------------*
*& -->  P1        TEXT
*& <--  P2        TEXT
*&---------------------------------------------------------------------*
FORM frm_layout_set .

  gs_lay-cwidth_opt = abap_true.
  gs_lay-box_fname = 'BOX'.    "标识是否选中
  gs_lay-stylefname = 'CELLSTYLE'.  "单元格编辑

ENDFORM.
*&---------------------------------------------------------------------*
*& FORM FRM_FIELD_SET
*&---------------------------------------------------------------------*
*& TEXT
*&---------------------------------------------------------------------*
*& -->  P1        TEXT
*& <--  P2        TEXT
*&---------------------------------------------------------------------*
FORM frm_field_set.

  DATA:lv_event    LIKE LINE OF gt_event.

  " 增加按钮事件
  gs_event-name = 'CALLER_EXIT'.
  gs_event-form = 'FRM_BUTTON'.
  APPEND gs_event TO gt_event.

  " Fieldcat
  DEFINE add_field.
    CLEAR: gs_fieldcat.
    gs_fieldcat-fieldname = &1.
    gs_fieldcat-scrtext_l = &2.
    gs_fieldcat-outputlen   = &3.
    gs_fieldcat-ref_field = &4.
    gs_fieldcat-ref_table = &5.
    APPEND gs_fieldcat TO gt_fieldcat.
  end-of-definition.

  add_field: 'FILE_NAME'    '文件名'   '' '' '',
             'ICON'         'PDF展示'  '' '' '',
             'CREATED_DATE' '创建日期' '' '' '',
             'CREATED_TIME' '创建时间' '' '' '',
             'CREATED_USER' '创建用户' '' '' ''.

ENDFORM.
*&---------------------------------------------------------------------*
*& FORM FRM_STATUS
*&---------------------------------------------------------------------*
*& TEXT
*&---------------------------------------------------------------------*
*& -->  P1        TEXT
*& <--  P2        TEXT
*&---------------------------------------------------------------------*
FORM frm_status USING p_extab TYPE slis_t_extab.

  SET PF-STATUS 'ST1'."EXCLUDING lt_fcode.
  SET TITLEBAR 'TI1'.

ENDFORM.
*&---------------------------------------------------------------------*
*& FORM FRM_COMMAND
*&---------------------------------------------------------------------*
*& TEXT
*&---------------------------------------------------------------------*
*& -->  P1        TEXT
*& <--  P2        TEXT
*&---------------------------------------------------------------------*
FORM frm_command USING p_ucomm TYPE sy-ucomm
                       ps_selfield  TYPE slis_selfield.

  DATA: lo_grid TYPE REF TO cl_gui_alv_grid,
        lv_code LIKE sy-ucomm.

  lv_code = p_ucomm.
  CLEAR:p_ucomm.

  ps_selfield-refresh = 'X'.

  CASE lv_code.
    WHEN 'ADD'.                   " 新增PDF

      PERFORM frm_upload_file.
      PERFORM frm_data_get.        " 数据读取

    WHEN 'DEL'.                   " 删除PDF

      LOOP AT gt_data INTO gs_data WHERE box = 'X'.
        PERFORM frm_file_delete USING gs_data-guid.
      ENDLOOP.
      IF sy-subrc NE 0.
        MESSAGE '请选择行' TYPE 'S' DISPLAY LIKE 'E'.
        EXIT.
      ELSE.
        PERFORM frm_data_get.    "数据读取
      ENDIF.

  ENDCASE.

*刷新alv屏幕数据
  CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR'
    IMPORTING
      e_grid = lo_grid.
*  CALL METHOD lo_grid->refresh_table_display.

ENDFORM.
*&---------------------------------------------------------------------*
*& FORM FRM_BUTTON
*&---------------------------------------------------------------------*
*& TEXT
*&---------------------------------------------------------------------*
*& -->  P1        TEXT
*& <--  P2        TEXT
*&---------------------------------------------------------------------*
FORM frm_button USING e_grid TYPE slis_data_caller_exit.

  CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR'
    IMPORTING
      e_grid = gv_grid.

  CREATE OBJECT gv_event_receiver. " 创建按钮事件
  SET HANDLER gv_event_receiver->handle_button_click FOR gv_grid.

ENDFORM.
*&---------------------------------------------------------------------*
*& FORM BUTTON_CLICK
*&---------------------------------------------------------------------*
*& TEXT
*&---------------------------------------------------------------------*
*& -->  P1        TEXT
*& <--  P2        TEXT
*&---------------------------------------------------------------------*
FORM button_click USING p_col_id
                        p_row_no TYPE lvc_s_roid.

  READ TABLE gt_data INTO gs_data INDEX p_row_no-row_id.
  IF sy-subrc = 0.
    PERFORM frm_show_pdf USING gs_data-guid.
  ENDIF.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form frm_upload_file
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM frm_upload_file .

  DATA:ev_name         TYPE string,
       ct_filetable    TYPE filetable,
       cv_rc           TYPE i,
       ev_filetype     TYPE char10,
       cv_uact         TYPE i,
       iv_bin_filesize TYPE i,
       lt_datatab      TYPE TABLE OF ssfdata,
       iv_buffer       TYPE xstring,
       lt_app_pdf      TYPE TABLE OF zbct_app_pdf.

  ev_filetype = 'BIN'.
  CONCATENATE '*' '.pdf' INTO ev_name.

  " 打开pdf.
  CALL METHOD cl_gui_frontend_services=>file_open_dialog
    EXPORTING
      default_filename        = ev_name
    CHANGING
      file_table              = ct_filetable
      rc                      = cv_rc
      user_action             = cv_uact
    EXCEPTIONS
      file_open_dialog_failed = 1
      cntl_error              = 2
      error_no_gui            = 3.

  IF cv_uact = cl_gui_frontend_services=>action_cancel.
    EXIT.
  ENDIF.

  " 读取路径
  READ TABLE ct_filetable INDEX 1 INTO ev_name.
  CHECK sy-subrc = 0.

  " 文件名称
  SPLIT ev_name AT '' INTO TABLE DATA(lt_split).
  DATA(lv_line) = lines( lt_split ).
  READ TABLE lt_split INTO DATA(lv_split) INDEX lv_line.

  " 上载
  CALL FUNCTION 'GUI_UPLOAD'
    EXPORTING
      filename        = ev_name
      filetype        = ev_filetype
    IMPORTING
      filelength      = iv_bin_filesize
    TABLES
      data_tab        = lt_datatab
    EXCEPTIONS
      file_open_error = 1
      file_read_error = 2
      invalid_type    = 3
      no_batch        = 4
      OTHERS          = 5.

  IF sy-subrc <> 0.
    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
    LEAVE PROGRAM.
  ENDIF.

  " 转换为二进制
  CALL FUNCTION 'SCMS_BINARY_TO_XSTRING'
    EXPORTING
      input_length = iv_bin_filesize
    IMPORTING
      buffer       = iv_buffer
    TABLES
      binary_tab   = lt_datatab
    EXCEPTIONS
      failed       = 1
      OTHERS       = 2.

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

  TRY.
      CALL METHOD cl_system_uuid=>create_uuid_x16_static
        RECEIVING
          uuid = DATA(lv_guid). "唯一标识
    CATCH cx_uuid_error.
  ENDTRY.

  " 存表
  APPEND VALUE #( guid         = lv_guid
                  file_name    = lv_split
                  file_cat     = gv_file_cat
                  file_content = iv_buffer
                  created_date = sy-datum
                  created_time = sy-uzeit
                  created_user = sy-uname ) TO lt_app_pdf.

  MODIFY zbct_app_pdf FROM TABLE lt_app_pdf.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form frm_file_delete
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM frm_file_delete USING ps_data_guid.

  DATA:lv_answer TYPE c.

  CALL FUNCTION 'POPUP_TO_CONFIRM'
    EXPORTING
      titlebar       = '删除PDF'
      text_question  = '将删除选中PDF内容,请确认!'
      text_button_1  = '是'
*     ICON_BUTTON_1  = ' '
      text_button_2  = '否'
*     ICON_BUTTON_2  = ' '
      default_button = '1'
      start_column   = 25
      start_row      = 6
    IMPORTING
      answer         = lv_answer
    EXCEPTIONS
      text_not_found = 1
      OTHERS         = 2.

  CHECK lv_answer EQ '1'.

  DELETE FROM zbct_app_pdf WHERE guid = ps_data_guid.
  IF sy-subrc = 0.
    MESSAGE '删除成功' TYPE 'S'.
    COMMIT WORK.
  ENDIF.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form frm_show_pdf
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*&      --> GS_DATA_GUID
*&---------------------------------------------------------------------*
FORM frm_show_pdf USING ps_data_guid.

  DATA: lt_datatab        TYPE TABLE OF ssfdata,
        ev_buffer         TYPE xstring,
        lv_full_name      TYPE string,
        lv_file_length    TYPE i,
        lv_temp_dir       TYPE string,
        lv_file_separator TYPE c LENGTH 1.

  SELECT SINGLE *
    FROM zbct_app_pdf
    INTO @DATA(ls_app_pdf)
   WHERE guid = @ps_data_guid.

  IF sy-subrc NE 0.
    MESSAGE '未抓取到该PDF,请检查' TYPE 'S' DISPLAY LIKE 'E'.
    RETURN.
  ENDIF.

  ev_buffer = ls_app_pdf-file_content.
  CALL FUNCTION 'SCMS_XSTRING_TO_BINARY'
    EXPORTING
      buffer        = ev_buffer
    IMPORTING
      output_length = lv_file_length
    TABLES
      binary_tab    = lt_datatab.

  CLEAR lv_temp_dir.
* 获取临时目录
  CALL METHOD cl_gui_frontend_services=>get_temp_directory
    CHANGING
      temp_dir             = lv_temp_dir
    EXCEPTIONS
      cntl_error           = 1
      error_no_gui         = 2
      not_supported_by_gui = 3
      OTHERS               = 4.

  cl_gui_cfw=>flush( ).

* 获取文件路径分隔符
  CLEAR lv_file_separator.
  CALL METHOD cl_gui_frontend_services=>get_file_separator
    CHANGING
      file_separator       = lv_file_separator
    EXCEPTIONS
      not_supported_by_gui = 1
      error_no_gui         = 2
      cntl_error           = 3
      OTHERS               = 4.
  IF sy-subrc <> 0.
    lv_file_separator = '/'.
  ENDIF.

* 文件全名
  lv_full_name = lv_temp_dir && lv_file_separator && ls_app_pdf-file_name.

* 下载文件
  CALL METHOD cl_gui_frontend_services=>gui_download
    EXPORTING
      bin_filesize            = lv_file_length
      filename                = lv_full_name
      filetype                = 'BIN'
    CHANGING
      data_tab                = lt_datatab
    EXCEPTIONS
      file_write_error        = 1
      no_batch                = 2
      gui_refuse_filetransfer = 3
      invalid_type            = 4
      no_authority            = 5
      unknown_error           = 6
      header_not_allowed      = 7
      separator_not_allowed   = 8
      filesize_not_allowed    = 9
      header_too_long         = 10
      dp_error_create         = 11
      dp_error_send           = 12
      dp_error_write          = 13
      unknown_dp_error        = 14
      access_denied           = 15
      dp_out_of_memory        = 16
      disk_full               = 17
      dp_timeout              = 18
      file_not_found          = 19
      dataprovider_exception  = 20
      control_flush_error     = 21
      not_supported_by_gui    = 22
      error_no_gui            = 23
      OTHERS                  = 24.
  IF sy-subrc <> 0.

  ENDIF.

* 打开文件
  CALL METHOD cl_gui_frontend_services=>execute
    EXPORTING
      document               = lv_full_name
    EXCEPTIONS
      cntl_error             = 1
      error_no_gui           = 2
      bad_parameter          = 3
      file_not_found         = 4
      path_not_found         = 5
      file_extension_unknown = 6
      error_execute_failed   = 7
      synchronous_failed     = 8
      not_supported_by_gui   = 9
      OTHERS                 = 10.
  IF sy-subrc <> 0.

  ENDIF.

ENDFORM.

 restful接口直接推出,给外围系统调用查看,源码如下

代码语言:javascript复制
METHOD download_file_by_pdf.

  TYPES:
    BEGIN OF ty_file,
      uuid      TYPE string,
      file_name TYPE string,
    END OF ty_file.

  DATA:
    lt_return       TYPE bapiret2_t,
    lt_header       TYPE tihttpnvp,
    ls_header       TYPE ihttpnvp,
    lt_file         TYPE STANDARD TABLE OF ty_file,
    ls_file         TYPE ty_file,
    lv_json         TYPE string,
    lv_uuid         TYPE sysuuid_c36,
    lv_sysuuid_c32  TYPE sysuuid_c32,
    lv_file_name    TYPE string,
    lv_file_content TYPE xstring,
    lv_file_length  TYPE i,
    lv_content_type TYPE string,
    lv_failed       TYPE abap_bool.

* 获取文件唯一标识
  lv_uuid = iv_uuid.
  TRANSLATE lv_uuid TO UPPER CASE.

  IF lv_uuid = 'HELP'.
    SELECT *
      FROM zbct_app_pdf
      INTO TABLE @DATA(lt_app_pdf)
     WHERE file_cat = @lv_uuid.

    CLEAR lt_file.
    LOOP AT lt_app_pdf INTO DATA(ls_app_pdf).
      lv_sysuuid_c32 = ls_app_pdf-guid.
      CALL METHOD cl_system_uuid=>convert_uuid_c32_static
        EXPORTING
          uuid     = lv_sysuuid_c32
        IMPORTING
          uuid_c36 = DATA(lv_uuid_c36).
      CLEAR ls_file.
      ls_file-uuid = lv_uuid_c36.
      TRANSLATE ls_file-uuid TO LOWER CASE.
      ls_file-file_name = ls_app_pdf-file_name.
      APPEND ls_file TO lt_file.
    ENDLOOP.

    SORT lt_file by file_name.

    CLEAR lv_json.
    CALL FUNCTION 'ZBC_FM_JSON_SERIALIZE'
      EXPORTING
        is_data = lt_file
      IMPORTING
        ev_json = lv_json.

    server->response->set_status( code = 200 reason = 'Ok' ).
    server->response->set_content_type( 'application/json' ).
    server->response->set_cdata( data = lv_json ).

    RETURN.
  ENDIF.

* 获取文件信息
  IF lv_uuid IS NOT INITIAL.
    CALL METHOD cl_system_uuid=>convert_uuid_c36_static
      EXPORTING
        uuid     = lv_uuid
      IMPORTING
        uuid_x16 = DATA(lv_guid).
    IF lv_guid IS NOT INITIAL.
      SELECT SINGLE *
        FROM zbct_app_pdf
        INTO @ls_app_pdf
       WHERE guid = @lv_guid.
      IF sy-subrc <> 0.
        CLEAR ls_app_pdf.
      ENDIF.
    ENDIF.
    IF ls_app_pdf IS INITIAL.
      lv_failed = abap_true.
    ENDIF.
  ENDIF.

  IF lv_failed IS INITIAL.
* 文件名称
    lv_file_name = ls_app_pdf-file_name.

* 文件类型
    lv_content_type = 'application/pdf'.

* 文件内容
    lv_file_content = ls_app_pdf-file_content.

* 返回文件名称
    CLEAR: lt_header, ls_header.
    ls_header-name = 'content-disposition'.
    ls_header-value = |outline; filename={ lv_file_name }|.
    server->response->set_header_fields( lt_header ).

    server->response->set_status( code = 200 reason = 'Ok' ).
    server->response->set_content_type( lv_content_type ).
    server->response->set_data( data = lv_file_content ).
  ELSE.
    server->response->set_status( code = 404 reason = '文件不存在' ).
  ENDIF.

ENDMETHOD.

0 人点赞