class ZCL_EXCEL_READER_2007 definition
public
final
create public .
*"* public components of class ZCL_EXCEL_READER_2007
*"* do not include other source files here!!!
public section.
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
*"* do not include other source files here!!!
private section.
data EXCEL2007 type XSTRING .
data ZIP type ref to CL_ABAP_ZIP .
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 .*"* 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
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.*"* use this source file for any macro definitions you need
*"* in the implementation part of the classmethod 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.
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_node TYPE REF TO if_ixml_node,
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,
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,
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.
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.
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( ).
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( ).
col = row_iterator->get_next( ).
WHILE NOT col IS INITIAL.
col_attributes = col->get_attributes( ).
attribute ?= col_attributes->get_named_item_ns( 'r' ).
r = attribute->get_value( ).
CLEAR: cell_data_type, cell_value.
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( ).
CASE cell_data_type.
WHEN 's'. " String
value_index = value_node->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( ).
ENDIF.
ENDCASE.
IF NOT cell_value 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
).
ENDIF.
col = row_iterator->get_next( ).
ENDWHILE.
ENDWHILE.
ENDWHILE.
WHEN OTHERS.
ENDCASE.
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 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.