SAP ABAP 通过OPEN DATASET语法上传文件到服务器

一、知悉上传后保存在那个目录下

1、判断目录是否存在

通过事务码AL11打开服务器目录清单,创建目录文件

点击“配置用户目录”按钮

输入目录参数、目录路径和服务器后,点击保存按钮

在目录清单中找到刚才配置的目录参数,双击该参数,若能够进入明细界面,则表示该目录是真实存在的,可以使用。若报错(如上图所示):Wrong order of calls <- 调用 opendir: No such file or directory(,,..),则表示该目录不存在,无效。

2、创建目录

项目上需要和外围系统做接口,上传图片到文件服务器上,让外围系统过来读取,但是为了减少SAP应用服务器的负担,需要一台独立的文件服务器共享目录到SAP应用服务器,

也就是NFS,实现往SAP应用服务器上写文件,实际上是写在了这台独立的文件服务器上。

我们需要让基础架构工程师把文件服务器和SAP应用服务器做NFS,也就是共享,只对该目录开放给SAP权限。

SAP中可以在该目录上新建文件夹也就是在该目录里新建目录。

通过事务码SM69进入(仅讨论文件服务器是Linux系统)

点击创建按钮,输入命令名称、操作系统命令、操作系统命令参数,勾选“允许的附件参数”(在执行时用来输入目录路径),然后点击保存

在详情页点击执行按钮,在附加参数字段输入目录路径,点击执行,即可创建目录

创建目录仅可以在已有目录下面创建文件夹,而不能跨多层创建。比如,现有的目录仅为/user/sap/111,只能创建其下层如/user/sap/111/222,而不能一次性创建多层,如/user/sap/111/222/333/444

目录创建完毕后,即可通过AL11创建目录文件了

附删除目录命令

二、文件上传服务器

1、在应用服务器中打开文件OPEN  DATASET  <dsn>  [options] 此语句打开文件 <dsn> 。如果不指定任何模式 选项,则文件将按二进 制模式打开。如果系统不能打开文件,则将系统字段 SY-SUBRC 设置为 8,否则 SY-SUBRC 返回 0

2、打开文件读取OPEN DATASET <dsn> FOR INPUT IN TEXT MODE ENCODING DEFAULT .(以TXT文件打开)

3、打开文件写入OPEN DATASET <dsn> FOR OUTPUT IN TEXT MODE ENCODING DEFAULT .(以TXT文件打开写入,这种是打开文件完全重写)

4、打开文件追加 OPEN DATASET <dsn> FOR APPENDING IN TEXT MODE ENCODING DEFAULT .(以TXT文件打开写入,这种是打开文件追加记录)

5、关闭应用服务器上的文件 CLOSE DATASET <dsn>.

6、删除应用服务器上的文件 DELETE DATASET <dsn>.

7、向应用服务器上文件上写入数据TRANSFER  <f>  to  <dsn>  [LENGTH <len>].

8、向应用服务器上文件上读取数据READ  DATASET  <dsn>  INTO  <f>  [LENGTH <len>].

FUNCTION zbc_fm_upload_picture.
*"----------------------------------------------------------------------
*"*"本地接口:
*"  IMPORTING
*"     VALUE(IV_FILE_NAME) OPTIONAL
*"     VALUE(IV_PATH_SAVE) OPTIONAL
*"     VALUE(IV_PATH_UPLOAD) OPTIONAL
*"     VALUE(IV_CONTENT) TYPE  XSTRING OPTIONAL
*"     VALUE(IV_SAVE) TYPE  FLAG DEFAULT 'X'
*"  EXPORTING
*"     VALUE(EV_TYPE) TYPE  MSGTY
*"     VALUE(EV_MESSAGE) TYPE  STRING
*"     VALUE(EV_PATH)
*"     VALUE(EV_CONTENT) TYPE  XSTRING
*"----------------------------------------------------------------------

  DATA: lt_pic_data TYPE solix_tab.
  DATA: lv_length  TYPE i,
        lv_len     TYPE i,
        lv_failed  TYPE abap_bool,
        lv_message TYPE string.
  DATA: lv_file_name   TYPE string,
        lv_path_upload TYPE string,
        lv_path_save   TYPE string,
        lv_content     TYPE xstring.

  DATA: lo_obj TYPE REF TO cl_gui_frontend_services.
  DATA: lt_file TYPE filetable,
        lv_rc   TYPE i.

  IF iv_save EQ 'X' AND iv_path_save IS INITIAL.
    ev_type = 'E'.
    ev_message = '保存文件路径为空,请检查!'.
  ENDIF.

  IF iv_content IS NOT INITIAL.
    ev_content = iv_content.
    lv_content = iv_content.
    CALL FUNCTION 'SCMS_XSTRING_TO_BINARY'
      EXPORTING
        buffer        = lv_content
