diff --git a/ZA2X/CLAS/ZCL_EXCEL_READER_2007.slnk b/ZA2X/CLAS/ZCL_EXCEL_READER_2007.slnk index ac047b8..f8f2b73 100644 --- a/ZA2X/CLAS/ZCL_EXCEL_READER_2007.slnk +++ b/ZA2X/CLAS/ZCL_EXCEL_READER_2007.slnk @@ -1,25 +1,28 @@ - - + + class ZCL_EXCEL_READER_2007 definition public final create public . +public section. *"* public components of class ZCL_EXCEL_READER_2007 *"* do not include other source files here!!! -public section. + type-pools IXML . interfaces ZIF_EXCEL_READER . *"* protected components of class ZCL_EXCEL_READER_2007 *"* do not include other source files here!!! protected section. - *"* private components of class ZCL_EXCEL_READER_2007 + private section. +*"* private components of class ZCL_EXCEL_READER_2007 *"* do not include other source files here!!! -private section. data EXCEL2007 type XSTRING . data ZIP type ref to CL_ABAP_ZIP . + data SHARED_STRINGS type STRINGTAB . + data STYLES type T_STYLE_REFS . methods GET_FROM_ZIP_ARCHIVE importing @@ -34,265 +37,121 @@ private section. returning value(R_IXML) type ref to IF_IXML_DOCUMENT raising - ZCX_EXCEL . + ZCX_EXCEL . + methods LOAD_WORKSHEET + importing + !IP_PATH type STRING + !IO_WORKSHEET type ref to ZCL_EXCEL_WORKSHEET . + methods FILL_STRUCT_FROM_ATTRIBUTES + importing + !IP_ELEMENT type ref to IF_IXML_ELEMENT + changing + !CP_STRUCTURE type ANY . + methods LOAD_WORKBOOK + 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_FONTS + importing + !IP_XML type ref to IF_IXML_DOCUMENT + returning + value(EP_FONTS) type T_FONTS . + methods LOAD_STYLE_FILLS + importing + !IP_XML type ref to IF_IXML_DOCUMENT + returning + value(EP_FILLS) type T_FILLS . + methods LOAD_STYLE_NUM_FORMATS + importing + !IP_XML type ref to IF_IXML_DOCUMENT + returning + value(EP_NUM_FORMATS) type T_NUM_FORMATS . + methods LOAD_STYLES + importing + !IP_PATH type STRING + !IP_EXCEL type ref to ZCL_EXCEL . + methods LOAD_SHARED_STRINGS + importing + !IP_PATH type STRING . *"* local class implementation for public class *"* use this source file for the implementation part of -*"* local helper classes +*"* 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: - BEGIN OF t_splice_entry, - name TYPE string, - offset TYPE i, - length TYPE i, - compressed TYPE i, - END OF t_splice_entry. - TYPES: - t_splice_entries TYPE STANDARD TABLE OF t_splice_entry WITH DEFAULT KEY. + 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. - TYPES: - BEGIN OF t_worksheet, - id TYPE string, - target TYPE string, - END OF t_worksheet. - TYPES: t_worksheets TYPE TABLE OF t_worksheet. + 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_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_relationships TYPE string VALUE 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'. - TYPE-POOLS: ixml. - DATA: rels TYPE REF TO if_ixml_document, - rels_coll TYPE REF TO if_ixml_node_collection, - rels_coll_index TYPE i, - workbook_path TYPE string, - rels_workbook_path TYPE string, - rels_workbook TYPE REF TO if_ixml_document, - rels_wb_coll TYPE REF TO if_ixml_node_collection, - rels_wb_coll_index TYPE i, - shared_strings_path TYPE string, - shared_strings TYPE REF TO if_ixml_document, - shared_strings_coll TYPE REF TO if_ixml_node_collection, - shared_strings_coll_index TYPE i, - worksheets TYPE t_worksheets, - workbook TYPE REF TO if_ixml_document, - workbook_coll TYPE REF TO if_ixml_node_collection, - workbook_index TYPE i, - worksheet_path TYPE string, - worksheet TYPE REF TO if_ixml_document, - worksheet_coll TYPE REF TO if_ixml_node_collection, - worksheet_index TYPE i. - - FIELD-SYMBOLS: <worksheet> TYPE t_worksheet. - - DATA: 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, - 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, - attr_type TYPE string, - attr_target TYPE string, - attr_id TYPE string, - tag_name TYPE string, - r TYPE string, - cell_data_type TYPE string, - cell_column TYPE zexcel_cell_column_alpha, - cell_row TYPE zexcel_cell_row, - value TYPE string, - 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. - - DATA: lo_worksheet TYPE REF TO zcl_excel_worksheet, - worksheet_title TYPE zexcel_sheet_title, - worksheet_id TYPE string. + 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. - rels_coll = rels->get_elements_by_tag_name( name = 'Relationship' ). - rels_coll_index = 0. - WHILE rels_coll_index < rels_coll->get_length( ). - node = rels_coll->get_item( rels_coll_index ). - rels_coll_index = rels_coll_index + 1. - attributes ?= node->get_attributes( ). - attribute ?= attributes->get_named_item_ns( 'Type' ). - attr_type = attribute->get_value( ). - CASE attr_type. + 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. - attribute ?= attributes->get_named_item_ns( 'Target' ). - workbook_path = attribute->get_value( ). + load_workbook( + ip_path = relationship-target + ip_excel = r_excel ). - CALL FUNCTION 'TRINT_SPLIT_FILE_AND_PATH' - EXPORTING - full_name = workbook_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 ). - rels_wb_coll = - rels_workbook->get_elements_by_tag_name( name = 'Relationship' ). - rels_wb_coll_index = 0. - WHILE rels_wb_coll_index < rels_wb_coll->get_length( ). - node = rels_wb_coll->get_item( rels_wb_coll_index ). - rels_wb_coll_index = rels_wb_coll_index + 1. - attributes ?= node->get_attributes( ). - attribute ?= attributes->get_named_item_ns( 'Type' ). - attr_type = attribute->get_value( ). - CASE attr_type. - WHEN lc_shared_strings. - " Read Shared Strings - attribute ?= attributes->get_named_item_ns( 'Target' ). - attr_target = attribute->get_value( ). - CONCATENATE dirname attr_target INTO shared_strings_path. - shared_strings = me->get_ixml_from_zip_archive( shared_strings_path ). - shared_strings_coll = - shared_strings->get_elements_by_tag_name( name = 'si' ). - shared_strings_coll_index = 0. - WHILE shared_strings_coll_index < shared_strings_coll->get_length( ). - node = shared_strings_coll->get_item( shared_strings_coll_index ). - shared_strings_coll_index = shared_strings_coll_index + 1. - si = node->get_children( ). - node = si->get_item( 0 ). - tag_name = node->get_name( ). - IF tag_name = 't'. - value = node->get_value( ). - APPEND value TO values. - ELSEIF tag_name = 'r'. - " TODO pharse Ritch text - ENDIF. - ENDWHILE. - WHEN lc_worksheet. - " Read worksheets - APPEND INITIAL LINE TO worksheets ASSIGNING <worksheet>. - attribute ?= attributes->get_named_item_ns( 'Id' ). - <worksheet>-id = attribute->get_value( ). - attribute ?= attributes->get_named_item_ns( 'Target' ). - <worksheet>-target = attribute->get_value( ). - " WRITE: / <worksheet>-id, ':', <worksheet>-target. - WHEN OTHERS. - ENDCASE. - ENDWHILE. - " Read Workbook - workbook = me->get_ixml_from_zip_archive( workbook_path ). - workbook_coll = workbook->get_elements_by_tag_name( name = 'sheet' ). - workbook_index = 0. - WHILE workbook_index < workbook_coll->get_length( ). - node = workbook_coll->get_item( workbook_index ). - workbook_index = workbook_index + 1. - attributes ?= node->get_attributes( ). - attribute ?= attributes->get_named_item_ns( 'name' ). - worksheet_title = attribute->get_value( ). - IF workbook_index > 1. - lo_worksheet = r_excel->add_new_worksheet( worksheet_title ). - ELSE. - lo_worksheet = r_excel->get_active_worksheet( ). - lo_worksheet->set_title( worksheet_title ). - ENDIF. - attribute ?= attributes->get_named_item_ns( - name = 'id' - uri = lc_relationships - ). - worksheet_id = attribute->get_value( ). - READ TABLE worksheets ASSIGNING <worksheet> - WITH KEY id = worksheet_id. - " WRITE: / worksheet_id, worksheet_title, <worksheet>-target. - CONCATENATE dirname <worksheet>-target INTO worksheet_path. - worksheet = me->get_ixml_from_zip_archive( worksheet_path ). - worksheet_coll = worksheet->get_elements_by_tag_name( name = 'row' ). - worksheet_index = 0. - WHILE worksheet_index < worksheet_coll->get_length( ). - node = worksheet_coll->get_item( worksheet_index ). - worksheet_index = worksheet_index + 1. - row = node->get_children( ). - row_iterator = row->create_iterator( ). - 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, cell_formula. - attribute ?= col_attributes->get_named_item_ns( 't' ). - IF attribute IS BOUND. - cell_data_type = attribute->get_value( ). - ENDIF. - - value_elem = cell->find_from_name( name = 'v' ). - - CASE cell_data_type. - 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 '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. - - 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 - IMPORTING - e_column = cell_column - e_row = cell_row - ). - lo_worksheet->set_cell( - EXPORTING - 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. - cell ?= row_iterator->get_next( ). - ENDWHILE. - ENDWHILE. - ENDWHILE. WHEN OTHERS. ENDCASE. + + node ?= node->get_next( ). ENDWHILE. -endmethod. +ENDMETHOD. method ZIF_EXCEL_READER~LOAD_FILE. @@ -359,10 +218,37 @@ endmethod. 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. @@ -398,12 +284,11 @@ endmethod. ENDIF. endmethod. - - - - - + + + + method GET_IXML_FROM_ZIP_ARCHIVE. TYPE-POOLS: ixml. @@ -427,6 +312,524 @@ endmethod. 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. + + 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, + 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, + 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. + + 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. + + 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 = color-rgb. + 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 ). + IF color-indexed IS NOT INITIAL. + fill->bgcolor = color-indexed. + ENDIF. + 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 = color-rgb. + "fill-> = color-theme. + "fill-> = 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 = color-rgb. + 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_sheet, + name TYPE string, + sheetId TYPE string, + id TYPE string, + END OF t_sheet. + + 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. + + 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' ). + 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( ). + 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. diff --git a/ZA2X/PROG/ZDEMO_EXCEL1.slnk b/ZA2X/PROG/ZDEMO_EXCEL1.slnk index 397dc96..9f6de52 100644 --- a/ZA2X/PROG/ZDEMO_EXCEL1.slnk +++ b/ZA2X/PROG/ZDEMO_EXCEL1.slnk @@ -1,12 +1,12 @@ - + - + + - *&---------------------------------------------------------------------* *& Report ZDEMO_EXCEL1 *& @@ -19,6 +19,7 @@ REPORT zdemo_excel1. DATA: lo_excel TYPE REF TO zcl_excel, lo_excel_writer TYPE REF TO zif_excel_writer, + lo_excel_reader TYPE REF TO zif_excel_reader, lo_worksheet TYPE REF TO zcl_excel_worksheet, lo_hyperlink TYPE REF TO zcl_excel_hyperlink, column_dimension TYPE REF TO zcl_excel_worksheet_columndime. @@ -33,7 +34,8 @@ DATA: lv_full_path TYPE string, CONSTANTS: lv_default_file_name TYPE string VALUE '01_HelloWorld.xlsx'. -PARAMETERS: p_path TYPE zexcel_export_dir. +PARAMETERS: p_path TYPE zexcel_export_dir, + p_reader TYPE abap_bool AS CHECKBOX. AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_path. lv_workdir = p_path. @@ -88,5 +90,28 @@ START-OF-SELECTION. cl_gui_frontend_services=>gui_download( EXPORTING bin_filesize = lv_bytecount filename = lv_full_path filetype = 'BIN' - CHANGING data_tab = lt_file_tab ). + CHANGING data_tab = lt_file_tab ). + + IF p_reader = abap_true. + CREATE OBJECT lo_excel_reader TYPE zcl_excel_reader_2007. + CREATE OBJECT lo_excel_writer TYPE zcl_excel_writer_2007. + lo_excel = lo_excel_reader->load_file( lv_full_path ). + lv_file = lo_excel_writer->write_file( lo_excel ). + REPLACE '.xlsx' IN lv_full_path WITH 'FromReader.xlsx'. + + " Convert to binary + CALL FUNCTION 'SCMS_XSTRING_TO_BINARY' + EXPORTING + buffer = lv_file + IMPORTING + output_length = lv_bytecount + TABLES + binary_tab = lt_file_tab. + + " Save the file + cl_gui_frontend_services=>gui_download( EXPORTING bin_filesize = lv_bytecount + filename = lv_full_path + filetype = 'BIN' + CHANGING data_tab = lt_file_tab ). + ENDIF. diff --git a/ZA2X/PROG/ZDEMO_EXCEL2.slnk b/ZA2X/PROG/ZDEMO_EXCEL2.slnk index 1ab3d9a..e2c63ea 100644 --- a/ZA2X/PROG/ZDEMO_EXCEL2.slnk +++ b/ZA2X/PROG/ZDEMO_EXCEL2.slnk @@ -1,12 +1,12 @@ - + - - + + + - *&---------------------------------------------------------------------* *& Report ZDEMO_EXCEL2 *& Test Styles for ABAP2XLSX @@ -19,6 +19,7 @@ REPORT zdemo_excel2. DATA: lo_excel TYPE REF TO zcl_excel, lo_excel_writer TYPE REF TO zif_excel_writer, + lo_excel_reader TYPE REF TO zif_excel_reader, lo_worksheet TYPE REF TO zcl_excel_worksheet, lo_style_bold TYPE REF TO zcl_excel_style, lo_style_underline TYPE REF TO zcl_excel_style, @@ -45,7 +46,8 @@ DATA: lv_full_path TYPE string, CONSTANTS: lv_default_file_name TYPE string VALUE '02_Styles.xlsx'. -PARAMETERS: p_path TYPE zexcel_export_dir. +PARAMETERS: p_path TYPE zexcel_export_dir, + p_reader TYPE abap_bool AS CHECKBOX. AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_path. lv_workdir = p_path. @@ -146,5 +148,28 @@ START-OF-SELECTION. cl_gui_frontend_services=>gui_download( EXPORTING bin_filesize = lv_bytecount filename = lv_full_path filetype = 'BIN' - CHANGING data_tab = lt_file_tab ). + CHANGING data_tab = lt_file_tab ). + + IF p_reader = abap_true. + CREATE OBJECT lo_excel_reader TYPE zcl_excel_reader_2007. + CREATE OBJECT lo_excel_writer TYPE zcl_excel_writer_2007. + lo_excel = lo_excel_reader->load_file( lv_full_path ). + lv_file = lo_excel_writer->write_file( lo_excel ). + REPLACE '.xlsx' IN lv_full_path WITH 'FromReader.xlsx'. + + " Convert to binary + CALL FUNCTION 'SCMS_XSTRING_TO_BINARY' + EXPORTING + buffer = lv_file + IMPORTING + output_length = lv_bytecount + TABLES + binary_tab = lt_file_tab. + + " Save the file + cl_gui_frontend_services=>gui_download( EXPORTING bin_filesize = lv_bytecount + filename = lv_full_path + filetype = 'BIN' + CHANGING data_tab = lt_file_tab ). + ENDIF.