需求如下:
甲方存在网络共享文件夹,要求sap功能将文件直接上传至网络共享路径下,且在后续功能中,涉及一个接口 将文件暴露为url作为参数值传输,分步实现。
1.上传文件至网络路径文件夹下
a.由于是网络路径,非FTP实现,所以非FTP实现方式,将路径/账号/密码 给到BASIS,将共享路径配置到SAP的服务器文件路径下,这样就可以通过类型操作SAP服务器文件一样操作共享路径下文件,BASIS配置完成后SAP AL11 需配置对应basis维护的路径,目录保持一致
双击可看到下层目录或文件即为配置正确
b.通过代码实现文件上传
DATA:lv_remote TYPE rcgfiletr-ftappl,
lv_name TYPE char128,
lv_pathname TYPE char128,
lv_code TYPE c
.
*--本地路径获取
DATA(path) = zcl_common=>file_get_path( iv_mask = '*' ).
CHECK path IS NOT INITIAL.
*--拆分文件名
zcl_common=>split_filename( EXPORTING file_and_path = path CHANGING file = lv_name pathname = lv_pathname ).
*--文件上传
lv_remote = |/sapecfiles/{ lv_name }|.
PERFORM frm_upload_service USING path lv_remote CHANGING lv_code.
zcl_common=>file_get_path
参数
value( IV_MASK ) TYPE CHAR128 OPTIONAL 128 个字元
value( RV_PATH ) TYPE RLGRAP-FILENAME 用于装载/卸载的局部文件
METHOD file_get_path.
IF iv_mask IS INITIAL.
iv_mask = 'Excel Files(*.xls;*.xlsx)|*.xls;*.xlsx|'.
ELSEIF iv_mask EQ '*'.
iv_mask = space.
ELSE.
ENDIF.
CALL FUNCTION 'WS_FILENAME_GET'
EXPORTING
mask = iv_mask
title = 'File Selection'
IMPORTING
filename = rv_path
EXCEPTIONS
inv_winsys = 1
no_batch = 2
selection_cancel = 3
selection_error = 4
OTHERS = 5.
IF sy-subrc <> 0.
MESSAGE:'打开路径失败' TYPE 'S' DISPLAY LIKE 'E' .
LEAVE TO LIST-PROCESSING..
ENDIF.
ENDMETHOD.
zcl_common=>split_filename
参数
value( FILE_AND_PATH ) TYPE ANY 文件路径&文件名
value( FILE ) TYPE ANY 文件名
value( PATHNAME ) TYPE ANY 文件路径
METHOD split_filename.
CALL FUNCTION 'STPU1_EXTRACT_FILENAME'
EXPORTING
file_and_path = file_and_path
IMPORTING
file = file
pathname = pathname.
ENDMETHOD.
PERFORM frm_upload_service
*&---------------------------------------------------------------------*
*& Form FRM_UPLOAD_SERVICE
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> PATH
*& --> LV_REMOTE
*&---------------------------------------------------------------------*
FORM frm_upload_service USING pv_path
pv_remote TYPE rcgfiletr-ftappl
CHANGING cv_code TYPE c.
"C13Z_FILE_UPLOAD_BINARY 函数校验 被调用程序
sy-cprog = 'RC1TCG3Z'.
CALL FUNCTION 'C13Z_FILE_UPLOAD_BINARY'
EXPORTING
i_file_front_end = pv_path
i_file_appl = pv_remote
i_file_overwrite = 'X' "是否覆盖
EXCEPTIONS
fe_file_not_exists = 1
fe_file_read_error = 2
ap_no_authority = 3
ap_file_open_error = 4
ap_file_exists = 5
OTHERS = 6.
IF sy-subrc NE 0.
MESSAGE ID sy-msgid TYPE 'S' NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4 DISPLAY LIKE 'E'.
cv_code = 'E'.
ELSE.
cv_code = 'S'.
MESSAGE '数据上传成功!' TYPE 'S'.
ENDIF.
sy-cprog = 'ZPPR0014'.
ENDFORM.
c.实现结果如下:
sap 服务器文件路径下文件
共享网络路径下文件:
2.HTTP 暴露文件地址,实现访问下载
a.SICF配置路径
若是避免弹框账号密码输入,需在登录数据配置账号密码
b. 处理器类代码编写
METHOD if_http_extension~handle_request.
DATA: lv_xstr TYPE xstring.
DATA: lt_xtab TYPE STANDARD TABLE OF sdokcntbin.
DATA:lv_length TYPE i,
lv_file TYPE string,
lv_msg TYPE string,
ls_guid_str TYPE string,
lv_type TYPE string.
DATA:wa_data(255) TYPE x,
lt_data LIKE TABLE OF wa_data.
DATA(lv_value) = server->request->get_form_field( name = 'DOCNAME' ).
CHECK lv_value IS NOT INITIAL.
SELECT SINGLE sapfile INTO lv_file
FROM zppt039
WHERE zfile = lv_value.
IF sy-subrc <> 0.
RETURN.
ENDIF.
OPEN DATASET lv_file FOR INPUT IN BINARY MODE MESSAGE lv_msg.
IF sy-subrc <> 0.
RETURN.
ENDIF.
FREE lt_xtab.
WHILE sy-subrc = 0.
READ DATASET lv_file INTO lv_xstr.
IF sy-subrc = 0.
cl_bcs_convert=>xstring_to_xtab(
EXPORTING
iv_xstring = lv_xstr
IMPORTING
et_xtab = lt_xtab ).
ENDIF.
ENDWHILE.
CLOSE DATASET lv_file.
CLEAR lv_xstr.
lv_xstr = cl_bcs_convert=>xtab_to_xstring( lt_xtab ).
CALL FUNCTION 'SCMS_XSTRING_TO_BINARY'
EXPORTING
buffer = lv_xstr
IMPORTING
output_length = lv_length
TABLES
binary_tab = lt_data.
IF lv_xstr IS NOT INITIAL.
server->response->append_data( data = lv_xstr length = lv_length ).
"Content-Disposition 设置,否则默认是打开,非下载
server->response->set_header_field( name = 'Content-Disposition' value = |attachment; filename="{ lv_value }"| ).
"application/octet-stream 类型可处理未知类型,适用于未知文件类型,由于 filename 包含文件名+类型, 可实现直接转换,或是固定某一类型,例如图片 可用 image/jpeg
server->response->set_header_field( name = 'Content-type' value = 'application/octet-stream').
server->response->set_header_field( name = 'Content-filename' value = lv_value ).
server->response->delete_header_field( name = 'Cache-Control' ).
server->response->delete_header_field( name = 'Expires' ).
ENDIF.
ENDMETHOD.
c.实现效果如下