*       APPEND_TO_TABLE       = ' '
      IMPORTING
        output_length = lv_len
      TABLES
        binary_tab    = lt_pic_data[].
  ELSE.
    IF iv_path_upload IS NOT INITIAL.
      lv_path_upload = iv_path_upload.
    ELSE.
      "弹窗获取文件上传路径
      CREATE OBJECT lo_obj.
      CALL METHOD lo_obj->file_open_dialog
        EXPORTING
          file_filter = 'PICTURE FILE(*.JPG;*.PNG;*.BMP)|*.JPG;*.PNG;*.BMP'
        CHANGING
          file_table  = lt_file
          rc          = lv_rc.
      READ TABLE lt_file INTO DATA(ls_file) INDEX 1.
      IF sy-subrc EQ 0.
        lv_path_upload = ls_file-filename.
      ENDIF.
    ENDIF.
    "上传文件
    CALL FUNCTION 'GUI_UPLOAD'
      EXPORTING
        filename   = lv_path_upload
        filetype   = 'BIN'
      IMPORTING
        filelength = lv_len
      TABLES
        data_tab   = lt_pic_data[].

    CALL FUNCTION 'SCMS_BINARY_TO_XSTRING'
      EXPORTING
        input_length = lv_len
      IMPORTING
        buffer       = ev_content
      TABLES
        binary_tab   = lt_pic_data[]
      EXCEPTIONS
        failed       = 1
        OTHERS       = 2.
  ENDIF.

  IF iv_save EQ 'X'.
    IF iv_file_name IS NOT INITIAL.
      lv_file_name = iv_path_save && '/' && iv_file_name.
    ELSE.
      IF lv_path_upload IS NOT INITIAL.
        SPLIT lv_path_upload AT '\' INTO TABLE DATA(lt_tab).
        DATA(lv_lines) = lines( lt_tab[] ).
        READ TABLE lt_tab INTO DATA(ls_tab) INDEX lv_lines.
        IF sy-subrc EQ 0.
          lv_file_name = ls_tab.
        ENDIF.
      ELSE.
        TRY.
            DATA(lv_uuid) = cl_system_uuid=>create_uuid_c22_static( ).
            lv_file_name = lv_uuid &&'.JPG'.
            lv_file_name = iv_path_save && '\' && iv_file_name.
            CONDENSE lv_file_name NO-GAPS.
          CATCH cx_uuid_error.
        ENDTRY.
      ENDIF.
    ENDIF.

*&---打开文件
    CLEAR lv_message.
    TRY.
        OPEN DATASET lv_file_name FOR OUTPUT IN BINARY MODE MESSAGE lv_message.
        IF sy-subrc EQ 8.
          lv_failed = abap_true.
          lv_message = '文件打开失败!'.
        ENDIF.
      CATCH cx_sy_file_open INTO DATA(lx_file_open).
        lv_failed = abap_true.
        lv_message = lx_file_open->get_text( ).
      CATCH cx_sy_codepage_converter_init INTO DATA(lx_codepage_converter_init).
        lv_failed = abap_true.
        lv_message = lx_codepage_converter_init->get_text( ).
      CATCH cx_sy_conversion_codepage INTO DATA(lx_conversion_codepage).
        lv_failed = abap_true.
        lv_message = lx_conversion_codepage->get_text( ).
      CATCH cx_sy_file_authority INTO DATA(lx_file_authority).
        lv_failed = abap_true.
        lv_message = lx_file_authority->get_text( ).
      CATCH cx_sy_pipes_not_supported INTO DATA(lx_pipes_not_supported).
        lv_failed = abap_true.
        lv_message = lx_pipes_not_supported->get_text( ).
      CATCH cx_sy_too_many_files INTO DATA(lx_too_many_files).
        lv_failed = abap_true.
        lv_message = lx_too_many_files->get_text( ).
      CATCH cx_root INTO DATA(lx_root).
        lv_failed = abap_true.
        lv_message = lx_root->get_text( ).
    ENDTRY.

    IF lv_failed EQ abap_true.
      ev_type = 'E'.
      ev_message = lv_message.
      EXIT.
    ENDIF.

