*"* 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.