一、知悉上传后保存在那个目录下
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.