abap 通用发送邮件程序(获取alv数据,带excel附件)

REPORT z_send_email_with_excel.

*&---------------------------------------------------------------------*

*& 选择屏幕定义

*&---------------------------------------------------------------------*

SELECTION-SCREEN BEGIN OF BLOCK blk1 WITH FRAME TITLE TEXT-001.

PARAMETERS: p_repid TYPE syrepid OBLIGATORY, " 报表程序名

p_varnt TYPE variant OBLIGATORY, " 变式名

p_email TYPE ad_smtpadr OBLIGATORY. " 收件邮箱

SELECTION-SCREEN END OF BLOCK blk1.

SELECTION-SCREEN BEGIN OF BLOCK blk2 WITH FRAME TITLE TEXT-002.

PARAMETERS: p_test AS CHECKBOX DEFAULT 'X'. " 测试模式

SELECTION-SCREEN END OF BLOCK blk2.

*&---------------------------------------------------------------------*

*& 数据类型定义

*&---------------------------------------------------------------------*

TYPES: BEGIN OF ty_config,

report_name TYPE syrepid,

variant_name TYPE variant,

email_to TYPE ad_smtpadr,

END OF ty_config.

*&---------------------------------------------------------------------*

*& 主程序逻辑

*&---------------------------------------------------------------------*

START-OF-SELECTION.

PERFORM main.

*&---------------------------------------------------------------------*

*& Form MAIN

*&---------------------------------------------------------------------*

FORM main.

DATA: ls_config TYPE ty_config.

" 填充配置结构

ls_config-report_name = p_repid.

ls_config-variant_name = p_varnt.

ls_config-email_to = p_email.

" 调用发送功能

PERFORM send_rpt_email USING ls_config-report_name

ls_config-variant_name

ls_config-email_to.

ENDFORM. " MAIN

*&---------------------------------------------------------------------*

*& Form SEND_RPT_EMAIL

*&---------------------------------------------------------------------*

FORM send_rpt_email USING iv_repid TYPE syrepid

iv_varnt TYPE variant

iv_email TYPE ad_smtpadr.

DATA: lt_email TYPE TABLE OF ad_smtpadr.

" 将邮箱地址转换为内表格式

APPEND iv_email TO lt_email.

" 显示开始信息

WRITE: / '开始处理报表:', iv_repid.

WRITE: / '使用变式: ', iv_varnt.

WRITE: / '收件人: ', iv_email.

WRITE: / '测试模式: ', p_test.

ULINE.

" 1. 获取报表数据

DATA: lr_data TYPE REF TO data.

PERFORM get_rpt_data USING iv_repid iv_varnt

CHANGING lr_data.

IF lr_data IS NOT BOUND.

WRITE: / '错误: 无法获取报表数据'.

RETURN.

ENDIF.

" 2. 转换为 Excel

DATA: lv_xstr TYPE xstring.

PERFORM create_xstring USING lr_data iv_repid

CHANGING lv_xstr.

IF lv_xstr IS INITIAL.

WRITE: / '错误: Excel 转换失败'.

RETURN.

ENDIF.

" 3. 发送邮件(测试模式下只模拟)

IF p_test = 'X'.

PERFORM simu_email USING lt_email lv_xstr iv_repid.

ELSE.

PERFORM send_email USING lt_email lv_xstr iv_repid.

ENDIF.

ENDFORM. " SEND_RPT_EMAIL

*&---------------------------------------------------------------------*

*& Form GET_RPT_DATA

*&---------------------------------------------------------------------*

FORM get_rpt_data USING iv_repid TYPE syrepid

iv_varnt TYPE variant

CHANGING cr_data TYPE REF TO data.

" 使用 CL_SALV_BS_RUNTIME_INFO 获取 ALV 数据

CL_SALV_BS_RUNTIME_INFO=>SET(

EXPORTING

display = abap_false

metadata = abap_false

data = abap_true

).

TRY.

" 提交报表到内存

SUBMIT (iv_repid) USING SELECTION-SET iv_varnt

AND RETURN.

