的整数倍,因为在上传的过程中使用的是xtab255类型的内表,当最后一行不满255个字节时,也会在后面补上直到255个字节,但补的都是00这样的字节,所以文件大小还是有区别的,但经过测试pdf与mp3在码流后面补00字节好像没有什么影响唯独是文件大小变大了。但如果是TXT文件,打开后发现多了很多空格(按理来说也是什么也没有,因为空格的ASCII码为32,但后面补的是00字节)
的倍数,否则编译出错个字面上的十六进制字符才能表示一个字符C,所以从c_total以十六进制方式赋值给ctab255 时,缩短了3/4
APPEND ctab255.
CLEAR: c_tmp1.
ENDIF.
ENDLOOP.
"可能是奇数后,所以需要判断一下,将最后一行也要附加上去
IF c_tmp1 IS NOT INITIAL.
<x> = c_tmp1.
APPEND ctab255.
ENDIF.
发送邮件
FORM send_email.
DATA: BEGIN OF addr_email OCCURS 0,
smtp_addr(241),
END OF addr_email.
DATA: i_receivers LIKE somlreci1 OCCURS 0 WITH HEADER LINE,
i_message LIKE solisti1 OCCURS 0 WITH HEADER LINE.
DATA: l_subject TYPE so_obj_des,
l_filename TYPE string.
SELECT smtp_addr FROM zmm_invtr_email INTO TABLE addr_email.
CHECK addr_email[] IS NOT INITIAL.
LOOP AT addr_email.
CLEAR:i_receivers.
i_receivers-receiver = addr_email-smtp_addr.
i_receivers-rec_type = 'U'.
i_receivers-com_type = 'INT'.
* i_receivers-copy = 'X'."CC
* i_receivers-blind_copy = 'X'."BCC
i_receivers-express = 'X'."TO
APPEND i_receivers.
ENDLOOP.
l_subject = `hi,baby`."邮件标题
l_filename = 'attach.txt'."附件文件名
i_message-line = `邮件的内容`.
APPEND i_message.
DATA: t_atthead TYPE STANDARD TABLE OF string,
return TYPE bapiret1.
PERFORM send_email_with_att_xls TABLES i_receivers
i_message
t_atthead
<stat_tab>
USING l_subject
sy-uname
l_filename
return.
* MESSAGE return-message TYPE 'S' DISPLAY LIKE return-type.
ENDFORM. "export_xls
*&---------------------------------------------------------------------*
*& Form send_email_with_att_xls
*&---------------------------------------------------------------------*
* 带XLS附件的邮件发送
*----------------------------------------------------------------------*
* -->T_RECEIVERS 邮件接收者
* -->T_MESSAGE 邮件内容
* -->T_ATTHEAD XLS附件中标题(XLS首行内容)
* -->T_ATTTAB 附件内容
* -->IM_SUBJECT 邮件标题
* -->IM_UNAME 邮件发送者
* -->IM_FILENAME 附件名称
* -->RETURN 返回信息
*----------------------------------------------------------------------*
FORM send_email_with_att_xls TABLES t_receivers STRUCTURE somlreci1
t_message STRUCTURE solisti1
t_atthead
t_atttab
USING im_subject TYPE so_obj_des
im_uname TYPE uname
im_filename TYPE string
return TYPE bapiret1.
CONSTANTS: c_tab TYPE c VALUE cl_abap_char_utilities=>horizontal_tab,
"回车换行,实质上对应 Xstring: 000D000A
c_crlf(2) TYPE c VALUE cl_abap_char_utilities=>cr_lf.
DATA: xstr TYPE xstring,
it_binary_attach TYPE solix_tab.
************************将内表所有的内容存储到一个字符串中
DATA: lc_descr_ref TYPE REF TO cl_abap_structdescr,
lv_value TYPE char128,
lv_temp TYPE string,
lv_mid TYPE string.
FIELD-SYMBOLS: <fs_table> TYPE ANY.
FIELD-SYMBOLS: <intable_wa> TYPE abap_compdescr.
CLEAR lv_temp.
"将头内表拼接成一个字符串
IF t_atthead[] IS NOT INITIAL.
LOOP AT t_atthead.
IF sy-tabix = 1.
lv_temp = t_atthead.
CONTINUE.
ENDIF.
CONCATENATE lv_temp t_atthead
INTO lv_temp SEPARATED BY c_tab.
ENDLOOP.
CONCATENATE lv_temp c_crlf INTO lv_mid.
ENDIF.
"将主体内表拼接成一个字符串
LOOP AT t_atttab.
lc_descr_ref ?= cl_abap_typedescr=>describe_by_data( t_atttab ).
LOOP AT lc_descr_ref->components ASSIGNING <intable_wa>.
ASSIGN COMPONENT sy-tabix OF STRUCTURE t_atttab TO <fs_table>.
"如果是数字类型时
IF <intable_wa>-type_kind = 'P' OR <intable_wa>-type_kind = 'F'
OR <intable_wa>-type_kind = 'I' OR <intable_wa>-type_kind = 'b'
OR <intable_wa>-type_kind = 's'.
IF <fs_table> = 0.
CLEAR lv_value.
ELSE.
WRITE <fs_table> TO lv_value.
CONDENSE lv_value NO-GAPS.
IF <fs_table> < 0."将负号提前
CALL FUNCTION 'CLOI_PUT_SIGN_IN_FRONT'
CHANGING
value = lv_value.
CONDENSE lv_value NO-GAPS.
ENDIF.
ENDIF.
ELSE.
lv_value = <fs_table>.
CONDENSE lv_value.
ENDIF.
IF sy-tabix = 1.
lv_temp = lv_value.
CONTINUE.
ENDIF.
CONCATENATE lv_temp lv_value
INTO lv_temp SEPARATED BY c_tab.
ENDLOOP.
CONCATENATE lv_mid lv_temp c_crlf INTO lv_mid.
ENDLOOP.
************************将字符进行编码转换,转换为二进制字节码流
DATA: l_codepage(4) TYPE n .
DATA: l_encoding(20).
"将外部字符集名转换为内部编码
CALL FUNCTION 'SCP_CODEPAGE_BY_EXTERNAL_NAME'
EXPORTING
external_name = 'UTF-8'
IMPORTING
sap_codepage = l_codepage.
l_encoding = l_codepage.
DATA: convout TYPE REF TO cl_abap_conv_out_ce.
"创建编码对象
convout = cl_abap_conv_out_ce=>create( encoding = l_encoding ).
convout->write( data = lv_mid )."编码
xstr = convout->get_buffer( )."获取码流
************************接口转换:将码流按使用的参数接口要求进行重组转换
"将 xstring 的字符串存储到行结构为 X 类型的内表中,以适合于邮件发
"送接口。该函数并不是将 xstring 字符转换为 二进制(因为xstring本身就
"是原生态,从函数名上看容易误导)。
CALL FUNCTION 'SCMS_XSTRING_TO_BINARY'
EXPORTING
buffer = xstr
TABLES
binary_tab = it_binary_attach.
*另外,也可以将行结构为 X 类型的内表中所有HEX内容拼接成一个Xstring并存储在l_xstr变量中,也不要被函*数名给迷糊了:并不是将二进制什么的转换为Xstring类型了,而只不过是将将内表结构转换为单一的字符串了
*data: l_xstr type xstring.
* clear l_xstr.
* call function 'SCMS_BINARY_TO_XSTRING'
* exporting
* input_length = l_len
* importing
* buffer = l_xstr
* tables
* binary_tab = it_binary_attach.
*-----------------------------------------------------------------------
* Send Email
*-----------------------------------------------------------------------
DATA: lv_title TYPE so_obj_des, " Email Title
lv_email TYPE adsmtp-smtp_addr, " Receiver
lv_attitle TYPE char50. " Attachment Title
DATA: send_request TYPE REF TO cl_bcs,
document TYPE REF TO cl_document_bcs,
conlengths TYPE so_obj_len,
html TYPE TABLE OF w3html,
recipient TYPE REF TO if_recipient_bcs,
sent_to_all TYPE os_boolean,
bcs_exception TYPE REF TO cx_bcs,
bcs_message TYPE string.
DATA: sender TYPE REF TO cl_sapuser_bcs.
TRY.
* 创建发送请求
CLEAR send_request.
send_request = cl_bcs=>create_persistent( ).
CLEAR: lv_title.
lv_title = im_subject.
* 创建并设置邮件文档
CLEAR html.
REFRESH html.
html = t_message[].
CLEAR document .
document = cl_document_bcs=>create_document(
i_type = 'RAW'
i_text = html
i_length = conlengths
i_subject = lv_title ).
CALL METHOD send_request->set_document( document ).
****************这里也可以从数据库表中读取码流
* DATA: BEGIN OF xtab255 OCCURS 0,
* x(255) TYPE x,
* END OF xtab255.
* FIELD-SYMBOLS: <cc> TYPE c.
*
* DATA: ctab255 TYPE STANDARD TABLE OF solisti1 WITH HEADER LINE.
*
* DATA: BEGIN OF pdf_table OCCURS 0,
* mandt TYPE zjzjpdf-mandt,
* row_order TYPE zjzjpdf-row_order,
* chr_count TYPE zjzjpdf-chr_count,
* content_hex(510),
* END OF pdf_table.
*
* CLEAR: pdf_table[].
* SELECT * INTO TABLE pdf_table FROM zjzjpdf.
* SORT pdf_table BY row_order.
*
* CLEAR: xtab255[].
* LOOP AT pdf_table.
* "将字面上的HEX转换为真正的HEX
* xtab255-x = pdf_table-content_hex.
* APPEND xtab255.
* ENDLOOP.
****************************
* 添加附件:如果有多个,则需要调用该方法多次
lv_attitle = im_filename.
CALL METHOD document->add_attachment
EXPORTING
* i_attachment_type = 'BIN'"在邮件中点击附件会弹出文件保存对话框。其他类型请参考SAPFSSOA程序include文件RSSOCONS
* i_attachment_type = 'PDF'
* i_attachment_type = 'TXT'
i_attachment_type = 'XLS'"文件类型,在邮件中就可以打开文件,不会弹出保存对话框
i_attachment_subject = lv_attitle
i_att_content_hex = it_binary_attach.
* i_att_content_hex = xtab255[].
* 设置发送者
sender = cl_sapuser_bcs=>create( im_uname ).
CALL METHOD send_request->set_sender
EXPORTING
i_sender = sender.
* 设置接收者
CLEAR recipient.
LOOP AT t_receivers.
CLEAR lv_email.
lv_email = t_receivers-receiver.
recipient =
cl_cam_address_bcs=>create_internet_address( lv_email ).
CALL METHOD send_request->add_recipient
EXPORTING
i_recipient = recipient
i_express = t_receivers-express
i_copy = t_receivers-copy
i_blind_copy = t_receivers-blind_copy.
ENDLOOP.
* E-mail
CALL METHOD send_request->set_status_attributes
EXPORTING
i_requested_status = 'E'
i_status_mail = 'E'.
CALL METHOD send_request->set_send_immediately( 'X' ).
* 发送邮件
CALL METHOD send_request->send(
EXPORTING
i_with_error_screen = 'X'
RECEIVING
result = sent_to_all ).
COMMIT WORK AND WAIT.
IF sent_to_all = 'X'.
return-message = 'E-mail send successfully'.
return-type = 'S'.
ELSE.
return-message = 'E-mail send unsuccessfully'.
return-type = 'E'.
ENDIF.
CATCH cx_bcs INTO bcs_exception.
bcs_message = bcs_exception->get_text( ).
return-message = bcs_message.
return-type = 'E'.
EXIT.
ENDTRY.
ENDFORM.