SAP ABAP 基于 CL_BCS 发送邮件

2024-03-07 01:40
文章标签 邮件 发送 sap abap cl bcs

本文主要是介绍SAP ABAP 基于 CL_BCS 发送邮件,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

1.前言:

2.介绍:

3.正文:

3.1自开发邮件发送工具类的使用:

3.2邮件模板上传及调用:

3.2.1 SO10上传邮件模板

3.2.2 SMW0上传html模板

3.2.3 SE80->Email Template创建邮件模板

3.3.模板中图片的替换

3.3.1 直接指定图片Base64编码

3.3.2 使用SMW0上传图片

3.3.3 使用SO2_MIME_REPOSITORY上传图片

3.4.Smartforms转PDF并添加为邮件附件

3.4.1 PDF合并功能:

3.5.ALV转换为PDF并添加为邮件附件

3.6.添加文件扩展名后缀为4位的附件,如xlsx附件

3.6.1添加本地上传的文件至邮件附件

3.6.2将程序内表转换为xlsx内容并添加至附件 

3.7.框架源码及表结构信息

3.8.SE38 Demo程序源码


1.前言:

总结这边文章起因是近期碰到需要使用ABAP给客户发送邮件功能,需求只是简单的发送邮件并且将明细内容以表格形式置于邮件正文中,之前只是知道大概怎么发送邮件,没有自己完整的从头写过,所以借着这个机会把发送邮件这部分能想到的需求全部进行集中测试实现,以后就不用再到处搜了。


2.介绍:

发送邮件的API有很多种,但是SAP早在note190669中就提到,推荐使用CL_BCS来进行邮件发送,BCS(Business Communication Service)接口提供了一种舒适的、基于类的方法来发送文档,比起API1接口,更易使用,参数更加清晰和容易理解,也不在需要填充让人难以理解的装箱单参数,此外,CL_BCS还提供了更多选项。

比较旧的功能模块:

  • SO_DOCUMENT_SEND_API1
  • SO_NEW_DOCUMENT_ATT_SEND_API1
  • SO_NEW_DOCUMENT_SEND_API1
  • SO_OBJECT_SEND
  • EFG_GEN_SEND_EMAIL
  • SO_DOCUMENT_REPOSITORY_MANAGER

SAP针对于CL_BCS提供了以下示例程序可供参考,这些程序是模板程序,不能直接执行,因为有些内容是硬编码的:

  • BCS_EXAMPLE_1:发送文本内容
  • BCS_EXAMPLE_2:发送文本内容及附件
  • BCS_EXAMPLE_3:根据用户名发送邮件
  • BCS_EXAMPLE_4:在选择框中选择收件人并发送邮件
  • BCS_EXAMPLE_5:发送文本内容及Doc文件附件
  • BCS_EXAMPLE_6:发送PDF附件(AdobeFrom转PDF)
  • BCS_EXAMPLE_7:发送XLS附件
  • BCS_EXAMPLE_8:将假脱机请求列表中的PDF文件转为邮件附件发送

3.正文:

2023.12.08日更新,更新内容已在底部源码中添加

追加添加xlsx附件的实现:

        1.添加本地上传的xlsx附件;

        2.添加通过内表转换的xlsx附件。

基于平时开发习惯,我将邮件功能调用的部分基于CL_BCS封装成了一个自开发工具类,将一些通用功能进行封装,可以使代码调用时,可以减少重复的代码量,基于该封装类我同时创建了一份参考代码,其中包括以下功能:

  • 发送正文格式为普通文本格式的邮件
  • 发送正文格式为html的邮件(html部分由ABAP代码手工生成)
  • 发送正文格式基于电子邮件模板的邮件(SE80->Email Template,可与CDS关联)
  • 发送正文格式基于电子邮件模板的邮件(SMW0->上传HTML Template)
  • 在邮件正文中动态替换SMW0上传的图片
  • 在邮件正文中动态替换SO2_MIME_REPOSITORY上传的图片
  • 在邮件中添加.txt格式附件
  • 在邮件中添加.csv格式附件
  • 在邮件中添加.xlsx格式附件(本地上传&内表转换)
  • 在邮件中添加由Smartforms转换为PDF的附件(可进行多个PDF合并)
  • 在邮件中添加由ALV打印为表格格式PDF的附件

在实现这些功能的过程中,或多或少都碰到了一些问题,在后文中我会将解决方式详细补充。 

Demo程序效果:

 

3.1自开发邮件发送工具类的使用:

以下代码截图为封装的工具类的部分源码,完整源码会在最下面附上。

实例化邮件对象:

*       create instance of CL_BCSlo_send_request = cl_bcs=>create_persistent( ).

设置发件人:

*       Set sender email addresslo_mail_from = cl_cam_address_bcs=>create_internet_address( iv_mail_from_address ).lo_send_request->set_sender( lo_mail_from ).

设置收件人及立即发送:

*       Set receiver email addressLOOP AT it_mail_to_address INTO DATA(ls_mail_to_address).lo_mail_to = cl_cam_address_bcs=>create_internet_address( ls_mail_to_address ).*         Send immediatelylo_send_request->set_send_immediately( i_send_immediately = abap_true ).*         Set addresslo_send_request->add_recipient( i_recipient = lo_mail_toi_express   = abap_true ).ENDLOOP.

设置抄送人及立即发送,i_copy 参数指定为'X'即可:

*       Set CC email addressLOOP AT it_mail_cc_address INTO DATA(ls_mail_cc_address).lo_mail_cc = cl_cam_address_bcs=>create_internet_address( ls_mail_cc_address ).*         Send immediatelylo_send_request->set_send_immediately( i_send_immediately = abap_true ).*         Set addresslo_send_request->add_recipient( i_recipient = lo_mail_cci_copy      = abap_truei_express   = abap_true ).ENDLOOP.

文本类型正文,i_type 类型可以是 'RAW','TXT' 等:

          lt_mail_body = ls_body_in-body_tline-tline.*         Create mail body document objectlo_document = cl_document_bcs=>create_document(i_type    = ls_body_in-body_tline-typei_text    = lt_mail_bodyi_subject = iv_title ).

HTML类型正文,i_type 类型为 'HTM':

*         Convert string to solitablt_mail_body = cl_bcs_convert=>string_to_soli(EXPORTINGiv_string = ls_body_in-body_html-html).*         Create mail body document objectlo_document = cl_document_bcs=>create_document(i_type    = ls_body_in-body_html-typei_text    = lt_mail_bodyi_subject = iv_title ).

SE80创建的邮件模板内容动态替换:

*       Standard Template ->SE80->Email TemplateIF ls_body_in-body_template IS NOT INITIAL.CLEAR:ls_body_in-body_tline,ls_body_in-body_html,ls_body_in-body_temp_smw0.*         Build document object with templatebuild_document_with_template(EXPORTINGis_body_temp = ls_body_in-body_templateIMPORTINGeo_document = lo_documentes_return   = es_return).CHECK es_return-type <> gc_type_e.ENDIF.

SMW0邮件模板内容动态替换:

*       Template ->SMW0IF ls_body_in-body_temp_smw0 IS NOT INITIAL.CLEAR:ls_body_in-body_tline,ls_body_in-body_html,ls_body_in-body_template.*         Build document object with templatebuild_document_with_temp_smw0(EXPORTINGis_body_temp = ls_body_in-body_temp_smw0IMPORTINGeo_document = lo_documentes_return   = es_return).CHECK es_return-type <> gc_type_e.ENDIF.

添加邮件附件:

*       Add attachmentIF it_attachment IS NOT INITIAL.LOOP AT it_attachment INTO DATA(ls_attachment).lo_document->add_attachment( i_attachment_type    = ls_attachment-typei_attachment_subject = ls_attachment-att_namei_attachment_size    = ls_attachment-sizei_att_content_hex    = ls_attachment-body_content ).ENDLOOP.ENDIF.

构建邮件主体及邮件发送:

*       Binding mail bodylo_send_request->set_document( lo_document ).*       Send maillv_result = lo_send_request->send( i_with_error_screen = abap_true ).

获取邮件UUID,用于检索SOST中的状态:

*       Get UUIDlv_oid = lo_send_request->oid( ).

根据UUID检索邮件状态,因为CL_BCS类只负责发起邮件传输请求,无法立刻获取邮件的状态信息,虽然有函数 SX_SNDREC_SELECT 可以获取SOST的列表信息,但是该函数不能抓取到具体某一条记录,所以直接从底表抓取。(SAP发送邮件只负责将邮件推送至邮件服务器,然后再由邮件服务器发给收件人,至于收件人有没有收到该邮件,只有邮件服务器知道,SAP并不会接收到该反馈,所以SOST中状态成功只表明邮件已成功推送至邮件服务器)

此处使用时间戳来替代wait up to ** seconds的写法,使其只需要等待他真正所需要的时间,不需要浪费任何零点几秒,或者零点零几秒。

        IF lv_result = abap_true.COMMIT WORK AND WAIT.GET TIME STAMP FIELD ls_time-start.WHILE ls_time-elapsed < ls_time-limit.
*           Get mail send status in SOSTSELECT SINGLEa~objtp,a~objyr,a~objno,a~fortp,a~foryr,a~forno,a~rectp,a~recyr,a~recno,a~sndreq,b~status,b~msgid,b~msgty,b~msgv1,b~msgv2,b~msgv3,b~msgv4INTO @DATA(ls_mail_status)FROM soos AS aINNER JOIN soes AS bON a~rectp = b~rectpAND a~recyr = b~recyrAND a~recno = b~recnoWHERE a~sndreq = @lv_oid.IF ls_mail_status-msgid IS NOT INITIAL.EXIT.ENDIF.GET TIME STAMP FIELD ls_time-now.ls_time-elapsed = cl_abap_tstmp=>subtract(tstmp1 = ls_time-nowtstmp2 = ls_time-start).ENDWHILE.IF ls_mail_status-status <> gc_success_status.es_return-type    = ls_mail_status-msgty.lv_msgno = ls_mail_status-status.CALL FUNCTION 'BAPI_MESSAGE_GETDETAIL'EXPORTINGid         = ls_mail_status-msgidnumber     = lv_msgnotextformat = gc_textformatmessage_v1 = ls_mail_status-msgv1message_v2 = ls_mail_status-msgv2message_v3 = ls_mail_status-msgv3message_v4 = ls_mail_status-msgv4IMPORTINGmessage    = es_return-message.ELSE.es_return-type    = gc_type_s.es_return-message = 'Mail send success.'(002).ENDIF.ELSE.ROLLBACK WORK.es_return-type    = gc_type_e.es_return-message = 'Mail send failed, Please use tcode SOST to check detail.'(003).ENDIF.