" 获取数据引用

CL_SALV_BS_RUNTIME_INFO=>GET_DATA_REF( IMPORTING r_data = cr_data ).

WRITE: / '成功获取报表数据'.

CATCH cx_salv_bs_sc_runtime_info.

WRITE: / '错误: 报表不是 ALV 格式或执行失败'.

CLEAR cr_data.

ENDTRY.

CL_SALV_BS_RUNTIME_INFO=>CLEAR_ALL( ).

ENDFORM. " GET_RPT_DATA

*&---------------------------------------------------------------------*

*& Form CREATE_XSTRING

*&---------------------------------------------------------------------*

FORM create_xstring USING ir_data TYPE REF TO data

iv_repid TYPE syrepid

CHANGING cv_xstring TYPE xstring.

FIELD-SYMBOLS: <lt_table> TYPE STANDARD TABLE.

DATA: lt_fcat TYPE lvc_t_fcat.

" 分配数据到字段符号

ASSIGN ir_data->* TO <lt_table>.

" 检查表是否为空

IF lines( <lt_table> ) = 0.

WRITE: / '警告: 报表数据为空'.

RETURN.

ENDIF.

TRY.

" 创建 SALV 表

cl_salv_table=>factory(

IMPORTING

r_salv_table = DATA(lo_table)

CHANGING

t_table = <lt_table> ).

" 获取字段目录

lt_fcat = cl_salv_controller_metadata=>get_lvc_fieldcatalog(

r_columns = lo_table->get_columns( )

r_aggregations = lo_table->get_aggregations( ) ).

" 创建结果数据对象

DATA(lo_result) = cl_salv_ex_util=>factory_result_data_table(

r_data = ir_data

t_fieldcatalog = lt_fcat ).

" 转换为 XLSX

cl_salv_bs_tt_util=>if_salv_bs_tt_util~transform(

EXPORTING

xml_type = if_salv_bs_xml=>c_type_xlsx

xml_version = cl_salv_bs_a_xml_base=>get_version( )

r_result_data = lo_result

xml_flavour = if_salv_bs_c_tt=>c_tt_xml_flavour_export

gui_type = if_salv_bs_xml=>c_gui_type_gui

IMPORTING

xml = cv_xstring ).

WRITE: / '成功生成 Excel 文件, 大小:', xstrlen( cv_xstring ), 'bytes'.

CATCH cx_root INTO DATA(lx_error).

WRITE: / 'Excel 转换错误:', lx_error->get_text( ).

CLEAR cv_xstring.

ENDTRY.

ENDFORM. " CREATE_XSTRING

*&---------------------------------------------------------------------*

*& Form SIMU_EMAIL

*&---------------------------------------------------------------------*

FORM simu_email USING it_email TYPE table

iv_xstr TYPE xstring

iv_repid TYPE syrepid.

DATA: lv_email TYPE ad_smtpadr.

WRITE: / '=== 测试模式 - 邮件发送模拟 ==='.

WRITE: / '收件人列表:'.

LOOP AT it_email INTO lv_email.

WRITE: / ' -', lv_email.

ENDLOOP.

WRITE: / '邮件主题: 报表', iv_repid, '数据导出'.

WRITE: / '附件: 已生成 Excel 文件 (不实际发送)'.

WRITE: / '如需实际发送,请取消选择"测试模式"'.

ENDFORM. " SIMU_EMAIL

*&---------------------------------------------------------------------*

*& Form SEND_EMAIL

*&---------------------------------------------------------------------*

FORM send_email USING it_email TYPE table

iv_xstr TYPE xstring

iv_repid TYPE syrepid.

DATA: lv_email TYPE ad_smtpadr,

lv_attach_size TYPE so_obj_len.

TRY.

" 计算附件大小

lv_attach_size = xstrlen( iv_xstr ).

" 创建发送请求

DATA(lo_send_request) = cl_bcs=>create_persistent( ).

" 创建邮件正文