*&---写入文件
    LOOP AT lt_pic_data INTO DATA(ls_pic_data).
      DESCRIBE FIELD ls_pic_data-line LENGTH lv_length IN BYTE MODE.
      IF lv_length > lv_len.
        lv_length = lv_len.
      ELSE.
        SUBTRACT lv_length FROM lv_len."等同于 lv_len = lv_len - lv_length
      ENDIF.
      CHECK lv_length > 0.
      CLEAR lv_message.
      TRY.
          TRANSFER ls_pic_data-line TO lv_file_name LENGTH lv_length.
        CATCH cx_sy_codepage_converter_init INTO lx_codepage_converter_init.
          lv_failed = abap_true.
          lv_message = lx_codepage_converter_init->get_text( ).
          EXIT.
        CATCH cx_sy_conversion_codepage INTO lx_conversion_codepage.
          lv_failed = abap_true.
          lv_message = lx_conversion_codepage->get_text( ).
          EXIT.
        CATCH cx_sy_file_authority INTO lx_file_authority.
          lv_failed = abap_true.
          lv_message = lx_file_authority->get_text( ).
          EXIT.
        CATCH cx_sy_file_io INTO DATA(lx_file_io).
          lv_failed = abap_true.
          lv_message = lx_file_io->get_text( ).
          EXIT.
        CATCH cx_sy_file_open INTO lx_file_open.
          lv_failed = abap_true.
          lv_message = lx_file_open->get_text( ).
          EXIT.
        CATCH cx_sy_file_open_mode INTO DATA(lx_file_open_mode).
          lv_failed = abap_true.
          lv_message = lx_file_open_mode->get_text( ).
          EXIT.
        CATCH cx_sy_pipe_reopen INTO DATA(lx_pipe_reopen).
          lv_failed = abap_true.
          lv_message = lx_pipe_reopen->get_text( ).
          EXIT.
        CATCH cx_sy_too_many_files INTO lx_too_many_files.
          lv_failed = abap_true.
          lv_message = lx_too_many_files->get_text( ).
          EXIT.
        CATCH cx_root INTO lx_root.
          lv_failed = abap_true.
          lv_message = lx_root->get_text( ).
          EXIT.
      ENDTRY.
      CLEAR: ls_pic_data.
    ENDLOOP.

    IF lv_failed EQ abap_true.
      ev_type = 'E'.
      ev_message = lv_message.
      "删除该文件
*      DELETE DATASET lv_file_name.
      EXIT.
    ENDIF.

* 关闭文件
    CLEAR lv_message.
    TRY.
        CLOSE DATASET lv_file_name.
      CATCH cx_sy_file_close INTO DATA(lx_file_close).
        lv_failed = abap_true.
        lv_message = lx_file_close->get_text( ).
      CATCH cx_root INTO lx_root.
        lv_failed = abap_true.
        lv_message = lx_root->get_text( ).
    ENDTRY.

    IF lv_failed EQ abap_true.
      ev_type = 'E'.
      ev_message = lv_message.
    ELSE.
      ev_type = 'S'.
      ev_message = '文件已上传至服务器!'.
      ev_path = lv_file_name.
    ENDIF.
  ENDIF.


ENDFUNCTION.

三、读取图片并展示

代码

FUNCTION zbc_fm_get_picture.
*"----------------------------------------------------------------------
*"*"本地接口:
*"  IMPORTING
*"     VALUE(IV_FULL_NAME) OPTIONAL
*"     VALUE(IV_CONTENT) TYPE  XSTRING OPTIONAL
*"  EXPORTING
*"     VALUE(EV_TYPE) TYPE  MSGTY
*"     VALUE(EV_MESSAGE) TYPE  STRING
*"     VALUE(EV_CONTENT) TYPE  XSTRING
*"     VALUE(ET_DATA) TYPE  SOLIX_TAB
*"     VALUE(EV_URL)
*"----------------------------------------------------------------------

  DATA:
    lt_solix         TYPE solix_tab,
    ls_solix         TYPE solix,
    lv_command       TYPE sxpgcolist-name,
    lv_parameters    TYPE sxpgcolist-parameters,
    lv_opsystem      TYPE sxpgcolist-opsystem,
    lv_status        TYPE extcmdexex-status,
    lv_exitcode      TYPE extcmdexex-exitcode,
    lt_protocol      TYPE STANDARD TABLE OF btcxpm,
    lv_file_name     TYPE string,
    lv_file_path     TYPE string,
    lv_full_name     TYPE string,
    lv_file_length   TYPE i,
    lv_max_length    TYPE i,
    lv_actual_length TYPE i,
    lv_failed        TYPE abap_bool,
    lv_message       TYPE string.

  DATA: g_docking_container TYPE REF TO cl_gui_docking_container,
        g_splitter          TYPE REF TO cl_gui_splitter_container,
        c_pic               TYPE REF TO cl_gui_container,
        g_container_2       TYPE REF TO cl_gui_container,
        go_pic              TYPE REF TO cl_gui_picture.
  CONSTANTS:
    cns_extension TYPE i VALUE 3000.  "Docking size
  DATA: len         TYPE i,
        url(256),
        resu        TYPE i VALUE 123,
        path_string TYPE string.

  DATA: lv_subtype TYPE char4.

  lv_full_name = iv_full_name.

  IF iv_content IS INITIAL.