具体实现细节可以阅读底部源码,下面只介绍其中一些功能的实现过程。

3.2邮件模板上传及调用:

SAP中目前我了解到的有以下三种方式来创建邮件模板:

3.2.1 SO10上传邮件模板

跟长文本一样的形式,通过READ_TEXT获取到长文本后,对某些变量进行替换,来构建正文内容,其实也可以直接维护一段html进去,在运行时替换到里面的某些标记字符,有些项目对邮件内容格式没有太多要求,且只有一些简单的文本内容时,会选择此方式进行邮件模板的维护。

在查阅相关资料时看到SO10似乎还支持上传一些具有富文本格式的RTF文件作为模板,配合READ_TEXT 和 CONVERT_ITF_TO_STREAM_TEXT 可以得到具有格式的邮件内容,不过我没有对此过多研究,具有复杂格式的邮件模板使用下面两种方式我觉得会更方便一些。

3.2.2 SMW0上传html模板

事先通过Vscode或者一些在线html编辑工具,构建好自己想要的效果的html文件,将其保存到本地,并通过SMW0上传,我这里用了一个在线网站去编写了html代码,因为可以即时生成预览画面,方便调整。

 

在模板中预留了一些占位符,在后续传值时会被程序传入的内容动态替换掉。


调用方式:

    key-objid = is_body_temp-id.IMPORT html TO lt_html_table FROM DATABASE wwwdata(ht) ID key.IF sy-subrc <> 0.
*     Object &1 does not exist in Web RepositoryMESSAGE s000(swww) WITH is_body_temp-id INTO es_return-message.es_return-type = gc_type_e.RETURN.ENDIF.lv_html_string = cl_bcs_convert=>txt_to_string( EXPORTING it_soli = lt_html_table ).LOOP AT is_body_temp-replace_info INTO DATA(ls_repace_info).REPLACE ALL OCCURRENCES OF ls_repace_info-mark_fieldIN lv_html_stringWITH cl_bcs_convert=>txt_to_string( EXPORTING it_soli = ls_repace_info-body_html ).ENDLOOP.lt_html_table = cl_bcs_convert=>string_to_soli( EXPORTING iv_string = lv_html_string ).DATA(lo_multipart) = NEW cl_gbt_multirelated_service( ).lo_multipart->set_main_html(EXPORTINGcontent = lt_html_table).

先从 WWWDATA 表中取出html数据,转换为string后,根据传入的标记字段名mark_field去替换对应的内容,本来SAP提供了一个替换SMW0模板内容的函数 WWW_HTML_MERGER,但是该函数有个bug,由于他返回的html是CHAR255的表类型,而函数中替换逻辑是循环这个表去根据传入的内容进行替换,这就有可能会有两个问题:

问题1有可能解析出来模板里的标记字段刚好被分隔到了两行中,这样就无法检索到这个标记字段进行替换。

.......<!--Do
cument--> ......

问题2有可能我要替换的内容超过了255个长度,那么就会导致内容丢失。

<tr><td>Document</td>............<t

所以需要将html表转换为string类型后,再依次去替换内容。


3.2.3 SE80->Email Template创建邮件模板

以下是Email Template的一些特性:

1.可以关联CDS VIEW,使用CDS VIEW可以在调用时通过传入CDS KEY,来自动填充通过 {{}}包裹的字段变量,包括标题和正文,如上图中的{{banfn}},注意区分大小写,适合正文中只需要单条数据进行填充的邮件模板,因为框架源码中使用的是SELECT SINGLE来获取的CDS VIEW数据,此时代码中只需传入发件人,收件人,抄送人,CDS KEY即可生成邮件并发送,不需要额外代码。

2.支持多语言版本,调用时可以传入指定语言和默认语言,当指定语言版本的模板不存在时,会以默认语言版本生成邮件内容。 

3.可以直接进行内容预览,点击Preview按钮即可直接查看html预览画面,方便修正一些信息。

4.支持在右侧编辑区域构建html及纯文本格式的邮件内容,可以附加一些字体及样式等控制(最好使用内联方式指定样式,因为很多邮箱产品基于各种因素会对邮件内容进行截取,很多时候<body>标签之外的内容都会截取,所以style声明的一些样式控制在某些邮箱中可能不会生效)。

5.该应用在Fiori中比起SO10有更好的界面。


创建CDS:

普通CDS创建完成后填入邮件模板会报下面这个错误:

在CDS VIEW的属性中,进行发布后就可以消除这个提示:

创建Email Template内容:

除了手动编写,Vscode或者在线网站编写html外,还有一种方式也可以快速的生成html,借助word工具,将邮件需要内容填写好,包括字体样式颜色等,直接另存为.html格式,好处是借助这种方式生成的html的样式控制都是内联方式的,可以直接上传到邮件模板中去,不好的地方是,转换的html内容非常长,包含了一些无用信息。

同SMW0上传的模板一样,有些CDS VIEW不能获取的信息,html中仍需要留下标记字段,在代码中进行替换:

 


调用方式:

① 根据模板ID(SE80创建的模板名)获取模板对象实例。

② CDS KEY赋值,例:

namevalue
BANFN0010000129

③ 根据指定的模板语言及CDS KEY获取替换后内容的html内容及邮件标题。

④ 根据传入的替换信息,替换html模板中仍未填充的动态变量,例:

mark_fieldbody_html
<!--&APPROVER&-->MrMeng
<!--&TableContent&--><tr><td>物料A</td><td>12348523</td></tr>...

⑤ 将String类型html转换为类需要的类型。

⑥ 将最终完整的信息进行绑定。


3.3.模板中图片的替换

邮件正文中的图片可以有三种方式进行替换:

3.3.1 直接指定图片Base64编码

直接在src中指定图片的Base64编码,但是通常图片的Base64编码会非常长,会让你的html充满大量的字符,会显得很臃肿,如果某些图片是固定的,也可以使用这种方式去创建模板。

3.3.2 使用SMW0上传图片

需要注意的是,如果系统中没有分配图片类型对应的MIME TYPE,创建的时候需要注意,TYPE不能只填png,需要填写完整的类型名称 image/png,因为后续函数获取图片信息时,有一处硬编码,只填写png时会引发系统dump。

 获取图片信息:

    DATA:lt_query       TYPE STANDARD TABLE OF w3query,ls_query       TYPE w3query,lt_html        TYPE STANDARD TABLE OF w3html,lv_length      TYPE w3param-cont_len,lv_return_code TYPE w3param-ret_code.CHECK iv_smw0_name IS NOT INITIAL.ls_query-name  = gc_object_id.ls_query-value = iv_smw0_name.APPEND ls_query TO lt_query.*   Get content from SMW0
*   This function is obsolete,MIME Repository is recommendedCALL FUNCTION 'WWW_GET_MIME_OBJECT'TABLESquery_string        = lt_queryhtml                = lt_htmlmime                = et_solixCHANGINGreturn_code         = lv_return_codecontent_type        = ev_typecontent_length      = lv_lengthEXCEPTIONSobject_not_found    = 1parameter_not_found = 2OTHERS              = 3.IF sy-subrc <> 0.
*     Implement suitable error handling hereENDIF.ev_length = lv_length.

 Tips:该函数调用时会提示函数已弃用,所以不是很建议用这种方式。

替换模板中图片:

① 获取实例

② 将替换完毕的正文内容进行绑定

③ 获取图片信息

④ 绑定图片信息

⑤ 根据绑定了正文及图片信息的对象生成最终完整的邮件对象

3.3.3 使用SO2_MIME_REPOSITORY上传图片

使用事务代码 SO2_MIME_REPOSITORY 上传图片,或者从以下入口进入MIME Repository。

 

关于MIME Repository的更多信息,可以阅读Jerry老师的这篇文章。

SAP ABAP MIME Repository 和 API 介绍icon-default.png?t=N7T8https://blog.csdn.net/i042416/article/details/129785805?ops_request_misc=&request_id=c36bf275b8ae432e9b36e6ae3486f0d4&biz_id=&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~koosearch~default-1-129785805-null-null.268%5Ev1%5Econtrol&utm_term=MIME%20&spm=1018.2226.3001.4450 本例中我没有上传个人的图片,发现有现有的图片可以测试用,该图片在路径/SAP/PUBLIC下。

 获取图片信息:

    DATA:lo_mr_api  TYPE REF TO if_mr_api,lv_content TYPE xstring.CHECK iv_mime_path IS NOT INITIAL.lo_mr_api = cl_mime_repository_api=>get_api( ).lo_mr_api->get(EXPORTINGi_url       = iv_mime_pathIMPORTINGe_content   = lv_contente_mime_type = ev_type).et_solix = cl_bcs_convert=>xstring_to_solix( EXPORTING iv_xstring = lv_content ).

对于邮件中内容格式的各种转换,SAP提供了一个工具类,提供了丰富的内容格式转换方法,使用该工具类,基本可以完成使用过程中任意格式之间的转换。

替换模板中的图片:

3.4.Smartforms转PDF并添加为邮件附件

主要参数为以下三个参数:

no_dialog:       保证不显示弹窗

tdnewid:          设置创建假脱机请求

user_settings:置空,保证上面两个参数生效

调用CONVERT_OTFSPOOLJOB_2_PDF将打印池中的信息转换为PDF。

SAP标准参考程序:RSTXPDFT4。

 

3.4.1 PDF合并功能:

SAP提供了工具类CL_RSPO_PDF_MERGE,可以便捷的实现将多个PDF合并为同一个PDF。

SAP标准参考程序:RSPO_TEST_MERGE_PDF_FILES。

3.5.ALV转换为PDF并添加为邮件附件

主要问题点有以下三点:

PRINT = 'X' :保证ALV不显示,只作为后台打印。

