ABAP Reading Excel Method Encyclopedia

Preface

ABAP reads Excel files is a relatively common development, which can be implemented in a variety of ways. OLE is an older technology with slow speed and has requirements for the host (system, office version, etc.); the latest solution is to use Excel files Converted to XML for parsing, using the latest object-oriented programming, easy to understand, and good compatibility.

method

Standard function

Function name Description
TEXT_CONVERT_XLS_TO_SAP Parse Excel data directly into ABAP internal table, but the internal table structure needs to be consistent with the Excel structure
ALSM_EXCEL_TO_INTERNAL_TABL Read the data in the dimensions of the cell, but the maximum length is only 50 characters

Customization method
Through the custom function, it is possible to read larger length content and multiple sheet
structure definitions
Insert picture description here

class ZCL_MDG_IF_TOOLS definition
  public
  final
  create public .

public section.
  type-pools OLE2 .

  types:
  types TY_D_ITABVALUE type ZSMDG_ALSMEX_TABLINE-VALUE .
  types TY_ITAB type ZSMDG_ALSMEX_TABLINE .
  types:
    ty_t_itab type table of zsmdg_alsmex_tabline .
  types:
    begin of ty_s_senderline,
        line(4096) type c,
      end of ty_s_senderline .
  types TY_SENDER type TY_S_SENDERLINE .
  types:
    ty_t_sender type table of ty_s_senderline .
  constants GC_ESC type C value '"' ##NO_TEXT.

  class-methods READ_EXCEL_MULTIPLE_SHEETS
    importing
      !FILENAME type RLGRAP-FILENAME
      !I_BEGIN_COL type I default 1
      !I_BEGIN_ROW type I default 2
      !I_END_COL type I default 99
      !I_END_ROW type I default 100000
      !SHEET_INDEX type I optional
      !SHEET_NAME type ALSMEX_TABLINE-VALUE optional
    exporting
      !INTERN type ZMDG_ALSMEX_TABLINE_T
    exceptions
      INCONSISTENT_PARAMETERS
      UPLOAD_OLE .
 
  protected section.

    class-methods line_to_cell_esc_sep
      changing
        !i_string       type any
        !i_sic_int      type i
        !i_separator    type c
        !i_intern_value type ty_d_itabvalue .
    class-methods line_to_cell_separat
      changing
        !i_line      type any
        !i_row       type sy-tabix
        !ch_cell_col type kcd_ex_col
        !i_separator type c
        !i_fdpos     type sy-fdpos
        !i_intern    type ty_t_itab .

    class-methods separated_to_intern_convert
      changing
        !i_tab       type ty_t_sender
        !i_separator type c
        !i_intern    type ty_t_itab .
  private section.

ENDCLASS.



CLASS ZCL_MDG_IF_TOOLS IMPLEMENTATION.
* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Protected Method ZCL_MDG_IF_TOOLS=>LINE_TO_CELL_ESC_SEP
* +-------------------------------------------------------------------------------------------------+
* | [<-->] I_STRING                       TYPE        ANY
* | [<-->] I_SIC_INT                      TYPE        I
* | [<-->] I_SEPARATOR                    TYPE        C
* | [<-->] I_INTERN_VALUE                 TYPE        TY_D_ITABVALUE
* +--------------------------------------------------------------------------------------</SIGNATURE>
  method line_to_cell_esc_sep.
    data: l_int         type i,
          l_cell_end(2).
    field-symbols: <l_cell> type any.
    l_cell_end = gc_esc.
    l_cell_end+1 = i_separator .

    if i_string cs gc_esc.
      i_string = i_string+1.
      if i_string cs l_cell_end.
        l_int = sy-fdpos.
        assign i_string(l_int) to <l_cell>.
        i_intern_value = <l_cell>.
        l_int = l_int + 2.
        i_sic_int = l_int.
        i_string = i_string+l_int.
      elseif i_string cs gc_esc.
*     letzte Celle
        l_int = sy-fdpos.
        assign i_string(l_int) to <l_cell>.
        i_intern_value = <l_cell>.
        l_int = l_int + 1.
        i_sic_int = l_int.
        i_string = i_string+l_int.
        l_int = strlen( i_string ).
        if l_int > 0 . message x001(kx) . endif.
      else.
        message x001(kx) .  
      endif.
    endif.
  endmethod.


