*"* use this source file for the definition and implementation of *"* local helper classes, interface definitions and type *"* declarations * Signal "not found" class lcx_not_found implementation. method constructor. super->constructor( textid = textid previous = previous ). me->error = error. endmethod. method if_message~get_text. result = error. endmethod. endclass. *"* use this source file for any type of declarations (class *"* definitions, interfaces or type declarations) you need for *"* components in the private section * Signal for "Not found" class lcx_not_found definition inheriting from cx_static_check. public section. data error type string. methods constructor importing error type string textid type sotr_conc optional previous type ref to cx_root optional. methods if_message~get_text redefinition. endclass. *"* use this source file for any macro definitions you need *"* in the implementation part of the class *"* use this source file for your ABAP unit test classes CLASS lcl_test DEFINITION DEFERRED. CLASS zcl_excel_reader_huge_file DEFINITION LOCAL FRIENDS lcl_test. * CLASS lcl_test DEFINITION FOR TESTING " #AU Risk_Level Harmless INHERITING FROM cl_aunit_assert. " #AU Duration Short PRIVATE SECTION. DATA: out TYPE REF TO zcl_excel_reader_huge_file, " object under test excel TYPE REF TO zcl_excel, worksheet TYPE REF TO zcl_excel_worksheet. METHODS: setup, test_number FOR TESTING, test_shared_string FOR TESTING, test_shared_string_missing FOR TESTING, test_inline_string FOR TESTING, test_boolean FOR TESTING, test_style FOR TESTING, test_style_missing FOR TESTING, test_formula FOR TESTING, test_read_shared_strings FOR TESTING, test_skip_to_inexistent FOR TESTING, get_reader IMPORTING iv_xml TYPE string RETURNING VALUE(eo_reader) TYPE REF TO if_sxml_reader, assert_value_equals IMPORTING iv_row TYPE i DEFAULT 1 iv_col TYPE i DEFAULT 1 iv_value TYPE string, assert_formula_equals IMPORTING iv_row TYPE i DEFAULT 1 iv_col TYPE i DEFAULT 1 iv_formula TYPE string, assert_style_equals IMPORTING iv_row TYPE i DEFAULT 1 iv_col TYPE i DEFAULT 1 iv_style TYPE zexcel_cell_style, assert_datatype_equals IMPORTING iv_row TYPE i DEFAULT 1 iv_col TYPE i DEFAULT 1 iv_datatype TYPE string. ENDCLASS. "lcl_test DEFINITION * CLASS lcl_test IMPLEMENTATION. * METHOD test_number. DATA lo_reader TYPE REF TO if_sxml_reader. lo_reader = get_reader( `<c r="A1" t="n"><v>17</v></c>` ). out->read_worksheet_data( io_reader = lo_reader io_worksheet = worksheet ). assert_value_equals( `17` ). assert_datatype_equals( `n` ). ENDMETHOD. "test_shared_string * METHOD test_shared_string. DATA lo_reader TYPE REF TO if_sxml_reader. APPEND `Test` TO out->shared_strings. lo_reader = get_reader( `<c r="A1" t="s"><v>0</v></c>` ). out->read_worksheet_data( io_reader = lo_reader io_worksheet = worksheet ). assert_value_equals( `Test` ). assert_datatype_equals( `s` ). ENDMETHOD. "test_shared_string * METHOD test_shared_string_missing. DATA: lo_reader TYPE REF TO if_sxml_reader, lo_ex TYPE REF TO lcx_not_found, lv_text TYPE string. lo_reader = get_reader( `<c r="A1" t="s"><v>0</v></c>` ). TRY. out->read_worksheet_data( io_reader = lo_reader io_worksheet = worksheet ). fail(`Index to non-existent shared string should give an error`). CATCH lcx_not_found INTO lo_ex. lv_text = lo_ex->get_text( ). " >>> May inspect the message in the debugger ENDTRY. ENDMETHOD. * METHOD test_inline_string. DATA lo_reader TYPE REF TO if_sxml_reader. lo_reader = get_reader( `<c r="A1" t="inlineStr"><is><t>Alpha</t></is></c>` ). out->read_worksheet_data( io_reader = lo_reader io_worksheet = worksheet ). assert_value_equals( `Alpha` ). assert_datatype_equals( `inlineStr` ). ENDMETHOD. "test_inline_string * METHOD test_boolean. DATA lo_reader TYPE REF TO if_sxml_reader. lo_reader = get_reader( `<c r="A1" t="b"><v>1</v></c>` ). out->read_worksheet_data( io_reader = lo_reader io_worksheet = worksheet ). assert_value_equals( `1` ). assert_datatype_equals( `b` ). ENDMETHOD. "test_boolean * METHOD test_formula. DATA lo_reader TYPE REF TO if_sxml_reader. lo_reader = get_reader( `<c r="A1" t="n"><f>A2*A2</f></c>` ). out->read_worksheet_data( io_reader = lo_reader io_worksheet = worksheet ). assert_formula_equals( `A2*A2` ). assert_datatype_equals( `n` ). ENDMETHOD. "test_formula * METHOD test_style. DATA: lo_reader TYPE REF TO if_sxml_reader, lo_style TYPE REF TO zcl_excel_style, lv_guid TYPE zexcel_cell_style. CREATE OBJECT lo_style. APPEND lo_style TO out->styles. lv_guid = lo_style->get_guid( ). lo_reader = get_reader( `<c r="A1" s="0"><v>18</v></c>` ). out->read_worksheet_data( io_reader = lo_reader io_worksheet = worksheet ). assert_style_equals( lv_guid ). ENDMETHOD. "test_style * METHOD test_style_missing. DATA: lo_reader TYPE REF TO if_sxml_reader, lo_ex TYPE REF TO lcx_not_found, lv_text TYPE string. lo_reader = get_reader( `<c r="A1" s="0"><v>18</v></c>` ). TRY. out->read_worksheet_data( io_reader = lo_reader io_worksheet = worksheet ). fail(`Reference to non-existent style should throw an lcx_not_found exception`). CATCH lcx_not_found INTO lo_ex. lv_text = lo_ex->get_text( ). " >>> May inspect the message in the debugger ENDTRY. ENDMETHOD. "test_style * METHOD test_read_shared_strings. DATA: lo_reader TYPE REF TO if_sxml_reader, lt_act TYPE stringtab, lt_exp TYPE stringtab. lo_reader = cl_sxml_string_reader=>create( cl_abap_codepage=>convert_to( `<sst><si><t/></si><si><t>Alpha</t></si><si><t>Bravo</t></si></sst>` ) ). APPEND : `` TO lt_exp, `Alpha` TO lt_exp, `Bravo` TO lt_exp. lt_act = out->read_shared_strings( lo_reader ). assert_equals( act = lt_act exp = lt_exp ). ENDMETHOD. * METHOD test_skip_to_inexistent. DATA: lo_reader TYPE REF TO if_sxml_reader, lo_ex TYPE REF TO lcx_not_found, lv_text TYPE string. lo_reader = cl_sxml_string_reader=>create( cl_abap_codepage=>convert_to( `<sst><si><t/></si><si><t>Alpha</t></si><si><t>Bravo</t></si></sst>` ) ). TRY. out->skip_to( iv_element_name = `nonExistingElement` io_reader = lo_reader ). fail(`Skipping to non-existing element must raise lcx_not_found exception`). CATCH lcx_not_found INTO lo_ex. lv_text = lo_ex->get_text( ). " May inspect exception text in debugger ENDTRY. ENDMETHOD. * METHOD get_reader. DATA: lv_full TYPE string. CONCATENATE `<root><sheetData><row>` iv_xml `</row></sheetData></root>` INTO lv_full. eo_reader = cl_sxml_string_reader=>create( cl_abap_codepage=>convert_to( lv_full ) ). ENDMETHOD. "get_reader * METHOD assert_value_equals. FIELD-SYMBOLS: <ls_cell_data> TYPE zexcel_s_cell_data. READ TABLE worksheet->sheet_content ASSIGNING <ls_cell_data> WITH TABLE KEY cell_row = iv_row cell_column = iv_col. assert_subrc( sy-subrc ). assert_equals( act = <ls_cell_data>-cell_value exp = iv_value ). ENDMETHOD. "assert_value_equals ** METHOD assert_formula_equals. FIELD-SYMBOLS: <ls_cell_data> TYPE zexcel_s_cell_data. READ TABLE worksheet->sheet_content ASSIGNING <ls_cell_data> WITH TABLE KEY cell_row = iv_row cell_column = iv_col. assert_subrc( sy-subrc ). assert_equals( act = <ls_cell_data>-cell_formula exp = iv_formula ). ENDMETHOD. "assert_formula_equals * METHOD assert_style_equals. FIELD-SYMBOLS: <ls_cell_data> TYPE zexcel_s_cell_data. READ TABLE worksheet->sheet_content ASSIGNING <ls_cell_data> WITH TABLE KEY cell_row = iv_row cell_column = iv_col. assert_subrc( sy-subrc ). assert_equals( act = <ls_cell_data>-cell_style exp = iv_style ). ENDMETHOD. * METHOD assert_datatype_equals. FIELD-SYMBOLS: <ls_cell_data> TYPE zexcel_s_cell_data. READ TABLE worksheet->sheet_content ASSIGNING <ls_cell_data> WITH TABLE KEY cell_row = iv_row cell_column = iv_col. assert_subrc( sy-subrc ). assert_equals( act = <ls_cell_data>-data_type exp = iv_datatype ). ENDMETHOD. "assert_datatype_equals METHOD setup. CREATE OBJECT out. CREATE OBJECT excel. CREATE OBJECT worksheet EXPORTING ip_excel = excel. ENDMETHOD. "setup ENDCLASS. "lcl_test IMPLEMENTATION method FILL_CELL_FROM_ATTRIBUTES. while io_reader->node_type ne c_end_of_stream. io_reader->next_attribute( ). if io_reader->node_type ne c_attribute. exit. endif. case io_reader->name. when `t`. es_cell-datatype = io_reader->value. when `s`. if io_reader->value is not initial. es_cell-style = get_style( io_reader->value ). endif. when `r`. es_cell-coord = get_cell_coord( io_reader->value ). endcase. endwhile. io_reader->current_node( ). endmethod. method GET_CELL_COORD. zcl_excel_common=>convert_columnrow2column_a_row( exporting i_columnrow = iv_coord importing e_column = es_coord-column e_row = es_coord-row ). endmethod. method GET_SHARED_STRING. data: lv_tabix type i. lv_tabix = iv_index + 1. read table shared_strings into ev_value index lv_tabix. if sy-subrc ne 0. raise exception type lcx_not_found exporting error = |Entry { iv_index } not found in Shared String Table|. endif. endmethod. method GET_STYLE. data: lv_tabix type i, lo_style type ref to zcl_excel_style. if gs_buffer_style-index ne iv_index. lv_tabix = iv_index + 1. read table styles into lo_style index lv_tabix. if sy-subrc ne 0. raise exception type lcx_not_found exporting error = |Entry { iv_index } not found in Style Table|. else. gs_buffer_style-index = iv_index. gs_buffer_style-guid = lo_style->get_guid( ). endif. endif. ev_style_guid = gs_buffer_style-guid. endmethod. method GET_SXML_READER. data: lv_xml type xstring. lv_xml = get_from_zip_archive( iv_path ). eo_reader = cl_sxml_string_reader=>create( lv_xml ). endmethod. method LOAD_SHARED_STRINGS. data: lo_reader type ref to if_sxml_reader. lo_reader = get_sxml_reader( ip_path ). shared_strings = read_shared_strings( lo_reader ). endmethod. method LOAD_WORKSHEET. data: lo_reader type ref to if_sxml_reader. lo_reader = get_sxml_reader( ip_path ). read_worksheet_data( io_reader = lo_reader io_worksheet = io_worksheet ). endmethod. method PUT_CELL_TO_WORKSHEET. call method io_worksheet->set_cell exporting ip_column = is_cell-column ip_row = is_cell-row ip_value = is_cell-value ip_formula = is_cell-formula ip_data_type = is_cell-datatype ip_style = is_cell-style. endmethod. method READ_SHARED_STRINGS. while io_reader->node_type ne c_end_of_stream. io_reader->next_node( ). if io_reader->node_type eq c_element_close and io_reader->name eq `t`. append io_reader->value to et_shared_strings. endif. endwhile. endmethod. method READ_WORKSHEET_DATA. data: ls_cell type t_cell. * Skip to <sheetData> element skip_to( iv_element_name = `sheetData` io_reader = io_reader ). * Main loop: Evaluate the <c> elements and its children while io_reader->node_type ne c_end_of_stream. io_reader->next_node( ). case io_reader->node_type. when c_element_open. if io_reader->name eq `c`. ls_cell = fill_cell_from_attributes( io_reader ). endif. when c_element_close. case io_reader->name. when `c`. put_cell_to_worksheet( is_cell = ls_cell io_worksheet = io_worksheet ). when `f`. ls_cell-formula = io_reader->value. when `v`. if ls_cell-datatype eq `s`. ls_cell-value = get_shared_string( ls_cell-value ). else. ls_cell-value = io_reader->value. endif. when `is`. ls_cell-value = io_reader->value. when `sheetData`. exit. endcase. endcase. endwhile. endmethod. method SKIP_TO. * Skip forward to given element while io_reader->name ne iv_element_name or io_reader->node_type ne c_element_open. io_reader->next_node( ). if io_reader->node_type = c_end_of_stream. raise exception type lcx_not_found exporting error = |XML error: Didn't find element <{ iv_element_name }>|. endif. endwhile. endmethod.