GET_PRINT_PARAMETERS:通过设定好打印设备,格式化样式,不显示弹窗等参数,得到完整打印参数。

NEW-PAGE PRINT...: 保证打印时不会出现选打印设备的弹窗,不介意弹窗的可以不加这句代码,但是加了句代码会带来一个额外的问题,下面会说。

调用 CONVERT_ABAPSPOOLJOB_2_PDF 可以直接获取到 PDF 的 XSTRING 类型内容,后续可以自行选择是否删除打印池中的记录。

问题点

使用NEW-PAGE PRINT...带来的问题是,虽然弹窗没有了,但是调用ALV刷新方法时会引发系统dump。

原因是该语法之后调用ALV DISPLAY函数会产生一条新的屏幕堆栈记录,我没有详细追究其原理,只是确定了解决方式,在调用刷新之前,进行如下处理即可解决。

至此,一些特殊的问题点已补充完毕。下面是完整的框架源码及表结构信息。 


3.6.添加文件扩展名后缀为4位的附件,如xlsx附件

3.6.1添加本地上传的文件至邮件附件

BCS框架提供的文件扩展名是3位字符的,所以像xlsx,docx之类的内容将无法直接添附,如果需要添附4位扩展名的文件作为附件,需要使用关键字"&SO_FILENAME="来确定附件名称和类型。

更多信息可查阅note:1459896 - BCS:支持四位数文件扩展名 - SAP for Me

参考代码:

 

3.6.2将程序内表转换为xlsx内容并添加至附件 

核心方法是使用cl_salv_bs_lex=>export_from_result_data_table来进行内容格式转换,所需要的fieldcat也可以自己手动创建,这个有很多种方法,这里不做赘述。

3.7.框架源码及表结构信息:

 其他的系统标准结构在源码中都能看到。