DATA(lt_body) = VALUE bcsy_text(

( line = 'Dear Sir/Madam,' )

( line = '' )

( line = '' )

( line = |这是报表 { iv_repid } 的数据导出文件,请查收。| )

( line = '' )

( line = |生成时间:{ sy-datum } { sy-uzeit }| )

( line = '' )

( line = 'Best regards,' )

( line = 'SAP System' )

).

" 设置文档对象

DATA: lv_subject TYPE so_obj_des.

CONCATENATE '报表' iv_repid '数据导出' INTO lv_subject SEPARATED BY space.

DATA(lo_document) = cl_document_bcs=>create_document(

i_type = 'RAW'

i_text = lt_body

i_subject = lv_subject ).

" 添加附件

DATA: lv_attach_sub TYPE sood-objdes.

CONCATENATE iv_repid '' sy-datum '' sy-uzeit INTO lv_attach_sub.

lv_attach_sub = lv_attach_sub && '.xlsx'.

lo_document->add_attachment(

i_attachment_type = 'BIN'

i_attachment_size = lv_attach_size

i_attachment_subject = lv_attach_sub

i_att_content_hex = cl_bcs_convert=>xstring_to_solix( iv_xstr ) ).

" 添加文档到发送请求

lo_send_request->set_document( lo_document ).

" 设置发件人(使用默认发件人)

DATA(lo_sender) = cl_sapuser_bcs=>create( sy-uname ).

lo_send_request->set_sender( lo_sender ).

" 设置收件人

LOOP AT it_email INTO lv_email.

DATA(lo_recipient) = cl_cam_address_bcs=>create_internet_address( lv_email ).

lo_send_request->add_recipient(

i_recipient = lo_recipient

i_express = abap_true ).

ENDLOOP.

" 发送邮件

DATA(lv_sent_to_all) = lo_send_request->send( ).

COMMIT WORK.

IF lv_sent_to_all = abap_true.

WRITE: / '成功: 邮件已发送!'.

" 立即发送出站邮件

WAIT UP TO 2 SECONDS.

SUBMIT rsconn01 WITH mode = 'INT' AND RETURN.

ELSE.

WRITE: / '警告: 邮件可能未发送给所有收件人'.

ENDIF.

CATCH cx_send_req_bcs INTO DATA(lx_req_bcs).

WRITE: / '发送请求错误:', lx_req_bcs->get_text( ).

CATCH cx_document_bcs INTO DATA(lx_doc_bcs).

WRITE: / '文档创建错误:', lx_doc_bcs->get_text( ).

CATCH cx_address_bcs INTO DATA(lx_add_bcs).

WRITE: / '地址错误:', lx_add_bcs->get_text( ).

CATCH cx_root INTO DATA(lx_error).

WRITE: / '邮件发送错误:', lx_error->get_text( ).

ENDTRY.

ENDFORM. " SEND_EMAIL

*&---------------------------------------------------------------------*

*& 初始化事件

*&---------------------------------------------------------------------*

INITIALIZATION.

相关推荐
HeathlX6 小时前
ABAP-OO:(4)封装、继承、多态
abap
CircleMouse7 小时前
如何设置wps单元格下拉选项设置
excel·wps
zhangjin122212 小时前
kettle插件-excel插件,kettle读取excel动态表头,kettle根据列名读取excel
excel·kettle·kettle excel插件·kettle 动态excel
小狼Solar16 小时前
SAP Business Partner WebService 使用问题大全
sap·bp·mdg·数据分发·业务合作伙伴
远洪1 天前
excel 找出两列不同的数据
excel
pcplayer1 天前
非常好用的 Excel 读写控件
excel·delphi·office
Navicat中国1 天前
使用 Navicat 导入向导导入 Excel 数据时,系统提示导入成功,表中也能看到数据,但行数统计显示为 0,这是什么原因?
数据库·excel·导入
穿着内裤的外星人1 天前
触控精灵远程读写Excel步骤配置
excel
duangww2 天前
OPEN SQL去掉文本中间的空格
数据库·abap
是孑然呀2 天前
【小记】excel vlookup一对多(第二篇)
excel