* 打开文件
    CLEAR lv_message.
    TRY.
        OPEN DATASET lv_full_name FOR INPUT IN BINARY MODE MESSAGE lv_message.
        IF SY-SUBRC NE 0.
          lv_failed = abap_true.
          lv_message = '文件打开失败!'.
        ENDIF.
      CATCH cx_sy_file_open INTO DATA(lx_file_open).
        lv_failed = abap_true.
        lv_message = lx_file_open->get_text( ).
      CATCH cx_sy_codepage_converter_init INTO DATA(lx_codepage_converter_init).
        lv_failed = abap_true.
        lv_message = lx_codepage_converter_init->get_text( ).
      CATCH cx_sy_conversion_codepage INTO DATA(lx_conversion_codepage).
        lv_failed = abap_true.
        lv_message = lx_conversion_codepage->get_text( ).
      CATCH cx_sy_file_authority INTO DATA(lx_file_authority).
        lv_failed = abap_true.
        lv_message = lx_file_authority->get_text( ).
      CATCH cx_sy_pipes_not_supported INTO DATA(lx_pipes_not_supported).
        lv_failed = abap_true.
        lv_message = lx_pipes_not_supported->get_text( ).
      CATCH cx_sy_too_many_files INTO DATA(lx_too_many_files).
        lv_failed = abap_true.
        lv_message = lx_too_many_files->get_text( ).
      CATCH cx_root INTO DATA(lx_root).
        lv_failed = abap_true.
        lv_message = lx_root->get_text( ).
    ENDTRY.

    IF lv_failed IS NOT INITIAL.
      ev_type = 'E'.
      ev_message = lv_message.
      EXIT.
    ENDIF.

* 读文件
    CLEAR: lt_solix, lv_file_length.
    DO.
      CLEAR: ls_solix, lv_actual_length, lv_message.
      lv_max_length = 255.
      TRY.
          READ DATASET lv_full_name INTO ls_solix-line MAXIMUM LENGTH lv_max_length ACTUAL LENGTH lv_actual_length.
        CATCH cx_sy_codepage_converter_init INTO lx_codepage_converter_init.
          lv_failed = abap_true.
          lv_message = lx_codepage_converter_init->get_text( ).
        CATCH cx_sy_conversion_codepage INTO lx_conversion_codepage.
          lv_failed = abap_true.
          lv_message = lx_conversion_codepage->get_text( ).
        CATCH cx_sy_file_authority INTO lx_file_authority.
          lv_failed = abap_true.
          lv_message = lx_file_authority->get_text( ).
        CATCH cx_sy_file_io INTO DATA(lx_file_io).
          lv_failed = abap_true.
          lv_message = lx_file_io->get_text( ).
        CATCH cx_sy_file_open INTO lx_file_open.
          lv_failed = abap_true.
          lv_message = lx_file_open->get_text( ).
        CATCH cx_sy_file_open_mode INTO DATA(lx_file_open_mode).
          lv_failed = abap_true.
          lv_message = lx_file_open_mode->get_text( ).
        CATCH cx_sy_pipe_reopen INTO DATA(lx_pipe_reopen).
          lv_failed = abap_true.
          lv_message = lx_pipe_reopen->get_text( ).
        CATCH cx_root INTO lx_root.
          lv_failed = abap_true.
          lv_message = lx_root->get_text( ).
      ENDTRY.
      IF lv_failed IS NOT INITIAL.
        ev_type = 'E'.
        ev_message = lv_message.
        EXIT.
      ENDIF.
      IF lv_actual_length IS INITIAL.
        EXIT.
      ENDIF.
      ADD lv_actual_length TO lv_file_length.
      APPEND ls_solix TO lt_solix.
    ENDDO.