CLASS zprbccl_send_mail DEFINITIONPUBLICFINALCREATE PUBLIC .PUBLIC SECTION.CONSTANTS gc_type_e TYPE char1 VALUE 'E' ##NO_TEXT.CONSTANTS gc_type_s TYPE char1 VALUE 'S' ##NO_TEXT.CONSTANTS gc_state_a TYPE r3state VALUE 'A' ##NO_TEXT.CONSTANTS gc_object_id TYPE w3_qname VALUE '_OBJECT_ID' ##NO_TEXT.CONSTANTS gc_textformat TYPE bapi_tfrmt VALUE 'ASC' ##NO_TEXT.CONSTANTS gc_success_status TYPE so_rec_sta VALUE '073' ##NO_TEXT.CONSTANTS gc_command_r TYPE char1 VALUE 'R' ##NO_TEXT.CLASS-METHODS send_mailIMPORTING!iv_title             TYPE so_obj_des OPTIONAL!iv_mail_from_address TYPE ad_smtpadr!it_mail_to_address   TYPE zprbct_mail_address!it_mail_cc_address   TYPE zprbct_mail_address OPTIONAL!is_body              TYPE zprbcs_mail_body!it_attachment        TYPE zprbct_mail_attachment OPTIONAL!iv_commit_work       TYPE commitwork DEFAULT 'X'EXPORTINGVALUE(es_return)      TYPE bapiret2 .PROTECTED SECTION.PRIVATE SECTION.CLASS-METHODS build_document_with_temp_smw0IMPORTING!is_body_temp TYPE zprbcs_mail_temp_smw0EXPORTING!es_return    TYPE bapiret2!eo_document  TYPE REF TO cl_document_bcs .CLASS-METHODS build_document_with_templateIMPORTING!is_body_temp TYPE zprbcs_mail_templateEXPORTING!es_return    TYPE bapiret2!eo_document  TYPE REF TO cl_document_bcs .CLASS-METHODS get_image_solix_smw0IMPORTING!iv_smw0_name TYPE w3objidEXPORTING!ev_type      TYPE w3conttype!et_solix     TYPE solix_tab!ev_length    TYPE so_obj_len .CLASS-METHODS get_image_solix_mimeIMPORTING!iv_mime_path TYPE stringEXPORTING!ev_type      TYPE w3conttype!ev_length    TYPE so_obj_len!et_solix     TYPE solix_tab .
ENDCLASS.CLASS ZPRBCCL_SEND_MAIL IMPLEMENTATION.* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Private Method ZPRBCCL_SEND_MAIL=>BUILD_DOCUMENT_WITH_TEMPLATE
* +-------------------------------------------------------------------------------------------------+
* | [--->] IS_BODY_TEMP                   TYPE        ZPRBCS_MAIL_TEMPLATE
* | [<---] ES_RETURN                      TYPE        BAPIRET2
* | [<---] EO_DOCUMENT                    TYPE REF TO CL_DOCUMENT_BCS
* +--------------------------------------------------------------------------------------</SIGNATURE>METHOD build_document_with_template.DATA:lo_email_api      TYPE REF TO if_smtg_email_api,lo_exception      TYPE REF TO cx_smtg_email_common,lv_subject        TYPE string,lv_title          TYPE so_obj_des,lv_body_html      TYPE string,lt_body_html_soli TYPE soli_tab,lt_image_solix    TYPE solix_tab,lv_image_type     TYPE w3conttype,lv_image_length   TYPE so_obj_len,lt_data_key       TYPE if_smtg_email_template=>ty_gt_data_key.DATA:lo_excep_smtg_email_common TYPE REF TO cx_smtg_email_common,lo_excep_document_bcs      TYPE REF TO cx_document_bcs,lo_excep_gbt_mime          TYPE REF TO cx_gbt_mime,lo_excep_bcom_mime         TYPE REF TO cx_bcom_mime.CHECK is_body_temp-id IS NOT INITIAL.TRY .
*       Get template objectlo_email_api = cl_smtg_email_api=>get_instance( iv_template_id = is_body_temp-id  ).MOVE-CORRESPONDING is_body_temp-cds_key TO lt_data_key.TRY .
*           Get html body and replace parameters by cds key.
*           If a cds variable needs to be replaced, it should look like this {{BUKRS}}lo_email_api->render(EXPORTINGiv_language = sy-languit_data_key = lt_data_keyIMPORTINGev_body_html = lv_body_htmlev_subject   = lv_subject).lv_title = lv_subject.*           If the template include some content need to replace,
*           You should set the MARK_FIELD and BODY_HTML,LOOP AT is_body_temp-replace_info INTO DATA(ls_replace_info).REPLACE ls_replace_info-mark_field IN lv_body_html WITH ls_replace_info-body_html.REPLACE ls_replace_info-mark_field IN lv_title     WITH ls_replace_info-body_html.ENDLOOP.lt_body_html_soli = cl_bcs_convert=>string_to_soli( lv_body_html ).DATA(lo_multipart) = NEW cl_gbt_multirelated_service( ).lo_multipart->set_main_html(EXPORTINGcontent     = lt_body_html_soli).*           If you want set some image,you must set value for 'CID',
*           you can only choose one parameter between 'SMW0_NAME' and 'MIME_PATH'.LOOP AT is_body_temp-image_info INTO DATA(ls_image_info).IF ls_image_info-cid IS INITIAL.CONTINUE.ENDIF.IF ls_image_info-smw0_name IS NOT INITIAL.
*               Get SMW0 object contentget_image_solix_smw0(EXPORTINGiv_smw0_name = ls_image_info-smw0_nameIMPORTINGet_solix  = lt_image_solixev_type   = lv_image_typeev_length = lv_image_length).lo_multipart->add_binary_part(EXPORTINGcontent      = lt_image_solixcontent_type = lv_image_typelength       = lv_image_lengthcontent_id   = ls_image_info-cid).ENDIF.IF ls_image_info-mime_path IS NOT INITIAL.
*               Get MIME object contentget_image_solix_mime(EXPORTINGiv_mime_path = ls_image_info-mime_pathIMPORTINGet_solix  = lt_image_solixev_type   = lv_image_typeev_length = lv_image_length).*               Add image contentlo_multipart->add_binary_part(EXPORTINGcontent      = lt_image_solixcontent_type = lv_image_typelength       = lv_image_lengthcontent_id   = ls_image_info-cid).ENDIF.CLEAR:lt_image_solix,lv_image_type,lv_image_length.ENDLOOP.TRY .
*               Generate email document objecteo_document = cl_document_bcs=>create_from_multirelated(EXPORTINGi_subject          = lv_titlei_multirel_service = lo_multipart ).CATCH cx_document_bcs INTO lo_excep_document_bcs.es_return-type    = gc_type_e.es_return-message = lo_excep_document_bcs->get_text( ).RETURN.CATCH cx_gbt_mime INTO lo_excep_gbt_mime.es_return-type    = gc_type_e.es_return-message = lo_excep_gbt_mime->get_text( ).RETURN.CATCH cx_bcom_mime INTO lo_excep_bcom_mime.es_return-type    = gc_type_e.es_return-message = lo_excep_bcom_mime->get_text( ).RETURN.ENDTRY.CATCH cx_smtg_email_common INTO lo_excep_smtg_email_common.es_return-type    = gc_type_e.es_return-message = lo_excep_smtg_email_common->get_text( ).RETURN.ENDTRY.CATCH cx_smtg_email_common INTO lo_excep_smtg_email_common.es_return-type    = gc_type_e.es_return-message = lo_excep_smtg_email_common->get_text( ).RETURN.ENDTRY.ENDMETHOD.* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Private Method ZPRBCCL_SEND_MAIL=>GET_IMAGE_SOLIX_MIME
* +-------------------------------------------------------------------------------------------------+
* | [--->] IV_MIME_PATH                   TYPE        STRING
* | [<---] EV_TYPE                        TYPE        W3CONTTYPE
* | [<---] EV_LENGTH                      TYPE        SO_OBJ_LEN
* | [<---] ET_SOLIX                       TYPE        SOLIX_TAB
* +--------------------------------------------------------------------------------------</SIGNATURE>METHOD get_image_solix_mime.DATA:lo_mr_api  TYPE REF TO if_mr_api,lv_content TYPE xstring.CHECK iv_mime_path IS NOT INITIAL.lo_mr_api = cl_mime_repository_api=>get_api( ).lo_mr_api->get(EXPORTINGi_url       = iv_mime_pathIMPORTINGe_content   = lv_contente_mime_type = ev_type).et_solix = cl_bcs_convert=>xstring_to_solix( EXPORTING iv_xstring = lv_content ).ENDMETHOD.* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Private Method ZPRBCCL_SEND_MAIL=>GET_IMAGE_SOLIX_SMW0
* +-------------------------------------------------------------------------------------------------+
* | [--->] IV_SMW0_NAME                   TYPE        W3OBJID
* | [<---] EV_TYPE                        TYPE        W3CONTTYPE
* | [<---] ET_SOLIX                       TYPE        SOLIX_TAB
* | [<---] EV_LENGTH                      TYPE        SO_OBJ_LEN
* +--------------------------------------------------------------------------------------</SIGNATURE>METHOD get_image_solix_smw0.DATA:lt_query       TYPE STANDARD TABLE OF w3query,ls_query       TYPE w3query,lt_html        TYPE STANDARD TABLE OF w3html,lv_length      TYPE w3param-cont_len,lv_return_code TYPE w3param-ret_code.CHECK iv_smw0_name IS NOT INITIAL.ls_query-name  = gc_object_id.ls_query-value = iv_smw0_name.APPEND ls_query TO lt_query.*   Get content from SMW0
*   This function is obsolete,MIME Repository is recommendedCALL FUNCTION 'WWW_GET_MIME_OBJECT'TABLESquery_string        = lt_queryhtml                = lt_htmlmime                = et_solixCHANGINGreturn_code         = lv_return_codecontent_type        = ev_typecontent_length      = lv_lengthEXCEPTIONSobject_not_found    = 1parameter_not_found = 2OTHERS              = 3.IF sy-subrc <> 0.
*     Implement suitable error handling hereENDIF.ev_length = lv_length.ENDMETHOD.* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Public Method ZPRBCCL_SEND_MAIL=>SEND_MAIL
* +-------------------------------------------------------------------------------------------------+
* | [--->] IV_TITLE                       TYPE        SO_OBJ_DES(optional)
* | [--->] IV_MAIL_FROM_ADDRESS           TYPE        AD_SMTPADR
* | [--->] IT_MAIL_TO_ADDRESS             TYPE        ZPRBCT_MAIL_ADDRESS
* | [--->] IT_MAIL_CC_ADDRESS             TYPE        ZPRBCT_MAIL_ADDRESS(optional)
* | [--->] IS_BODY                        TYPE        ZPRBCS_MAIL_BODY
* | [--->] IT_ATTACHMENT                  TYPE        ZPRBCT_MAIL_ATTACHMENT(optional)
* | [--->] IV_COMMIT_WORK                 TYPE        COMMITWORK (default ='X')
* | [<---] ES_RETURN                      TYPE        BAPIRET2
* +--------------------------------------------------------------------------------------</SIGNATURE>METHOD send_mail.DATA:lo_send_request  TYPE REF TO cl_bcs,lo_mail_from     TYPE REF TO cl_cam_address_bcs,lo_mail_to       TYPE REF TO cl_cam_address_bcs,lo_mail_cc       TYPE REF TO cl_cam_address_bcs,lt_mail_body     TYPE soli_tab,lt_attc_body     TYPE solix_tab,ls_body_in       TYPE zprbcs_mail_body,lo_document      TYPE REF TO cl_document_bcs,lv_result        TYPE os_boolean,lo_bcs_exception TYPE REF TO cx_root,lv_oid           TYPE sysuuid_x,lv_msgno         TYPE symsgno,lt_att_head      TYPE soli_tab,lv_text_line     TYPE soli,lv_filename      TYPE string.DATA:BEGIN OF ls_time,start   TYPE timestampl,                                        "Start timenow     TYPE timestampl,                                        "End timeelapsed TYPE tzntstmpl,                                         "Elapsed timelimit   TYPE tzntstmpl VALUE 3,                                 "Max secondsEND OF ls_time.CLEAR es_return.TRY .
*       create instance of CL_BCSlo_send_request = cl_bcs=>create_persistent( ).*       Set sender email addresslo_mail_from = cl_cam_address_bcs=>create_internet_address( iv_mail_from_address ).lo_send_request->set_sender( lo_mail_from ).*       Set receiver email addressLOOP AT it_mail_to_address INTO DATA(ls_mail_to_address).IF ls_mail_to_address IS INITIAL.es_return-type    = gc_type_e.es_return-message = 'The email address cannot be empty.'(001).RETURN.ENDIF.lo_mail_to = cl_cam_address_bcs=>create_internet_address( ls_mail_to_address ).*         Send immediatelylo_send_request->set_send_immediately( i_send_immediately = abap_true ).*         Set addresslo_send_request->add_recipient( i_recipient = lo_mail_toi_express   = abap_true ).ENDLOOP.*       Set CC email addressLOOP AT it_mail_cc_address INTO DATA(ls_mail_cc_address).IF ls_mail_to_address IS INITIAL.es_return-type    = gc_type_e.es_return-message = 'The email address cannot be empty.'(001).RETURN.ENDIF.lo_mail_cc = cl_cam_address_bcs=>create_internet_address( ls_mail_cc_address ).*         Send immediatelylo_send_request->set_send_immediately( i_send_immediately = abap_true ).*         Set addresslo_send_request->add_recipient( i_recipient = lo_mail_cci_copy      = abap_truei_express   = abap_true ).ENDLOOP.ls_body_in = is_body.*       Text bodyIF ls_body_in-body_tline IS NOT INITIAL.CLEAR:ls_body_in-body_html,ls_body_in-body_template,ls_body_in-body_temp_smw0.lt_mail_body = ls_body_in-body_tline-tline.*         Create mail body document objectlo_document = cl_document_bcs=>create_document(i_type    = ls_body_in-body_tline-typei_text    = lt_mail_bodyi_subject = iv_title ).ENDIF.*       HTML bodyIF ls_body_in-body_html IS NOT INITIAL.CLEAR:ls_body_in-body_tline,ls_body_in-body_template,ls_body_in-body_temp_smw0.*         Convert string to solitablt_mail_body = cl_bcs_convert=>string_to_soli(EXPORTINGiv_string = ls_body_in-body_html-html).*         Create mail body document objectlo_document = cl_document_bcs=>create_document(i_type    = ls_body_in-body_html-typei_text    = lt_mail_bodyi_subject = iv_title ).ENDIF.*       Standard Template ->SE80->Email TemplateIF ls_body_in-body_template IS NOT INITIAL.CLEAR:ls_body_in-body_tline,ls_body_in-body_html,ls_body_in-body_temp_smw0.*         Build document object with templatebuild_document_with_template(EXPORTINGis_body_temp = ls_body_in-body_templateIMPORTINGeo_document = lo_documentes_return   = es_return).CHECK es_return-type <> gc_type_e.ENDIF.*       Template ->SMW0IF ls_body_in-body_temp_smw0 IS NOT INITIAL.CLEAR:ls_body_in-body_tline,ls_body_in-body_html,ls_body_in-body_template.*         Build document object with templatebuild_document_with_temp_smw0(EXPORTINGis_body_temp = ls_body_in-body_temp_smw0IMPORTINGeo_document = lo_documentes_return   = es_return).CHECK es_return-type <> gc_type_e.ENDIF.*       Add attachmentIF it_attachment IS NOT INITIAL.LOOP AT it_attachment INTO DATA(ls_attachment).lv_filename = ls_attachment-att_name.CONCATENATE '&SO_FILENAME=' lv_filename INTO lv_text_line.APPEND lv_text_line TO lt_att_head.lo_document->add_attachment( i_attachment_type    = ls_attachment-typei_attachment_subject = ls_attachment-att_namei_attachment_size    = ls_attachment-sizei_att_content_hex    = ls_attachment-body_contenti_attachment_header  = lt_att_head ).CLEAR:lv_filename,lv_text_line,lt_att_head.ENDLOOP.ENDIF.*       Binding mail bodylo_send_request->set_document( lo_document ).*       Send maillv_result = lo_send_request->send( i_with_error_screen = abap_true ).*       Get UUIDlv_oid = lo_send_request->oid( ).IF lv_result = abap_true.IF iv_commit_work = abap_true.COMMIT WORK AND WAIT.GET TIME STAMP FIELD ls_time-start.WHILE ls_time-elapsed < ls_time-limit.
*           Get mail send status in SOSTSELECT SINGLEa~objtp,a~objyr,a~objno,a~fortp,a~foryr,a~forno,a~rectp,a~recyr,a~recno,a~sndreq,b~status,b~msgid,b~msgty,b~msgv1,b~msgv2,b~msgv3,b~msgv4INTO @DATA(ls_mail_status)FROM soos AS aINNER JOIN soes AS bON a~rectp = b~rectpAND a~recyr = b~recyrAND a~recno = b~recnoWHERE a~sndreq = @lv_oid.IF ls_mail_status-msgid IS NOT INITIAL.EXIT.ENDIF.GET TIME STAMP FIELD ls_time-now.ls_time-elapsed = cl_abap_tstmp=>subtract(tstmp1 = ls_time-nowtstmp2 = ls_time-start).ENDWHILE.IF ls_mail_status-status <> gc_success_status.es_return-type    = ls_mail_status-msgty.lv_msgno = ls_mail_status-status.CALL FUNCTION 'BAPI_MESSAGE_GETDETAIL'EXPORTINGid         = ls_mail_status-msgidnumber     = lv_msgnotextformat = gc_textformatmessage_v1 = ls_mail_status-msgv1message_v2 = ls_mail_status-msgv2message_v3 = ls_mail_status-msgv3message_v4 = ls_mail_status-msgv4IMPORTINGmessage    = es_return-message.ELSE.es_return-type    = gc_type_s.es_return-message = 'Mail send success.'(002).ENDIF.ELSE.es_return-type    = gc_type_s.es_return-message = 'Mail send success.'(002).ENDIF.ELSE.IF iv_commit_work = abap_true.ROLLBACK WORK.ENDIF.es_return-type    = gc_type_e.es_return-message = 'Mail send failed, Please use tcode SOST to check detail.'(003).ENDIF.CATCH cx_bcs INTO lo_bcs_exception.es_return-type    = gc_type_e.es_return-message = lo_bcs_exception->get_text( ).ENDTRY.ENDMETHOD.* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Private Method ZPRBCCL_SEND_MAIL=>BUILD_DOCUMENT_WITH_TEMP_SMW0
* +-------------------------------------------------------------------------------------------------+
* | [--->] IS_BODY_TEMP                   TYPE        ZPRBCS_MAIL_TEMP_SMW0
* | [<---] ES_RETURN                      TYPE        BAPIRET2
* | [<---] EO_DOCUMENT                    TYPE REF TO CL_DOCUMENT_BCS
* +--------------------------------------------------------------------------------------</SIGNATURE>METHOD build_document_with_temp_smw0.DATA:lt_html_table   TYPE swww_t_html_table,lv_html_string  TYPE string,lt_merge_table  TYPE swww_t_merge_table,ls_merge_table  TYPE swww_t_merge_item,lt_image_solix  TYPE solix_tab,lv_image_type   TYPE w3conttype,lv_image_length TYPE so_obj_len.DATA:key TYPE wwwdataid.DATA:lo_excep_smtg_email_common TYPE REF TO cx_smtg_email_common,lo_excep_document_bcs      TYPE REF TO cx_document_bcs,lo_excep_gbt_mime          TYPE REF TO cx_gbt_mime,lo_excep_bcom_mime         TYPE REF TO cx_bcom_mime.CHECK is_body_temp-id IS NOT INITIAL.*   Set replace body
*    LOOP AT is_body_temp-replace_info INTO DATA(ls_repace_info).
*      ls_merge_table-name    = ls_repace_info-mark_field.
*      ls_merge_table-command = gc_command_r.
*      ls_merge_table-html[]  = ls_repace_info-body_html.
*      APPEND ls_merge_table TO lt_merge_table.
*      CLEAR ls_merge_table.
*    ENDLOOP.*   Replace html body
*    CALL FUNCTION 'WWW_HTML_MERGER'
*      EXPORTING
*        template           = is_body_temp-id
**       MERGE_TEXTPOOL     =
**       TEMPLATE_TABLE     =
*      IMPORTING
*        html_table         = lt_html_table
*      CHANGING
*        merge_table        = lt_merge_table
*      EXCEPTIONS
*        template_not_found = 1
*        OTHERS             = 2.key-objid = is_body_temp-id.IMPORT html TO lt_html_table FROM DATABASE wwwdata(ht) ID key.IF sy-subrc <> 0.
*     Object &1 does not exist in Web RepositoryMESSAGE s000(swww) WITH is_body_temp-id INTO es_return-message.es_return-type = gc_type_e.RETURN.ENDIF.lv_html_string = cl_bcs_convert=>txt_to_string( EXPORTING it_soli = lt_html_table ).LOOP AT is_body_temp-replace_info INTO DATA(ls_repace_info).REPLACE ALL OCCURRENCES OF ls_repace_info-mark_fieldIN lv_html_stringWITH cl_bcs_convert=>txt_to_string( EXPORTING it_soli = ls_repace_info-body_html ).ENDLOOP.lt_html_table = cl_bcs_convert=>string_to_soli( EXPORTING iv_string = lv_html_string ).DATA(lo_multipart) = NEW cl_gbt_multirelated_service( ).lo_multipart->set_main_html(EXPORTINGcontent = lt_html_table).*   If you want set some image,you must set value for 'CID',
*   you can only choose one parameter between 'SMW0_NAME' and 'MIME_PATH'.LOOP AT is_body_temp-image_info INTO DATA(ls_image_info).IF ls_image_info-cid IS INITIAL.CONTINUE.ENDIF.IF ls_image_info-smw0_name IS NOT INITIAL.
*       Get SMW0 object contentget_image_solix_smw0(EXPORTINGiv_smw0_name = ls_image_info-smw0_nameIMPORTINGet_solix  = lt_image_solixev_type   = lv_image_typeev_length = lv_image_length).lo_multipart->add_binary_part(EXPORTINGcontent      = lt_image_solixcontent_type = lv_image_typelength       = lv_image_lengthcontent_id   = ls_image_info-cid).ENDIF.IF ls_image_info-mime_path IS NOT INITIAL.
*       Get MIME object contentget_image_solix_mime(EXPORTINGiv_mime_path = ls_image_info-mime_pathIMPORTINGet_solix  = lt_image_solixev_type   = lv_image_typeev_length = lv_image_length).*       Add image contentlo_multipart->add_binary_part(EXPORTINGcontent      = lt_image_solixcontent_type = lv_image_typelength       = lv_image_lengthcontent_id   = ls_image_info-cid).ENDIF.CLEAR:lt_image_solix,lv_image_type,lv_image_length.ENDLOOP.TRY .
*       Generate email document objecteo_document = cl_document_bcs=>create_from_multirelated(EXPORTINGi_subject          = is_body_temp-titlei_multirel_service = lo_multipart ).CATCH cx_document_bcs INTO lo_excep_document_bcs.es_return-type    = gc_type_e.es_return-message = lo_excep_document_bcs->get_text( ).RETURN.CATCH cx_gbt_mime INTO lo_excep_gbt_mime.es_return-type    = gc_type_e.es_return-message = lo_excep_gbt_mime->get_text( ).RETURN.CATCH cx_bcom_mime INTO lo_excep_bcom_mime.es_return-type    = gc_type_e.es_return-message = lo_excep_bcom_mime->get_text( ).RETURN.ENDTRY.ENDMETHOD.
ENDCLASS.

