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.

相关推荐
忘忧记6 小时前
Excel拆分和合并优化版本
windows·microsoft·excel
牵牛老人7 小时前
Qt 中如何操作 Excel 表格:主流开源库说明介绍与 QXlsx 库应用全解析
qt·开源·excel
十碗饭吃不饱7 小时前
RuoYi/ExcelUtil修改(导入excel表时,表中字段没有映射上数据库表字段)
数据库·windows·excel
林月明16 小时前
【VBA】自动设置excel目标列的左邻列格式
开发语言·excel·vba·格式
JavaOpsPro19 小时前
审计 jenkins获取构建历史,生成excel
运维·jenkins·excel
CodeCraft Studio21 小时前
国产化Excel开发组件Spire.XLS教程:在Python中将Pandas DataFrame导出到Excel的详细教程
python·excel·pandas
电话交换机IPPBX-3CX21 小时前
在 MS Excel 和 Google Sheets 中生成 3CX 可视化通话报告
excel·ip pbx·电话交换机·google表格·可视化报表
星空的资源小屋1 天前
Antares SQL,一款跨平台开源 SQL 客户端
数据库·人工智能·pdf·开源·电脑·excel·1024程序员节
萌新小码农‍2 天前
SpringBoot+alibaba的easyexcel实现前端使用excel表格批量插入
前端·spring boot·excel