前言
沒啥特殊需求,就是有個庫齡報表用戶想整郵件發送
實現
用的最簡單的XLS文件作為excel附件發送出去
觀察XLS文件的純文本格式,每列之間用TAB制表符分隔,每行之間用回車符分隔
思路也比較明確,在SAP中實現這種格式,再轉二進制流就好了
下面的代碼替換掉lt_data就可以直接使用,用的動態內表自動將內表轉成純文本
*&---------------------------------------------------------------------*
*& Form frm_2023122702
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM frm_2023122702 .TYPES: BEGIN OF ty_mrtab,matnr TYPE mara-matnr,maktx TYPE makt-maktx,mtart TYPE mara-mtart,END OF ty_mrtab.FIELD-SYMBOLS: <gt_table> TYPE table. "DYNAMIC TABLE INDICATE" 容器字段FIELD-SYMBOLS: <fs_data> TYPE any,<fs_cell_data> TYPE any.DATA: lr_data TYPE REF TO data,lo_descr TYPE REF TO cl_abap_typedescr,lo_str_descr_in TYPE REF TO cl_abap_structdescr,ls_abap_comp_descr TYPE abap_compdescr."附件參數DATA: lt_otf TYPE TABLE OF itcoo,lt_tline TYPE TABLE OF tline,lt_record TYPE TABLE OF solisti1,ls_otf TYPE itcoo,ls_tline TYPE tline,ls_record TYPE solisti1."郵件參數DATA: lv_size TYPE i, "郵件附件大小lv_lines_txt TYPE i, "郵件文本行數lv_lines_bin TYPE i, "郵件附件行數lv_benfile TYPE xstring,lv_object TYPE char50, "郵件主題lv_filename TYPE char50,lt_objpack TYPE TABLE OF sopcklsti1 , "郵件內容 正文+附件lt_objtxt TYPE TABLE OF solisti1 , "正文內容lt_objbin TYPE TABLE OF solisti1 , "附件內容lt_reclist TYPE TABLE OF somlreci1 , "收件人ls_doc_chng TYPE sodocchgi1, "郵件屬性ls_objpack TYPE sopcklsti1,ls_objtxt TYPE solisti1,ls_objbin TYPE solisti1,ls_reclist TYPE somlreci1.DATA: lv_str TYPE string,lv_cell TYPE string.* 需要轉excel的內表DATA: lt_data TYPE TABLE OF ty_mrtab.lt_data = VALUE #( ( matnr = '100' maktx = '硅粉621,純度≥99.1%,P<80ppm;B<50ppm' mtart = '1000' )( matnr = '200' maktx = '硅粉621,純度≥99.1%,P<80ppm;B<50ppm' mtart = '1000' ) )." 轉動態內表以符合各種場景ASSIGN lt_data TO <gt_table>.*&--獲取lt_data的表結構CREATE DATA lr_data LIKE LINE OF <gt_table>.ASSIGN lr_data->* TO <fs_data>." EXCEL表頭
* LOOP AT gt_fieldcat_alv INTO DATA(ls_fieldcat_alv).
* " 單元格 + TAB符
* lv_str = lv_str && ls_fieldcat_alv-seltext_l && cl_abap_char_utilities=>horizontal_tab.
* ENDLOOP.
* " 最后使用回車符換行
* lv_str = lv_str && cl_abap_char_utilities=>cr_lf.*&--獲取內表列字段CALL METHOD cl_abap_structdescr=>describe_by_dataEXPORTINGp_data = <fs_data>RECEIVINGp_descr_ref = lo_descr.lo_str_descr_in ?= lo_descr.*&--EXCEL表體LOOP AT <gt_table> ASSIGNING <fs_data>.
* CLEAR: lv_str,lv_start,lv_end." 循環每行的每個單元格LOOP AT lo_str_descr_in->components INTO ls_abap_comp_descr." 根據字段名找到字段ASSIGN COMPONENT ls_abap_comp_descr-name OF STRUCTURE <fs_data> TO <fs_cell_data>." 去除首尾引號,否則xls文件中tab符會有問題lv_cell = <fs_cell_data>.REPLACE ALL OCCURRENCES OF REGEX '^"*|"*$' IN lv_cell WITH ''." 單元格 + TAB符lv_str = lv_str && lv_cell && cl_abap_char_utilities=>horizontal_tab.ENDLOOP." 最后使用回車符換行lv_str = lv_str && cl_abap_char_utilities=>cr_lf.ENDLOOP."string類型-> XSTRINGCALL FUNCTION 'SCMS_STRING_TO_XSTRING'EXPORTINGtext = lv_str
* mimetype = 'XLS'encoding = '8404' "防止中文亂碼IMPORTINGbuffer = lv_benfileEXCEPTIONSfailed = 1OTHERS = 2.IF lv_benfile IS NOT INITIAL.CALL FUNCTION 'SCMS_XSTRING_TO_BINARY'EXPORTINGbuffer = lv_benfileIMPORTINGoutput_length = lv_sizeTABLESbinary_tab = lt_record.ENDIF."將轉換后的文件添加到郵件附件APPEND LINES OF lt_record TO lt_objbin.* &---郵件處理" 獲取收件人SELECT DISTINCTsmtp_addrFROM zmmt045INTO TABLE @DATA(lt_receiver).lv_size = lines( lt_objbin ) * 255."添加郵件正文ls_objtxt = 'ZMMR011報表已導出,請查看附件'. "APPEND ls_objtxt TO lt_objtxt."郵件正文行數lv_lines_txt = lines( lt_objtxt ).lv_object = 'ZMMR011導出'. " 標題:ZMMR011報表lv_filename = 'ZMMR011.XLS'. " 附件XLS命名ls_doc_chng-obj_langu = sy-langu.ls_doc_chng-obj_name = 'Email'. " Email
* ls_doc_chng-expiry_dat = sy-datum + 10. " 郵件過期日,在此日期后郵件將無法被查看ls_doc_chng-obj_descr = lv_object. "郵件標題
* ls_doc_chng-sensitivty = 'F'. " 郵件保密等級ls_doc_chng-doc_size = lv_lines_txt * 255 + lv_size.ls_doc_chng-priority = '3'. " 1:低優先級 3:普通優先級 5:高優先級CLEAR ls_objpack-transf_bin.ls_objpack-head_start = 1.ls_objpack-head_num = 0.ls_objpack-body_start = 1.ls_objpack-body_num = lv_lines_txt.ls_objpack-doc_type = 'RAW'.APPEND ls_objpack TO lt_objpack.CLEAR:lv_lines_bin.ls_objpack-transf_bin = 'X'.ls_objpack-head_start = 1.ls_objpack-head_num = 1.ls_objpack-body_start = 1.lv_lines_bin = lines( lt_objbin ).ls_objpack-doc_size = lv_size .ls_objpack-body_num = lv_lines_bin.ls_objpack-doc_type = 'XLS'.ls_objpack-obj_descr = lv_filename.APPEND ls_objpack TO lt_objpack.lt_reclist = VALUE #( FOR lw_receiver IN lt_receiver( receiver = lw_receiver " 收件人郵箱rec_type = 'U' ) ).CALL FUNCTION 'SO_NEW_DOCUMENT_ATT_SEND_API1'EXPORTINGdocument_data = ls_doc_chng " 郵件屬性put_in_outbox = ''commit_work = 'X'TABLESpacking_list = lt_objpack " 郵件內容contents_bin = lt_objbin " 附件內容(二進制)contents_txt = lt_objtxt " 郵件內容(直接填入)receivers = lt_reclist " 收件箱地址EXCEPTIONStoo_many_receivers = 1document_not_sent = 2document_type_not_exist = 3operation_no_authorization = 4parameter_error = 5x_error = 6enqueue_error = 7OTHERS = 8.IF sy-subrc = 0.
* es_return-type = 'S'.
* es_return-message = es_return-message && TEXT-m19. " 郵件發送成功WAIT UP TO 1 SECONDS." 立即發送郵件SUBMIT rsconn01 "#EC CI_SUBMITWITH mode = 'INT' WITH output = '' AND RETURN. ".ELSE.
* es_return-type = 'S'.
* es_return-message = es_return-message && TEXT-m20. " 郵件發送失敗ENDIF.ENDFORM.