Skip to content

Instantly share code, notes, and snippets.

@js1972
Created August 15, 2014 03:31
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save js1972/08af3bccd75e99a77cb8 to your computer and use it in GitHub Desktop.
Save js1972/08af3bccd75e99a77cb8 to your computer and use it in GitHub Desktop.
ABAP program to send email with images and charts. Not written by me, but I've tested it and it works - clean up before use (I've only added comments to clear things up)!!! This abap shows how to create a multi-part email to display inline images as well as attachments. It also shows how to generate a chart in abap (IGS) and get its image, as we…
report y_test_email_with_chart.
type-pools: abap .
tables: sflight .
constants: image_name_01 type string value 'Sailing.jpg' .
constants: image_name_02 type string value 'chart_01.jpg' .
constants: c_series_01 type string value 'series_01' .
*----------------------------------------------------------------------*
types: begin of tp_suma_1 .
include type sflight as sflight renaming with suffix _sflight .
types: end of tp_suma_1 .
types: tp_suma_1_tab type table of tp_suma_1 .
*----------------------------------------------------------------------*
*----------------------------------------------------------------------*
class cl_htm definition .
public section.
constants: cr_lf type string value '<cr_lf>' .
data: htm_string type string .
methods: append
importing fragment type any .
private section.
methods: edit_value
importing fragment type any
changing buffer type string .
endclass. "cl_htm DEFINITION
*----------------------------------------------------------------------*
*----------------------------------------------------------------------*
class cl_htm implementation.
*----------------------------------------------------------------------*
method: append .
data: buffer type string .
me->edit_value( exporting fragment = fragment changing buffer = buffer ) .
condense buffer .
concatenate htm_string buffer into htm_string .
endmethod. "append
*----------------------------------------------------------------------*
method: edit_value .
data: inttype type inttype .
describe field fragment type inttype .
data: edited type so_text255 .
write fragment to edited left-justified .
if buffer eq cl_htm=>cr_lf .
return .
endif .
case inttype .
when 'I' or 'P' .
if fragment lt 0 .
write fragment to edited+1 no-sign left-justified .
write '-' to edited+0(1) .
buffer = edited .
endif .
when others .
buffer = fragment .
endcase .
endmethod. "edit_minus_value
*----------------------------------------------------------------------*
endclass. "cl_htm IMPLEMENTATION
*----------------------------------------------------------------------*
*----------------------------------------------------------------------*
class cl_str definition .
public section .
class-methods: to_string
importing input type any
returning value(output) type string .
endclass . "cl_string DEFINITION
*----------------------------------------------------------------------*
*----------------------------------------------------------------------*
class cl_str implementation.
method: to_string .
data: buffer type char64 .
data: string type string .
write input to buffer left-justified.
replace all occurrences of ',' in buffer with '' .
output = buffer .
endmethod . "to_string
endclass . "cl_str IMPLEMENTATION
*----------------------------------------------------------------------*
*----------------------------------------------------------------------*
selection-screen begin of block block02 with frame .
parameters: p_fname type ssfscreen-fname default 'SF_EXAMPLE_01' .
selection-screen skip .
parameters: p_sndr_1 type adsmtp-smtp_addr .
selection-screen skip .
parameters: p_rcpn_1 type adsmtp-smtp_addr .
selection-screen skip .
parameters: p_sbjct type so_obj_des .
selection-screen skip .
select-options: s_carrid for sflight-carrid .
select-options: s_connid for sflight-connid .
select-options: s_fldate for sflight-fldate .
selection-screen skip .
parameters: p_debug type debug_flg .
selection-screen end of block block02 .
*----------------------------------------------------------------------*
initialization .
perform at_initialization .
at selection-screen output .
perform at_selection_screen_output .
at selection-screen .
perform at_selection_screen_input .
start-of-selection .
perform at_start_of_selection .
*----------------------------------------------------------------------*
form at_initialization .
data: st_address type bapiaddr3 .
data: it_return type bapirettab .
call function 'BAPI_USER_GET_DETAIL'
exporting
username = sy-uname
importing
address = st_address
tables
return = it_return.
p_sndr_1 = st_address-e_mail .
p_rcpn_1 = st_address-e_mail .
concatenate 'Hi there-' sy-datum '-' sy-uzeit '(EX)' into p_sbjct .
data: it_seltexts type table of rsseltexts .
data: st_seltexts like line of it_seltexts .
st_seltexts-name = 'P_SNDR_1' .
st_seltexts-kind = 'P' .
st_seltexts-text = 'Sender mail ' .
append st_seltexts to it_seltexts .
st_seltexts-name = 'P_RCPN_1' .
st_seltexts-kind = 'P' .
st_seltexts-text = 'Recipient mail 1 ' .
append st_seltexts to it_seltexts .
call function 'SELECTION_TEXTS_MODIFY'
exporting
program = sy-cprog
tables
seltexts = it_seltexts
exceptions
program_not_found = 1
program_cannot_be_generated = 2
others = 3.
endform . "at_initialization
*----------------------------------------------------------------------*
form at_selection_screen_output .
endform . "at_selection_screen_output
*----------------------------------------------------------------------*
form at_selection_screen_input .
endform . "at_selection_screen_input
*----------------------------------------------------------------------*
form at_start_of_selection .
perform mail_1_main .
endform . "at_start_of_selection
*----------------------------------------------------------------------*
form mail_1_main .
data: ob_gbt_multirelated_service type ref to cl_gbt_multirelated_service.
create object ob_gbt_multirelated_service .
"setup the html document for body of email - references the multi-part
"attachments setup below to display inline.
perform mail_1_prep_1
changing
ob_gbt_multirelated_service .
"get pic and add as binary multi-part attachment to email (will show inline)
perform mail_1_prep_2
changing
ob_gbt_multirelated_service .
"generate chart and add as binary multi-part attachment to email (will show inline)
perform mail_1_prep_3
changing
ob_gbt_multirelated_service .
"create a multi-part email with BCS
data: ob_document_bcs type ref to cl_document_bcs.
ob_document_bcs = cl_document_bcs=>create_from_multirelated(
i_subject = p_sbjct
i_multirel_service = ob_gbt_multirelated_service ).
"add chart as email attachment as well
perform mail_1_prep_4
changing
ob_document_bcs .
"call a smartform, convert to pdf and add as attachment
perform mail_1_prep_5
changing
ob_document_bcs .
"standard BCS sending stuff...
data: ob_bcs type ref to cl_bcs.
data: ob_sapuser_bcs type ref to cl_sapuser_bcs.
data: ob_cam_address_bcs type ref to cl_cam_address_bcs .
ob_bcs = cl_bcs=>create_persistent( ).
call method ob_bcs->set_document( ob_document_bcs ).
ob_cam_address_bcs = cl_cam_address_bcs=>create_internet_address( p_sndr_1 ).
call method ob_bcs->set_sender
exporting
i_sender = ob_cam_address_bcs.
data: smtp_addr type adsmtp-smtp_addr .
ob_cam_address_bcs = cl_cam_address_bcs=>create_internet_address( p_rcpn_1 ).
call method ob_bcs->add_recipient
exporting
i_recipient = ob_cam_address_bcs.
data: result type abap_bool .
call method ob_bcs->send
exporting
i_with_error_screen = abap_true
receiving
result = result.
commit work .
endform . "mail_1_main
*----------------------------------------------------------------------*
form mail_1_prep_1
changing
ob_gbt_multirelated_service type ref to cl_gbt_multirelated_service .
data: content type xstring.
"get the pic from the mime repository - not sure why this is here - its done later!
perform mail_1_image_1
changing
content .
data: ob_htm type ref to cl_htm .
create object ob_htm .
call method ob_htm->append
exporting
fragment = :
'<P>' ,
'Hi there' ,
'</P>' .
* Works in outlook.
call method ob_htm->append
exporting
fragment = :
'<img src="cid:' , image_name_01 , '" alt="' , image_name_01 , '" align="middle" />'.
call method ob_htm->append
exporting
fragment = '<br><br>'.
call method ob_htm->append
exporting
fragment = :
'<img src="cid:' , image_name_02 , '" alt="' , image_name_02 , '" align="middle" />'.
call method ob_htm->append
exporting
fragment = '<br><br>'.
* Does not work in outlook
* DATA: encoded TYPE string .
*
* CALL METHOD cl_http_utility=>if_http_utility~encode_x_base64
* EXPORTING
* unencoded = content
* RECEIVING
* encoded = encoded.
* CALL METHOD ob_htm->append
* EXPORTING
* fragment = :
* '<img src="data:image/gif;base64,' , encoded ,
* ' "alt="Happy birthday" align="middle" width="304" height="228" />'.
data: it_soli type soli_tab .
call method cl_bcs_convert=>string_to_soli
exporting
iv_string = ob_htm->htm_string
receiving
et_soli = it_soli.
call method ob_gbt_multirelated_service->set_main_html
exporting
content = it_soli
filename = 'main_html.htm'
description = 'main_html.htm'. "Title
* CALL METHOD cl_document_bcs=>create_document
* EXPORTING
* i_type = 'HTM'
* i_subject = p_sbjct
* i_text = it_soli
** i_hex = it_solix
* RECEIVING
* result = ob_document_bcs.
endform . "mail_1_prep_1
*----------------------------------------------------------------------*
form mail_1_prep_2
changing
ob_gbt_multirelated_service type ref to cl_gbt_multirelated_service .
* From http://scn.sap.com/docs/DOC-42618
data: content type xstring.
"get the pic fropm the mime repository
perform mail_1_image_1
changing
content .
data: it_solix type solix_tab .
call method cl_bcs_convert=>xstring_to_solix
exporting
iv_xstring = content
receiving
et_solix = it_solix.
data: description type so_obj_des .
data: obj_len type so_obj_len .
obj_len = xstrlen( content ).
call method ob_gbt_multirelated_service->add_binary_part
exporting
content = it_solix
filename = image_name_01
extension = 'JPG'
description = description
content_type = 'image/jpg'
length = obj_len
content_id = image_name_01.
endform . "mail_1_prep_2
*----------------------------------------------------------------------*
form mail_1_prep_3
changing
ob_gbt_multirelated_service type ref to cl_gbt_multirelated_service .
data: xstring type xstring.
perform do_igs_chart
changing
xstring .
data: it_solix type solix_tab .
call method cl_bcs_convert=>xstring_to_solix
exporting
iv_xstring = xstring
receiving
et_solix = it_solix.
data: description type so_obj_des .
data: obj_len type so_obj_len .
obj_len = xstrlen( xstring ).
call method ob_gbt_multirelated_service->add_binary_part
exporting
content = it_solix
filename = image_name_02
extension = 'GIF'
description = description
content_type = 'image/gif'
length = obj_len
content_id = image_name_02.
endform . "mail_1_prep_3
*----------------------------------------------------------------------*
form mail_1_prep_4
changing
ob_document_bcs type ref to cl_document_bcs .
data: xstring type xstring.
perform do_igs_chart
changing
xstring .
data: it_solix type solix_tab .
call method cl_bcs_convert=>xstring_to_solix
exporting
iv_xstring = xstring
receiving
et_solix = it_solix.
data: attachment_subject type so_obj_des .
message s000(oo) with 'attachment chart' space into attachment_subject .
try.
call method ob_document_bcs->add_attachment
exporting
i_attachment_type = 'gif'
i_attachment_subject = attachment_subject
i_att_content_hex = it_solix.
catch cx_document_bcs .
endtry.
endform . "mail_1_prep_4
*----------------------------------------------------------------------*
form mail_1_prep_5
changing
ob_document_bcs type ref to cl_document_bcs .
data: customer type scustom .
data: bookings type ty_bookings .
data: connections type ty_connections .
data: formname type tdsfname .
data: fm_name type rs38l_fnam .
formname = p_fname .
call function 'SSF_FUNCTION_MODULE_NAME'
exporting
formname = p_fname
importing
fm_name = fm_name
exceptions
no_form = 1
no_function_module = 2
others = 3.
if sy-subrc ne 0 .
return .
endif .
data: st_control_parameters type ssfctrlop .
data: st_output_options type ssfcompop .
data: st_job_output_info type ssfcrescl .
st_control_parameters-no_dialog = abap_true .
st_control_parameters-getotf = abap_true .
call function fm_name
exporting
control_parameters = st_control_parameters
output_options = st_output_options
customer = customer
bookings = bookings
connections = connections
importing
job_output_info = st_job_output_info
exceptions
formatting_error = 1
internal_error = 2
send_error = 3
user_canceled = 4
others = 5.
if sy-subrc eq 4 .
return .
endif .
if sy-subrc ne 0.
message id sy-msgid type sy-msgty number sy-msgno
with sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
endif.
data: bin_file type xstring .
data: it_lines_dummy type tline_tab .
data: bin_filesize type i .
call function 'CONVERT_OTF'
exporting
format = 'PDF'
importing
bin_file = bin_file
bin_filesize = bin_filesize
tables
otf = st_job_output_info-otfdata
lines = it_lines_dummy
exceptions
err_max_linewidth = 1
err_format = 2
err_conv_not_possible = 3
err_bad_otf = 4
others = 5.
data: it_solix type solix_tab .
call method cl_bcs_convert=>xstring_to_solix
exporting
iv_xstring = bin_file
receiving
et_solix = it_solix.
data: attachment_subject type so_obj_des .
message s000(oo) with 'attachment PDF hex' space into attachment_subject .
try.
call method ob_document_bcs->add_attachment
exporting
i_attachment_type = 'pdf'
i_attachment_subject = attachment_subject
i_att_content_hex = it_solix.
catch cx_document_bcs .
endtry.
endform . "mail_1_prep_5
*----------------------------------------------------------------------*
*----------------------------------------------------------------------*
form mail_1_image_1
changing
content type xstring.
data: ob_mr_api type ref to if_mr_api .
ob_mr_api = cl_mime_repository_api=>if_mr_api~get_api( ).
data: i_url type string value '/SAP/PUBLIC/AES/SAP Sailing.jpg' .
call method ob_mr_api->get
exporting
i_url = i_url
importing
* e_is_folder = is_folder
e_content = content
* e_loio = l_loio
exceptions
parameter_missing = 1
error_occured = 2
not_found = 3
permission_failure = 4
others = 5.
endform . "mail_1_image_1
*----------------------------------------------------------------------*
form get_suma_1
changing
it_suma_1 type tp_suma_1_tab .
clear: it_suma_1[] .
data: it_sflight type flighttab .
select * into table it_sflight
from sflight
where
carrid in s_carrid and
connid in s_connid and
fldate in s_fldate .
field-symbols: <st_sflight> like line of it_sflight .
data: st_suma_1 like line of it_suma_1 .
loop at it_sflight assigning <st_sflight> .
clear st_suma_1 .
st_suma_1-sflight = <st_sflight> .
clear: st_suma_1-sflight-fldate,
st_suma_1-sflight-connid,
st_suma_1-sflight-planetype ,
st_suma_1-sflight-currency .
collect st_suma_1 into it_suma_1 .
endloop .
endform . "get_suma_1
*----------------------------------------------------------------------*
form do_igs_chart
changing
xstring type xstring.
data: ob_igs_chart_engine type ref to cl_igs_chart_engine .
data: ob_ixml type ref to if_ixml .
create object ob_igs_chart_engine
exporting
destination = 'IGS_RFC_DEST'.
ob_ixml = cl_ixml=>create( ).
perform do_igs_chart_1
changing
ob_igs_chart_engine
ob_ixml .
call method ob_igs_chart_engine->execute .
data: it_image_mime type w3mimetabtype .
data: image_size type w3param-cont_len ,
image_type type w3param-cont_type .
call method ob_igs_chart_engine->get_image
importing
image = it_image_mime
image_size = image_size
image_type = image_type.
field-symbols: <st_image_mime> like line of it_image_mime .
loop at it_image_mime assigning <st_image_mime>.
concatenate xstring <st_image_mime>-line into xstring in byte mode.
endloop.
endform . "do_IGS_chart
*----------------------------------------------------------------------*
form do_igs_chart_1
changing
ob_igs_chart_engine type ref to cl_igs_chart_engine
ob_ixml type ref to if_ixml .
data: it_suma_1 type tp_suma_1_tab .
perform get_suma_1
changing
it_suma_1 .
perform do_igs_chart_1_data_1
using
it_suma_1
changing
ob_igs_chart_engine
ob_ixml .
perform do_igs_chart_1_cust_1
changing
ob_igs_chart_engine
ob_ixml .
endform . "do_gui_chart_1
*----------------------------------------------------------------------*
form do_igs_chart_1_data_1
using
it_suma_1 type tp_suma_1_tab
changing
ob_igs_chart_engine type ref to cl_igs_chart_engine
ob_ixml type ref to if_ixml .
data: ob_ixml_document type ref to if_ixml_document ,
ob_ixml_encoding type ref to if_ixml_encoding .
data: ob_simplechartdata type ref to if_ixml_element ,
ob_categories type ref to if_ixml_element ,
ob_category type ref to if_ixml_element ,
ob_series type ref to if_ixml_element ,
ob_point type ref to if_ixml_element ,
ob_value type ref to if_ixml_element ,
l_string type string .
ob_ixml_document = ob_ixml->create_document( ).
ob_ixml_encoding = ob_ixml->create_encoding(
byte_order = if_ixml_encoding=>co_little_endian
character_set = 'utf-8' ) .
ob_ixml_document->set_encoding( ob_ixml_encoding ).
ob_simplechartdata = ob_ixml_document->create_simple_element(
name = 'ChartData' parent = ob_ixml_document ).
ob_categories = ob_ixml_document->create_simple_element(
name = 'Categories' parent = ob_simplechartdata ) .
field-symbols: <st_suma_1> like line of it_suma_1 .
ob_series = ob_ixml_document->create_simple_element(
name = 'Series' parent = ob_simplechartdata ).
ob_series->set_attribute( name = 'label' value = 'Occupied seats in economy class' ).
ob_series->set_attribute( name = 'customizing' value = c_series_01 ).
data: a_string type string .
loop at it_suma_1 assigning <st_suma_1> .
ob_category = ob_ixml_document->create_simple_element(
name = 'Category' parent = ob_categories ).
a_string = cl_str=>to_string( <st_suma_1>-sflight-carrid ) .
ob_category->if_ixml_node~set_value( a_string ) .
ob_point = ob_ixml_document->create_simple_element(
name = 'Point' parent = ob_series ).
a_string = cl_str=>to_string( <st_suma_1>-sflight-seatsocc ) .
concatenate 'Seats = ' a_string into a_string respecting blanks .
ob_point->set_attribute( name = 'label' value = a_string ) .
ob_value = ob_ixml_document->create_simple_element(
name = 'Value' parent = ob_point ).
ob_value->set_attribute( name = 'Type' value = 'y' ) .
a_string = cl_str=>to_string( <st_suma_1>-sflight-seatsocc ) .
ob_value->if_ixml_node~set_value( a_string ).
endloop .
ob_igs_chart_engine->set_data( data_doc = ob_ixml_document ) .
endform . "do_chart_1_data_2
*----------------------------------------------------------------------*
form do_igs_chart_1_cust_1
changing
ob_igs_chart_engine type ref to cl_igs_chart_engine
ob_ixml type ref to if_ixml .
data: ob_ixml_document type ref to if_ixml_document ,
ob_ixml_encoding type ref to if_ixml_encoding .
data: ob_sapchartcustomizing type ref to if_ixml_element ,
ob_globalsettings type ref to if_ixml_element ,
ob_defaults type ref to if_ixml_element ,
ob_charttype type ref to if_ixml_element ,
ob_elements type ref to if_ixml_element ,
ob_charttypes type ref to if_ixml_element ,
ob_columns type ref to if_ixml_element ,
ob_values type ref to if_ixml_element ,
ob_series type ref to if_ixml_element ,
ob_element type ref to if_ixml_element ."Reused as leaf
ob_ixml_document = ob_ixml->create_document( ).
ob_ixml_encoding = ob_ixml->create_encoding(
byte_order = if_ixml_encoding=>co_little_endian
character_set = 'utf-8' ) .
ob_ixml_document->set_encoding( ob_ixml_encoding ) .
ob_sapchartcustomizing = ob_ixml_document->create_simple_element(
name = 'SAPChartCustomizing' parent = ob_ixml_document ) .
ob_sapchartcustomizing->set_attribute( name = 'version' value = '2.0' ) .
ob_globalsettings = ob_ixml_document->create_simple_element(
name = 'GlobalSettings' parent = ob_sapchartcustomizing ) .
ob_element = ob_ixml_document->create_simple_element(
name = 'Dimension' parent = ob_globalsettings ) .
ob_element->if_ixml_node~set_value( 'Three' ) .
* ob_element->if_ixml_node~set_value( 'Two' ) .
ob_element = ob_ixml_document->create_simple_element(
name = 'ColorPalette' parent = ob_globalsettings ) .
ob_element->if_ixml_node~set_value( 'Streamline' ) .
ob_defaults = ob_ixml_document->create_simple_element(
name = 'Defaults' parent = ob_globalsettings ) .
ob_charttype = ob_ixml_document->create_simple_element(
name = 'ChartType' parent = ob_defaults ) .
* ob_charttype->if_ixml_node~set_value( 'Doughnut' ).
* ob_charttype->if_ixml_node~set_value( 'Pie' ).
* ob_charttype->if_ixml_node~set_value( 'Lines' ).
ob_charttype->if_ixml_node~set_value( 'Columns' ) .
ob_elements = ob_ixml_document->create_simple_element(
name = 'Elements' parent = ob_sapchartcustomizing ) .
ob_charttypes = ob_ixml_document->create_simple_element(
name = 'ChartTypes' parent = ob_elements ) .
ob_columns = ob_ixml_document->create_simple_element(
name = 'Columns' parent = ob_charttypes ) .
ob_element = ob_ixml_document->create_simple_element(
name = 'VaryColorsByPoint' parent = ob_columns ) .
ob_element->if_ixml_node~set_value( 'true' ) .
""""
ob_values = ob_ixml_document->create_simple_element(
name = 'Values' parent = ob_sapchartcustomizing ) .
ob_series = ob_ixml_document->create_simple_element(
name = 'Series' parent = ob_values ) .
ob_series->set_attribute( name = 'id' value = c_series_01 ) .
ob_element = ob_ixml_document->create_simple_element(
name = 'ShowLabel' parent = ob_series ) .
ob_element->if_ixml_node~set_value( 'true' ) .
ob_igs_chart_engine->set_customizing( custom_doc = ob_ixml_document ) .
endform . "do_chart_1_cust_1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment