ABAP发送表格/附件类邮件

在SAP实施中,邮件发送功能在很多项目都会用到,而且往往是把内表以Excel或者CSV的格式发送附件,最好是这个表格也可以显示在正文中,这样的话如果数据行数比较少,就不需要打开附件了。

发送的邮件如下图所示:
f53e1c022033d0df8456500cd06ca19b.png

以往这种需要都是每个程序单独写好长的代码,代码的工作量非常大,本文就是把功能都集成到几个子程序和函数中,大大减少了开发工作量。

程序特点:
1、支持发送到多个外部邮箱
2、支持发送到SAP账号(使用事务码SBWP看邮件)
3、可以选择是否紧急邮件
4、支持多个内表发送,表格和附件分别显示
5、附件压缩为ZIP文件
6、邮件表格界面友好美观
7、如果正文表格未显示所有内表行,则最后一行为省略号

示例代码:

REPORT zsenmail NO STANDARD PAGE HEADING.


TABLES adr6.
DATA: BEGIN OF gt_out OCCURS 0,
        bukrs TYPE t001-bukrs,
        butxt TYPE t001-butxt,
        ort01 TYPE t001-ort01,
        land1 TYPE t001-land1,
        waers TYPE t001-waers,
        spras TYPE t001-spras,
      END OF gt_out.


SELECT-OPTIONS s_smtp FOR adr6-smtp_addr NO INTERVALS OBLIGATORY.
PARAMETERS p_subj TYPE so_obj_des DEFAULT '发送邮件测试'.


AT SELECTION-SCREEN OUTPUT.
  %_s_smtp_%_app_%-text = '接收邮箱'.
  %_p_subj_%_app_%-text = '邮件主题'.


START-OF-SELECTION.
  SELECT * INTO CORRESPONDING FIELDS OF TABLE gt_out FROM t001.
  PERFORM sendmail.
  MESSAGE s000(oo) WITH 'Done'.


*&---------------------------------------------------------------------*
*& sendmail
*&---------------------------------------------------------------------*
FORM sendmail.
  DATA lv_string TYPE string.
  DATA lv_csvxstr TYPE xstring.
  DATA lv_binlen  TYPE i.
  DATA lt_html TYPE TABLE OF w3html WITH HEADER LINE.
  DATA lt_smtp TYPE TABLE OF piqapp_email WITH HEADER LINE.
  DATA lt_atta TYPE wlftt_mail_attachment WITH HEADER LINE.


***邮件内容文本
  APPEND 'TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST<br/>' TO lt_html.
  APPEND 'TEST TEST TEST TEST TEST TEST TEST TEST <br/>' TO lt_html.
  APPEND 'TEST TEST TEST TEST <br/><br/>' TO lt_html.


***下面显示表格,如果有多个内表需要发送,重复下面4个步骤即可
***内表转为CSV文件
  PERFORM itab_to_csv IN PROGRAM zrpubform
                     TABLES gt_out
                     USING '公司代码,名称,城市,国家,货币,语言' "CSV文件的标题
                     CHANGING lv_string lv_csvxstr.


***压缩CSV文件
  PERFORM xstr2zipxstr IN PROGRAM zrpubform
                       USING 'BUKRS.XLS' lv_csvxstr
                       CHANGING lv_csvxstr.


***压缩文件作为附件
  CALL FUNCTION 'SCMS_XSTRING_TO_BINARY'
    EXPORTING
      buffer        = lv_csvxstr
    IMPORTING
      output_length = lv_binlen
    TABLES
      binary_tab    = lt_atta-binary_content.
  lt_atta-description = 'BUKRS.zip'.
  lt_atta-binary_size = lv_binlen.
  APPEND lt_atta.


***内表的前N条以表格的形式显示在邮件正文中
  PERFORM itab_to_mail_body IN PROGRAM zrpubform
                            TABLES gt_out lt_html
                            USING '公司代码列表:' "表格上面文本
                                  '公司代码,名称,城市,国家,货币,语言' "表格标题
                                  'XXXXXX'  "要显示的列,按照顺序,如果显示为X,不显示为空格
                                  '10'.     "显示内表前N行,如果内表大于N行则最后一行显示省略号


***接收邮箱
  LOOP AT s_smtp.
    APPEND s_smtp-low TO lt_smtp.
  ENDLOOP.


***调用发送函数
  CALL FUNCTION 'ZPUB_SEND_MAIL'
    EXPORTING
      subject   = p_subj
      commit    = 'X'
      atta_tab  = lt_atta[]
    TABLES
      mail_body = lt_html
      recv_smtp = lt_smtp.
ENDFORM.

几个子程序如下:

