把ABAP 内表作为Excel附件发送邮件

2023-02-18 14:15发布

I would like to share a different approach in sending an xls type document
using cl_bcs. This is a just a copy of
http://abapblog.com/articles/tricks/33-create-xlsx-mhtml-file-from-internal-table-in-background
only that his post is to upload it in presentation server, so credits to the owner of that post.

The requirement was to make an attachment of xls type same as in ALV when we save
it into spreadsheet->Excel(in office 2007.....) Question is why this type? Because the sample
from BCS_EXAMPLE_7(the itab to binary in this example 7 is buggy) does not make the columns auto-fit, specially when end-users does not

want to click on the column in excel and resize the column.

Make a subroutine:

Important parameters here:

lt_binary_content → converted itab to binary

r_mail→ range type if email parameters are more than 1

 

FORM f_mail_send .

  DATA:
        lt_binary_content type solix_tab,
        lv_size TYPE so_obj_len,
        r_mail TYPE ace_generic_range_t,
       st_mail TYPE ace_generic_range,
       lv_count TYPE char2,
       lv_var TYPE char8.
  FIELD-SYMBOLS: <fs_mail> TYPE any.
  REFRESH: lt_binary_content.
  CLEAR: st_mail, lv_count, lv_var.


  PERFORM f_build_email_data CHANGING lt_binary_content
                                       lv_size.

  zcl_bcs_send=>mail_send( im_tab = lt_binary_content
                           im_recipient = r_mail
                           im_size = lv_size
                         im_tcode = sy-tcode ). *-this can be hardcoded

ENDFORM.                    " F_MAIL_SEND


FORM f_build_email_data  CHANGING p_lt_binary_content
         TYPE STANDARD TABLE
                             p_size TYPE so_obj_len.
  DATA: e_xstring TYPE xstring.
  DATA: mt_fcat TYPE lvc_t_fcat,
        ms_fcat TYPE lvc_s_fcat,
      st_fieldcat  TYPE slis_fieldcat_alv.
  DATA: mt_data       TYPE REF TO data.
  DATA: m_flavour TYPE string.
  DATA: m_version TYPE string.
  DATA: mo_result_data TYPE REF TO cl_salv_ex_result_data_table.
  DATA: mo_columns  TYPE REF TO cl_salv_columns_table.
  DATA: mo_aggreg   TYPE REF TO cl_salv_aggregations.
  DATA: mo_salv_table  TYPE REF TO cl_salv_table.
  DATA: m_file_type TYPE salv_bs_constant.
  DATA: out_length TYPE i.
  FIELD-SYMBOLS <tab> TYPE ANY TABLE.

  CLEAR: e_xstring, ms_fcat, st_fieldcat, m_flavour, m_version,
         mo_result_data, mo_columns, mo_aggreg, mo_salv_table,
         m_file_type, out_length, mt_data.
  REFRESH: it_fieldcat[].

*-It_final here is the final itab same parameter you pass in

your alv grid
  GET REFERENCE OF it_final INTO mt_data.

*-Move your field catalog to mt_fcat make sure to populate

*-ms_fcat-seltext, because it can be that in your field cat the headings

*-are in seltext_l or seltext_m or seltext_s
  LOOP AT it_fieldcat INTO st_fieldcat.
    MOVE-CORRESPONDING st_fieldcat TO ms_fcat.
    MOVE: st_fieldcat-seltext_l TO ms_fcat-seltext.
    APPEND ms_fcat TO mt_fcat.
    CLEAR: ms_fcat, st_fieldcat.
  ENDLOOP.

  IF cl_salv_bs_a_xml_base=>get_version( ) EQ if_salv_bs_xml=>version_25 OR
     cl_salv_bs_a_xml_base=>get_version( ) EQ if_salv_bs_xml=>version_26.

    mo_result_data = cl_salv_ex_util=>factory_result_data_table(
        r_data                      = mt_data
        t_fieldcatalog              = mt_fcat
    ).

    CASE cl_salv_bs_a_xml_base=>get_version( ).
      WHEN if_salv_bs_xml=>version_25.
        m_version = if_salv_bs_xml=>version_25.
      WHEN if_salv_bs_xml=>version_26.
        m_version = if_salv_bs_xml=>version_26.
    ENDCASE.

    m_file_type = if_salv_bs_xml=>c_type_xlsx.
    m_flavour = if_salv_bs_c_tt=>c_tt_xml_flavour_export.

    "transformation of data to excel
    CALL METHOD cl_salv_bs_tt_util=>if_salv_bs_tt_util~transform
      EXPORTING
        xml_type      = m_file_type
        xml_version   = m_version
        r_result_data = mo_result_data
        xml_flavour   = m_flavour
        gui_type      = if_salv_bs_xml=>c_gui_type_gui
      IMPORTING
        xml           = e_xstring.
  endif.

  call function 'SCMS_XSTRING_TO_BINARY'
      exporting
        buffer          = e_xstring
      importing
        output_length   = out_length
      tables
        binary_tab      = p_lt_binary_content.

  MOVE: out_length TO p_size.

ENDFORM.                    " F_BUILD_EMAIL_DATA


Static class: zcl_bcs_send=>mail_send

Code:

*--Run Date and Run Time
v_rundate = sy-datum.
v_runtime = sy-uzeit.
concatenate v_rundate v_runtime into timestamp.
try.
* -------- create persistent send request ------------------------
lcl_send_request = cl_bcs=>create_persistent( ).

* -------- create and set document with attachment ---------------
* create document object from internal table with text
concatenate im_tcode 'Result' '-' timestamp
sy-sysid into lv_subject
separated by space.
concatenate 'The Attached document is the output listing of'
im_tcode into lv_text separated by space.
append lv_text to lt_main_text.
append text-001 to lt_main_text.
append text-002 to lt_main_text.
lcl_document = cl_document_bcs=>create_document(
i_type = 'RAW'
i_text = lt_main_text
i_subject = lv_subject ). "#EC NOTEXT

* add the spread sheet as attachment to document object
clear: lv_subject.
concatenate im_tcode '_' v_rundate
v_runtime '_' sy-sysid into lv_filename.
lcl_document->add_attachment(
i_attachment_type = 'xls'
i_attachment_subject = lv_filename
i_attachment_size = im_size
i_att_content_hex = im_tab ).

* add document object to send request
lcl_send_request->set_document( lcl_document ).

* --------- add recipient (e-mail address) -----------------------
* create recipient object
LOOP AT im_recipient INTO ls_recipient.
lv_mailto = ls_recipient-low.
lcl_recipient = cl_cam_address_bcs=>create_internet_address( lv_mailto ).

* add recipient object to send request
lcl_send_request->add_recipient( lcl_recipient ).
CLEAR: ls_recipient.
ENDLOOP.
* Send now
lcl_send_request->set_send_immediately( 'X' ).
* Outbox
lcl_send_request->send_request->set_link_to_outbox( 'X' ).
* ---------- send document ---------------------------------------
lv_sent_to_all = lcl_send_request->send( i_with_error_screen = 'X' ).

commit work.

if lv_sent_to_all is initial.
message i500(sbcoms) with lv_mailto.
else.
message s022(so).
endif.

* ------------ exception handling ----------------------------------
* replace this rudimentary exception handling with your own one !!!
catch cx_bcs into lcl_bcs_exception.
message i865(so) with lcl_bcs_exception->error_type.
endtry.


endmethod.

 


赞赏支持