* 转换二进制
    IF lt_solix IS NOT INITIAL.
      CALL FUNCTION 'SCMS_BINARY_TO_XSTRING'
        EXPORTING
          input_length = lv_file_length
        IMPORTING
          buffer       = ev_content
        TABLES
          binary_tab   = lt_solix
        EXCEPTIONS
          failed       = 1
          OTHERS       = 2.
      et_data[] = lt_solix[].
    ENDIF.

* 关闭文件
    CLEAR lv_message.
    TRY.
        CLOSE DATASET lv_full_name.
      CATCH cx_sy_file_close INTO DATA(lx_file_close).
        lv_failed = abap_true.
        lv_message = lx_file_close->get_text( ).
      CATCH cx_root INTO lx_root.
        lv_failed = abap_true.
        lv_message = lx_root->get_text( ).
    ENDTRY.

    IF lv_message IS NOT INITIAL.
      ev_type = 'E'.
      ev_message = lv_message.
      EXIT.
    ENDIF.
  ELSE.
    CALL FUNCTION 'SCMS_XSTRING_TO_BINARY'
      EXPORTING
        buffer        = iv_content
*       APPEND_TO_TABLE       = ' '
      IMPORTING
        output_length = lv_file_length
      TABLES
        binary_tab    = lt_solix.
    et_data[] = lt_solix[].
  ENDIF.

* 创建图片URL
  SPLIT iv_full_name AT '.' INTO TABLE DATA(lt_tab).
  DATA(lv_lines) = lines( lt_tab[] ).
  READ TABLE lt_tab INTO DATA(ls_tab) INDEX lv_lines.
  IF sy-subrc EQ 0.
    lv_subtype = ls_tab.
  ELSE.
    lv_subtype = 'JPG'.
  ENDIF.
  CALL FUNCTION 'DP_CREATE_URL'
    EXPORTING
      type    = 'IMAGE'
      subtype = lv_subtype "JPG
    TABLES
      data    = lt_solix
    CHANGING
      url     = url.

  ev_url = url.

  CLEAR: gv_url.
  gv_url = url.
  CHECK gv_url IS NOT INITIAL.

  CALL SCREEN 0100 STARTING AT 5 5 .



ENDFUNCTION.

屏幕0100

抬头参数定义 

DATA: go_pic              TYPE REF TO cl_gui_picture,
      g_docking_container TYPE REF TO cl_gui_docking_container,
      g_splitter          TYPE REF TO cl_gui_splitter_container,
      c_pic               TYPE REF TO cl_gui_container.
DATA: container_1 TYPE REF TO cl_gui_custom_container.
DATA: gv_url(256) TYPE c.
DATA: ok_code TYPE sy-ucomm.

PBO 进行容器实例化并展示图片


*&---------------------------------------------------------------------*
*&      Module  STATUS_0100  OUTPUT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
MODULE status_0100 OUTPUT.
  SET PF-STATUS 'STATUS_0100'.
*  SET TITLEBAR 'xxx'.

  IF container_1 IS INITIAL."创建框体
    CREATE OBJECT container_1
      EXPORTING
        container_name = 'PIC_CONTAINER'.

    CREATE OBJECT go_pic
      EXPORTING
        parent = container_1.

* 3,居中显示
    CALL METHOD go_pic->set_display_mode
      EXPORTING
        display_mode = cl_gui_picture=>DISPLAY_MODE_NORMAL_CENTER.

    CALL METHOD go_pic->load_picture_from_url
      EXPORTING
        url    = gv_url.
  ENDIF.


ENDMODULE.

PAI进行按钮事件捕捉和退出


*&---------------------------------------------------------------------*
*&      Module  USER_COMMAND_0100  INPUT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
MODULE user_command_0100 INPUT.

  CASE sy-ucomm.
    WHEN 'BACK' OR '&F03' OR '&F12' OR '&F15'.
      CALL METHOD go_pic->clear_picture.
      CALL METHOD cl_gui_cfw=>flush.
*      (必须释放对象,否则会出现同一屏幕上操作图片无法刷新的情况)
      LEAVE TO SCREEN 0.
    WHEN OTHERS.
  ENDCASE.

ENDMODULE.

GUI状态

图片展示结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值