*<SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Protected Method ZCL_MDG_IF_TOOLS=>LINE_TO_CELL_SEPARAT
* +-------------------------------------------------------------------------------------------------+
* | [<-->] I_LINE                         TYPE        ANY
* | [<-->] I_ROW                          TYPE        SY-TABIX
* | [<-->] CH_CELL_COL                    TYPE        KCD_EX_COL
* | [<-->] I_SEPARATOR                    TYPE        C
* | [<-->] I_FDPOS                        TYPE        SY-FDPOS
* | [<-->] I_INTERN                       TYPE        TY_T_ITAB
* +--------------------------------------------------------------------------------------</SIGNATURE>
  method line_to_cell_separat.

    data: l_string   type ty_s_senderline.
    data  l_sic_int  type i.
    data:ls_intern type zsmdg_alsmex_tabline.

    clear ls_intern.
    l_sic_int = i_fdpos.
    ls_intern-row = i_row.
    l_string = i_line.
    ls_intern-col = ch_cell_col.
* csv Dateien mit separator in Zelle: --> ;"abc;cd";
    if ( i_separator = ';' or  i_separator = ',' ) and
    l_string(1) = gc_esc.
      line_to_cell_esc_sep(
      changing
        i_string = l_string
        i_sic_int = l_sic_int
        i_separator = i_separator
        i_intern_value = ls_intern-value
        ).
    else.
      if l_sic_int > 0.
        ls_intern-value = i_line(l_sic_int).
      endif.
    endif.
    if l_sic_int > 0.
      append ls_intern to i_intern.
    endif.
    l_sic_int = l_sic_int + 1.
    i_line = i_line+l_sic_int.
  endmethod.

*<SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Public Method ZCL_MDG_IF_TOOLS=>READ_EXCEL_MULTIPLE_SHEETS
* +-------------------------------------------------------------------------------------------------+
* | [--->] FILENAME                       TYPE        RLGRAP-FILENAME
* | [--->] I_BEGIN_COL                    TYPE        I (default =1)
* | [--->] I_BEGIN_ROW                    TYPE        I (default =2)
* | [--->] I_END_COL                      TYPE        I (default =99)
* | [--->] I_END_ROW                      TYPE        I (default =100000)
* | [--->] SHEET_INDEX                    TYPE        I(optional)
* | [--->] SHEET_NAME                     TYPE        ALSMEX_TABLINE-VALUE(optional)
* | [<---] INTERN                         TYPE        ZMDG_ALSMEX_TABLINE_T
* | [EXC!] INCONSISTENT_PARAMETERS
* | [EXC!] UPLOAD_OLE
* +--------------------------------------------------------------------------------------</SIGNATURE>
  method read_excel_multiple_sheets.


    data: excel_tab     type ty_t_sender.
    data: ld_separator  type  c.
    data: application type  ole2_object,
          workbook    type  ole2_object,
          range       type  ole2_object,
          worksheet   type  ole2_object.
    data: h_cell  type  ole2_object,
          h_cell1 type  ole2_object.
    data:
          ld_rc             type i.
*   Rückgabewert der Methode "clipboard_export     "

* Makro für Fehlerbehandlung der Methods
    define m_message.
      CASE sy-subrc.
      WHEN 0.
      WHEN 1.
        MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
        WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
      WHEN OTHERS. RAISE upload_ole.
      ENDCASE.
    end-of-definition.


* check parameters
    if i_begin_row > i_end_row.
      raise inconsistent_parameters.
    endif.
    if i_begin_col > i_end_col.
      raise inconsistent_parameters.
    endif.

* Get TAB-sign for separation of fields
    class cl_abap_char_utilities definition load.
    ld_separator = cl_abap_char_utilities=>horizontal_tab.

* open file in Excel
    if application-header = space or application-handle = -1.
      create object application 'Excel.Application'.
      m_message.
    endif.
    call method  of application    'Workbooks' = workbook.
    m_message.
    call method  of workbook 'Open'    exporting #1 = filename.
    m_message.

*  set property of application 'Visible' = 1.
*  m_message.
*-------ADD START---------
    if sheet_name is not initial.
      call method of application 'WORKSHEETS' = worksheet
      exporting
        #1 = sheet_name.

      if sy-subrc ne 0.
        return.
      endif.

      call method of worksheet 'Activate'.
      m_message.
    elseif sheet_index is not initial.
      call method of application 'WORKSHEETS' = worksheet
      exporting
        #1 = sheet_index.

      if sy-subrc ne 0.
        return.
      endif.

      call method of worksheet 'Activate'.
      m_message.
    else."默认模式
      get property of  application 'ACTIVESHEET' = worksheet.
      m_message.
    endif.
*-------ADD END---------

* mark whole spread sheet
    call method of worksheet 'Cells' = h_cell
    exporting #1 = i_begin_row #2 = i_begin_col.
    m_message.
    call method of worksheet 'Cells' = h_cell1
    exporting #1 = i_end_row #2 = i_end_col.
    m_message.

    call method  of worksheet 'RANGE' = range
    exporting #1 = h_cell #2 = h_cell1.
    m_message.
    call method of range 'SELECT'.
    m_message.

