From ff8cd877f960083e26c153b1fee5e882861dd642 Mon Sep 17 00:00:00 2001 From: Tomek Mackowski Date: Wed, 13 Apr 2011 22:18:10 +0000 Subject: [PATCH] Fix #82 - data types from source sheets are preserver in the reader Fix #80 - both value and formula are read by the reader These 2 fixes allow reading xlsx templates with values of different types and formulas and saving them back git-svn-id: https://subversion.assembla.com/svn/abap2xlsx/trunk@159 b7d68dce-7c3c-4a99-8ce0-9ea847f5d049 --- ZA2X/CLAS/ZCL_EXCEL_READER_2007.slnk | 52 ++++++++++------- ZA2X/CLAS/ZCL_EXCEL_WORKSHEET.slnk | 86 ++++++++++++++++------------ 2 files changed, 79 insertions(+), 59 deletions(-) diff --git a/ZA2X/CLAS/ZCL_EXCEL_READER_2007.slnk b/ZA2X/CLAS/ZCL_EXCEL_READER_2007.slnk index 824aea1..ac047b8 100644 --- a/ZA2X/CLAS/ZCL_EXCEL_READER_2007.slnk +++ b/ZA2X/CLAS/ZCL_EXCEL_READER_2007.slnk @@ -99,11 +99,12 @@ private section. FIELD-SYMBOLS: <worksheet> TYPE t_worksheet. DATA: node TYPE REF TO if_ixml_node, - value_node TYPE REF TO if_ixml_node, + value_elem TYPE REF TO if_ixml_element, + formula_elem TYPE REF TO if_ixml_element, si TYPE REF TO if_ixml_node_list, row TYPE REF TO if_ixml_node_list, row_iterator TYPE REF TO if_ixml_node_iterator, - col TYPE REF TO if_ixml_node, + cell TYPE REF TO if_ixml_element, attributes TYPE REF TO if_ixml_named_node_map, attribute TYPE REF TO if_ixml_node, col_attributes TYPE REF TO if_ixml_named_node_map, @@ -119,6 +120,7 @@ private section. values TYPE stringtab, value_index TYPE i, cell_value TYPE zexcel_cell_value, + cell_formula TYPE zexcel_cell_formula, stripped_name TYPE chkfile, dirname TYPE string. @@ -232,34 +234,40 @@ private section. worksheet_index = worksheet_index + 1. row = node->get_children( ). row_iterator = row->create_iterator( ). - col = row_iterator->get_next( ). - WHILE NOT col IS INITIAL. - col_attributes = col->get_attributes( ). + cell ?= row_iterator->get_next( ). + WHILE NOT cell IS INITIAL. + col_attributes = cell->get_attributes( ). attribute ?= col_attributes->get_named_item_ns( 'r' ). r = attribute->get_value( ). - CLEAR: cell_data_type, cell_value. + CLEAR: cell_data_type, cell_value, cell_formula. attribute ?= col_attributes->get_named_item_ns( 't' ). IF attribute IS BOUND. cell_data_type = attribute->get_value( ). ENDIF. - " WRITE: / r, cell_data_type. - value_node = col->get_first_child( ). + + value_elem = cell->find_from_name( name = 'v' ). + CASE cell_data_type. - WHEN 's'. " String - value_index = value_node->get_value( ) + 1. + WHEN 's'. " String values are stored as index in shared string table + value_index = value_elem->get_value( ) + 1. READ TABLE values INTO cell_value INDEX value_index. - WHEN 'b'. " Boolean - " TODO - WHEN 'inlineStr'. " inlineStr - " TODO - WHEN 'e'. " Error - " TODO - WHEN OTHERS. - IF value_node IS BOUND. - cell_value = value_node->get_value( ). + WHEN 'inlineStr'. " inlineStr values are kept in special node + value_elem = cell->find_from_name( name = 'is' ). + IF value_elem IS BOUND. + cell_value = value_elem->get_value( ). + ENDIF. + WHEN OTHERS. "other types are stored directly + IF value_elem IS BOUND. + cell_value = value_elem->get_value( ). ENDIF. ENDCASE. - IF NOT cell_value IS INITIAL. + + formula_elem = cell->find_from_name( name = 'f' ). + IF formula_elem IS BOUND. + cell_formula = formula_elem->get_value( ). + ENDIF. + + IF NOT cell_value IS INITIAL or NOT cell_formula is INITIAL. zcl_excel_common=>convert_columnrow2column_a_row( EXPORTING i_columnrow = r @@ -272,9 +280,11 @@ private section. ip_column = cell_column " Cell Column ip_row = cell_row " Cell Row ip_value = cell_value " Cell Value + ip_formula = cell_formula + ip_data_type = cell_data_type ). ENDIF. - col = row_iterator->get_next( ). + cell ?= row_iterator->get_next( ). ENDWHILE. ENDWHILE. ENDWHILE. diff --git a/ZA2X/CLAS/ZCL_EXCEL_WORKSHEET.slnk b/ZA2X/CLAS/ZCL_EXCEL_WORKSHEET.slnk index 2d4e23f..76ce257 100644 --- a/ZA2X/CLAS/ZCL_EXCEL_WORKSHEET.slnk +++ b/ZA2X/CLAS/ZCL_EXCEL_WORKSHEET.slnk @@ -174,7 +174,8 @@ public section. !IP_VALUE type SIMPLE optional !IP_FORMULA type ZEXCEL_CELL_FORMULA optional !IP_STYLE type ZEXCEL_CELL_STYLE optional - !IP_HYPERLINK type ref to ZCL_EXCEL_HYPERLINK optional . + !IP_HYPERLINK type ref to ZCL_EXCEL_HYPERLINK optional + !IP_DATA_TYPE type ZEXCEL_CELL_DATA_TYPE optional . methods SET_CELL_STYLE importing !IP_COLUMN type ZEXCEL_CELL_COLUMN_ALPHA @@ -3224,14 +3225,15 @@ endmethod. endmethod. - - - - - - - - method SET_CELL. + + + + + + + + + METHOD set_cell. DATA: lv_column TYPE zexcel_cell_column, ls_sheet_content TYPE zexcel_s_cell_data, @@ -3246,46 +3248,54 @@ endmethod. IF ip_value IS NOT SUPPLIED AND ip_formula IS NOT SUPPLIED. RAISE EXCEPTION TYPE zcx_excel - EXPORTING - error = 'Pleas provide the value or formula'. + EXPORTING + error = 'Pleas provide the value or formula'. ENDIF. lv_style_guid = ip_style. IF ip_value IS SUPPLIED. - DESCRIBE FIELD ip_value TYPE lv_value_type. - CASE lv_value_type. - WHEN cl_abap_typedescr=>typekind_int OR cl_abap_typedescr=>typekind_int1 OR cl_abap_typedescr=>typekind_int2 OR - cl_abap_typedescr=>typekind_float OR cl_abap_typedescr=>typekind_packed. - lv_value = zcl_excel_common=>number_to_excel_string( ip_value = ip_value ). + "if data type is passed just write the value. Otherwise map abap type to excel and perform conversion + "IP_DATA_TYPE is passed by excel reader so source types are preserved + IF ip_data_type IS SUPPLIED. + lv_value = ip_value. + lv_data_type = ip_data_type. + ELSE. + DESCRIBE FIELD ip_value TYPE lv_value_type. + CASE lv_value_type. + WHEN cl_abap_typedescr=>typekind_int OR cl_abap_typedescr=>typekind_int1 OR cl_abap_typedescr=>typekind_int2 OR + cl_abap_typedescr=>typekind_float OR cl_abap_typedescr=>typekind_packed. + lv_value = zcl_excel_common=>number_to_excel_string( ip_value = ip_value ). - WHEN cl_abap_typedescr=>typekind_char OR cl_abap_typedescr=>typekind_string OR cl_abap_typedescr=>typekind_num. - lv_value = ip_value. - lv_data_type = 's'. + WHEN cl_abap_typedescr=>typekind_char OR cl_abap_typedescr=>typekind_string OR cl_abap_typedescr=>typekind_num. + lv_value = ip_value. + lv_data_type = 's'. - WHEN cl_abap_typedescr=>typekind_date. - lv_value = zcl_excel_common=>date_to_excel_string( ip_value = ip_value ). + WHEN cl_abap_typedescr=>typekind_date. + lv_value = zcl_excel_common=>date_to_excel_string( ip_value = ip_value ). - IF ip_style IS NOT SUPPLIED. "get default date format in case parameter is initial - lo_style = excel->add_new_style( ). - lo_style->number_format->format_code = get_default_excel_date_format( ). - lv_style_guid = lo_style->get_guid( ). - ENDIF. + IF ip_style IS NOT SUPPLIED. "get default date format in case parameter is initial + lo_style = excel->add_new_style( ). + lo_style->number_format->format_code = get_default_excel_date_format( ). + lv_style_guid = lo_style->get_guid( ). + ENDIF. - WHEN cl_abap_typedescr=>typekind_time. - lv_value = zcl_excel_common=>time_to_excel_string( ip_value = ip_value ). + WHEN cl_abap_typedescr=>typekind_time. + lv_value = zcl_excel_common=>time_to_excel_string( ip_value = ip_value ). - IF ip_style IS NOT SUPPLIED. "get default time format for user in case parameter is initial - lo_style = excel->add_new_style( ). - lo_style->number_format->format_code = zcl_excel_style_number_format=>c_format_date_time6. - lv_style_guid = lo_style->get_guid( ). - ENDIF. + IF ip_style IS NOT SUPPLIED. "get default time format for user in case parameter is initial + lo_style = excel->add_new_style( ). + lo_style->number_format->format_code = zcl_excel_style_number_format=>c_format_date_time6. + lv_style_guid = lo_style->get_guid( ). + ENDIF. + + WHEN OTHERS. + RAISE EXCEPTION TYPE zcx_excel + EXPORTING + error = 'Invalid data type of input value'. + ENDCASE. + ENDIF. - WHEN OTHERS. - RAISE EXCEPTION TYPE zcx_excel - EXPORTING - error = 'Invalid data type of input value'. - ENDCASE. ENDIF. IF ip_hyperlink IS BOUND.