diff --git a/ZA2X/CLAS/ZCL_EXCEL_READER_2007.slnk b/ZA2X/CLAS/ZCL_EXCEL_READER_2007.slnk index c108348..be2fe01 100644 --- a/ZA2X/CLAS/ZCL_EXCEL_READER_2007.slnk +++ b/ZA2X/CLAS/ZCL_EXCEL_READER_2007.slnk @@ -249,6 +249,8 @@ protected section. + + @@ -258,50 +260,113 @@ protected section. - method ZIF_EXCEL_READER~CAN_READ_FILE. + METHOD zif_excel_reader~can_read_file. +*--------------------------------------------------------------------* +* issue #230 - Pimp my Code +* - Stefan Schmöcker, 2012-11-07 +* changes: nothind done in code +* but started discussion about killing this method +*--------------------------------------------------------------------* * For now always Unknown r_readable = abap_undefined. -endmethod. +ENDMETHOD. - method ZIF_EXCEL_READER~LOAD. + METHOD zif_excel_reader~load. +*--------------------------------------------------------------------* +* ToDos: +* 2do§1 Map Document Properties to ZCL_EXCEL +*--------------------------------------------------------------------* - CONSTANTS: - lc_core_properties TYPE string VALUE 'http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties', - lc_office_document TYPE string VALUE 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument', - lc_relationships TYPE string VALUE 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'. +*--------------------------------------------------------------------* +* issue #230 - Pimp my Code +* - Stefan Schmöcker, 2012-11-07 +* - ... +* changes: renaming variables to naming conventions +* removing unused variables +* aligning code +* adding comments to explain what we are trying to achieve +* commenting on problems/future enhancements/todos we already know of or should decide upon +* adding me-> where possible +*--------------------------------------------------------------------* - DATA: rels TYPE REF TO if_ixml_document, - node TYPE REF TO if_ixml_element, - relationship TYPE t_relationship. + CONSTANTS: lcv_core_properties TYPE string VALUE 'http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties', + lcv_office_document TYPE string VALUE 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument'. - me->excel2007 = i_excel2007. - rels = me->get_ixml_from_zip_archive( '_rels/.rels' ). + DATA: lo_rels TYPE REF TO if_ixml_document, + lo_node TYPE REF TO if_ixml_element, + ls_relationship TYPE t_relationship. + +*--------------------------------------------------------------------* +* $1 Create EXCEL-Object we want to return to caller + +* §2 We need to read the the file "\\_rels\.rels" because it tells +* us where in this folder structure the data for the workbook +* is located in the xlsx zip-archive +* +* The xlsx Zip-archive has generally the following folder structure: +* <root> | +* |--> _rels +* |--> doc_Props +* |--> xl | +* |--> _rels +* |--> theme +* |--> worksheets + +* §3 Extracting from this the path&file where the workbook is located +* Following is an example how this file could be set up +* <?xml version="1.0" encoding="UTF-8" standalone="true"?> +* - <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"> +* <Relationship Target="docProps/app.xml" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" Id="rId3"/> +* <Relationship Target="docProps/core.xml" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Id="rId2"/> +* <Relationship Target="xl/workbook.xml" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Id="rId1"/> +* </Relationships> +*--------------------------------------------------------------------* + + +*--------------------------------------------------------------------* +* $1 Create EXCEL-Object we want to return to caller +*--------------------------------------------------------------------* CREATE OBJECT r_excel. - node ?= rels->find_from_name( 'Relationship' ). - WHILE node IS BOUND. - fill_struct_from_attributes( EXPORTING ip_element = node CHANGING cp_structure = relationship ). +*--------------------------------------------------------------------* +* $2 Get file in folderstructure +*--------------------------------------------------------------------* + me->excel2007 = i_excel2007. + lo_rels = me->get_ixml_from_zip_archive( '_rels/.rels' ). - CASE relationship-type. - WHEN lc_core_properties. - " TODO Map Document Properties to ZCL_EXCEL - WHEN lc_office_document. - load_workbook( - ip_path = relationship-target - ip_excel = r_excel ). +*--------------------------------------------------------------------* +* $3 Cycle through the Relationship Tags and use the ones we need +*--------------------------------------------------------------------* + lo_node ?= lo_rels->find_from_name( 'Relationship' ). + WHILE lo_node IS BOUND. + + me->fill_struct_from_attributes( EXPORTING + ip_element = lo_node + CHANGING + cp_structure = ls_relationship ). + CASE ls_relationship-type. + + WHEN lcv_core_properties. + " 2do§1 Map Document Properties to ZCL_EXCEL + + WHEN lcv_office_document. + me->load_workbook( ip_path = ls_relationship-target + ip_excel = r_excel ). WHEN OTHERS. - ENDCASE. - node ?= node->get_next( ). + ENDCASE. + lo_node ?= lo_node->get_next( ). + ENDWHILE. -endmethod. + +ENDMETHOD. - method ZIF_EXCEL_READER~LOAD_FILE. + METHOD zif_excel_reader~load_file. *--------------------------------------------------------------------* * ToDos: * 2do§1 decision whether to load from frontend or backend @@ -326,20 +391,20 @@ endmethod. * added errorhandling for open dataset *--------------------------------------------------------------------* - CONSTANTS: lcv_load_from_frontend TYPE char1 VALUE 'F', - lcv_load_from_backend TYPE char1 VALUE 'B'. + CONSTANTS: lcv_load_from_frontend TYPE char1 VALUE 'F', + lcv_load_from_backend TYPE char1 VALUE 'B'. - DATA: lv_load_from_source TYPE char1, + DATA: lv_load_from_source TYPE char1, - lv_filelength TYPE i, - lt_binary_data TYPE STANDARD TABLE OF x255 WITH NON-UNIQUE DEFAULT KEY, - ls_binary_data LIKE LINE OF lt_binary_data, + lv_filelength TYPE i, + lt_binary_data TYPE STANDARD TABLE OF x255 WITH NON-UNIQUE DEFAULT KEY, + ls_binary_data LIKE LINE OF lt_binary_data, * Background processing - lv_max_length_line TYPE i, - lv_actual_length_line TYPE i, + lv_max_length_line TYPE i, + lv_actual_length_line TYPE i, - lv_errormessage TYPE string, " Can't pass '...'(abc) to exception-class - lv_excel_data TYPE xstring. " Binary content of .xlsx file + lv_errormessage TYPE string, " Can't pass '...'(abc) to exception-class + lv_excel_data TYPE xstring. " Binary content of .xlsx file *--------------------------------------------------------------------* @@ -435,104 +500,165 @@ endmethod. r_excel = me->zif_excel_reader~load( lv_excel_data ). -endmethod. +ENDMETHOD. - method FILL_STRUCT_FROM_ATTRIBUTES. - DATA: name TYPE string, - attributes TYPE REF TO if_ixml_named_node_map, - attribute TYPE REF TO if_ixml_attribute, - iterator TYPE REF TO if_ixml_node_iterator. + METHOD fill_struct_from_attributes. +*--------------------------------------------------------------------* +* issue #230 - Pimp my Code +* - Stefan Schmöcker, 2012-11-07 +* - ... +* changes: renaming variables to naming conventions +* aligning code +* adding comments to explain what we are trying to achieve +*--------------------------------------------------------------------* - FIELD-SYMBOLS: <component> TYPE any. + DATA: lv_name TYPE string, + lo_attributes TYPE REF TO if_ixml_named_node_map, + lo_attribute TYPE REF TO if_ixml_attribute, + lo_iterator TYPE REF TO if_ixml_node_iterator. + FIELD-SYMBOLS: <component> TYPE ANY. + +*--------------------------------------------------------------------* +* The values of named attributes of a tag are being read and moved into corresponding +* fields of given structure +* Behaves like move-corresonding tag to structure + +* Example: +* <Relationship Target="docProps/app.xml" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" Id="rId3"/> +* Here the attributes are Target, Type and Id. Thus if the passed +* structure has fieldnames Id and Target these would be filled with +* "rId3" and "docProps/app.xml" respectively +*--------------------------------------------------------------------* CLEAR cp_structure. - attributes = ip_element->get_attributes( ). - iterator = attributes->create_iterator( ). - attribute ?= iterator->get_next( ). - WHILE attribute IS BOUND. - name = attribute->get_name( ). - TRANSLATE name TO UPPER CASE. - ASSIGN COMPONENT name OF STRUCTURE cp_structure TO <component>. + lo_attributes = ip_element->get_attributes( ). + lo_iterator = lo_attributes->create_iterator( ). + lo_attribute ?= lo_iterator->get_next( ). + WHILE lo_attribute IS BOUND. + + lv_name = lo_attribute->get_name( ). + TRANSLATE lv_name TO UPPER CASE. + ASSIGN COMPONENT lv_name OF STRUCTURE cp_structure TO <component>. IF sy-subrc = 0. - <component> = attribute->get_value( ). + <component> = lo_attribute->get_value( ). ENDIF. - attribute ?= iterator->get_next( ). + lo_attribute ?= lo_iterator->get_next( ). + ENDWHILE. -endmethod. + + +ENDMETHOD. - method GET_FROM_ZIP_ARCHIVE. + METHOD get_from_zip_archive. +*--------------------------------------------------------------------* +* issue #230 - Pimp my Code +* - Stefan Schmöcker, 2012-11-07 +* - ... +* changes: aligning code +* adding comments to explain what we are trying to achieve +* changed message passed with exception +* message made to support multilinguality +*--------------------------------------------------------------------* + DATA: lv_errormessage TYPE string. " Can't pass '...'(abc) to exception-class + + +*--------------------------------------------------------------------* +* An xlsx-file is basically a zip-archive +* From this zip-archive we need to extract one file in binary form +*--------------------------------------------------------------------* + +*--------------------------------------------------------------------* +* Setup ABAP zip-class with binary exceldata if not done already +*--------------------------------------------------------------------* IF me->zip IS NOT BOUND. CREATE OBJECT me->zip. - zip->load( - EXPORTING - zip = me->excel2007 - EXCEPTIONS - zip_parse_error = 1 - OTHERS = 2 - ). + zip->load( EXPORTING + zip = me->excel2007 + EXCEPTIONS + zip_parse_error = 1 + OTHERS = 2 ). IF sy-subrc <> 0. + lv_errormessage = 'ZIP parse error'(002). RAISE EXCEPTION TYPE zcx_excel EXPORTING - error = 'ZIP parse error'. + error = lv_errormessage. ENDIF. ENDIF. - zip->get( - EXPORTING - name = i_filename - IMPORTING - content = r_content " Contents - EXCEPTIONS - zip_index_error = 1 - zip_decompression_error = 2 - OTHERS = 3 - ). +*--------------------------------------------------------------------* +* Extract requested filename from archive if possible +*--------------------------------------------------------------------* + zip->get( EXPORTING + name = i_filename + IMPORTING + content = r_content " Contents + EXCEPTIONS + zip_index_error = 1 + zip_decompression_error = 2 + OTHERS = 3 ). IF sy-subrc <> 0. + lv_errormessage = 'File not found in zip-archive'(003). RAISE EXCEPTION TYPE zcx_excel EXPORTING - error = 'ZIP index or decompression error'. + error = lv_errormessage. ENDIF. -endmethod. +ENDMETHOD. - method GET_IXML_FROM_ZIP_ARCHIVE. - TYPE-POOLS: ixml. + METHOD get_ixml_from_zip_archive. +*--------------------------------------------------------------------* +* ToDos: +* 2do§1 Add comment what is being achieved here +*--------------------------------------------------------------------* - DATA: content TYPE xstring. +*--------------------------------------------------------------------* +* issue #230 - Pimp my Code +* - Stefan Schmöcker, 2012-11-07 +* - ... +* changes: renaming variables to naming conventions +* removing unnecessary type-pool +* aligning code +*--------------------------------------------------------------------* - DATA: ixml TYPE REF TO if_ixml, - streamfactory TYPE REF TO if_ixml_stream_factory, - istream TYPE REF TO if_ixml_istream, - parser TYPE REF TO if_ixml_parser. + DATA: lv_content TYPE xstring, - content = me->get_from_zip_archive( i_filename ). - ixml = cl_ixml=>create( ). - streamfactory = ixml->create_stream_factory( ). - istream = streamfactory->create_istream_xstring( content ). - r_ixml = ixml->create_document( ). - parser = ixml->create_parser( stream_factory = streamfactory - istream = istream - document = r_ixml ). -* parser->set_normalizing( ). - parser->set_normalizing( is_normalizing ). - parser->set_validating( mode = if_ixml_parser=>co_no_validation ). - parser->parse( ). + lo_ixml TYPE REF TO if_ixml, + lo_streamfactory TYPE REF TO if_ixml_stream_factory, + lo_istream TYPE REF TO if_ixml_istream, + lo_parser TYPE REF TO if_ixml_parser. -endmethod. + +*--------------------------------------------------------------------* +* 2do§1 ???? Something happens here ??? +*--------------------------------------------------------------------* + lv_content = me->get_from_zip_archive( i_filename ). + lo_ixml = cl_ixml=>create( ). + lo_streamfactory = lo_ixml->create_stream_factory( ). + lo_istream = lo_streamfactory->create_istream_xstring( lv_content ). + r_ixml = lo_ixml->create_document( ). + lo_parser = lo_ixml->create_parser( stream_factory = lo_streamfactory + istream = lo_istream + document = r_ixml ). + + lo_parser->set_normalizing( is_normalizing ). + lo_parser->set_validating( mode = if_ixml_parser=>co_no_validation ). + lo_parser->parse( ). + +ENDMETHOD.