* copy marked area (whole spread sheet) into Clippboard
    call method of range 'COPY'.
    m_message.

* read clipboard into ABAP
    call method cl_gui_frontend_services=>clipboard_import
      importing
        data       = excel_tab
      exceptions
        cntl_error = 1
*       ERROR_NO_GUI         = 2
*       NOT_SUPPORTED_BY_GUI = 3
        others     = 4.
    if sy-subrc <> 0.
      message a037(alsmex).
    endif.

    separated_to_intern_convert(
    changing
     i_tab = excel_tab
     i_intern = intern
    i_separator = ld_separator
    ).

* clear clipboard
    refresh excel_tab.
    call method cl_gui_frontend_services=>clipboard_export
      importing
        data       = excel_tab
      changing
        rc         = ld_rc
      exceptions
        cntl_error = 1
*       ERROR_NO_GUI         = 2
*       NOT_SUPPORTED_BY_GUI = 3
        others     = 4.

* quit Excel and free ABAP Object - unfortunately, this does not kill
* the Excel process
    call method of application 'QUIT'.
    m_message.

* >>>>> Begin of change note 575877
* to kill the Excel process it's necessary to free all used objects
    free object h_cell.       m_message.
    free object h_cell1.      m_message.
    free object range.        m_message.
    free object worksheet.    m_message.
    free object workbook.     m_message.
    free object application.  m_message.
* <<<<< End of change note 575877
  endmethod.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Protected Method ZCL_MDG_IF_TOOLS=>SEPARATED_TO_INTERN_CONVERT
* +-------------------------------------------------------------------------------------------------+
* | [<-->] I_TAB                          TYPE        TY_T_SENDER
* | [<-->] I_SEPARATOR                    TYPE        C
* | [<-->] I_INTERN                       TYPE        TY_T_ITAB
* +--------------------------------------------------------------------------------------</SIGNATURE>
  method separated_to_intern_convert.
    data: l_sic_tabix type sy-tabix,
          l_sic_col   type kcd_ex_col.
    data: l_fdpos     type sy-fdpos.
    data:ls_intern type zsmdg_alsmex_tabline.

    refresh i_intern.

    loop at i_tab assigning field-symbol(<fs_tab>).
      l_sic_tabix = sy-tabix.
      l_sic_col = 0.
      while <fs_tab> ca i_separator.
        l_fdpos = sy-fdpos.
        l_sic_col = l_sic_col + 1.

        line_to_cell_separat(
        changing
          i_line = <fs_tab>
          i_intern = i_intern
          i_row = l_sic_tabix
          ch_cell_col = l_sic_col
          i_separator =   i_separator
          i_fdpos =    l_fdpos
         ).
      endwhile.
      if <fs_tab> <> space.
        clear ls_intern.
        ls_intern-row = l_sic_tabix.
        ls_intern-col = l_sic_col + 1.
        ls_intern-value = <fs_tab>.
        append ls_intern to i_intern.
      endif.
    endloop.
  endmethod.
ENDCLASS.

Object-oriented implementation

Class name Description
cl_fdt_xl_spreadsheet Based on cl_ixml, it can be read by sheet name
abap2xlsx Open source warehouse, available through abapgit

Reference Code

"首先获取文件流xstring
data(lo_excel) = new cl_fdt_xl_spreadsheet( document_name = ms_upload-file_name xdocument = ms_upload-file ).

    lo_excel->if_fdt_doc_spreadsheet~get_worksheet_names(
    importing
      worksheet_names = data(lt_worksheets)
    ).

    data:lr_sheet_data type ref to data.
    field-symbols:<ft_sheet_data> type index table.

    loop at lt_worksheets reference into data(lr_worksheet).
      data(lv_sheet_index) = sy-tabix.
      lr_sheet_data = lo_excel->if_fdt_doc_spreadsheet~get_itab_from_worksheet(
        worksheet_name = lr_worksheet->*
      ).

      if  <ft_sheet_data> is assigned.
        unassign <ft_sheet_data>.
      endif.
      assign lr_sheet_data->* to <ft_sheet_data>.
 endloop.

reference

For the writing of Excel files, technologies such as OLE or DOI are commonly used. Personally, I prefer to use the open source library abap2xlsx, or consider the implementation of xlsx workbench, refer to the following
https://github.com/sapmentors/abap2xlsx
https://blogs .sap.com/2014/04/22/xlsx-workbench/
https://blogs.sap.com/2020/05/22/best-way-to-generate-microsoft-excel-xlsx-from-template-in -abap/

Guess you like

Origin blog.csdn.net/u012232542/article/details/109752588