From e23995389549f4e9675d6d663e5b451b40f73f02 Mon Sep 17 00:00:00 2001 From: Gregor Wolf Date: Thu, 15 Dec 2011 21:32:29 +0000 Subject: [PATCH] Implemented Fix by Shahrin Shahrulzaman to add support for named rages for the Excel 2007 Reader #126 git-svn-id: https://subversion.assembla.com/svn/abap2xlsx/trunk@230 b7d68dce-7c3c-4a99-8ce0-9ea847f5d049 --- ZA2X/CLAS/ZCL_EXCEL_RANGE.slnk | 189 +-- ZA2X/CLAS/ZCL_EXCEL_READER_2007.slnk | 2044 +++++++++++++------------- 2 files changed, 1118 insertions(+), 1115 deletions(-) diff --git a/ZA2X/CLAS/ZCL_EXCEL_RANGE.slnk b/ZA2X/CLAS/ZCL_EXCEL_RANGE.slnk index 43d9a54..59c3fa0 100644 --- a/ZA2X/CLAS/ZCL_EXCEL_RANGE.slnk +++ b/ZA2X/CLAS/ZCL_EXCEL_RANGE.slnk @@ -1,90 +1,99 @@ - - - class ZCL_EXCEL_RANGE definition - public - final - create public . - -*"* public components of class ZCL_EXCEL_RANGE -*"* do not include other source files here!!! -public section. - - data NAME type ZEXCEL_RANGE_NAME . - data GUID type ZEXCEL_RANGE_GUID . - - methods CONSTRUCTOR . - methods GET_GUID - returning - value(EP_GUID) type ZEXCEL_RANGE_GUID . - methods SET_VALUE - importing - !IP_SHEET_NAME type ZEXCEL_SHEET_TITLE - !IP_START_ROW type ZEXCEL_CELL_ROW - !IP_START_COLUMN type ZEXCEL_CELL_COLUMN_ALPHA - !IP_STOP_ROW type ZEXCEL_CELL_ROW - !IP_STOP_COLUMN type ZEXCEL_CELL_COLUMN_ALPHA . - methods GET_VALUE - returning - value(EP_VALUE) type ZEXCEL_RANGE_VALUE . - *"* protected components of class ZABAP_EXCEL_WORKSHEET -*"* do not include other source files here!!! -protected section. - *"* private components of class ZCL_EXCEL_RANGE -*"* do not include other source files here!!! -private section. - - data VALUE type ZEXCEL_RANGE_VALUE . - *"* local class implementation for public class -*"* use this source file for the implementation part of -*"* local helper classes - *"* use this source file for any type declarations (class -*"* definitions, interfaces or data types) you need for method -*"* implementation or private method's signature - *"* use this source file for any macro definitions you need -*"* in the implementation part of the class - - - - - method CONSTRUCTOR. -endmethod. - - - - method GET_GUID. - - ep_guid = me->guid. - -endmethod. - - - - method GET_VALUE. - - ep_value = me->value. - -endmethod. - - - - - - - - method SET_VALUE. - DATA: lv_start_row_c TYPE char7, - lv_stop_row_c TYPE char7, - lv_value TYPE string. - lv_stop_row_c = ip_stop_row. - SHIFT lv_stop_row_c RIGHT DELETING TRAILING space. - SHIFT lv_stop_row_c LEFT DELETING LEADING space. - lv_start_row_c = ip_start_row. - SHIFT lv_start_row_c RIGHT DELETING TRAILING space. - SHIFT lv_start_row_c LEFT DELETING LEADING space. - lv_value = ip_sheet_name. - me->value = zcl_excel_common=>escape_string( ip_value = lv_value ). - - CONCATENATE me->value '!$' ip_start_column '$' lv_start_row_c ':$' ip_stop_column '$' lv_stop_row_c INTO me->value. -endmethod. - - + + + class ZCL_EXCEL_RANGE definition + public + final + create public . + +*"* public components of class ZCL_EXCEL_RANGE +*"* do not include other source files here!!! +public section. + + data NAME type ZEXCEL_RANGE_NAME . + data GUID type ZEXCEL_RANGE_GUID . + + methods CONSTRUCTOR . + methods GET_GUID + returning + value(EP_GUID) type ZEXCEL_RANGE_GUID . + methods SET_VALUE + importing + !IP_SHEET_NAME type ZEXCEL_SHEET_TITLE + !IP_START_ROW type ZEXCEL_CELL_ROW + !IP_START_COLUMN type ZEXCEL_CELL_COLUMN_ALPHA + !IP_STOP_ROW type ZEXCEL_CELL_ROW + !IP_STOP_COLUMN type ZEXCEL_CELL_COLUMN_ALPHA . + methods GET_VALUE + returning + value(EP_VALUE) type ZEXCEL_RANGE_VALUE . + methods SET_RANGE_VALUE + importing + !IP_VALUE type ZEXCEL_RANGE_VALUE . + *"* protected components of class ZABAP_EXCEL_WORKSHEET +*"* do not include other source files here!!! +protected section. + *"* private components of class ZCL_EXCEL_RANGE +*"* do not include other source files here!!! +private section. + + data VALUE type ZEXCEL_RANGE_VALUE . + *"* local class implementation for public class +*"* use this source file for the implementation part of +*"* local helper classes + *"* use this source file for any type declarations (class +*"* definitions, interfaces or data types) you need for method +*"* implementation or private method's signature + *"* use this source file for any macro definitions you need +*"* in the implementation part of the class + + + + + method CONSTRUCTOR. +endmethod. + + + + method GET_GUID. + + ep_guid = me->guid. + +endmethod. + + + + method GET_VALUE. + + ep_value = me->value. + +endmethod. + + + + method SET_RANGE_VALUE. + me->value = ip_value. +endmethod. + + + + + + + + method SET_VALUE. + DATA: lv_start_row_c TYPE char7, + lv_stop_row_c TYPE char7, + lv_value TYPE string. + lv_stop_row_c = ip_stop_row. + SHIFT lv_stop_row_c RIGHT DELETING TRAILING space. + SHIFT lv_stop_row_c LEFT DELETING LEADING space. + lv_start_row_c = ip_start_row. + SHIFT lv_start_row_c RIGHT DELETING TRAILING space. + SHIFT lv_start_row_c LEFT DELETING LEADING space. + lv_value = ip_sheet_name. + me->value = zcl_excel_common=>escape_string( ip_value = lv_value ). + + CONCATENATE me->value '!$' ip_start_column '$' lv_start_row_c ':$' ip_stop_column '$' lv_stop_row_c INTO me->value. +endmethod. + + diff --git a/ZA2X/CLAS/ZCL_EXCEL_READER_2007.slnk b/ZA2X/CLAS/ZCL_EXCEL_READER_2007.slnk index d8b0868..d225504 100644 --- a/ZA2X/CLAS/ZCL_EXCEL_READER_2007.slnk +++ b/ZA2X/CLAS/ZCL_EXCEL_READER_2007.slnk @@ -1,1045 +1,1039 @@ - - - + + - + - + - + - + - - class ZCL_EXCEL_READER_2007 definition - public - create public . - -public section. -*"* public components of class ZCL_EXCEL_READER_2007 -*"* do not include other source files here!!! - type-pools IXML . - - interfaces ZIF_EXCEL_READER . - PROTECTED SECTION. -*"* protected components of class ZCL_EXCEL_READER_2007 -*"* do not include other source files here!!! - - TYPES: - BEGIN OF t_relationship, - id TYPE string, - type TYPE string, - target TYPE string, - END OF t_relationship . - TYPES: - BEGIN OF t_fileversion, - appname TYPE string, - lastedited TYPE string, - lowestedited TYPE string, - rupbuild TYPE string, - codename TYPE string, - END OF t_fileversion . - TYPES: - BEGIN OF t_sheet, +"/> + - IXML - - - - - - method ZIF_EXCEL_READER~LOAD. - - CONSTANTS: - lc_core_properties TYPE string VALUE 'http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties', - lc_office_document TYPE string VALUE 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument', - lc_relationships TYPE string VALUE 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'. - - DATA: rels TYPE REF TO if_ixml_document, - node TYPE REF TO if_ixml_element, - relationship TYPE t_relationship. - - me->excel2007 = i_excel2007. - rels = me->get_ixml_from_zip_archive( '_rels/.rels' ). - - CREATE OBJECT r_excel. - - node ?= rels->find_from_name( 'Relationship' ). - WHILE node IS BOUND. - fill_struct_from_attributes( EXPORTING ip_element = node CHANGING cp_structure = relationship ). - - CASE relationship-type. - WHEN lc_core_properties. - " TODO Map Document Properties to ZCL_EXCEL - WHEN lc_office_document. - load_workbook( - ip_path = relationship-target - ip_excel = r_excel ). - - WHEN OTHERS. - ENDCASE. - - node ?= node->get_next( ). - ENDWHILE. - -endmethod. - - - method ZIF_EXCEL_READER~LOAD_FILE. - DATA: excel_data TYPE xstring. - DATA filelength TYPE i. - DATA bin_tab TYPE TABLE OF x255. - " Background processing - DATA bin_data LIKE LINE OF bin_tab. - DATA len TYPE i. - DATA alen TYPE i. - - IF sy-batch = abap_true. - DESCRIBE FIELD bin_data LENGTH len IN BYTE MODE. - OPEN DATASET i_filename FOR INPUT IN BINARY MODE. - WHILE sy-subrc = 0. - READ DATASET i_filename INTO bin_data MAXIMUM LENGTH len ACTUAL LENGTH alen. - APPEND bin_data TO bin_tab. - filelength = filelength + alen. - ENDWHILE. - CLOSE DATASET i_filename. - ELSE. - cl_gui_frontend_services=>gui_upload( - EXPORTING - filename = i_filename " Name of file - filetype = 'BIN' " File Type (ASCII, Binary) - IMPORTING - filelength = filelength - CHANGING - data_tab = bin_tab - EXCEPTIONS - file_open_error = 1 - file_read_error = 2 - no_batch = 3 - gui_refuse_filetransfer = 4 - invalid_type = 5 - no_authority = 6 - unknown_error = 7 - bad_data_format = 8 - header_not_allowed = 9 - separator_not_allowed = 10 - header_too_long = 11 - unknown_dp_error = 12 - access_denied = 13 - dp_out_of_memory = 14 - disk_full = 15 - dp_timeout = 16 - not_supported_by_gui = 17 - error_no_gui = 18 - OTHERS = 19 - ). - IF sy-subrc <> 0. - RAISE EXCEPTION TYPE zcx_excel - EXPORTING - error = 'A problem occured when reading the file'. - ENDIF. - ENDIF. - CALL FUNCTION 'SCMS_BINARY_TO_XSTRING' - EXPORTING - input_length = filelength - IMPORTING - buffer = excel_data - TABLES - binary_tab = bin_tab. - r_excel = me->zif_excel_reader~load( excel_data ). -endmethod. - - - - - method FILL_STRUCT_FROM_ATTRIBUTES. - DATA: name TYPE string, - attributes TYPE REF TO if_ixml_named_node_map, - attribute TYPE REF TO if_ixml_attribute, - iterator TYPE REF TO if_ixml_node_iterator. - - FIELD-SYMBOLS: <component> TYPE any. - - CLEAR cp_structure. - - attributes = ip_element->get_attributes( ). - iterator = attributes->create_iterator( ). - attribute ?= iterator->get_next( ). - WHILE attribute IS BOUND. - name = attribute->get_name( ). - TRANSLATE name TO UPPER CASE. - ASSIGN COMPONENT name OF STRUCTURE cp_structure TO <component>. - IF sy-subrc = 0. - <component> = attribute->get_value( ). - ENDIF. - attribute ?= iterator->get_next( ). - ENDWHILE. -endmethod. - - - - - - method GET_FROM_ZIP_ARCHIVE. - - 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. - RAISE EXCEPTION TYPE zcx_excel - EXPORTING - error = 'ZIP parse error'. - ENDIF. - ENDIF. - - 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. - RAISE EXCEPTION TYPE zcx_excel - EXPORTING - error = 'ZIP index or decompression error'. - ENDIF. - -endmethod. - - - - - - method GET_IXML_FROM_ZIP_ARCHIVE. - TYPE-POOLS: ixml. - - DATA: content TYPE xstring. - - DATA: ixml TYPE REF TO if_ixml, - streamfactory TYPE REF TO if_ixml_stream_factory, - istream TYPE REF TO if_ixml_istream, - parser TYPE REF TO if_ixml_parser. - - content = me->get_from_zip_archive( i_filename ). - ixml = cl_ixml=>create( ). - streamfactory = ixml->create_stream_factory( ). - istream = streamfactory->create_istream_xstring( content ). - r_ixml = ixml->create_document( ). - parser = ixml->create_parser( stream_factory = streamfactory - istream = istream - document = r_ixml ). - parser->set_normalizing( ). - parser->set_validating( mode = if_ixml_parser=>co_no_validation ). - parser->parse( ). - -endmethod. - - - - method LOAD_SHARED_STRINGS. - DATA: value TYPE string, - shared_strings_xml TYPE REF TO if_ixml_document, - tag_name TYPE string, - node TYPE REF TO if_ixml_element, - node2 TYPE REF TO if_ixml_element. - - shared_strings_xml = me->get_ixml_from_zip_archive( ip_path ). - node ?= shared_strings_xml->find_from_name( 'si' ). - WHILE node IS BOUND. - node2 ?= node->get_first_child( ). - tag_name = node2->get_name( ). - IF tag_name = 't'. - value = node2->get_value( ). - APPEND value TO shared_strings. - ELSEIF tag_name = 'r'. - " TODO pharse Ritch text - ENDIF. - - node ?= node->get_next( ). - ENDWHILE. - -endmethod. - - - - - method LOAD_STYLES. - TYPES: BEGIN OF t_xf, - applyalignment TYPE string, - applyborder TYPE string, - applyfill TYPE string, - applyfont TYPE string, - applynumberformat TYPE string, - applyprotection TYPE string, - borderid TYPE string, - fillid TYPE string, - fontid TYPE string, - numfmtid TYPE string, - pivotbutton TYPE string, - quoteprefix TYPE string, - xfid TYPE string, - END OF t_xf. - - TYPES: BEGIN OF t_alignment, - horizontal TYPE string, - indent TYPE string, - justifylastline TYPE string, - readingorder TYPE string, - relativeindent TYPE string, - shrinktofit TYPE string, - textrotation TYPE string, - vertical TYPE string, - wraptext TYPE string, - END OF t_alignment. - - TYPES: BEGIN OF t_protection, - hidden TYPE string, - locked TYPE string, - END OF t_protection. - - - DATA: styles_xml TYPE REF TO if_ixml_document, - iterator TYPE REF TO if_ixml_node_iterator, - nodes TYPE REF TO if_ixml_node_collection, - node TYPE REF TO if_ixml_element, - node2 TYPE REF TO if_ixml_element, - fills TYPE t_fills, - fill TYPE REF TO zcl_excel_style_fill, - num_formats TYPE t_num_formats, - num_format TYPE t_num_format, - cell_border TYPE REF TO zcl_excel_style_borders, - borders TYPE t_borders, - fonts TYPE t_fonts, - font TYPE REF TO zcl_excel_style_font, - style TYPE REF TO zcl_excel_style, - xf TYPE t_xf, - alignment TYPE t_alignment, - protection TYPE t_protection, - index TYPE i. - - styles_xml = me->get_ixml_from_zip_archive( ip_path ). - - num_formats = load_style_num_formats( styles_xml ). - fills = load_style_fills( styles_xml ). - borders = load_style_borders( styles_xml ). - fonts = load_style_fonts( styles_xml ). - - "we have all the components of style, now build the style objects - node = styles_xml->find_from_name( name = 'cellXfs' ). - IF node IS BOUND. - nodes = node->get_elements_by_tag_name( name = 'xf' ). - iterator = nodes->create_iterator( ). - node ?= iterator->get_next( ). - WHILE node IS BOUND. - style = ip_excel->add_new_style( ). - fill_struct_from_attributes( - EXPORTING - ip_element = node - CHANGING - cp_structure = xf ). - - IF xf-applyfill = '1' AND xf-fillid IS NOT INITIAL. - index = xf-fillid + 1. - READ TABLE fills INTO fill INDEX index. - IF sy-subrc = 0. - style->fill = fill. - ENDIF. - ENDIF. - - IF xf-numfmtid IS NOT INITIAL. - READ TABLE num_formats INTO num_format WITH TABLE KEY id = xf-numfmtid. - IF sy-subrc = 0. - style->number_format = num_format-format. - ENDIF. - ENDIF. - - IF xf-applyborder = '1' AND xf-borderid IS NOT INITIAL. - index = xf-borderid + 1. - READ TABLE borders INTO cell_border INDEX index. - IF sy-subrc = 0. - style->borders = cell_border. - ENDIF. - ENDIF. - - IF xf-applyfont = '1' AND xf-fontid IS NOT INITIAL. - index = xf-fontid + 1. - READ TABLE fonts INTO font INDEX index. - IF sy-subrc = 0. - style->font = font. - ENDIF. - ENDIF. - - node2 ?= node->find_from_name( 'alignment' ). - IF node2 IS BOUND. - fill_struct_from_attributes( - EXPORTING - ip_element = node2 - CHANGING - cp_structure = alignment ). - - IF alignment-horizontal IS NOT INITIAL. - style->alignment->horizontal = alignment-horizontal. - ENDIF. - - IF alignment-vertical IS NOT INITIAL. - style->alignment->vertical = alignment-vertical. - ENDIF. - - IF alignment-textrotation IS NOT INITIAL. - style->alignment->textrotation = alignment-textrotation. - ENDIF. - - IF alignment-wraptext = '1' OR alignment-wraptext = 'true'. - style->alignment->wraptext = abap_true. - ENDIF. - - IF alignment-shrinktofit = '1' OR alignment-shrinktofit = 'true'. - style->alignment->shrinktofit = abap_true. - ENDIF. - - IF alignment-indent IS NOT INITIAL. - style->alignment->indent = alignment-indent. - ENDIF. - ENDIF. - - node2 ?= node->find_from_name( 'protection' ). - IF node2 IS BOUND. - fill_struct_from_attributes( - EXPORTING - ip_element = node2 - CHANGING - cp_structure = protection ). - - IF protection-locked = '1' OR protection-locked = 'true'. - style->protection->locked = zcl_excel_style_protection=>c_protection_locked. - ELSE. - style->protection->locked = zcl_excel_style_protection=>c_protection_unlocked. - ENDIF. - - IF protection-hidden = '1' OR protection-hidden = 'true'. - style->protection->hidden = zcl_excel_style_protection=>c_protection_hidden. - ELSE. - style->protection->hidden = zcl_excel_style_protection=>c_protection_unhidden. - ENDIF. - - ENDIF. - - INSERT style INTO TABLE styles. - node ?= iterator->get_next( ). - ENDWHILE. - ENDIF. - -endmethod. - - - - - method LOAD_STYLE_BORDERS. - DATA: node TYPE REF TO if_ixml_element, - node2 TYPE REF TO if_ixml_element, - node3 TYPE REF TO if_ixml_element, - cell_border TYPE REF TO zcl_excel_style_borders, - border TYPE REF TO zcl_excel_style_border, - color TYPE t_color. - - node ?= ip_xml->find_from_name( 'border' ). - WHILE node IS BOUND. - CREATE OBJECT cell_border. - - IF node->get_attribute( 'diagonalDown' ) IS NOT INITIAL. - cell_border->diagonal_mode = zcl_excel_style_borders=>c_diagonal_down. - ENDIF. - - IF node->get_attribute( 'diagonalUp' ) IS NOT INITIAL. - IF cell_border->diagonal_mode = zcl_excel_style_borders=>c_diagonal_down. - cell_border->diagonal_mode = zcl_excel_style_borders=>c_diagonal_both. - ELSE. - cell_border->diagonal_mode = zcl_excel_style_borders=>c_diagonal_up. - ENDIF. - ENDIF. - - node2 ?= node->get_first_child( ). - WHILE node2 IS BOUND. - CREATE OBJECT border. - - CASE node2->get_name( ). - WHEN 'left'. - cell_border->left = border. - WHEN 'right'. - cell_border->right = border. - WHEN 'top'. - cell_border->top = border. - WHEN 'bottom'. - cell_border->down = border. - WHEN 'diagonal'. - cell_border->diagonal = border. - ENDCASE. - - border->border_style = node2->get_attribute( 'style' ). - node3 ?= node2->find_from_name( 'color' ). - IF node3 IS BOUND. - fill_struct_from_attributes( - EXPORTING - ip_element = node3 - CHANGING - cp_structure = color ). - - border->border_color-rgb = color-rgb. - IF color-indexed IS NOT INITIAL. - border->border_color-indexed = color-indexed. - ENDIF. - - IF color-theme IS NOT INITIAL. - border->border_color-theme = color-theme. - ENDIF. - border->border_color-tint = color-tint. - ENDIF. - - node2 ?= node2->get_next( ). - ENDWHILE. - - INSERT cell_border INTO TABLE ep_borders. - node ?= node->get_next( ). - ENDWHILE. -endmethod. - - - - - method LOAD_STYLE_FILLS. - DATA: value TYPE string, - node TYPE REF TO if_ixml_element, - node2 TYPE REF TO if_ixml_element, - node3 TYPE REF TO if_ixml_element, - fill TYPE REF TO zcl_excel_style_fill, - color TYPE t_color. - - node ?= ip_xml->find_from_name( 'fill' ). - WHILE node IS BOUND. - CREATE OBJECT fill. - node2 ?= node->get_first_child( ). - value = node2->get_name( ). - CASE value. - WHEN 'patternFill'. - fill->filltype = node2->get_attribute( 'patternType' ). - - node3 = node2->find_from_name( 'bgColor' ). - IF node3 IS BOUND. - fill_struct_from_attributes( - EXPORTING - ip_element = node3 - CHANGING - cp_structure = color ). - - fill->bgcolor-rgb = color-rgb. - IF color-indexed IS NOT INITIAL. - fill->bgcolor-indexed = color-indexed. - ENDIF. - - IF color-theme IS NOT INITIAL. - fill->bgcolor-theme = color-theme. - ENDIF. - fill->bgcolor-tint = color-tint. - ENDIF. - - node3 = node->find_from_name( 'fgColor' ). - IF node3 IS BOUND. - fill_struct_from_attributes( - EXPORTING - ip_element = node3 - CHANGING - cp_structure = color ). - - fill->fgcolor-rgb = color-rgb. - IF color-indexed IS NOT INITIAL. - fill->fgcolor-indexed = color-indexed. - ENDIF. - - IF color-theme IS NOT INITIAL. - fill->fgcolor-theme = color-theme. - ENDIF. - fill->fgcolor-tint = color-tint. - ENDIF. - WHEN 'gradientFill'. - "TODO - WHEN OTHERS. - ENDCASE. - - INSERT fill INTO TABLE ep_fills. - node ?= node->get_next( ). - ENDWHILE. - - -endmethod. - - - - - method LOAD_STYLE_FONTS. - DATA: value TYPE string, - node TYPE REF TO if_ixml_element, - node2 TYPE REF TO if_ixml_element, - node3 TYPE REF TO if_ixml_element, - font TYPE REF TO zcl_excel_style_font, - color TYPE t_color. - - node ?= ip_xml->find_from_name( 'font' ). - WHILE node IS BOUND. - CREATE OBJECT font. - IF node->find_from_name( 'b' ) IS BOUND. - font->bold = abap_true. - ENDIF. - - IF node->find_from_name( 'i' ) IS BOUND. - font->italic = abap_true. - ENDIF. - - node2 = node->find_from_name( 'u' ). - IF node2 IS BOUND. - font->underline = abap_true. - font->underline_mode = node2->get_attribute( 'val' ). - ENDIF. - - IF node->find_from_name( 'strike' ) IS BOUND. - font->strikethrough = abap_true. - ENDIF. - - node2 = node->find_from_name( 'sz' ). - IF node2 IS BOUND. - font->size = node2->get_attribute( 'val' ). - ENDIF. - - node2 = node->find_from_name( 'name' ). - IF node2 IS BOUND. - font->name = node2->get_attribute( 'val' ). - ENDIF. - - node2 = node->find_from_name( 'family' ). - IF node2 IS BOUND. - font->family = node2->get_attribute( 'val' ). - ENDIF. - - node2 = node->find_from_name( 'scheme' ). - IF node2 IS BOUND. - font->scheme = node2->get_attribute( 'val' ). - ENDIF. - - node2 = node->find_from_name( 'color' ). - IF node2 IS BOUND. - fill_struct_from_attributes( - EXPORTING - ip_element = node2 - CHANGING - cp_structure = color ). - - font->color-rgb = color-rgb. - IF color-indexed IS NOT INITIAL. - font->color-indexed = color-indexed. - ENDIF. - - IF color-theme IS NOT INITIAL. - font->color-theme = color-theme. - ENDIF. - font->color-tint = color-tint. - ENDIF. - - INSERT font INTO TABLE ep_fonts. - node ?= node->get_next( ). - ENDWHILE. - - -endmethod. - - - - - method LOAD_STYLE_NUM_FORMATS. - DATA: node TYPE REF TO if_ixml_element, - num_format TYPE t_num_format. - - node ?= ip_xml->find_from_name( 'numFmt' ). - WHILE node IS BOUND. - CLEAR num_format. - - CREATE OBJECT num_format-format. - num_format-format->format_code = node->get_attribute( 'formatCode' ). - num_format-id = node->get_attribute( 'numFmtId' ). - INSERT num_format INTO TABLE ep_num_formats. - node ?= node->get_next( ). - ENDWHILE. - - -endmethod. - - - - - METHOD load_workbook. - TYPES: BEGIN OF t_workbookview, - activetab TYPE string, - minimized TYPE string, - END OF t_workbookview. - - CONSTANTS: lc_shared_strings TYPE string VALUE 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings', - lc_worksheet TYPE string VALUE 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet', - lc_styles TYPE string VALUE 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles'. - - DATA: rels TYPE REF TO if_ixml_document, - rels_workbook_path TYPE string, - rels_workbook TYPE REF TO if_ixml_document, - path TYPE string, - worksheets TYPE TABLE OF t_relationship, - workbook TYPE REF TO if_ixml_document, - workbook_index TYPE i, - worksheet_path TYPE string, - sheet TYPE t_sheet, - node TYPE REF TO if_ixml_element, - stripped_name TYPE chkfile, - dirname TYPE string, - relationship TYPE t_relationship, - lo_worksheet TYPE REF TO zcl_excel_worksheet, - worksheet_title TYPE zexcel_sheet_title, - workbookview TYPE t_workbookview, - lv_active_tab TYPE zexcel_active_worksheet. - - FIELD-SYMBOLS: <worksheet> TYPE t_relationship. - - CALL FUNCTION 'TRINT_SPLIT_FILE_AND_PATH' - EXPORTING - full_name = ip_path - IMPORTING - stripped_name = stripped_name - file_path = dirname. - - " Read Workbook Relationships - CONCATENATE dirname '_rels/' stripped_name '.rels' - INTO rels_workbook_path. - - rels_workbook = me->get_ixml_from_zip_archive( rels_workbook_path ). - - node ?= rels_workbook->find_from_name( 'Relationship' ). - WHILE node IS BOUND. - fill_struct_from_attributes( EXPORTING ip_element = node CHANGING cp_structure = relationship ). - - CASE relationship-type. - WHEN lc_shared_strings. - " Read Shared Strings - CONCATENATE dirname relationship-target INTO path. - load_shared_strings( path ). - - WHEN lc_worksheet. - " Read worksheets - APPEND relationship TO worksheets. - - WHEN lc_styles. - CONCATENATE dirname relationship-target INTO path. - load_styles( - ip_path = path - ip_excel = ip_excel ). - - WHEN OTHERS. - ENDCASE. - - node ?= node->get_next( ). - ENDWHILE. - - " Read Workbook - workbook = me->get_ixml_from_zip_archive( ip_path ). - node ?= workbook->find_from_name( 'sheet' ). - workbook_index = 1. - WHILE node IS BOUND. - - fill_struct_from_attributes( - EXPORTING - ip_element = node - CHANGING - cp_structure = sheet ). - - worksheet_title = sheet-name. - IF workbook_index > 1. - lo_worksheet = ip_excel->add_new_worksheet( worksheet_title ). - ELSE. - lo_worksheet = ip_excel->get_active_worksheet( ). - lo_worksheet->set_title( worksheet_title ). - ENDIF. - - READ TABLE worksheets ASSIGNING <worksheet> - WITH KEY id = sheet-id. - " WRITE: / worksheet_id, worksheet_title, <worksheet>-target. - CONCATENATE dirname <worksheet>-target INTO worksheet_path. - load_worksheet( - ip_path = worksheet_path - io_worksheet = lo_worksheet ). - - node ?= node->get_next( ). - ADD 1 TO workbook_index. - ENDWHILE. - - node ?= workbook->find_from_name( 'workbookView' ). - IF node IS BOUND. - fill_struct_from_attributes( EXPORTING ip_element = node CHANGING cp_structure = workbookview ). - lv_active_tab = workbookview-activetab + 1. - ip_excel->set_active_sheet_index( lv_active_tab ). - ENDIF. -ENDMETHOD. - - - - - method LOAD_WORKSHEET. - TYPES: BEGIN OF t_cell, - r TYPE string, - t TYPE string, - s TYPE string, - END OF t_cell. - - DATA: worksheet TYPE REF TO if_ixml_document, - rows TYPE REF TO if_ixml_node_collection, - cells TYPE REF TO if_ixml_node_collection, - iterator TYPE REF TO if_ixml_node_iterator, - iterator2 TYPE REF TO if_ixml_node_iterator, - row TYPE REF TO if_ixml_element, - cell_elem TYPE REF TO if_ixml_element, - cell TYPE t_cell, - index TYPE i, - value_elem TYPE REF TO if_ixml_element, - formula_elem TYPE REF TO if_ixml_element, - cell_value TYPE zexcel_cell_value, - cell_formula TYPE zexcel_cell_formula, - cell_column TYPE zexcel_cell_column_alpha, - cell_row TYPE zexcel_cell_row, - style TYPE REF TO zcl_excel_style, - style_guid TYPE zexcel_cell_style. - - worksheet = me->get_ixml_from_zip_archive( ip_path ). - rows = worksheet->get_elements_by_tag_name( name = 'row' ). - iterator = rows->create_iterator( ). - row ?= iterator->get_next( ). - WHILE row IS BOUND. - cells = row->get_elements_by_tag_name( name = 'c' ). - iterator2 = cells->create_iterator( ). - cell_elem ?= iterator2->get_next( ). - WHILE cell_elem IS BOUND. - CLEAR: cell_value, cell_formula, style_guid. - - fill_struct_from_attributes( EXPORTING ip_element = cell_elem CHANGING cp_structure = cell ). - - value_elem = cell_elem->find_from_name( name = 'v' ). - - CASE cell-t. - WHEN 's'. " String values are stored as index in shared string table - index = value_elem->get_value( ) + 1. - READ TABLE shared_strings INTO cell_value INDEX index. - WHEN 'inlineStr'. " inlineStr values are kept in special node - value_elem = cell_elem->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. - - CLEAR style_guid. - "read style based on index - IF cell-s IS NOT INITIAL. - index = cell-s + 1. - READ TABLE styles INTO style INDEX index. - IF sy-subrc = 0. - style_guid = style->get_guid( ). - ENDIF. - ENDIF. - - formula_elem = cell_elem->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 OR style_guid IS NOT INITIAL. - zcl_excel_common=>convert_columnrow2column_a_row( - EXPORTING - i_columnrow = cell-r - IMPORTING - e_column = cell_column - e_row = cell_row - ). - io_worksheet->set_cell( - ip_column = cell_column " cell_elem Column - ip_row = cell_row " cell_elem Row - ip_value = cell_value " cell_elem Value - ip_formula = cell_formula - ip_data_type = cell-t - ip_style = style_guid ). - ENDIF. - - cell_elem ?= iterator2->get_next( ). - ENDWHILE. - row ?= iterator->get_next( ). - ENDWHILE. - -endmethod. - - + END OF t_range +"/> + + class ZCL_EXCEL_READER_2007 definition + public + create public . + +public section. +*"* public components of class ZCL_EXCEL_READER_2007 +*"* do not include other source files here!!! + type-pools IXML . + + interfaces ZIF_EXCEL_READER . + PROTECTED SECTION. +*"* protected components of class ZCL_EXCEL_READER_2007 +*"* do not include other source files here!!! + + TYPES: + BEGIN OF t_relationship, + id TYPE string, + type TYPE string, + target TYPE string, + END OF t_relationship . + TYPES: + BEGIN OF t_fileversion, + appname TYPE string, + lastedited TYPE string, + lowestedited TYPE string, + rupbuild TYPE string, + codename TYPE string, + END OF t_fileversion . + TYPES: + BEGIN OF t_sheet, + name TYPE string, + sheetid TYPE string, + id TYPE string, + END OF t_sheet . + TYPES: + BEGIN OF t_workbookpr, + codename TYPE string, + defaultthemeversion TYPE string, + END OF t_workbookpr . + TYPES: + BEGIN OF t_sheetpr, + codename TYPE string, + END OF t_sheetpr . + TYPES: + BEGIN OF t_range, + name TYPE string, + END OF t_range . + + METHODS fill_struct_from_attributes + IMPORTING + !ip_element TYPE REF TO if_ixml_element + CHANGING + !cp_structure TYPE any . + METHODS get_from_zip_archive + IMPORTING + !i_filename TYPE string + RETURNING + value(r_content) TYPE xstring + RAISING + zcx_excel . + METHODS get_ixml_from_zip_archive + IMPORTING + !i_filename TYPE string + RETURNING + value(r_ixml) TYPE REF TO if_ixml_document + RAISING + zcx_excel . + METHODS load_workbook + IMPORTING + !ip_path TYPE string + !ip_excel TYPE REF TO zcl_excel . + METHODS load_worksheet + IMPORTING + !ip_path TYPE string + !io_worksheet TYPE REF TO zcl_excel_worksheet . + private section. +*"* private components of class ZCL_EXCEL_READER_2007 +*"* do not include other source files here!!! + + data EXCEL2007 type XSTRING . + data ZIP type ref to CL_ABAP_ZIP . + data SHARED_STRINGS type STRINGTAB . + data STYLES type T_STYLE_REFS . + + methods LOAD_SHARED_STRINGS + importing + !IP_PATH type STRING . + methods LOAD_STYLES + importing + !IP_PATH type STRING + !IP_EXCEL type ref to ZCL_EXCEL . + methods LOAD_STYLE_BORDERS + importing + !IP_XML type ref to IF_IXML_DOCUMENT + returning + value(EP_BORDERS) type T_BORDERS . + methods LOAD_STYLE_FILLS + importing + !IP_XML type ref to IF_IXML_DOCUMENT + returning + value(EP_FILLS) type T_FILLS . + methods LOAD_STYLE_FONTS + importing + !IP_XML type ref to IF_IXML_DOCUMENT + returning + value(EP_FONTS) type T_FONTS . + methods LOAD_STYLE_NUM_FORMATS + importing + !IP_XML type ref to IF_IXML_DOCUMENT + returning + value(EP_NUM_FORMATS) type T_NUM_FORMATS . + *"* local class implementation for public class +*"* use this source file for the implementation part of +*"* local helper classes + TYPES: BEGIN OF t_relationship, + id TYPE string, + type TYPE string, + target TYPE string, + END OF t_relationship. + *"* use this source file for any type declarations (class +*"* definitions, interfaces or data types) you need for method +*"* implementation or private method's signature + + TYPES t_style_refs TYPE TABLE OF REF TO zcl_excel_style. + + TYPES: BEGIN OF t_num_format, + id TYPE string, + format TYPE REF TO zcl_excel_style_number_format, + END OF t_num_format. + TYPES t_num_formats TYPE HASHED TABLE OF t_num_format WITH UNIQUE KEY id. + + TYPES t_fills TYPE STANDARD TABLE OF REF TO zcl_excel_style_fill WITH DEFAULT KEY. + TYPES t_borders TYPE STANDARD TABLE OF REF TO zcl_excel_style_borders WITH DEFAULT KEY. + TYPES t_fonts TYPE STANDARD TABLE OF REF TO zcl_excel_style_font WITH DEFAULT KEY. + + TYPES: BEGIN OF t_color, + indexed TYPE string, + rgb TYPE string, + theme TYPE string, + tint TYPE string, + END OF t_color. + *"* use this source file for any macro definitions you need +*"* in the implementation part of the class + + IXML + + + + + + method ZIF_EXCEL_READER~LOAD. + + CONSTANTS: + lc_core_properties TYPE string VALUE 'http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties', + lc_office_document TYPE string VALUE 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument', + lc_relationships TYPE string VALUE 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'. + + DATA: rels TYPE REF TO if_ixml_document, + node TYPE REF TO if_ixml_element, + relationship TYPE t_relationship. + + me->excel2007 = i_excel2007. + rels = me->get_ixml_from_zip_archive( '_rels/.rels' ). + + CREATE OBJECT r_excel. + + node ?= rels->find_from_name( 'Relationship' ). + WHILE node IS BOUND. + fill_struct_from_attributes( EXPORTING ip_element = node CHANGING cp_structure = relationship ). + + CASE relationship-type. + WHEN lc_core_properties. + " TODO Map Document Properties to ZCL_EXCEL + WHEN lc_office_document. + load_workbook( + ip_path = relationship-target + ip_excel = r_excel ). + + WHEN OTHERS. + ENDCASE. + + node ?= node->get_next( ). + ENDWHILE. + +endmethod. + + + method ZIF_EXCEL_READER~LOAD_FILE. + DATA: excel_data TYPE xstring. + DATA filelength TYPE i. + DATA bin_tab TYPE TABLE OF x255. + " Background processing + DATA bin_data LIKE LINE OF bin_tab. + DATA len TYPE i. + DATA alen TYPE i. + + IF sy-batch = abap_true. + DESCRIBE FIELD bin_data LENGTH len IN BYTE MODE. + OPEN DATASET i_filename FOR INPUT IN BINARY MODE. + WHILE sy-subrc = 0. + READ DATASET i_filename INTO bin_data MAXIMUM LENGTH len ACTUAL LENGTH alen. + APPEND bin_data TO bin_tab. + filelength = filelength + alen. + ENDWHILE. + CLOSE DATASET i_filename. + ELSE. + cl_gui_frontend_services=>gui_upload( + EXPORTING + filename = i_filename " Name of file + filetype = 'BIN' " File Type (ASCII, Binary) + IMPORTING + filelength = filelength + CHANGING + data_tab = bin_tab + EXCEPTIONS + file_open_error = 1 + file_read_error = 2 + no_batch = 3 + gui_refuse_filetransfer = 4 + invalid_type = 5 + no_authority = 6 + unknown_error = 7 + bad_data_format = 8 + header_not_allowed = 9 + separator_not_allowed = 10 + header_too_long = 11 + unknown_dp_error = 12 + access_denied = 13 + dp_out_of_memory = 14 + disk_full = 15 + dp_timeout = 16 + not_supported_by_gui = 17 + error_no_gui = 18 + OTHERS = 19 + ). + IF sy-subrc <> 0. + RAISE EXCEPTION TYPE zcx_excel + EXPORTING + error = 'A problem occured when reading the file'. + ENDIF. + ENDIF. + CALL FUNCTION 'SCMS_BINARY_TO_XSTRING' + EXPORTING + input_length = filelength + IMPORTING + buffer = excel_data + TABLES + binary_tab = bin_tab. + r_excel = me->zif_excel_reader~load( excel_data ). +endmethod. + + + + + method FILL_STRUCT_FROM_ATTRIBUTES. + DATA: name TYPE string, + attributes TYPE REF TO if_ixml_named_node_map, + attribute TYPE REF TO if_ixml_attribute, + iterator TYPE REF TO if_ixml_node_iterator. + + FIELD-SYMBOLS: <component> TYPE any. + + CLEAR cp_structure. + + attributes = ip_element->get_attributes( ). + iterator = attributes->create_iterator( ). + attribute ?= iterator->get_next( ). + WHILE attribute IS BOUND. + name = attribute->get_name( ). + TRANSLATE name TO UPPER CASE. + ASSIGN COMPONENT name OF STRUCTURE cp_structure TO <component>. + IF sy-subrc = 0. + <component> = attribute->get_value( ). + ENDIF. + attribute ?= iterator->get_next( ). + ENDWHILE. +endmethod. + + + + + + method GET_FROM_ZIP_ARCHIVE. + + 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. + RAISE EXCEPTION TYPE zcx_excel + EXPORTING + error = 'ZIP parse error'. + ENDIF. + ENDIF. + + 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. + RAISE EXCEPTION TYPE zcx_excel + EXPORTING + error = 'ZIP index or decompression error'. + ENDIF. + +endmethod. + + + + + + method GET_IXML_FROM_ZIP_ARCHIVE. + TYPE-POOLS: ixml. + + DATA: content TYPE xstring. + + DATA: ixml TYPE REF TO if_ixml, + streamfactory TYPE REF TO if_ixml_stream_factory, + istream TYPE REF TO if_ixml_istream, + parser TYPE REF TO if_ixml_parser. + + content = me->get_from_zip_archive( i_filename ). + ixml = cl_ixml=>create( ). + streamfactory = ixml->create_stream_factory( ). + istream = streamfactory->create_istream_xstring( content ). + r_ixml = ixml->create_document( ). + parser = ixml->create_parser( stream_factory = streamfactory + istream = istream + document = r_ixml ). + parser->set_normalizing( ). + parser->set_validating( mode = if_ixml_parser=>co_no_validation ). + parser->parse( ). + +endmethod. + + + + method LOAD_SHARED_STRINGS. + DATA: value TYPE string, + shared_strings_xml TYPE REF TO if_ixml_document, + tag_name TYPE string, + node TYPE REF TO if_ixml_element, + node2 TYPE REF TO if_ixml_element. + + shared_strings_xml = me->get_ixml_from_zip_archive( ip_path ). + node ?= shared_strings_xml->find_from_name( 'si' ). + WHILE node IS BOUND. + node2 ?= node->get_first_child( ). + tag_name = node2->get_name( ). + IF tag_name = 't'. + value = node2->get_value( ). + APPEND value TO shared_strings. + ELSEIF tag_name = 'r'. + " TODO pharse Ritch text + ENDIF. + + node ?= node->get_next( ). + ENDWHILE. + +endmethod. + + + + + method LOAD_STYLES. + TYPES: BEGIN OF t_xf, + applyalignment TYPE string, + applyborder TYPE string, + applyfill TYPE string, + applyfont TYPE string, + applynumberformat TYPE string, + applyprotection TYPE string, + borderid TYPE string, + fillid TYPE string, + fontid TYPE string, + numfmtid TYPE string, + pivotbutton TYPE string, + quoteprefix TYPE string, + xfid TYPE string, + END OF t_xf. + + TYPES: BEGIN OF t_alignment, + horizontal TYPE string, + indent TYPE string, + justifylastline TYPE string, + readingorder TYPE string, + relativeindent TYPE string, + shrinktofit TYPE string, + textrotation TYPE string, + vertical TYPE string, + wraptext TYPE string, + END OF t_alignment. + + TYPES: BEGIN OF t_protection, + hidden TYPE string, + locked TYPE string, + END OF t_protection. + + + DATA: styles_xml TYPE REF TO if_ixml_document, + iterator TYPE REF TO if_ixml_node_iterator, + nodes TYPE REF TO if_ixml_node_collection, + node TYPE REF TO if_ixml_element, + node2 TYPE REF TO if_ixml_element, + fills TYPE t_fills, + fill TYPE REF TO zcl_excel_style_fill, + num_formats TYPE t_num_formats, + num_format TYPE t_num_format, + cell_border TYPE REF TO zcl_excel_style_borders, + borders TYPE t_borders, + fonts TYPE t_fonts, + font TYPE REF TO zcl_excel_style_font, + style TYPE REF TO zcl_excel_style, + xf TYPE t_xf, + alignment TYPE t_alignment, + protection TYPE t_protection, + index TYPE i. + + styles_xml = me->get_ixml_from_zip_archive( ip_path ). + + num_formats = load_style_num_formats( styles_xml ). + fills = load_style_fills( styles_xml ). + borders = load_style_borders( styles_xml ). + fonts = load_style_fonts( styles_xml ). + + "we have all the components of style, now build the style objects + node = styles_xml->find_from_name( name = 'cellXfs' ). + IF node IS BOUND. + nodes = node->get_elements_by_tag_name( name = 'xf' ). + iterator = nodes->create_iterator( ). + node ?= iterator->get_next( ). + WHILE node IS BOUND. + style = ip_excel->add_new_style( ). + fill_struct_from_attributes( + EXPORTING + ip_element = node + CHANGING + cp_structure = xf ). + + IF xf-applyfill = '1' AND xf-fillid IS NOT INITIAL. + index = xf-fillid + 1. + READ TABLE fills INTO fill INDEX index. + IF sy-subrc = 0. + style->fill = fill. + ENDIF. + ENDIF. + + IF xf-numfmtid IS NOT INITIAL. + READ TABLE num_formats INTO num_format WITH TABLE KEY id = xf-numfmtid. + IF sy-subrc = 0. + style->number_format = num_format-format. + ENDIF. + ENDIF. + + IF xf-applyborder = '1' AND xf-borderid IS NOT INITIAL. + index = xf-borderid + 1. + READ TABLE borders INTO cell_border INDEX index. + IF sy-subrc = 0. + style->borders = cell_border. + ENDIF. + ENDIF. + + IF xf-applyfont = '1' AND xf-fontid IS NOT INITIAL. + index = xf-fontid + 1. + READ TABLE fonts INTO font INDEX index. + IF sy-subrc = 0. + style->font = font. + ENDIF. + ENDIF. + + node2 ?= node->find_from_name( 'alignment' ). + IF node2 IS BOUND. + fill_struct_from_attributes( + EXPORTING + ip_element = node2 + CHANGING + cp_structure = alignment ). + + IF alignment-horizontal IS NOT INITIAL. + style->alignment->horizontal = alignment-horizontal. + ENDIF. + + IF alignment-vertical IS NOT INITIAL. + style->alignment->vertical = alignment-vertical. + ENDIF. + + IF alignment-textrotation IS NOT INITIAL. + style->alignment->textrotation = alignment-textrotation. + ENDIF. + + IF alignment-wraptext = '1' OR alignment-wraptext = 'true'. + style->alignment->wraptext = abap_true. + ENDIF. + + IF alignment-shrinktofit = '1' OR alignment-shrinktofit = 'true'. + style->alignment->shrinktofit = abap_true. + ENDIF. + + IF alignment-indent IS NOT INITIAL. + style->alignment->indent = alignment-indent. + ENDIF. + ENDIF. + + node2 ?= node->find_from_name( 'protection' ). + IF node2 IS BOUND. + fill_struct_from_attributes( + EXPORTING + ip_element = node2 + CHANGING + cp_structure = protection ). + + IF protection-locked = '1' OR protection-locked = 'true'. + style->protection->locked = zcl_excel_style_protection=>c_protection_locked. + ELSE. + style->protection->locked = zcl_excel_style_protection=>c_protection_unlocked. + ENDIF. + + IF protection-hidden = '1' OR protection-hidden = 'true'. + style->protection->hidden = zcl_excel_style_protection=>c_protection_hidden. + ELSE. + style->protection->hidden = zcl_excel_style_protection=>c_protection_unhidden. + ENDIF. + + ENDIF. + + INSERT style INTO TABLE styles. + node ?= iterator->get_next( ). + ENDWHILE. + ENDIF. + +endmethod. + + + + + method LOAD_STYLE_BORDERS. + DATA: node TYPE REF TO if_ixml_element, + node2 TYPE REF TO if_ixml_element, + node3 TYPE REF TO if_ixml_element, + cell_border TYPE REF TO zcl_excel_style_borders, + border TYPE REF TO zcl_excel_style_border, + color TYPE t_color. + + node ?= ip_xml->find_from_name( 'border' ). + WHILE node IS BOUND. + CREATE OBJECT cell_border. + + IF node->get_attribute( 'diagonalDown' ) IS NOT INITIAL. + cell_border->diagonal_mode = zcl_excel_style_borders=>c_diagonal_down. + ENDIF. + + IF node->get_attribute( 'diagonalUp' ) IS NOT INITIAL. + IF cell_border->diagonal_mode = zcl_excel_style_borders=>c_diagonal_down. + cell_border->diagonal_mode = zcl_excel_style_borders=>c_diagonal_both. + ELSE. + cell_border->diagonal_mode = zcl_excel_style_borders=>c_diagonal_up. + ENDIF. + ENDIF. + + node2 ?= node->get_first_child( ). + WHILE node2 IS BOUND. + CREATE OBJECT border. + + CASE node2->get_name( ). + WHEN 'left'. + cell_border->left = border. + WHEN 'right'. + cell_border->right = border. + WHEN 'top'. + cell_border->top = border. + WHEN 'bottom'. + cell_border->down = border. + WHEN 'diagonal'. + cell_border->diagonal = border. + ENDCASE. + + border->border_style = node2->get_attribute( 'style' ). + node3 ?= node2->find_from_name( 'color' ). + IF node3 IS BOUND. + fill_struct_from_attributes( + EXPORTING + ip_element = node3 + CHANGING + cp_structure = color ). + + border->border_color-rgb = color-rgb. + IF color-indexed IS NOT INITIAL. + border->border_color-indexed = color-indexed. + ENDIF. + + IF color-theme IS NOT INITIAL. + border->border_color-theme = color-theme. + ENDIF. + border->border_color-tint = color-tint. + ENDIF. + + node2 ?= node2->get_next( ). + ENDWHILE. + + INSERT cell_border INTO TABLE ep_borders. + node ?= node->get_next( ). + ENDWHILE. +endmethod. + + + + + method LOAD_STYLE_FILLS. + DATA: value TYPE string, + node TYPE REF TO if_ixml_element, + node2 TYPE REF TO if_ixml_element, + node3 TYPE REF TO if_ixml_element, + fill TYPE REF TO zcl_excel_style_fill, + color TYPE t_color. + + node ?= ip_xml->find_from_name( 'fill' ). + WHILE node IS BOUND. + CREATE OBJECT fill. + node2 ?= node->get_first_child( ). + value = node2->get_name( ). + CASE value. + WHEN 'patternFill'. + fill->filltype = node2->get_attribute( 'patternType' ). + + node3 = node2->find_from_name( 'bgColor' ). + IF node3 IS BOUND. + fill_struct_from_attributes( + EXPORTING + ip_element = node3 + CHANGING + cp_structure = color ). + + fill->bgcolor-rgb = color-rgb. + IF color-indexed IS NOT INITIAL. + fill->bgcolor-indexed = color-indexed. + ENDIF. + + IF color-theme IS NOT INITIAL. + fill->bgcolor-theme = color-theme. + ENDIF. + fill->bgcolor-tint = color-tint. + ENDIF. + + node3 = node->find_from_name( 'fgColor' ). + IF node3 IS BOUND. + fill_struct_from_attributes( + EXPORTING + ip_element = node3 + CHANGING + cp_structure = color ). + + fill->fgcolor-rgb = color-rgb. + IF color-indexed IS NOT INITIAL. + fill->fgcolor-indexed = color-indexed. + ENDIF. + + IF color-theme IS NOT INITIAL. + fill->fgcolor-theme = color-theme. + ENDIF. + fill->fgcolor-tint = color-tint. + ENDIF. + WHEN 'gradientFill'. + "TODO + WHEN OTHERS. + ENDCASE. + + INSERT fill INTO TABLE ep_fills. + node ?= node->get_next( ). + ENDWHILE. + + +endmethod. + + + + + method LOAD_STYLE_FONTS. + DATA: value TYPE string, + node TYPE REF TO if_ixml_element, + node2 TYPE REF TO if_ixml_element, + node3 TYPE REF TO if_ixml_element, + font TYPE REF TO zcl_excel_style_font, + color TYPE t_color. + + node ?= ip_xml->find_from_name( 'font' ). + WHILE node IS BOUND. + CREATE OBJECT font. + IF node->find_from_name( 'b' ) IS BOUND. + font->bold = abap_true. + ENDIF. + + IF node->find_from_name( 'i' ) IS BOUND. + font->italic = abap_true. + ENDIF. + + node2 = node->find_from_name( 'u' ). + IF node2 IS BOUND. + font->underline = abap_true. + font->underline_mode = node2->get_attribute( 'val' ). + ENDIF. + + IF node->find_from_name( 'strike' ) IS BOUND. + font->strikethrough = abap_true. + ENDIF. + + node2 = node->find_from_name( 'sz' ). + IF node2 IS BOUND. + font->size = node2->get_attribute( 'val' ). + ENDIF. + + node2 = node->find_from_name( 'name' ). + IF node2 IS BOUND. + font->name = node2->get_attribute( 'val' ). + ENDIF. + + node2 = node->find_from_name( 'family' ). + IF node2 IS BOUND. + font->family = node2->get_attribute( 'val' ). + ENDIF. + + node2 = node->find_from_name( 'scheme' ). + IF node2 IS BOUND. + font->scheme = node2->get_attribute( 'val' ). + ENDIF. + + node2 = node->find_from_name( 'color' ). + IF node2 IS BOUND. + fill_struct_from_attributes( + EXPORTING + ip_element = node2 + CHANGING + cp_structure = color ). + + font->color-rgb = color-rgb. + IF color-indexed IS NOT INITIAL. + font->color-indexed = color-indexed. + ENDIF. + + IF color-theme IS NOT INITIAL. + font->color-theme = color-theme. + ENDIF. + font->color-tint = color-tint. + ENDIF. + + INSERT font INTO TABLE ep_fonts. + node ?= node->get_next( ). + ENDWHILE. + + +endmethod. + + + + + method LOAD_STYLE_NUM_FORMATS. + DATA: node TYPE REF TO if_ixml_element, + num_format TYPE t_num_format. + + node ?= ip_xml->find_from_name( 'numFmt' ). + WHILE node IS BOUND. + CLEAR num_format. + + CREATE OBJECT num_format-format. + num_format-format->format_code = node->get_attribute( 'formatCode' ). + num_format-id = node->get_attribute( 'numFmtId' ). + INSERT num_format INTO TABLE ep_num_formats. + node ?= node->get_next( ). + ENDWHILE. + + +endmethod. + + + + + method LOAD_WORKBOOK. + + CONSTANTS: lc_shared_strings TYPE string VALUE 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings', + lc_worksheet TYPE string VALUE 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet', + lc_styles TYPE string VALUE 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles'. + + DATA: rels TYPE REF TO if_ixml_document, + rels_workbook_path TYPE string, + rels_workbook TYPE REF TO if_ixml_document, + path TYPE string, + worksheets TYPE TABLE OF t_relationship, + workbook TYPE REF TO if_ixml_document, + workbook_index TYPE i, + worksheet_path TYPE string, + sheet TYPE t_sheet, + range TYPE t_range, + range_value TYPE zexcel_range_value, + node TYPE REF TO if_ixml_element, + stripped_name TYPE chkfile, + dirname TYPE string, + relationship TYPE t_relationship, + lo_worksheet TYPE REF TO zcl_excel_worksheet, + lo_range TYPE REF TO zcl_excel_range, + worksheet_title TYPE zexcel_sheet_title. + + FIELD-SYMBOLS: <worksheet> TYPE t_relationship. + + CALL FUNCTION 'TRINT_SPLIT_FILE_AND_PATH' + EXPORTING + full_name = ip_path + IMPORTING + stripped_name = stripped_name + file_path = dirname. + + " Read Workbook Relationships + CONCATENATE dirname '_rels/' stripped_name '.rels' + INTO rels_workbook_path. + + rels_workbook = me->get_ixml_from_zip_archive( rels_workbook_path ). + + node ?= rels_workbook->find_from_name( 'Relationship' ). + WHILE node IS BOUND. + fill_struct_from_attributes( EXPORTING ip_element = node CHANGING cp_structure = relationship ). + + CASE relationship-type. + WHEN lc_shared_strings. + " Read Shared Strings + CONCATENATE dirname relationship-target INTO path. + load_shared_strings( path ). + + WHEN lc_worksheet. + " Read worksheets + APPEND relationship TO worksheets. + + WHEN lc_styles. + CONCATENATE dirname relationship-target INTO path. + load_styles( + ip_path = path + ip_excel = ip_excel ). + + WHEN OTHERS. + ENDCASE. + + node ?= node->get_next( ). + ENDWHILE. + + " Read Workbook + workbook = me->get_ixml_from_zip_archive( ip_path ). + node ?= workbook->find_from_name( 'sheet' ). + workbook_index = 1. + WHILE node IS BOUND. + + fill_struct_from_attributes( + EXPORTING + ip_element = node + CHANGING + cp_structure = sheet ). + + worksheet_title = sheet-name. + IF workbook_index > 1. + lo_worksheet = ip_excel->add_new_worksheet( worksheet_title ). + ELSE. + lo_worksheet = ip_excel->get_active_worksheet( ). + lo_worksheet->set_title( worksheet_title ). + ENDIF. + + READ TABLE worksheets ASSIGNING <worksheet> + WITH KEY id = sheet-id. + " WRITE: / worksheet_id, worksheet_title, <worksheet>-target. + CONCATENATE dirname <worksheet>-target INTO worksheet_path. + load_worksheet( + ip_path = worksheet_path + io_worksheet = lo_worksheet ). + + node ?= node->get_next( ). + ADD 1 TO workbook_index. + ENDWHILE. + + "Can I reuse the workbook variable? + "workbook = me->get_ixml_from_zip_archive( ip_path ). + node ?= workbook->find_from_name( 'definedName' ). + WHILE node IS BOUND. + + fill_struct_from_attributes( + EXPORTING + ip_element = node + CHANGING + cp_structure = range ). + range_value = node->get_value( ). + + lo_range = ip_excel->add_new_range( ). + lo_range->name = range-name. + lo_range->set_range_value( range_value ). + + node ?= node->get_next( ). + ENDWHILE. + +endmethod. + + + + + method LOAD_WORKSHEET. + TYPES: BEGIN OF t_cell, + r TYPE string, + t TYPE string, + s TYPE string, + END OF t_cell. + + DATA: worksheet TYPE REF TO if_ixml_document, + rows TYPE REF TO if_ixml_node_collection, + cells TYPE REF TO if_ixml_node_collection, + iterator TYPE REF TO if_ixml_node_iterator, + iterator2 TYPE REF TO if_ixml_node_iterator, + row TYPE REF TO if_ixml_element, + cell_elem TYPE REF TO if_ixml_element, + cell TYPE t_cell, + index TYPE i, + value_elem TYPE REF TO if_ixml_element, + formula_elem TYPE REF TO if_ixml_element, + cell_value TYPE zexcel_cell_value, + cell_formula TYPE zexcel_cell_formula, + cell_column TYPE zexcel_cell_column_alpha, + cell_row TYPE zexcel_cell_row, + style TYPE REF TO zcl_excel_style, + style_guid TYPE zexcel_cell_style. + + worksheet = me->get_ixml_from_zip_archive( ip_path ). + rows = worksheet->get_elements_by_tag_name( name = 'row' ). + iterator = rows->create_iterator( ). + row ?= iterator->get_next( ). + WHILE row IS BOUND. + cells = row->get_elements_by_tag_name( name = 'c' ). + iterator2 = cells->create_iterator( ). + cell_elem ?= iterator2->get_next( ). + WHILE cell_elem IS BOUND. + CLEAR: cell_value, cell_formula, style_guid. + + fill_struct_from_attributes( EXPORTING ip_element = cell_elem CHANGING cp_structure = cell ). + + value_elem = cell_elem->find_from_name( name = 'v' ). + + CASE cell-t. + WHEN 's'. " String values are stored as index in shared string table + index = value_elem->get_value( ) + 1. + READ TABLE shared_strings INTO cell_value INDEX index. + WHEN 'inlineStr'. " inlineStr values are kept in special node + value_elem = cell_elem->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. + + CLEAR style_guid. + "read style based on index + IF cell-s IS NOT INITIAL. + index = cell-s + 1. + READ TABLE styles INTO style INDEX index. + IF sy-subrc = 0. + style_guid = style->get_guid( ). + ENDIF. + ENDIF. + + formula_elem = cell_elem->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 OR style_guid IS NOT INITIAL. + zcl_excel_common=>convert_columnrow2column_a_row( + EXPORTING + i_columnrow = cell-r + IMPORTING + e_column = cell_column + e_row = cell_row + ). + io_worksheet->set_cell( + ip_column = cell_column " cell_elem Column + ip_row = cell_row " cell_elem Row + ip_value = cell_value " cell_elem Value + ip_formula = cell_formula + ip_data_type = cell-t + ip_style = style_guid ). + ENDIF. + + cell_elem ?= iterator2->get_next( ). + ENDWHILE. + row ?= iterator->get_next( ). + ENDWHILE. + +endmethod. + +