ABAP 发送带EXCEL邮件

前言

没啥特殊需求,就是有个库龄报表用户想整邮件发送

实现

用的最简单的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_data
    EXPORTING
      p_data      = <fs_data>
    RECEIVING
      p_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类型-> XSTRING
  CALL FUNCTION 'SCMS_STRING_TO_XSTRING'
    EXPORTING
      text     = lv_str
*     mimetype = 'XLS'
      encoding = '8404' "防止中文乱码
    IMPORTING
      buffer   = lv_benfile
    EXCEPTIONS
      failed   = 1
      OTHERS   = 2.

  IF lv_benfile IS NOT INITIAL.
    CALL FUNCTION 'SCMS_XSTRING_TO_BINARY'
      EXPORTING
        buffer        = lv_benfile
      IMPORTING
        output_length = lv_size
      TABLES
        binary_tab    = lt_record.
  ENDIF.

  "将转换后的文件添加到邮件附件
  APPEND LINES OF lt_record TO lt_objbin.

*  &---邮件处理

  " 获取收件人
  SELECT DISTINCT
    smtp_addr
  FROM zmmt045
  INTO 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'
    EXPORTING
      document_data              = ls_doc_chng  " 邮件属性
      put_in_outbox              = ''
      commit_work                = 'X'
    TABLES
      packing_list               = lt_objpack  " 邮件内容
      contents_bin               = lt_objbin   " 附件内容(二进制)
      contents_txt               = lt_objtxt   " 邮件内容(直接填入)
      receivers                  = lt_reclist  " 收件箱地址
    EXCEPTIONS
      too_many_receivers         = 1
      document_not_sent          = 2
      document_type_not_exist    = 3
      operation_no_authorization = 4
      parameter_error            = 5
      x_error                    = 6
      enqueue_error              = 7
      OTHERS                     = 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_SUBMIT
    WITH mode = 'INT' WITH output = '' AND RETURN. ".
  ELSE.
*    es_return-type = 'S'.
*    es_return-message = es_return-message && TEXT-m20. " 邮件发送失败
  ENDIF.

ENDFORM.
  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
ABAP语言中,可以使用函数模块 `SO_NEW_DOCUMENT_ATT_SEND_API1` 来发送Outlook邮件。 首先,我们需要准备好发送邮件的数据。需要设置邮件的主题、收件人地址、发件人地址以及邮件正文内容。下面是一个示例代码: ``` DATA: lv_subject TYPE so_obj_des, lv_sender TYPE sy-uname, lt_receivers TYPE STANDARD TABLE OF so_obj_nam, ls_receiver TYPE so_obj_nam, lv_text TYPE soli. lv_subject = '这是邮件的主题'. lv_sender = '发件人的邮箱地址'. ls_receiver-name = '收件人的邮箱地址'. APPEND ls_receiver TO lt_receivers. lv_text = '邮件的正文内容'. ``` 接下来,我们需要通过函数模块 `SO_DOCUMENT_SEND_API1` 来创建邮件对象并发送邮件。下面是一个示例代码: ``` DATA: lv_document_data TYPE sodocchgi1, lv_document_type TYPE so_obj_tp, lv_length TYPE sopcklen. lv_document_type = 'RAW'. lv_length = STRLEN( lv_text ). lv_document_data-obj_name = lv_sender. lv_document_data-obj_descr = lv_subject. lv_document_data-sensitivty = 'F'. CALL FUNCTION 'SO_NEW_DOCUMENT_ATT_SEND_API1' EXPORTING document_data = lv_document_data document_type = lv_document_type commit_work = 'X' TABLES packing_list = lt_packing_list EXCEPTIONS too_many_recipients = 1 document_not_sent = 2 document_type_not_exist = 3 operation_no_authorization = 4 parameter_error = 5 x_error = 6 enqueue_error = 7 OTHERS = 8. ``` 以上代码中,我们创建了一个邮件对象,并指定了相关的属性,例如发件人地址、收件人地址、主题和邮件正文内容。然后,通过调用函数模块 `SO_NEW_DOCUMENT_ATT_SEND_API1` 来发送邮件,其中需要传入邮件对象的信息和其他参数。如果发送成功,邮件将通过Outlook发送给指定的收件人。 需要注意的是,在使用此方法发送邮件之前,需要首先配置好Outlook的相关设置,确保ABAP系统能够正确连接和发送邮件。另外,还可以通过不同的参数设置更多的邮件属性,例如附件、HTML格式等。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值