3.8.SE38 Demo程序源码:

CDS VIEW可自行换成自己需要的CDS VIEW名称

*&---------------------------------------------------------------------*
*& Report ZTEST_SEND_MAIL
*&---------------------------------------------------------------------*
*& Author: DeveloperMrMeng
*& Date:   2023/07/16
*&---------------------------------------------------------------------*
*& The sample program includes the following functions:
*& 1. send mail with txt body
*& 2. send mail with html body(use abap build body)
*& 3. send mail with template (SE80->create email template)
*&    3.1  replace fields with cds
*& 4. send mail with template (SMW0)
*& 5. add image with SMW0
*& 6. add image with SO2_MIME_REPOSITORY
*& 7. add attchment
*&    7.1  add .txt file
*&    7.2  add .csv file
*&    7.3  add .xlsx file
*&    7.4  add .pdf from smartforms
*&         7.4.1  Mergae PDF
*&    7.4  add .pdf from alv
*&---------------------------------------------------------------------*
REPORT ztest_send_mail.
TABLES:eban.TYPES:ty_alv TYPE zstest_send_mail,tt_alv TYPE STANDARD TABLE OF ty_alv.DATA:gt_alv    TYPE tt_alv,gs_alv    TYPE ty_alv,gt_sf_alv TYPE tt_alv.DATA:go_alv_grid TYPE REF TO cl_gui_alv_grid,gt_fieldcat TYPE lvc_t_fcat,gs_layout   TYPE lvc_s_layo.CONSTANTS:gc_temp_smw0 TYPE w3objid VALUE 'ZTEST_TEMP_SMW0'.SELECT-OPTIONS:s_banfn FOR eban-banfn.START-OF-SELECTION.PERFORM frm_get_data.PERFORM frm_show_alv.
*&---------------------------------------------------------------------*
*& Form frm_get_data
*&---------------------------------------------------------------------*
*& Get data
*&---------------------------------------------------------------------*
FORM frm_get_data .
* Get relevant dataSELECT a~banfn,                                                       "Purchase Requisition Numbera~bnfpo,                                                       "Item number of purchase requisitiona~bsart,                                                       "Order Type (Purchasing)a~frgst,                                                       "Release strategy in the purchase requisitiona~frggr,                                                       "Release groupa~zrelcode_next,                                               "Release code(Next)b~approver,                                                    "Approverb~email,                                                       "Approver’s Emaila~ekgrp,                                                       "Purchasing Groupa~werks,                                                       "Planta~ernam,                                                       "Name of Person who Created the Objecta~afnam,                                                       "Name of requisitioner/requestera~matnr,                                                       "Material Numbera~txz01,                                                       "Short Texta~menge,                                                       "Quantitya~meins,                                                       "Base Unit of Measurea~value_item,                                                  "Total value at time of releasea~frgdt,                                                       "Purchase Requisition Release Datea~lfdat,                                                       "Delivery datea~webaz,                                                       "Goods receipt processing time in daysa~matkl,                                                       "Material Groupa~dispo,                                                       "MRP Controllera~lifnr                                                        "Account Number of Vendor or CreditorFROM zprmmt_relstat_pr AS aINNER JOIN zprmmtapprinfo AS bON a~frggr = b~frggr
*     AND a~frgst = b~frgstAND a~zrelcode_next = b~frgcoWHERE a~banfn IN @s_banfnAND b~email IS NOT INITIALAND b~approver IS NOT INITIALINTO TABLE @DATA(lt_data).IF lt_data IS INITIAL.MESSAGE 'No data' TYPE 'S'.LEAVE LIST-PROCESSING.ENDIF.SORT lt_data BY banfn ASCENDINGbnfpo ASCENDING.LOOP AT lt_data INTO DATA(ls_data).gs_alv-banfn      = ls_data-banfn.                                  "Purchase Requisition Numbergs_alv-bnfpo      = ls_data-bnfpo.                                  "Item number of purchase requisitiongs_alv-bsart      = ls_data-bsart.                                  "Order Type (Purchasing)gs_alv-frgst      = ls_data-frgst.                                  "Release strategy in the purchase requisitiongs_alv-frggr      = ls_data-frggr.                                  "Release groupgs_alv-frgco      = ls_data-zrelcode_next.                          "Release code(Next)gs_alv-approver   = ls_data-approver.                               "Approvergs_alv-email      = ls_data-email.                                  "Approver’s Emailgs_alv-ekgrp      = ls_data-ekgrp.                                  "Purchasing Groupgs_alv-werks      = ls_data-werks.                                  "Plantgs_alv-ernam      = ls_data-ernam.                                  "Name of Person who Created the Objectgs_alv-afnam      = ls_data-afnam.                                  "Name of requisitioner/requestergs_alv-matnr      = ls_data-matnr.                                  "Material Numbergs_alv-txz01      = ls_data-txz01.                                  "Short Textgs_alv-menge      = ls_data-menge.                                  "Quantitygs_alv-meins      = ls_data-meins.                                  "Base Unit of Measuregs_alv-value_item = ls_data-value_item.                             "Total value at time of releasegs_alv-frgdt      = ls_data-frgdt.                                  "Purchase Requisition Release Dategs_alv-lfdat      = ls_data-lfdat.                                  "Delivery dategs_alv-webaz      = ls_data-webaz.                                  "Goods receipt processing time in daysgs_alv-matkl      = ls_data-matkl.                                  "Material Groupgs_alv-dispo      = ls_data-dispo.                                  "MRP Controllergs_alv-lifnr      = ls_data-lifnr.                                  "Account Number of Vendor or CreditorAPPEND gs_alv TO gt_alv.CLEAR gs_alv.ENDLOOP.SORT gt_alv BY banfn ASCENDINGbnfpo ASCENDINGemail ASCENDING.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form frm_show_alv
*&---------------------------------------------------------------------*
*& Show ALV
*&---------------------------------------------------------------------*
FORM frm_show_alv .
* Set layoutgs_layout-zebra      = 'X'.gs_layout-cwidth_opt = 'X'.gs_layout-box_fname  = 'CBOX'.gs_layout-sel_mode   = 'D'.* Get fieldcatCALL FUNCTION 'LVC_FIELDCATALOG_MERGE' ##FM_SUBRC_OKEXPORTINGi_structure_name       = 'ZSTEST_SEND_MAIL'i_bypassing_buffer     = abap_trueCHANGINGct_fieldcat            = gt_fieldcatEXCEPTIONSinconsistent_interface = 1program_error          = 2OTHERS                 = 3.* Hide checkboxREAD TABLE gt_fieldcat ASSIGNING FIELD-SYMBOL(<fs_fieldcat>)WITH KEY fieldname = 'CBOX'.IF sy-subrc = 0.<fs_fieldcat>-no_out = 'X'.<fs_fieldcat>-tech   = 'X'.ENDIF.* ALV displayCALL FUNCTION 'REUSE_ALV_GRID_DISPLAY_LVC'EXPORTINGi_callback_program       = syst-repidit_fieldcat_lvc          = gt_fieldcati_callback_user_command  = 'FRM_USER_COMMAND'i_callback_pf_status_set = 'FRM_PF_STATUS_SET'is_layout_lvc            = gs_layouti_save                   = 'A'TABLESt_outtab                 = gt_alvEXCEPTIONSprogram_error            = 1OTHERS                   = 2.IF sy-subrc <> 0.MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgnoWITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form frm_pf_status_set
*&---------------------------------------------------------------------*
*& Set status
*&---------------------------------------------------------------------*
FORM frm_pf_status_set USING rt_extab TYPE slis_t_extab.SET PF-STATUS 'STATUS'." EXCLUDING RT_EXTAB.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form frm_user_command
*&---------------------------------------------------------------------*
*& Process user command
*&---------------------------------------------------------------------*
FORM frm_user_command USING r_ucomm LIKE sy-ucommrs_selfield TYPE slis_selfield.DATA:lo_grid   TYPE REF TO cl_gui_alv_grid,ls_stable TYPE lvc_s_stbl,ls_layout TYPE lvc_s_layo.DATA:lo_control TYPE REF TO cl_gui_control,lt_control TYPE cnto_control_list.CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR'IMPORTINGe_grid = lo_grid.CASE r_ucomm.
*   Send mailWHEN 'SEND'.
*     Send test emailPERFORM frm_send_test_email.WHEN OTHERS.ENDCASE.************************************************************************
* If you use NEW-PAGE to process ALV->PDF,you need to delete the subscriber index 1.cl_gui_cfw=>get_subscriber_by_id(EXPORTINGshellid = 0IMPORTINGsubscriber = lo_controlEXCEPTIONScntl_error = 1).IF lo_control IS NOT INITIAL.cl_gui_cfw=>unsubscribe( EXPORTING ref = lo_control ).ENDIF.
************************************************************************CALL METHOD lo_grid->get_frontend_layoutIMPORTINGes_layout = ls_layout.ls_layout-cwidth_opt = 'X'.* Set Optimize column widthCALL METHOD lo_grid->set_frontend_layoutEXPORTINGis_layout = ls_layout.ls_stable-row = 'X'.ls_stable-col = 'X'.* Refresh ALVCALL METHOD lo_grid->refresh_table_displayEXPORTINGis_stable = ls_stableEXCEPTIONSfinished  = 1OTHERS    = 2.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form frm_send_test_email
*&---------------------------------------------------------------------*
*& Send test email
*&---------------------------------------------------------------------*
FORM frm_send_test_email .DATA:lt_alv_mail TYPE tt_alv,ls_alv_mail TYPE ty_alv.* Email parametersDATA:lv_message         TYPE string,lv_html_string     TYPE string,ls_body            TYPE zprbcs_mail_body,lt_mail_to_address TYPE zprbct_mail_address,ls_mail_to_address TYPE ad_smtpadr,ls_mail_template   TYPE zprbcs_mail_template,ls_mail_temp_smw0  TYPE zprbcs_mail_temp_smw0,lt_cds_key         TYPE zprbct_mail_cds_key_value,ls_cds_key         TYPE zprbcs_mail_cds_key_value,lt_temp_replace    TYPE zprbct_mail_temp_replace,ls_temp_replace    TYPE zprbcs_mail_temp_replace,lt_temp_rep_smw0   TYPE zprbct_mail_temp_smw0_replace,ls_temp_rep_smw0   TYPE zprbcs_mail_temp_smw0_replace,lt_body_html_smw0  TYPE w3html_tab,ls_body_html_smw0  TYPE w3html,lv_html_str_smw0   TYPE string,lv_approver        TYPE string,lt_images          TYPE zprbct_mail_temp_img,ls_images          TYPE zprbcs_mail_temp_img,lt_attch           TYPE zprbct_mail_attachment,ls_attch           TYPE zprbcs_mail_attachment,ls_return          TYPE bapiret2.DATA:lo_bcs TYPE REF TO cx_bcs.DATA:lv_test_file TYPE string VALUE 'C:\Users\MrMeng\Desktop\EXPORT1.XLSX',lv_file_len  TYPE i,lt_solix_tab TYPE solix_tab.lt_alv_mail = gt_alv.DELETE lt_alv_mail WHERE cbox IS INITIAL.CHECK lt_alv_mail IS NOT INITIAL.SORT lt_alv_mail BY banfn ASCENDINGbnfpo ASCENDINGemail ASCENDING.LOOP AT lt_alv_mail INTO ls_alv_mailGROUP BY ( banfn = ls_alv_mail-banfnemail = ls_alv_mail-email ) ASCENDINGREFERENCE INTO DATA(lo_mail_data).CLEAR gt_sf_alv.LOOP AT GROUP lo_mail_data ASSIGNING FIELD-SYMBOL(<fs_mail_data>).
**********************************************************************
*     Build html replace info ->SE80->Email template
**********************************************************************
*     Set CDS Keyls_cds_key-value = <fs_mail_data>-banfn.*     Set approverlv_approver = <fs_mail_data>-approver.*     Set receiver addressls_mail_to_address = <fs_mail_data>-email.*     Dynamic HTML body: <tr/><td/>lv_html_string = lv_html_string &&'<tr>' &&'<td>' && <fs_mail_data>-banfn &&      '</td>' &&'<td>' && <fs_mail_data>-bnfpo &&      '</td>' &&'<td>' && <fs_mail_data>-bsart &&      '</td>' &&'<td>' && <fs_mail_data>-frggr &&      '</td>' &&'<td>' && <fs_mail_data>-frgst &&      '</td>' &&'<td>' && <fs_mail_data>-frgco &&      '</td>' &&'<td>' && <fs_mail_data>-ekgrp &&      '</td>' &&'<td>' && <fs_mail_data>-werks &&      '</td>' &&'<td>' && <fs_mail_data>-ernam &&      '</td>' &&'<td>' && <fs_mail_data>-afnam &&      '</td>' &&'<td>' && <fs_mail_data>-matnr &&      '</td>' &&'<td>' && <fs_mail_data>-txz01 &&      '</td>' &&'<td>' && <fs_mail_data>-menge &&      '</td>' &&'<td>' && <fs_mail_data>-meins &&      '</td>' &&'<td>' && <fs_mail_data>-value_item && '</td>' &&'<td>' && <fs_mail_data>-frgdt &&      '</td>' &&'<td>' && <fs_mail_data>-lfdat &&      '</td>' &&'<td>' && <fs_mail_data>-webaz &&      '</td>' &&'<td>' && <fs_mail_data>-matkl &&      '</td>' &&'<td>' && <fs_mail_data>-dispo &&      '</td>' &&'<td>' && <fs_mail_data>-lifnr &&      '</td>' &&'</tr>'.APPEND <fs_mail_data> TO gt_sf_alv.ENDLOOP.*   Set template replace content --Approverls_temp_replace-mark_field = '<!--&APPROVER&-->'.ls_temp_replace-body_html  = lv_approver.APPEND ls_temp_replace TO lt_temp_replace.*   Set template replace content --Tablels_temp_replace-mark_field = '<!--&TableContent&-->'.ls_temp_replace-body_html  = lv_html_string.APPEND ls_temp_replace TO lt_temp_replace.*   Set template replace content --System Datels_temp_replace-mark_field = '<!--&SystemDate&-->'.ls_temp_replace-body_html  = sy-datlo.APPEND ls_temp_replace TO lt_temp_replace.SORT lt_temp_replace BY mark_field ASCENDING.DELETE ADJACENT DUPLICATES FROM lt_temp_replace COMPARING mark_field.*   CDS Keyls_cds_key-name = 'BANFN'.APPEND ls_cds_key TO lt_cds_key.**********************************************************************
*   Build html replace info ->SMW0
**********************************************************************ls_temp_rep_smw0-mark_field = '<!--&DocNumber&-->'.ls_body_html_smw0-line = <fs_mail_data>-banfn.APPEND ls_body_html_smw0 TO lt_body_html_smw0.ls_temp_rep_smw0-body_html = lt_body_html_smw0.APPEND ls_temp_rep_smw0 TO lt_temp_rep_smw0.ls_temp_rep_smw0-mark_field = '<!--&TableContent&-->'.ls_temp_rep_smw0-body_html = cl_bcs_convert=>string_to_soli( EXPORTING iv_string = lv_html_string ).APPEND ls_temp_rep_smw0 TO lt_temp_rep_smw0.**********************************************************************
*   Email Address info
**********************************************************************APPEND ls_mail_to_address TO lt_mail_to_address.SORT lt_mail_to_address ASCENDING.DELETE ADJACENT DUPLICATES FROM lt_mail_to_address COMPARING ALL FIELDS.**********************************************************************
*   Email Image with SMW0
**********************************************************************ls_images-cid       = 'SAP_LOGO_SMW0'.ls_images-smw0_name = 'ZSAP_LOGO'.APPEND ls_images TO lt_images.CLEAR ls_images.**********************************************************************
*   Email Image with SO2_MIME_REPOSITORY
**********************************************************************ls_images-cid       = 'SAP_LOGO_MIME'.ls_images-mime_path = '/SAP/PUBLIC/SAPLOGO_TR.bmp'.APPEND ls_images TO lt_images.CLEAR ls_images.**********************************************************************
*   Email Attchment - txt
**********************************************************************ls_attch-type     = 'TXT'.ls_attch-att_name = 'TestTXT.txt'.TRY .cl_bcs_convert=>string_to_solix(EXPORTINGiv_string = 'Hello word'IMPORTINGet_solix = ls_attch-body_contentev_size  = ls_attch-size).APPEND ls_attch TO lt_attch.CLEAR ls_attch.CATCH cx_bcs INTO lo_bcs.ENDTRY.**********************************************************************
*   Email Attchment - csv
**********************************************************************ls_attch-type     = 'CSV'.ls_attch-att_name = 'TestCSV.csv'.DATA(lv_string) = 'Hello' && ',' && 'World' && cl_abap_char_utilities=>cr_lf &&'Hello' && ',' && 'DeveloperMrMeng'.TRY .cl_bcs_convert=>string_to_solix(EXPORTINGiv_string = lv_stringIMPORTINGet_solix = ls_attch-body_contentev_size  = ls_attch-size).APPEND ls_attch TO lt_attch.CLEAR ls_attch.CATCH cx_bcs INTO lo_bcs.ENDTRY.**********************************************************************
*   Email Attchment - xlsx ->from upload file
**********************************************************************ls_attch-type     = 'BIN'.ls_attch-att_name = 'TestXLSX.xlsx'.CALL METHOD cl_gui_frontend_services=>gui_uploadEXPORTINGfilename   = lv_test_filefiletype   = 'BIN'IMPORTINGfilelength = lv_file_lenCHANGINGdata_tab   = lt_solix_tab.ls_attch-body_content = lt_solix_tab.ls_attch-size         = lv_file_len.CONDENSE ls_attch-size NO-GAPS.APPEND ls_attch TO lt_attch.CLEAR ls_attch.**********************************************************************
*   Email Attchment - xlsx ->from internal table
**********************************************************************ls_attch-type     = 'BIN'.ls_attch-att_name = 'TestXLSX_InternalTable.xlsx'.*   Internal table to xlsxPERFORM frm_get_it_xlsx_solix CHANGING ls_attch-body_contentls_attch-size.APPEND ls_attch TO lt_attch.CLEAR ls_attch.**********************************************************************
*   Email Attchment - Smartform to PDF
**********************************************************************ls_attch-type     = 'PDF'.ls_attch-att_name = 'TestPDF_Smartforms.pdf'.*   Smartform convert to PDFPERFORM frm_get_sf_pdf_solix CHANGING ls_attch-body_contentls_attch-size.APPEND ls_attch TO lt_attch.CLEAR ls_attch.**********************************************************************
*   Email Attchment - ALV to PDF
**********************************************************************ls_attch-type     = 'PDF'.ls_attch-att_name = 'TestPDF_ALV.pdf'.*   ALV convert to PDFPERFORM frm_get_alv_pdf_solix CHANGING ls_attch-body_contentls_attch-size.APPEND ls_attch TO lt_attch.CLEAR ls_attch.**********************************************************************
*   Email template ->SE80->Email template
**********************************************************************ls_mail_template-id           = 'ZTEST_TEMP_DEMO'.ls_mail_template-cds_key      = lt_cds_key.ls_mail_template-replace_info = lt_temp_replace.ls_mail_template-image_info   = lt_images.ls_body-body_template  = ls_mail_template.
**********************************************************************
*   Email template ->SMW0
**********************************************************************
*    ls_mail_temp_smw0-id           = 'ZTEMP_SMW0'.
*    ls_mail_temp_smw0-title        = 'This is a test title'.
*    ls_mail_temp_smw0-replace_info = lt_temp_rep_smw0.
*    ls_mail_temp_smw0-image_info   = lt_images.
*
*    ls_body-body_temp_smw0 = ls_mail_temp_smw0.*   Send Mailzprbccl_send_mail=>send_mail(EXPORTINGiv_mail_from_address = 'tian.meng@hand-china.com'it_mail_to_address   = lt_mail_to_addressis_body              = ls_bodyit_attachment        = lt_attchIMPORTINGes_return            = ls_return).IF sy-batch = abap_true.ASSIGN COMPONENT 'BANFN' OF STRUCTURE lo_mail_data TO FIELD-SYMBOL(<fs_banfn>).*     &1 send mail success.MESSAGE s057(zprbcmsg) WITH <fs_banfn>.ELSE.LOOP AT GROUP lo_mail_data ASSIGNING <fs_mail_data>.READ TABLE gt_alv ASSIGNING FIELD-SYMBOL(<fs_alv>)WITH KEY banfn = <fs_mail_data>-banfnbnfpo = <fs_mail_data>-bnfpoemail = <fs_mail_data>-emailBINARY SEARCH.IF ls_return-type = 'S'.<fs_alv>-icon = icon_led_green.ELSE.<fs_alv>-icon = icon_led_red.ENDIF.<fs_alv>-msg = ls_return-message.ENDLOOP.ENDIF.CLEAR:lv_html_string,lt_mail_to_address,ls_mail_to_address,ls_body,lt_cds_key,ls_cds_key,ls_temp_replace,lt_temp_replace,lt_temp_rep_smw0,ls_temp_rep_smw0,lt_body_html_smw0,ls_body_html_smw0,ls_return.ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form frm_get_sf_pdf_solix
*&---------------------------------------------------------------------*
*& Smartform convert to PDF
*&---------------------------------------------------------------------*
*&      <-- CS_ATTCH_BODY_CONTENT
*&      <-- CS_ATTCH_SIZE
*&---------------------------------------------------------------------*
FORM frm_get_sf_pdf_solix  CHANGING cs_attch_body_content TYPE solix_tabcs_attch_size TYPE so_obj_len.DATA:lv_fname TYPE rs38l_fnam.DATA:ls_control_para    TYPE ssfctrlop,ls_output_option   TYPE ssfcompop,ls_job_output_info TYPE ssfcrescl,lv_spoolid         TYPE rspoid.DATA:lv_size    TYPE i,lv_xstring TYPE xstring.* Get dynamic runtime function nameCALL FUNCTION 'SSF_FUNCTION_MODULE_NAME'EXPORTINGformname           = 'ZTEST_SF2PDF'
*     VARIANT            = ' '
*     DIRECT_CALL        = ' 'IMPORTINGfm_name            = lv_fnameEXCEPTIONSno_form            = 1no_function_module = 2OTHERS             = 3.IF sy-subrc <> 0.
*   Implement suitable error handling hereENDIF.*  ls_control_para-getotf    = 'X'.ls_control_para-no_dialog = 'X'.ls_output_option-tddest   = 'LP01'.ls_output_option-tdnewid  = 'X'.* Call SmartformsCALL FUNCTION lv_fnameEXPORTINGcontrol_parameters = ls_control_paraoutput_options     = ls_output_optionuser_settings      = ''IMPORTINGjob_output_info    = ls_job_output_infoEXCEPTIONSformatting_error   = 1internal_error     = 2send_error         = 3user_canceled      = 4OTHERS             = 5.IF sy-subrc <> 0.
*   Implement suitable error handling hereENDIF.CHECK ls_job_output_info-spoolids IS NOT INITIAL.READ TABLE ls_job_output_info-spoolids INTO DATA(ls_spoolids) INDEX 1.lv_spoolid = ls_spoolids.* Convert OTF to PDFCALL FUNCTION 'CONVERT_OTFSPOOLJOB_2_PDF'EXPORTINGsrc_spoolid              = lv_spoolid
*     NO_DIALOG                = 'X'
*     DST_DEVICE               =pdf_destination          = 'X'no_background            = 'X'
*     USE_CASCADING            = ' '
*     MODIFIED_PARAM_TABLE     =IMPORTINGpdf_bytecount            = lv_size
*     PDF_SPOOLID              =
*     OTF_PAGECOUNT            =
*     BTC_JOBNAME              =
*     BTC_JOBCOUNT             =bin_file                 = lv_xstring
*   TABLES
*     PDF                      =EXCEPTIONSerr_no_otf_spooljob      = 1err_no_spooljob          = 2err_no_permission        = 3err_conv_not_possible    = 4err_bad_dstdevice        = 5user_cancelled           = 6err_spoolerror           = 7err_temseerror           = 8err_btcjob_open_failed   = 9err_btcjob_submit_failed = 10err_btcjob_close_failed  = 11OTHERS                   = 12.IF sy-subrc <> 0.
*   Implement suitable error handling hereENDIF.TRY .DATA(lo_pdf_merge) = NEW cl_rspo_pdf_merge( ).lo_pdf_merge->check_document(EXPORTINGdocument   = lv_xstringIMPORTINGerror_text = DATA(error_text)rc         = DATA(rc)).lo_pdf_merge->add_document( lv_xstring ).lo_pdf_merge->add_document( lv_xstring ).lo_pdf_merge->merge_documents(IMPORTINGmerged_document = DATA(lv_new_xstring)).CATCH cx_rspo_pdf_merge.ENDTRY.lv_size = xstrlen( lv_new_xstring ).cs_attch_body_content = cl_bcs_convert=>xstring_to_solix( EXPORTING iv_xstring = lv_new_xstring ).cs_attch_size         = lv_size.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form frm_get_alv_pdf_solix
*&---------------------------------------------------------------------*
*& ALV convert to PDF
*&---------------------------------------------------------------------*
*&      <-- CS_ATTCH_BODY_CONTENT
*&      <-- CS_ATTCH_SIZE
*&---------------------------------------------------------------------*
FORM frm_get_alv_pdf_solix  CHANGING cs_attch_body_content TYPE solix_tabcs_attch_size TYPE so_obj_len.DATA:ls_print       TYPE lvc_s_prnt,lv_spoolid     TYPE rspoid,lv_spoolid_del TYPE rqident,lt_pdf_tab     TYPE STANDARD TABLE OF tline,lv_pdf_xstring TYPE xstring,lv_pdf_size    TYPE i.ls_print-print = 'X'.* Set print no dialogCALL FUNCTION 'GET_PRINT_PARAMETERS'EXPORTINGdestination            = 'LP01'immediately            = 'X'layout                 = 'X_65_255'mode                   = 'BATCH'no_dialog              = 'X'IMPORTINGout_parameters         = ls_print-print_ctrl-pri_params
*     VALID                  =
*     VALID_FOR_SPOOL_CREATION       =EXCEPTIONSarchive_info_not_found = 1invalid_print_params   = 2invalid_archive_params = 3OTHERS                 = 4.IF sy-subrc <> 0.
*   Implement suitable error handling hereELSE.ls_print-print                  = 'X'.ls_print-no_change_print_params = 'X'.NEW-PAGE PRINT ON NEW-SECTION PARAMETERS ls_print-print_ctrl-pri_params NO DIALOG.*   ALV displayCALL FUNCTION 'REUSE_ALV_GRID_DISPLAY_LVC'EXPORTING
*       i_callback_program = syst-repidit_fieldcat_lvc = gt_fieldcatis_layout_lvc   = gs_layoutis_print_lvc    = ls_printTABLESt_outtab        = gt_sf_alvEXCEPTIONSprogram_error   = 1OTHERS          = 2.IF sy-subrc <> 0.MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgnoWITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.ELSE.CHECK sy-spono IS NOT INITIAL.lv_spoolid = sy-spono.*     Get PDF contentCALL FUNCTION 'CONVERT_ABAPSPOOLJOB_2_PDF'EXPORTINGsrc_spoolid              = lv_spoolidpdf_destination          = 'X'
*         NO_DIALOG                =IMPORTINGpdf_bytecount            = lv_pdf_sizebin_file                 = lv_pdf_xstringEXCEPTIONSerr_no_abap_spooljob     = 1err_no_spooljob          = 2err_no_permission        = 3err_conv_not_possible    = 4err_bad_destdevice       = 5user_cancelled           = 6err_spoolerror           = 7err_temseerror           = 8err_btcjob_open_failed   = 9err_btcjob_submit_failed = 10err_btcjob_close_failed  = 11OTHERS                   = 12.IF sy-subrc <> 0.
*       Implement suitable error handling hereENDIF.cs_attch_body_content = cl_bcs_convert=>xstring_to_solix( EXPORTING iv_xstring = lv_pdf_xstring ).cs_attch_size         = lv_pdf_size.lv_spoolid_del = lv_spoolid.CALL FUNCTION 'RSPO_R_RDELETE_SPOOLREQ'EXPORTINGspoolid = lv_spoolid_del.ENDIF.NEW-PAGE PRINT OFF.ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form frm_get_it_xlsx_solix
*&---------------------------------------------------------------------*
*& Convert internal table to xlsx
*&---------------------------------------------------------------------*
*&      <-- CS_ATTCH_BODY_CONTENT
*&      <-- CS_ATTCH_SIZE
*&---------------------------------------------------------------------*
FORM frm_get_it_xlsx_solix CHANGING cs_attch_body_content TYPE solix_tabcs_attch_size TYPE so_obj_len.TYPES:BEGIN OF ty_test,userid   TYPE string,username TYPE string,END OF ty_test,tt_test TYPE STANDARD TABLE OF ty_test.DATA:lt_test     TYPE tt_test,lv_xstring  TYPE xstring,lv_string   TYPE string,lv_codepage TYPE cpcodepage.DATA:lo_bcs TYPE REF TO cx_bcs.lt_test = VALUE #( ( userid = 'DeveloperMrMeng' username = 'Hello World' )( userid = 'DeveloperMrMeng' username = 'Hello ABAP'  ) ).DATA(lt_data) = REF #( lt_test ).FIELD-SYMBOLS: <tab> TYPE STANDARD TABLE.ASSIGN lt_data->* TO <tab>.TRY.cl_salv_table=>factory(EXPORTINGlist_display = abap_falseIMPORTINGr_salv_table = DATA(salv_table)CHANGINGt_table      = <tab>).DATA(lt_fcat) = cl_salv_controller_metadata=>get_lvc_fieldcatalog(r_columns      = salv_table->get_columns( )r_aggregations = salv_table->get_aggregations( )).CATCH cx_salv_msg.RETURN.ENDTRY.* Convert table to xstringcl_salv_bs_lex=>export_from_result_data_table(EXPORTINGis_format            = if_salv_bs_lex_format=>mc_format_xlsxir_result_data_table = cl_salv_ex_util=>factory_result_data_table(r_data         = lt_datat_fieldcatalog = lt_fcat)IMPORTINGer_result_file       = lv_xstring ).TRY .cl_bcs_convert=>xstring_to_solix(EXPORTINGiv_xstring = lv_xstringRECEIVINGet_solix = cs_attch_body_content).cs_attch_size = xstrlen( lv_xstring ).CATCH cx_bcs INTO lo_bcs.ENDTRY.
ENDFORM.

