最近遇到了一个需求,在sap后台按月将数据导入到ftp服务器上,并保存为excel文件。之前的做法是将文件生成到本地,然后上传到sap服务器上。但是sap服务器后台运行程序的时候并不存在本地路径,因此要求直接将内表保存为excel格式传输到ftp上。据我了解,sap并不支持ole的传输,于是就想到使用xml方式传输到ftp上,然后将扩展名保存为*.xls同样可以使用excel打开。于是对程序进行了如下的改写。
1.创建XML文件
l_ixml = cl_ixml=>create( ).
* Creating the dom object model
l_document = l_ixml->create_document( ).
* Create root node 'Workbook'
l_element_root = l_document->create_simple_element(
name = 'Workbook'
* uri = 'urn:schemas-microsoft-com:office:spreadsheet'
parent = l_document ).
l_element_root->set_attribute(
name = 'xmlns'
value = 'urn:schemas-microsoft-com:office:spreadsheet' ).
ns_attribute = l_document->create_namespace_decl(
name = 'ss'
prefix = 'xmlns'
uri = 'urn:schemas-microsoft-com:office:spreadsheet' ).
l_element_root->set_attribute_node( ns_attribute ).
ns_attribute = l_document->create_namespace_decl(
name = 'x'
prefix = 'xmlns'
uri = 'urn:schemas-microsoft-com:office:excel' ).
l_element_root->set_attribute_node( ns_attribute ).
* Create node for document properties.
r_element_properties = l_document->create_simple_element(
name = 'DocumentProperties'
parent = l_element_root ).
l_value = sy-uname.
l_document->create_simple_element(
name = 'Author'
value = l_value
parent = r_element_properties ).
2.创建excel表名
r_worksheet = l_document->create_simple_element(
name = 'Worksheet '
parent = l_element_root ).
r_worksheet->set_attribute_ns(
name = 'Name'
prefix = 'ss'
value = table_name ).
* table
* <Table ss:ExpandedColumnCount="3" ss:ExpandedRowCount="1" x:FullColumns="1" x:FullRows="1">
r_table = l_document->create_simple_element(
name = 'Table'
parent = r_worksheet ).
3.创建column
因为xml格式的excel为先column,然后再每个row下存在cell,所以先循环输出column。
LOOP AT i_table INTO wa_tab.
r_column = l_document->create_simple_element(
name = 'Column'
parent = r_table ).
endloop.
4.row和内容类型
r_row = l_document->create_simple_element(
name = 'Row'
parent = r_table ).
r_cell = l_document->create_simple_element(
name = 'Cell'
parent = r_row ).
r_data = l_document->create_simple_element(
name = 'Data'
value = '人员基本信息'
parent = r_cell ).
r_data->set_attribute_ns(
name = 'Type'
prefix = 'ss'
value = 'String' ).
将内表填写到excel表格内
loop at i_table ASSIGNING <data_line>.
i_index = i_index + 1.
l_index = i_index.
r_row = l_document->create_simple_element(
name = 'Row'
parent = r_table ).
r_cell = l_document->create_simple_element(
name = 'Cell'
parent = r_row ).
r_data = l_document->create_simple_element(
name = 'Data'
value = l_index
parent = r_cell ).
r_data->set_attribute_ns(
name = 'Type'
prefix = 'ss'
value = 'String' ).
desc_struc ?= cl_abap_typedescr=>describe_by_data( i_table )."因为内表的每列数据要填写到excel的每行内。所以使用该方法将内表转换。
* perform get_cell using t_itab-bukrs.
loop at desc_struc->components ASSIGNING <field_name>.
ASSIGN COMPONENT <field_name>-name OF STRUCTURE <data_line> TO <field>."动态绑定表格内容。
CHECK sy-subrc IS INITIAL.
r_cell = l_document->create_simple_element(
name = 'Cell'
parent = r_row ).
l_value = <field_name>-name.
l_type = <field_name>-type_kind. "fieldname, scrtext_m etc.
CASE l_type.
WHEN 'I' OR 'P' OR 'F' OR 'N'.
l_type = 'String'.
l_value = <field>.
CONDENSE l_value NO-GAPS.
WHEN 'D' OR 'T'.
l_type = 'String'.
WRITE <field> TO l_text.
l_value = l_text.
WHEN OTHERS.
* l_value = <field>. "Without conversion exit
WRITE <field> TO l_text.
SHIFT l_text LEFT DELETING LEADING space.
l_value = l_text.
l_type = 'String'.
ENDCASE.
r_data = l_document->create_simple_element(
name = 'Data'
value = l_value
parent = r_cell ).
r_data->set_attribute_ns(
name = 'Type'
prefix = 'ss'
value = l_type ).
endloop.
ENDLOOP.
xml生成输出
l_streamfactory = l_ixml->create_stream_factory( ).
* Connect internal XML table to stream factory
l_ostream = l_streamfactory->create_ostream_itable( table = l_xml_table ).
* rendering the document
l_renderer = l_ixml->create_renderer( ostream = l_ostream
document = l_document ).
l_rc = l_renderer->render( ).
* saving the xml document
l_xml_size = l_ostream->get_num_written_raw( ).
最后 使用上传方法绑定内表名称,完成上传。
CALL FUNCTION 'FTP_R3_TO_SERVER'
EXPORTING
handle = hdl
fname = 'Excle.xls'"此处将xml文件作为excel格式保存,不影响访问。
blob_length = l_xml_size
TABLES
blob = l_xml_table.
至此,通过xml完成直接将内表中的数据作为文件保存到ftp上。完成数据的上传。