*&---------------------------------------------------------------------*
*& 内表转为CSV文件
*&---------------------------------------------------------------------*
FORM itab_to_csv TABLES t_intab USING pv_header
                 CHANGING cv_str cv_utf8x.
  DATA: lo_csv TYPE REF TO cl_rsda_csv_converter.
  DATA: lv_str TYPE char2048.


  CALL METHOD cl_rsda_csv_converter=>create
    RECEIVING
      r_r_conv = lo_csv.


  IF pv_header IS NOT INITIAL.
    cv_str = pv_header && %_cr_lf.
  ENDIF.


  LOOP AT t_intab.
    CALL METHOD lo_csv->structure_to_csv
      EXPORTING
        i_s_data = t_intab
      IMPORTING
        e_data   = lv_str.
    cv_str = cv_str && lv_str && %_cr_lf.
  ENDLOOP.


  CALL FUNCTION 'SCMS_STRING_TO_XSTRING'
    EXPORTING
      text     = cv_str
      mimetype = 'UTF8'
    IMPORTING
      buffer   = cv_utf8x
    EXCEPTIONS
      failed   = 1
      OTHERS   = 2.
  IF sy-subrc = 0.
    cv_utf8x = cl_abap_char_utilities=>byte_order_mark_utf8 && cv_utf8x.
  ENDIF.
ENDFORM.


*&---------------------------------------------------------------------*
*& XSTRING压缩为ZIP文件XSTRING
*&---------------------------------------------------------------------*
FORM xstr2zipxstr USING pv_filename pv_xstr CHANGING cv_zipxstr.
  DATA: lo_zip TYPE REF TO cl_abap_zip.
  DATA: lv_str TYPE string.


  lv_str = pv_filename.
  CREATE OBJECT lo_zip.
  CALL METHOD lo_zip->add
    EXPORTING
      name    = lv_str
      content = pv_xstr.
  CALL METHOD lo_zip->save
    RECEIVING
      zip = cv_zipxstr.
ENDFORM.


*&---------------------------------------------------------------------*
*& 内表写到邮件表格
*&---------------------------------------------------------------------*
FORM itab_to_mail_body TABLES t_intab t_contents STRUCTURE solisti1
                       USING pv_text pv_coldesc pv_mask pv_toline.
  DATA: lt_conts TYPE TABLE OF solisti1 WITH HEADER LINE,
        lt_title TYPE TABLE OF char40 WITH HEADER LINE.
  DATA: subrc   TYPE sy-subrc,
        index   TYPE sy-index,
        charc   TYPE char2048,
        charstr TYPE string,
        lmask   TYPE char200,
        omitnum TYPE i,
        ftype .
  FIELD-SYMBOLS <fs_fld> .


  CHECK t_intab[] IS NOT INITIAL.


  SPLIT pv_coldesc AT ',' INTO TABLE lt_title.
  lmask = pv_mask.


  APPEND pv_text TO lt_conts.
  APPEND:
    `<style type="text/css">.solid{BORDER-TOP: 1px solid;` TO lt_conts,
    `BORDER-RIGHT:1px solid;BORDER-BOTTOM: 1px solid;    ` TO lt_conts,
    `BORDER-LEFT: 1px solid}</style><table border=1      ` TO lt_conts,
    `cellpadding=2 style='border-collapse:collapse;font-`  TO lt_conts,
    `size:10.5pt'><tbody><tr style="background:#DDD9C4;">` TO lt_conts.


  LOOP AT lt_title.
    APPEND |<td class="solid">{ lt_title }</td>| TO lt_conts.
  ENDLOOP.
  APPEND `</tr>` TO lt_conts.


  LOOP AT t_intab FROM 0 TO pv_toline.
    APPEND '<tr>' TO lt_conts.
    CLEAR omitnum.
    DO.
      index = sy-index - 1.
      ASSIGN COMPONENT sy-index OF STRUCTURE t_intab TO <fs_fld>.
      IF sy-subrc <> 0.
        EXIT.
      ENDIF.


      CHECK lmask+index(1) = 'X' OR lmask = ''.
      omitnum = omitnum + 1.


      DESCRIBE FIELD <fs_fld> TYPE ftype.
      CASE ftype.
        WHEN 'I' OR 'P' OR 'F' OR 'a' OR 'e' OR 'b' OR 's'.
          charc = abs( <fs_fld> ).
          CONDENSE charc NO-GAPS.
          IF <fs_fld> < 0.
            CONCATENATE '-' charc INTO charc.
          ENDIF.
          charstr = charc.
        WHEN 'D' OR 'T'.
          IF <fs_fld> IS INITIAL OR <fs_fld> = ''.
            charc = ''.
          ELSE.
            WRITE <fs_fld> TO charc .
          ENDIF.
          charstr = charc.
        WHEN 'X' OR 'y' OR 'g'.
          charstr = <fs_fld> .
        WHEN OTHERS.
          WRITE <fs_fld> TO charc .
          charstr = charc.
      ENDCASE.
      APPEND |<td class="solid">{ charstr }</td>| TO lt_conts.
    ENDDO.
    APPEND `</tr>` TO lt_conts.
  ENDLOOP.
  IF lines( t_intab ) > pv_toline.
    APPEND '<tr>' TO lt_conts.
    DO omitnum TIMES.
      APPEND |<td class="solid">...</td>| TO lt_conts.
    ENDDO.
    APPEND '</tr>' TO lt_conts.
  ENDIF.
  APPEND '</tbody></table> <br/> ' TO lt_conts.


  APPEND LINES OF lt_conts TO t_contents.
ENDFORM.

发送函数:

FUNCTION zpub_send_mail.
*"----------------------------------------------------------------------
*"*"本地接口:
*"  IMPORTING
*"     VALUE(SUBJECT) TYPE  SO_OBJ_DES
*"     VALUE(SENDER) TYPE  AD_SMTPADR OPTIONAL
*"     VALUE(EXPRESS) TYPE  OS_BOOLEAN OPTIONAL
*"     VALUE(COMMIT) TYPE  CHAR1 OPTIONAL
*"     VALUE(ATTA_TAB) TYPE  WLFTT_MAIL_ATTACHMENT OPTIONAL
*"  EXPORTING
*"     VALUE(RTYPE) TYPE  BAPI_MTYPE
*"     VALUE(RTMSG) TYPE  BAPI_MSG
*"  TABLES
*"      MAIL_BODY STRUCTURE  SOLISTI1 OPTIONAL
*"      RECV_USER STRUCTURE  SSCRUSER OPTIONAL
*"      RECV_SMTP STRUCTURE  PIQAPP_EMAIL OPTIONAL
*"----------------------------------------------------------------------
  DATA lr_email  TYPE REF TO cl_bcs.
  DATA lr_body   TYPE REF TO cl_document_bcs.
  DATA lr_sender TYPE REF TO if_sender_bcs.
  DATA lr_recver TYPE REF TO if_recipient_bcs.
  DATA lr_cxbcs  TYPE REF TO cx_bcs.
  DATA ls_atta   TYPE wlfs_mail_attachment.
  DATA lv_result TYPE os_boolean.


  TRY.
      lr_email = cl_bcs=>create_persistent( ).
      lr_body = cl_document_bcs=>create_document( i_type = 'HTM'
                                                  i_text = mail_body[]
                                                  i_subject = subject ).
      LOOP AT atta_tab INTO ls_atta.
        CALL METHOD lr_body->add_attachment
          EXPORTING
            i_attachment_type    = ls_atta-type
            i_attachment_subject = ls_atta-description
            i_attachment_size    = ls_atta-binary_size
            i_att_content_hex    = ls_atta-binary_content.
      ENDLOOP.
      lr_email->set_document( lr_body ).


      IF sender IS INITIAL.
        lr_sender = cl_sapuser_bcs=>create( sy-uname ).
      ELSE.
        CALL METHOD cl_cam_address_bcs=>create_internet_address
          EXPORTING
            i_address_string = sender
            i_address_name   = 'Sender'
          RECEIVING
            result           = lr_sender.
      ENDIF.
      lr_email->set_sender( lr_sender ).


      LOOP AT recv_user.
        lr_recver = cl_sapuser_bcs=>create( recv_user-uname ).
        lr_email->add_recipient( i_recipient = lr_recver i_express = express ).
      ENDLOOP.


      LOOP AT recv_smtp.
        lr_recver = cl_cam_address_bcs=>create_internet_address( recv_smtp-e_mail ).
        lr_email->add_recipient( i_recipient = lr_recver i_express = express ).
      ENDLOOP.


      lr_email->set_send_immediately( 'X' ).
      lv_result = lr_email->send( i_with_error_screen = '' ).
      IF lv_result = 'X'.
        IF commit IS NOT INITIAL.
          COMMIT WORK. "在Update进程或者增强里面,禁止提交
        ENDIF.
      ENDIF.
    CATCH cx_bcs INTO lr_cxbcs. " cx_root INTO lr_cxroot.
      rtype = 'E'.
      rtmsg = lr_cxbcs->get_text( ).
  ENDTRY.
ENDFUNCTION.

6986f394f542b759d63ca2ac85930ec2.jpeg

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值