diff --git a/README.md b/README.md index 66616e0..4b9fb62 100644 --- a/README.md +++ b/README.md @@ -5,3 +5,5 @@ Please refer to the official wiki for the [abapGit installation guide](https://a Note that the **Demo programs** are provided in a [separate repository](https://github.com/abap2xlsx/demos), and can be installed after abap2xlsx. For questions, bug reports and more information on contributing to the project, please refer to the [contributing guidelines](./CONTRIBUTING.md). + +Version support: minimum tested version is SAP_ABA 731, it might work on older versions still but we need volunteers to test it. diff --git a/docs/index.md b/docs/index.md index 1f37211..55a6b35 100644 --- a/docs/index.md +++ b/docs/index.md @@ -7,3 +7,4 @@ This community project allows you to generate Professional Excel spreadsheets di * [SAPLink](SAPLink-installation) (obsolete) * [F.A.Q.](FAQ) * [abap2xlsx Calender Gallery](abap2xlsx-Calender-Gallery) +* [Demos](https://github.com/abap2xlsx/demos) diff --git a/src/not_cloud/zexcel_template_get_types.prog.abap b/src/not_cloud/zexcel_template_get_types.prog.abap index 7b26177..b0506b7 100644 --- a/src/not_cloud/zexcel_template_get_types.prog.abap +++ b/src/not_cloud/zexcel_template_get_types.prog.abap @@ -166,7 +166,10 @@ FORM get_types . = 'DATA: lo_data type ref to ZCL_EXCEL_TEMPLATE_DATA.'. ENDIF. - cl_demo_output=>new( 'TEXT' )->display( lt_res ). + LOOP AT lt_res ASSIGNING . + cl_demo_output=>write_text( ). + ENDLOOP. + cl_demo_output=>display( ). ENDFORM. diff --git a/src/zcl_excel_theme_fmt_scheme.clas.abap b/src/zcl_excel_theme_fmt_scheme.clas.abap index 07c8a65..d224c8b 100644 --- a/src/zcl_excel_theme_fmt_scheme.clas.abap +++ b/src/zcl_excel_theme_fmt_scheme.clas.abap @@ -19,15 +19,18 @@ CLASS zcl_excel_theme_fmt_scheme DEFINITION METHODS get_default_fmt RETURNING VALUE(rv_string) TYPE string . + + METHODS parse_string + IMPORTING iv_string TYPE string + RETURNING VALUE(ri_node) TYPE REF TO if_ixml_node. ENDCLASS. -CLASS zcl_excel_theme_fmt_scheme IMPLEMENTATION. +CLASS ZCL_EXCEL_THEME_FMT_SCHEME IMPLEMENTATION. METHOD build_xml. - DATA: lo_xml TYPE REF TO cl_xml_document. DATA: lo_node TYPE REF TO if_ixml_node. DATA: lo_elements TYPE REF TO if_ixml_element. CHECK io_document IS BOUND. @@ -35,9 +38,7 @@ CLASS zcl_excel_theme_fmt_scheme IMPLEMENTATION. IF lo_elements IS BOUND. IF fmt_scheme IS INITIAL. - CREATE OBJECT lo_xml. - lo_xml->parse_string( get_default_fmt( ) ). - lo_node = lo_xml->get_first_node( ). + lo_node = parse_string( get_default_fmt( ) ). lo_elements->append_child( new_child = lo_node ). ELSE. lo_elements->append_child( new_child = fmt_scheme ). @@ -191,4 +192,28 @@ CLASS zcl_excel_theme_fmt_scheme IMPLEMENTATION. METHOD load. fmt_scheme = zcl_excel_common=>clone_ixml_with_namespaces( io_fmt_scheme ). ENDMETHOD. "load + + + METHOD parse_string. + DATA li_stream TYPE REF TO if_ixml_istream. + DATA li_ixml TYPE REF TO if_ixml. + DATA li_document TYPE REF TO if_ixml_document. + DATA li_factory TYPE REF TO if_ixml_stream_factory. + DATA li_parser TYPE REF TO if_ixml_parser. + DATA li_istream TYPE REF TO if_ixml_istream. + + li_ixml = cl_ixml=>create( ). + li_document = li_ixml->create_document( ). + li_factory = li_ixml->create_stream_factory( ). + li_istream = li_factory->create_istream_string( iv_string ). + li_parser = li_ixml->create_parser( + stream_factory = li_factory + istream = li_istream + document = li_document ). + li_parser->add_strip_space_element( ). + li_parser->parse( ). + li_istream->close( ). + ri_node = li_document->get_first_child( ). + + ENDMETHOD. ENDCLASS. diff --git a/src/zcl_excel_theme_fmt_scheme.clas.testclasses.abap b/src/zcl_excel_theme_fmt_scheme.clas.testclasses.abap new file mode 100644 index 0000000..c213b73 --- /dev/null +++ b/src/zcl_excel_theme_fmt_scheme.clas.testclasses.abap @@ -0,0 +1,54 @@ +CLASS ltcl_test DEFINITION FOR TESTING DURATION SHORT RISK LEVEL HARMLESS. + PRIVATE SECTION. + METHODS build_xml FOR TESTING. + + DATA mi_ixml TYPE REF TO if_ixml. + DATA mi_document TYPE REF TO if_ixml_document. + METHODS setup. + METHODS render + RETURNING + VALUE(rv_xml) TYPE string. +ENDCLASS. + + +CLASS ltcl_test IMPLEMENTATION. + + METHOD setup. + mi_ixml = cl_ixml=>create( ). + mi_document = mi_ixml->create_document( ). + ENDMETHOD. + + METHOD render. + DATA li_ostream TYPE REF TO if_ixml_ostream. + DATA li_renderer TYPE REF TO if_ixml_renderer. + DATA li_factory TYPE REF TO if_ixml_stream_factory. + + li_factory = mi_ixml->create_stream_factory( ). + li_ostream = li_factory->create_ostream_cstring( rv_xml ). + li_renderer = mi_ixml->create_renderer( + ostream = li_ostream + document = mi_document ). + li_renderer->render( ). + ENDMETHOD. + + METHOD build_xml. + DATA lo_theme_fmt TYPE REF TO zcl_excel_theme_fmt_scheme. + DATA li_ixml TYPE REF TO if_ixml. + DATA li_document TYPE REF TO if_ixml_document. + DATA lv_xml TYPE string. + + mi_document->create_simple_element( + name = zcl_excel_theme=>c_theme_elements + parent = mi_document ). + + CREATE OBJECT lo_theme_fmt. + lo_theme_fmt->build_xml( mi_document ). + + lv_xml = render( ). + + cl_abap_unit_assert=>assert_char_cp( + act = lv_xml + exp = '**' ). + ENDMETHOD. + +ENDCLASS. diff --git a/src/zcl_excel_theme_fmt_scheme.clas.xml b/src/zcl_excel_theme_fmt_scheme.clas.xml index 5d7457d..eae2c4a 100644 --- a/src/zcl_excel_theme_fmt_scheme.clas.xml +++ b/src/zcl_excel_theme_fmt_scheme.clas.xml @@ -10,6 +10,7 @@ X X X + X diff --git a/src/zcl_excel_worksheet.clas.testclasses.abap b/src/zcl_excel_worksheet.clas.testclasses.abap index a4c17ec..65d9be1 100644 --- a/src/zcl_excel_worksheet.clas.testclasses.abap +++ b/src/zcl_excel_worksheet.clas.testclasses.abap @@ -129,32 +129,32 @@ CLASS ltc_normalize_column_heading DEFINITION FOR TESTING DURATION SHORT. PRIVATE SECTION. - TYPES : BEGIN OF ty_parameters, - BEGIN OF input, - default_descr TYPE c LENGTH 1, - field_catalog TYPE zexcel_t_fieldcatalog, - END OF input, - BEGIN OF output, - field_catalog TYPE zexcel_t_fieldcatalog, - END OF output, - END OF ty_parameters. - DATA: - cut TYPE REF TO zcl_excel_worksheet. "class under test - METHODS setup. + DATA: + cut TYPE REF TO zcl_excel_worksheet, "class under test + default_descr TYPE c LENGTH 1 VALUE '?'. + METHODS: + prefer_small_text FOR TESTING RAISING cx_static_check, prefer_medium_text FOR TESTING RAISING cx_static_check, prefer_long_text FOR TESTING RAISING cx_static_check, default_text_if_none FOR TESTING RAISING cx_static_check, - invalid_default_descr FOR TESTING RAISING cx_static_check. + invalid_default_descr FOR TESTING RAISING cx_static_check, - METHODS assert - IMPORTING - input TYPE ty_parameters-input - exp TYPE ty_parameters-output - RAISING - cx_static_check. + assert + IMPORTING + ip_scrtext_s TYPE scrtext_s OPTIONAL + ip_scrtext_m TYPE scrtext_m OPTIONAL + ip_scrtext_l TYPE scrtext_l OPTIONAL + ip_colname_exp TYPE zexcel_column_name OPTIONAL, + + assert_multi + IMPORTING + it_fc TYPE zexcel_t_fieldcatalog OPTIONAL + it_colname_exp TYPE stringtab OPTIONAL, + + setup. ENDCLASS. @@ -1012,214 +1012,208 @@ ENDCLASS. CLASS ltc_normalize_column_heading IMPLEMENTATION. - METHOD setup. - - DATA: lo_excel TYPE REF TO zcl_excel. - - CREATE OBJECT lo_excel. - - TRY. - CREATE OBJECT cut - EXPORTING - ip_excel = lo_excel. - CATCH zcx_excel. - cl_abap_unit_assert=>fail( 'Could not create instance' ). - ENDTRY. - - ENDMETHOD. - METHOD prefer_small_text. - DATA: input TYPE ty_parameters-input, - exp TYPE ty_parameters-output, - field TYPE zexcel_s_fieldcatalog. - input-default_descr = 'S'. + default_descr = 'S'. - field-dynpfld = abap_true. + assert( + ip_scrtext_s = 'Column1_S' + ip_scrtext_m = 'Column1_M' + ip_scrtext_l = 'Column1_L' + ip_colname_exp = 'Column1_S' + ). - field-scrtext_s = 'Column1_S'. - field-scrtext_m = 'Column1_M'. - field-scrtext_l = 'Column1_L'. - APPEND field TO input-field_catalog. - field-scrtext_l = 'Column1_S'. - APPEND field TO exp-field_catalog. - field-scrtext_s = ''. - field-scrtext_m = 'Column2_M'. - field-scrtext_l = 'Column2_L'. - APPEND field TO input-field_catalog. - field-scrtext_l = 'Column2_M'. - APPEND field TO exp-field_catalog. + assert( + ip_scrtext_m = 'Column1_M' + ip_scrtext_l = 'Column1_L' + ip_colname_exp = 'Column1_M' + ). - field-scrtext_s = ''. - field-scrtext_m = 'Column3_M'. - field-scrtext_l = ''. - APPEND field TO input-field_catalog. - field-scrtext_l = 'Column3_M'. - APPEND field TO exp-field_catalog. - field-scrtext_s = ''. - field-scrtext_m = ''. - field-scrtext_l = 'Column4_L'. - APPEND field TO input-field_catalog. - field-scrtext_l = 'Column4_L'. - APPEND field TO exp-field_catalog. + assert( + ip_scrtext_m = 'Column1_M' + ip_colname_exp = 'Column1_M' + ). + + assert( + ip_scrtext_l = 'Column1_L' + ip_colname_exp = 'Column1_L' + ). - assert( input = input exp = exp ). ENDMETHOD. METHOD prefer_medium_text. - DATA: input TYPE ty_parameters-input, - exp TYPE ty_parameters-output, - field TYPE zexcel_s_fieldcatalog. - input-default_descr = 'M'. + default_descr = 'M'. - field-dynpfld = abap_true. + assert( + ip_scrtext_s = 'Column1_S' + ip_scrtext_m = 'Column1_M' + ip_scrtext_l = 'Column1_L' + ip_colname_exp = 'Column1_M' ). - field-scrtext_s = 'Column1_S'. - field-scrtext_m = 'Column1_M'. - field-scrtext_l = 'Column1_L'. - APPEND field TO input-field_catalog. - field-scrtext_l = 'Column1_M'. - APPEND field TO exp-field_catalog. + assert( + ip_scrtext_s = 'Column1_S' + ip_scrtext_l = 'Column1_L' + ip_colname_exp = 'Column1_S' ). - field-scrtext_s = 'Column2_S'. - field-scrtext_m = ''. - field-scrtext_l = 'Column2_L'. - APPEND field TO input-field_catalog. - field-scrtext_l = 'Column2_S'. - APPEND field TO exp-field_catalog. + assert( + ip_scrtext_s = 'Column1_S' + ip_colname_exp = 'Column1_S' ). - field-scrtext_s = 'Column3_S'. - field-scrtext_m = ''. - field-scrtext_l = ''. - APPEND field TO input-field_catalog. - field-scrtext_l = 'Column3_S'. - APPEND field TO exp-field_catalog. - - field-scrtext_s = ''. - field-scrtext_m = ''. - field-scrtext_l = 'Column4_L'. - APPEND field TO input-field_catalog. - field-scrtext_l = 'Column4_L'. - APPEND field TO exp-field_catalog. - - assert( input = input exp = exp ). + assert( + ip_scrtext_s = 'Column1_L' + ip_colname_exp = 'Column1_L' ). ENDMETHOD. METHOD prefer_long_text. - DATA: input TYPE ty_parameters-input, - exp TYPE ty_parameters-output, - field TYPE zexcel_s_fieldcatalog. - input-default_descr = 'L'. + default_descr = 'L'. - field-dynpfld = abap_true. + assert( + ip_scrtext_s = 'Column1_S' + ip_scrtext_m = 'Column1_M' + ip_scrtext_l = 'Column1_L' + ip_colname_exp = 'Column1_L' ). - field-scrtext_s = 'Column1_S'. - field-scrtext_m = 'Column1_M'. - field-scrtext_l = 'Column1_L'. - APPEND field TO input-field_catalog. - field-scrtext_l = 'Column1_L'. - APPEND field TO exp-field_catalog. + assert( + ip_scrtext_s = 'Column1_S' + ip_scrtext_m = 'Column1_M' + ip_colname_exp = 'Column1_M' ). - field-scrtext_s = 'Column2_S'. - field-scrtext_m = 'Column2_M'. - field-scrtext_l = ''. - APPEND field TO input-field_catalog. - field-scrtext_l = 'Column2_M'. - APPEND field TO exp-field_catalog. + assert( + ip_scrtext_s = 'Column1_S' + ip_colname_exp = 'Column1_S' ). - field-scrtext_s = 'Column3_S'. - field-scrtext_m = ''. - field-scrtext_l = ''. - APPEND field TO input-field_catalog. - field-scrtext_l = 'Column3_S'. - APPEND field TO exp-field_catalog. - - assert( input = input exp = exp ). - - ENDMETHOD. - - METHOD default_text_if_none. - DATA: input TYPE ty_parameters-input, - exp TYPE ty_parameters-output, - field TYPE zexcel_s_fieldcatalog. - - input-default_descr = 'S'. - - field-dynpfld = abap_true. - - field-scrtext_s = ''. - field-scrtext_m = ''. - field-scrtext_l = ''. - APPEND field TO input-field_catalog. - field-scrtext_l = 'Column'. - APPEND field TO exp-field_catalog. - - field-scrtext_s = ''. - field-scrtext_m = ''. - field-scrtext_l = ''. - APPEND field TO input-field_catalog. - field-scrtext_l = 'Column 1'. - APPEND field TO exp-field_catalog. - - assert( input = input exp = exp ). ENDMETHOD. METHOD invalid_default_descr. - DATA: input TYPE ty_parameters-input, - exp TYPE ty_parameters-output, - field TYPE zexcel_s_fieldcatalog. - input-default_descr = '?'. + default_descr = '?'. - field-dynpfld = abap_true. + assert( + ip_scrtext_s = 'Column1_S' + ip_scrtext_m = 'Column1_M' + ip_scrtext_l = 'Column1_L' + ip_colname_exp = 'Column1_M' ). - field-scrtext_s = 'Column1_S'. - field-scrtext_m = 'Column1_M'. - field-scrtext_l = 'Column1_L'. - APPEND field TO input-field_catalog. - field-scrtext_l = 'Column1_M'. - APPEND field TO exp-field_catalog. + assert( + ip_scrtext_s = 'Column1_S' + ip_scrtext_l = 'Column1_L' + ip_colname_exp = 'Column1_S' ). - field-scrtext_s = 'Column2_S'. - field-scrtext_m = ''. - field-scrtext_l = 'Column2_L'. - APPEND field TO input-field_catalog. - field-scrtext_l = 'Column2_S'. - APPEND field TO exp-field_catalog. + assert( + ip_scrtext_s = 'Column1_S' + ip_colname_exp = 'Column1_S' ). - field-scrtext_s = 'Column3_S'. - field-scrtext_m = ''. - field-scrtext_l = ''. - APPEND field TO input-field_catalog. - field-scrtext_l = 'Column3_S'. - APPEND field TO exp-field_catalog. + assert( + ip_scrtext_l = 'Column1_L' + ip_colname_exp = 'Column1_L' ). - field-scrtext_s = ''. - field-scrtext_m = ''. - field-scrtext_l = 'Column4_L'. - APPEND field TO input-field_catalog. - field-scrtext_l = 'Column4_L'. - APPEND field TO exp-field_catalog. - - assert( input = input exp = exp ). ENDMETHOD. + METHOD default_text_if_none. + + default_descr = 'S'. + + CONSTANTS: lc_initial_line TYPE zexcel_s_fieldcatalog VALUE IS INITIAL. + DATA lt_fc TYPE zexcel_t_fieldcatalog. + APPEND lc_initial_line TO : lt_fc, lt_fc. + + DATA lt_colname_exp TYPE stringtab. + APPEND: + `Column` TO lt_colname_exp, + `Column 1` TO lt_colname_exp. + + assert_multi( + it_fc = lt_fc + it_colname_exp = lt_colname_exp + ). + + + ENDMETHOD. + + METHOD assert. - DATA: act TYPE ty_parameters-output. - act-field_catalog = cut->normalize_column_heading_texts( - iv_default_descr = input-default_descr - it_field_catalog = input-field_catalog ). + DATA: + ls_fc TYPE zexcel_s_fieldcatalog, + lt_fc TYPE zexcel_t_fieldcatalog. + ls_fc-dynpfld = abap_true. + ls_fc-scrtext_s = ip_scrtext_s. + ls_fc-scrtext_m = ip_scrtext_m. + ls_fc-scrtext_l = ip_scrtext_l. + APPEND ls_fc TO lt_fc. - cl_abap_unit_assert=>assert_equals( exp = exp-field_catalog act = act-field_catalog ). + DATA lt_fc_result TYPE zexcel_t_fieldcatalog. + + lt_fc_result = cut->normalize_column_heading_texts( + iv_default_descr = default_descr + it_field_catalog = lt_fc ). + + FIELD-SYMBOLS TYPE zexcel_s_fieldcatalog. + READ TABLE lt_fc_result ASSIGNING INDEX 1. + + cl_abap_unit_assert=>assert_equals( + act = -column_name + exp = ip_colname_exp + quit = if_aunit_constants=>no + ). + + ENDMETHOD. + + METHOD assert_multi. + + DATA: + lt_fc LIKE it_fc, + ls_fc LIKE LINE OF it_fc. + ls_fc-dynpfld = abap_true. + lt_fc = it_fc. + MODIFY lt_fc FROM ls_fc TRANSPORTING dynpfld WHERE dynpfld = space. + + DATA lt_fc_result TYPE zexcel_t_fieldcatalog. + lt_fc_result = cut->normalize_column_heading_texts( + iv_default_descr = default_descr + it_field_catalog = lt_fc + ). + + DATA lt_colname_act TYPE stringtab. + FIELD-SYMBOLS: TYPE zexcel_s_fieldcatalog. + LOOP AT lt_fc_result ASSIGNING . + APPEND -column_name TO lt_colname_act. + ENDLOOP. + + cl_abap_unit_assert=>assert_equals( + act = lt_colname_act + exp = it_colname_exp + quit = if_aunit_constants=>no + ). + + ENDMETHOD. + + METHOD setup. + + DATA: + lo_ex TYPE REF TO zcx_excel, + lv_ex_text TYPE string, + lv_msg TYPE string. + + TRY. + DATA lo_excel TYPE REF TO zcl_excel. + CREATE OBJECT lo_excel. + CREATE OBJECT cut EXPORTING ip_excel = lo_excel. + CATCH zcx_excel INTO lo_ex. + lv_ex_text = lo_ex->get_text( ). + CONCATENATE `Could not create instance:` lv_ex_text + INTO lv_msg + SEPARATED BY space. + cl_abap_unit_assert=>fail( lv_ex_text ). + ENDTRY. ENDMETHOD. diff --git a/src/zcl_excel_writer_huge_file.clas.abap b/src/zcl_excel_writer_huge_file.clas.abap index c63c76a..eff006e 100644 --- a/src/zcl_excel_writer_huge_file.clas.abap +++ b/src/zcl_excel_writer_huge_file.clas.abap @@ -105,7 +105,7 @@ CLASS zcl_excel_writer_huge_file IMPLEMENTATION. ls_shared_string-string_value = -cell_value. REPLACE ALL OCCURRENCES OF REGEX lv_invalid IN ls_shared_string-string_value WITH ` `. - APPEND ls_shared_string TO shared_strings. + INSERT ls_shared_string INTO TABLE shared_strings. ENDLOOP.