diff --git a/ZA2X/CLAS/ZCL_EXCEL_READER_2007.slnk b/ZA2X/CLAS/ZCL_EXCEL_READER_2007.slnk index b7bff91..3817624 100644 --- a/ZA2X/CLAS/ZCL_EXCEL_READER_2007.slnk +++ b/ZA2X/CLAS/ZCL_EXCEL_READER_2007.slnk @@ -1,6 +1,6 @@ - - + - - - - - - - - - - - - - - - - *"* local class implementation for public class @@ -88,61 +88,175 @@ id TYPE string, type TYPE string, target TYPE string, - END OF t_relationship. + END OF t_relationship. + +* + CLASS lcl_abap_zip_archive DEFINITION + INHERITING FROM lcl_zip_archive + CREATE PRIVATE. + PUBLIC SECTION. + CLASS-METHODS create + IMPORTING i_data TYPE xstring + RETURNING value(r_zip) TYPE REF TO lcl_zip_archive + RAISING zcx_excel. + METHODS read REDEFINITION. + PRIVATE SECTION. + DATA: abap_zip TYPE REF TO cl_abap_zip. + METHODS constructor IMPORTING i_data TYPE xstring + RAISING zcx_excel. + ENDCLASS. "lcl_abap_zip_archive DEFINITION + +* + CLASS lcl_alternate_zip_archive DEFINITION + INHERITING FROM lcl_zip_archive + CREATE PRIVATE. + PUBLIC SECTION. + CLASS-METHODS create + IMPORTING i_data TYPE xstring + i_alternate_zip_class TYPE seoclsname + RETURNING value(r_zip) TYPE REF TO lcl_zip_archive + RAISING zcx_excel. + METHODS read REDEFINITION. + PRIVATE SECTION. + DATA: alternate_zip TYPE REF TO object. + METHODS constructor + IMPORTING i_data TYPE xstring + i_alternate_zip_class TYPE seoclsname + RAISING zcx_excel. + ENDCLASS. "lcl_alternate_zip_archive DEFINITION + +* + CLASS lcl_abap_zip_archive IMPLEMENTATION. + METHOD create. + CREATE OBJECT r_zip TYPE lcl_abap_zip_archive + EXPORTING + i_data = i_data. + ENDMETHOD. "create + METHOD constructor. + DATA: lv_errormessage TYPE string. + super->constructor( ). + CREATE OBJECT abap_zip. + abap_zip->load( + EXPORTING + zip = i_data + EXCEPTIONS + zip_parse_error = 1 + OTHERS = 2 ). + IF sy-subrc <> 0. + lv_errormessage = 'ZIP parse error'(002). + RAISE EXCEPTION TYPE zcx_excel + EXPORTING + error = lv_errormessage. + ENDIF. + + ENDMETHOD. "constructor + METHOD read. + DATA: lv_errormessage TYPE string. + CALL METHOD abap_zip->get + EXPORTING + name = i_filename + IMPORTING + content = r_content + 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 = lv_errormessage. + ENDIF. + + ENDMETHOD. "read + ENDCLASS. "lcl_abap_zip_archive IMPLEMENTATION + +* + CLASS lcl_alternate_zip_archive IMPLEMENTATION. + METHOD create. + CREATE OBJECT r_zip TYPE lcl_alternate_zip_archive + EXPORTING + i_alternate_zip_class = i_alternate_zip_class + i_data = i_data. + ENDMETHOD. "create + METHOD constructor. + DATA: lv_errormessage TYPE string. + super->constructor( ). + CREATE OBJECT alternate_zip TYPE (i_alternate_zip_class). + TRY. + CALL METHOD alternate_zip->('LOAD') + EXPORTING + zip = i_data + EXCEPTIONS + zip_parse_error = 1 + OTHERS = 2. + CATCH cx_sy_dyn_call_illegal_method. + lv_errormessage = 'Method LOAD missing in alternative zipclass'. "#EC NOTEXT This is a workaround until class CL_ABAP_ZIP is fixed + RAISE EXCEPTION TYPE zcx_excel + EXPORTING + error = lv_errormessage. + ENDTRY. + + IF sy-subrc <> 0. + lv_errormessage = 'ZIP parse error'(002). + RAISE EXCEPTION TYPE zcx_excel + EXPORTING + error = lv_errormessage. + ENDIF. + + ENDMETHOD. "constructor + METHOD read. + DATA: lv_errormessage TYPE string. + TRY. + CALL METHOD alternate_zip->('GET') + EXPORTING + name = i_filename + IMPORTING + content = r_content " Contents + EXCEPTIONS + zip_index_error = 1 + zip_decompression_error = 2 + OTHERS = 3. + CATCH cx_sy_dyn_call_illegal_method. + lv_errormessage = 'Method GET missing in alternative zipclass'. "#EC NOTEXT This is a workaround until class CL_ABAP_ZIP is fixed + RAISE EXCEPTION TYPE zcx_excel + EXPORTING + error = lv_errormessage. + ENDTRY. + IF sy-subrc <> 0. + lv_errormessage = 'File not found in zip-archive'(003). + RAISE EXCEPTION TYPE zcx_excel + EXPORTING + error = lv_errormessage. + ENDIF. + + ENDMETHOD. "read + ENDCLASS. "lcl_alternate_zip_archive IMPLEMENTATION *"* use this source file for any type declarations (class *"* definitions, interfaces or data types) you need for method -*"* implementation or private method's signature +*"* implementation or private method's signature + +* +class lcl_zip_archive definition abstract. + public section. + methods read abstract + importing i_filename type csequence + returning value(r_content) type xstring " Remember copy-on-write! + raising zcx_excel. +endclass. *"* use this source file for any macro definitions you need *"* in the implementation part of the class - - - - - - - IXML - - - - - - - - method ZIF_EXCEL_READER~CAN_READ_FILE. -*--------------------------------------------------------------------* -* issue #230 - Pimp my Code -* - Stefan Schmöcker, (done) 2012-11-07 -* - ... -* changes: nothing done in code -* but started discussion about killing this method -*--------------------------------------------------------------------* -* For now always Unknown - r_readable = abap_undefined. - endmethod. - + + + + - method ZIF_EXCEL_READER~LOAD. + METHOD zif_excel_reader~load. *--------------------------------------------------------------------* * ToDos: * 2do§1 Map Document Properties to ZCL_EXCEL -*--------------------------------------------------------------------* - -*--------------------------------------------------------------------* -* issue #230 - Pimp my Code -* - Stefan Schmöcker, (done) 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 -*--------------------------------------------------------------------* -* issue#234 - error reading xlsx written by libre office -* - Stefan Schmöcker, 2012-11-07 -* changes: passing new optional input parameter to private attribute *--------------------------------------------------------------------* CONSTANTS: lcv_core_properties TYPE string VALUE 'http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties', @@ -184,37 +298,36 @@ *--------------------------------------------------------------------* CREATE OBJECT r_excel. -*--------------------------------------------------------------------* -* issue#234 - error reading xlsx written by libre office - me->zif_excel_reader~gv_use_alternate_zip = i_use_alternate_zip. -*--------------------------------------------------------------------* - + zip = create_zip_archive( i_xlsx_binary = i_excel2007 + i_use_alternate_zip = i_use_alternate_zip ). *--------------------------------------------------------------------* * §2 Get file in folderstructure *--------------------------------------------------------------------* - me->excel2007 = i_excel2007. - lo_rels = me->get_ixml_from_zip_archive( '_rels/.rels' ). + lo_rels = get_ixml_from_zip_archive( '_rels/.rels' ). *--------------------------------------------------------------------* * §3 Cycle through the Relationship Tags and use the ones we need *--------------------------------------------------------------------* - lo_node ?= lo_rels->find_from_name( 'Relationship' ). "#EC NOTEXT + lo_node ?= lo_rels->find_from_name( 'Relationship' ). "#EC NOTEXT WHILE lo_node IS BOUND. - me->fill_struct_from_attributes( EXPORTING - ip_element = lo_node - CHANGING - cp_structure = ls_relationship ). + fill_struct_from_attributes( EXPORTING + ip_element = lo_node + CHANGING + cp_structure = ls_relationship ). CASE ls_relationship-type. + WHEN lcv_office_document. +*--------------------------------------------------------------------* +* Parse workbook - main part here +*--------------------------------------------------------------------* + load_workbook( iv_workbook_full_filename = ls_relationship-target + io_excel = r_excel ). + WHEN lcv_core_properties. " 2do§1 Map Document Properties to ZCL_EXCEL - WHEN lcv_office_document. - me->load_workbook( iv_workbook_full_filename = ls_relationship-target - io_excel = r_excel ). - WHEN OTHERS. ENDCASE. @@ -223,61 +336,49 @@ ENDWHILE. - endmethod. +ENDMETHOD. METHOD zif_excel_reader~load_file. -*--------------------------------------------------------------------* -* ToDos: -* 2do§1 decision whether to load from frontend or backend -* current behavior ( autodecide ) should be default -* add optional parameter to allow user to choose -* to load from backend even when online -* 2do§2 loosen typing of i_filename to CLIKE -*--------------------------------------------------------------------* + + DATA: lv_excel_data TYPE xstring. *--------------------------------------------------------------------* -* issue #230 - Pimp my Code -* - Stefan Schmöcker, (done) 2012-11-05 -* - ... -* changes: renaming variables to naming conventions -* renaming variables to indicate what they are used for -* adding comments to explain what we are trying to achieve -* message made to support multilinguality -* aligning code -* commenting on problems/future enhancements/todos we already know of or should decide upon -* adding issue # that has initiated the change - date provided to allow cleaning of code after a certain period -* explicit declaration of type of table instead of implicit declaration -* added errorhandling for open dataset +* Read file into binary string *--------------------------------------------------------------------* -* issue#234 - error reading xlsx written by libre office -* - Stefan Schmöcker, 2012-11-07 -* changes: passing new optional input parameter to private attribute -*--------------------------------------------------------------------* - - DATA: lv_excel_data TYPE xstring. - -* issue#234 - error reading xlsx written by libre office - me->zif_excel_reader~gv_use_alternate_zip = i_use_alternate_zip. - - IF i_from_applserver = abap_true. - lv_excel_data = me->read_from_applserver( i_filename = i_filename ). - ELSE. - lv_excel_data = me->read_from_local_file( i_filename = i_filename ). - ENDIF. + IF i_from_applserver = abap_true. + lv_excel_data = read_from_applserver( i_filename ). + ELSE. + lv_excel_data = read_from_local_file( i_filename ). + ENDIF. *--------------------------------------------------------------------* -* issue#234 - error reading xlsx written by libre office - r_excel = me->zif_excel_reader~load( i_excel2007 = lv_excel_data - i_use_alternate_zip = i_use_alternate_zip ). +* Parse Excel data into ZCL_EXCEL object from binary string *--------------------------------------------------------------------* + r_excel = zif_excel_reader~load( i_excel2007 = lv_excel_data + i_use_alternate_zip = i_use_alternate_zip ). - ENDMETHOD. +ENDMETHOD. + + + + + + METHOD create_zip_archive. + CASE i_use_alternate_zip. + WHEN space. + e_zip = lcl_abap_zip_archive=>create( i_xlsx_binary ). + WHEN OTHERS. + e_zip = lcl_alternate_zip_archive=>create( i_data = i_xlsx_binary + i_alternate_zip_class = i_use_alternate_zip ). + ENDCASE. +ENDMETHOD. + - method FILL_STRUCT_FROM_ATTRIBUTES. + method fill_struct_from_attributes. *--------------------------------------------------------------------* * issue #230 - Pimp my Code * - Stefan Schmöcker, (done) 2012-11-07 @@ -287,12 +388,12 @@ * adding comments to explain what we are trying to achieve *--------------------------------------------------------------------* - 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. + 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. + field-symbols: <component> type any. *--------------------------------------------------------------------* * The values of named attributes of a tag are being read and moved into corresponding @@ -305,182 +406,54 @@ * structure has fieldnames Id and Target these would be filled with * "rId3" and "docProps/app.xml" respectively *--------------------------------------------------------------------* - CLEAR cp_structure. + clear cp_structure. lo_attributes = ip_element->get_attributes( ). lo_iterator = lo_attributes->create_iterator( ). lo_attribute ?= lo_iterator->get_next( ). - WHILE lo_attribute IS BOUND. + 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. + translate lv_name to upper case. + assign component lv_name of structure cp_structure to <component>. + if sy-subrc = 0. <component> = lo_attribute->get_value( ). - ENDIF. + endif. lo_attribute ?= lo_iterator->get_next( ). - ENDWHILE. + endwhile. - endmethod. +endmethod. - method GET_FROM_ZIP_ARCHIVE. -*--------------------------------------------------------------------* -* issue #230 - Pimp my Code -* - Stefan Schmöcker, (done) 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 -*--------------------------------------------------------------------**--------------------------------------------------------------------* -* issue#234 - error reading xlsx written by libre office -* - Stefan Schmöcker, 2012-11-07 -* changes: copying coding and using ALTERNATE_ZIP in ELSE-Branch -*--------------------------------------------------------------------* + METHOD get_from_zip_archive. - DATA: lv_errormessage TYPE string. " Can't pass '...'(abc) to exception-class + ASSERT zip IS BOUND. " zip object has to exist at this point + r_content = zip->read( i_filename ). -*--------------------------------------------------------------------* -* An xlsx-file is basically a zip-archive -* From this zip-archive we need to extract one file in binary form -*--------------------------------------------------------------------* - IF me->zif_excel_reader~gv_use_alternate_zip IS INITIAL. "+#234 -*--------------------------------------------------------------------* -* 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 ). - IF sy-subrc <> 0. - lv_errormessage = 'ZIP parse error'(002). - RAISE EXCEPTION TYPE zcx_excel - EXPORTING - error = lv_errormessage. - ENDIF. - ENDIF. - -*--------------------------------------------------------------------* -* 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 = lv_errormessage. - ENDIF. -*--------------------------------------------------------------------* -* issue#234 - begin of insertion -*--------------------------------------------------------------------* - ELSE. -*--------------------------------------------------------------------* -* Setup alternate ABAP zip-class with binary exceldata if not done already -* May become obsolete if SAP fixes standard CL_ABAP_ZIP -*--------------------------------------------------------------------* - IF me->alternate_zip IS NOT BOUND. - CREATE OBJECT me->alternate_zip TYPE (zif_excel_reader~gv_use_alternate_zip). - TRY. - CALL METHOD me->alternate_zip->('LOAD') - EXPORTING - zip = me->excel2007 - EXCEPTIONS - zip_parse_error = 1 - OTHERS = 2. - CATCH cx_sy_dyn_call_illegal_method. - lv_errormessage = 'Method LOAD missing in alternative zipclass'. "#EC NOTEXT This is a workaround until class CL_ABAP_ZIP is fixed - RAISE EXCEPTION TYPE zcx_excel - EXPORTING - error = lv_errormessage. - ENDTRY. - - IF sy-subrc <> 0. - lv_errormessage = 'ZIP parse error'(002). - RAISE EXCEPTION TYPE zcx_excel - EXPORTING - error = lv_errormessage. - ENDIF. - ENDIF. - -*--------------------------------------------------------------------* -* Extract requested filename from archive if possible -*--------------------------------------------------------------------* - TRY. - CALL METHOD me->alternate_zip->('GET') - EXPORTING - name = i_filename - IMPORTING - content = r_content " Contents - EXCEPTIONS - zip_index_error = 1 - zip_decompression_error = 2 - OTHERS = 3. - CATCH cx_sy_dyn_call_illegal_method. - lv_errormessage = 'Method GET missing in alternative zipclass'. "#EC NOTEXT This is a workaround until class CL_ABAP_ZIP is fixed - RAISE EXCEPTION TYPE zcx_excel - EXPORTING - error = lv_errormessage. - ENDTRY. - IF sy-subrc <> 0. - lv_errormessage = 'File not found in zip-archive'(003). - RAISE EXCEPTION TYPE zcx_excel - EXPORTING - error = lv_errormessage. - ENDIF. - ENDIF. -*--------------------------------------------------------------------* -* issue#234 - end of insertion -*--------------------------------------------------------------------* - - endmethod. +ENDMETHOD. - + - method GET_IXML_FROM_ZIP_ARCHIVE. -*--------------------------------------------------------------------* -* ToDos: -* 2do§1 Add comment what is being achieved here -*--------------------------------------------------------------------* - -*--------------------------------------------------------------------* -* issue #230 - Pimp my Code -* - Stefan Schmöcker, (done) 2012-11-07 -* - ... -* changes: renaming variables to naming conventions -* removing unnecessary type-pool -* aligning code -*--------------------------------------------------------------------* + METHOD get_ixml_from_zip_archive. DATA: lv_content TYPE xstring, - 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. - *--------------------------------------------------------------------* -* 2do§1 ???? Something happens here ??? +* Load XML file from archive into an input stream, +* and parse that stream into an ixml object *--------------------------------------------------------------------* lv_content = me->get_from_zip_archive( i_filename ). lo_ixml = cl_ixml=>create( ). @@ -490,17 +463,16 @@ 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. +ENDMETHOD. - - - - + + + + method LOAD_DRAWING_ANCHOR. TYPES: BEGIN OF t_c_nv_pr, @@ -651,7 +623,7 @@ - + method LOAD_SHARED_STRINGS. *--------------------------------------------------------------------* * ToDos: @@ -771,7 +743,7 @@ - + method LOAD_STYLES. *--------------------------------------------------------------------* @@ -1495,9 +1467,9 @@ endmethod. - - - + + + method LOAD_WORKBOOK. *--------------------------------------------------------------------* * ToDos: @@ -1916,7 +1888,7 @@ - + method LOAD_WORKSHEET. *--------------------------------------------------------------------* * ToDos: @@ -2616,10 +2588,10 @@ endmethod. - - - - + + + + method LOAD_WORKSHEET_DRAWING. TYPES: BEGIN OF t_c_nv_pr, @@ -2735,9 +2707,9 @@ endmethod. - - - + + + METHOD read_from_applserver. DATA: lv_filelength TYPE i, @@ -2779,9 +2751,9 @@ binary_tab = lt_binary_data. ENDMETHOD. - - - + + + METHOD read_from_local_file. DATA: lv_filelength TYPE i, lt_binary_data TYPE STANDARD TABLE OF x255 WITH NON-UNIQUE DEFAULT KEY, @@ -2838,9 +2810,9 @@ ENDMETHOD. - - - + + + method RESOLVE_PATH. *--------------------------------------------------------------------* * ToDos: @@ -2882,7 +2854,7 @@ endmethod. - + method RESOLVE_REFERENCED_FORMULAE. TYPES: BEGIN OF ty_referenced_cells, sheet TYPE REF TO zcl_excel_worksheet,