以上。

这篇关于SAP ABAP 基于 CL_BCS 发送邮件的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/782062

相关文章

Django中使用SMTP实现邮件发送功能

《Django中使用SMTP实现邮件发送功能》在Django中使用SMTP发送邮件是一个常见的需求,通常用于发送用户注册确认邮件、密码重置邮件等,下面我们来看看如何在Django中配置S... 目录1. 配置 Django 项目以使用 SMTP2. 创建 Django 应用3. 添加应用到项目设置4. 创建

Android中如何实现adb向应用发送特定指令并接收返回

1 ADB发送命令给应用 1.1 发送自定义广播给系统或应用 adb shell am broadcast 是 Android Debug Bridge (ADB) 中用于向 Android 系统发送广播的命令。通过这个命令,开发者可以发送自定义广播给系统或应用,触发应用中的广播接收器(BroadcastReceiver)。广播机制是 Android 的一种组件通信方式,应用可以监听广播来执行

61.以太网数据回环实验(4)以太网数据收发器发送模块

(1)状态转移图: (2)IP数据包格式: (3)UDP数据包格式: (4)以太网发送模块代码: module udp_tx(input wire gmii_txc ,input wire reset_n ,input wire tx_start_en , //以太网开始发送信

SAP学习笔记 - 开发02 - BTP实操流程(账号注册,BTP控制台,BTP集成开发环境搭建)

上一章讲了 BAPI的概念,以及如何调用SAP里面的既存BAPI。 SAP学习笔记 - 开发01 - BAPI是什么?通过界面和ABAP代码来调用BAPI-CSDN博客 本章继续讲开发相关的内容,主要就是BTP的实际操作流程,比如账号注册,登录,BTP集成开发环境的搭建这方面。 目录 1,账号注册 2,BTP登录URL 3,如何在BTP上进行开发? 以下是详细内容。 1,账

Jasperreports+jaspersoft studio 实现单个或多个jrxml(jasper)文件生成一个pdf文件,并利用Servlet发送该pdf文件到浏览器中展示

Jasperreports+jaspersoft studio 实现单个或多个jrxml(jasper)文件生成一个pdf文件,并利用Servlet发送该pdf文件到浏览器中展示; 代码如下: Demo07.jrxml <?xml version="1.0" encoding="UTF-8"?><!-- Created with Jaspersoft Studio version 6.6.

SAP项目中沟通的几点总结

最近参与的公司SAP RISE项目,由于是国际项目,全程远程实施,所以沟通显得尤为重要,有几点总结跟大家分享。   1.     提前沟通 提前沟通比事后沟通效果好太多。作为项目管理者,需要把下一步的计划等信息提前通过一定的形式(会议、邮件、Teams Channel等)传播出去。而不是等着这个事情发生了,项目组成员来询问,一方面这样很浪费时间,也会对项目进队产生影响,所以作为项目管理者永

node.js实现阿里云短信发送

效果图 实现 一、准备工作 1、官网直达网址: 阿里云 - 短信服务 2、按照首页提示依次完成相应资质认证和短信模板审核; 3、获取你的accessKeySecret和accessKeyId; 方法如下: 获取AccessKey-阿里云帮助中心 4、获取SignName(签名名称)和 TemplateCode(模板code); 二、代码实现 1、项目结构 【/c

springboot项目编写发送异常日志到企微工具包

1.创建基础Bean public final class ThreadFactory implements java.util.concurrent.ThreadFactory {private static final AtomicInteger poolNumber = new AtomicInteger(1);private final ThreadGroup group;priva

怎么利用NodeJS发送视频短信

随着5G时代的来临,企业的数字化转型步伐日益加快,视频短信作为新兴的数字营销工具,正逐步展现出其大的潜力。视频群发短信以其独特的形式和内容,将图片、文字、视频、声音融为一体,为用户带来全新的直观感受,为企业营销注入新的活力。 支持免费对接试用乐讯通PaaS平台 找好用的短信平台,选择乐讯通,短信群发|短信平台|群发短信软件|群发短信平台|乐讯通PaaS平台http://yun.loktong

socket函数接收发送详解

http://blog.csdn.net/g_brightboy/article/details/12854117 http://blog.csdn.net/liangkaiyang/article/details/5931901 send。。。 这里只描述同步Socket的send函数的执行流程。 当调用该函数时,send先比较待发送数据的长度