2020.02.28 ABAP随笔- EXCEL批导程式3 - CL_EHFND_XLSX类 比较好用快速准确

Posted jxzhu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2020.02.28 ABAP随笔- EXCEL批导程式3 - CL_EHFND_XLSX类 比较好用快速准确相关的知识,希望对你有一定的参考价值。

怎么找到这个类的呢,是因为Wang Jerry 的一篇文章。感谢sap研究院大佬让我更透彻的了解了一下XLSX其实就是多个XML文件组合成的。

文章链接如下,请大家自行关注查看:

https://mp.weixin.qq.com/s/29v98Z4mgFboZjBTLsiWbw

技术图片

关键      DATA error_text TYPE string.

      lv_filename = p_file.
      CHECK lv_filename IS NOT INITIAL.
      CALL METHOD zcl_document_jxzhu=>import_document_from_frontend  "调用方法获取Excel数据
        EXPORTING
          pi_filename     = lv_filename " 文件路径
*         pi_sheetname    = ‘Sheet1‘ "sheet 页名称
*         start_row       = ‘2‘ "开始获取的行号
          check_structure = abap_on  "是否匹配结构去获取excel数据(X为 excel排列顺序和内表字段顺序无关,仅用结构来匹配)
        IMPORTING
          error_text      = error_text  "错误消息
        CHANGING
          pt_tab          = lt_zmmt001
        EXCEPTIONS
          file_open_error = 1
          OTHERS          = 2.
      IF sy-subrc <> 0.
*       Implement suitable error handling here
      ENDIF.
      cl_demo_output=>display( lt_zmmt001 ).


"下列代码实现了Excel 单个sheet页的导入 代码可以直接使用
METHOD import_document_from_frontend. *create a xlsx handler DATA(xlsxhandler) = cl_ehfnd_xlsx=>get_instance( )."创建了句柄 *open xlsx into xstring TRY. DATA(xstring_excel) = cl_openxml_helper=>load_local_file( pi_filename ). "获取excel路径 为 xstring格式
CATCH cx_openxml_not_found INTO DATA(openxml_not_found). error_text = openxml_not_found->get_text( ). ENDTRY. IF error_text IS NOT INITIAL. MESSAGE e001(00) RAISING file_open_error WITH error_text. ENDIF. *load the xlsx TRY. DATA(xlsxdocument) = xlsxhandler->load_doc( iv_file_data = xstring_excel ). "加载excel
CATCH cx_openxml_format INTO DATA(openxml_format). error_text = openxml_format->get_text( ). CATCH cx_openxml_not_allowed INTO DATA(openxml_not_allowed). error_text = openxml_not_allowed->get_text( ). CATCH cx_dynamic_check INTO DATA(dynamic_check). error_text = dynamic_check->get_text( ). ENDTRY. IF error_text IS NOT INITIAL. MESSAGE e001(00) RAISING file_open_error WITH error_text. ENDIF. *extract data from sheet ( pi_sheetname) TRY. DATA(firstsheet) = xlsxdocument->get_sheet_by_name( iv_sheet_name = pi_sheetname ). CATCH cx_openxml_format INTO openxml_format. error_text = openxml_format->get_text( ). error_text = |Error occurs when extract data from specific sheet: | && error_text. CATCH cx_openxml_not_found INTO openxml_not_found. error_text = openxml_not_found->get_text( ). error_text = |Error occurs when extract data from specific sheet: | && error_text . ENDTRY. IF error_text IS NOT INITIAL. MESSAGE e001(00) RAISING file_open_error WITH error_text. ENDIF. *extract data from first sheet IF firstsheet IS INITIAL . CLEAR error_text. TRY. firstsheet = xlsxdocument->get_sheet_by_id( iv_sheet_id = 1 ). CATCH cx_openxml_format INTO openxml_format. error_text = openxml_format->get_text( ) . error_text = |Error occurs when extract data from first sheet: | && error_text . CATCH cx_openxml_not_found INTO openxml_not_found. error_text = openxml_not_found->get_text( ). error_text = |Error occurs when extract data from first sheet: | && error_text . CATCH cx_dynamic_check INTO dynamic_check. error_text = |Error occurs when extract data from first sheet: | && dynamic_check->get_text( ) . ENDTRY. ENDIF. IF error_text IS NOT INITIAL. MESSAGE e001(00) RAISING file_open_error WITH error_text. ENDIF. "return if no sheet in xlsx file CHECK NOT firstsheet IS INITIAL. "check file structure, first line of excel file DATA(columncount) = firstsheet->get_last_column_number_in_row( 1 ). "获取第1行列数 (一共几列) DATA column TYPE i VALUE 1. "data tablecomponents type cl_abap_structdescr=>component_table. *get the components of structure DATA lw_tab_ref TYPE REF TO data. CREATE DATA lw_tab_ref LIKE LINE OF pt_tab. DATA tablestructure TYPE REF TO cl_abap_structdescr. tablestructure ?= cl_abap_typedescr=>describe_by_data_ref( lw_tab_ref ). "获取内表的 components DATA(tablecomponents) = tablestructure->get_components( ). "get the content of excel. TYPES: BEGIN OF columninfo, column TYPE i, columnname TYPE string, END OF columninfo. TYPES columnsinfo TYPE STANDARD TABLE OF columninfo WITH EMPTY KEY. DATA columnfromfile TYPE columnsinfo. IF check_structure = abap_on. * get the title row compare with tab structure if need DO columncount TIMES. DATA(cellvalue) = firstsheet->get_cell_content( EXPORTING iv_row = 1 iv_column = column ). APPEND INITIAL LINE TO columnfromfile ASSIGNING FIELD-SYMBOL(<columnfromfile>). <columnfromfile>-column = column. <columnfromfile>-columnname = cellvalue. IF line_exists( tablecomponents[ name = cellvalue ] ). DELETE tablecomponents WHERE name = cellvalue. ELSE. error_text = error_text && |,{ cellvalue }|. ENDIF. column = column + 1. ENDDO. IF error_text IS NOT INITIAL. MESSAGE e001(00) RAISING file_open_error WITH error_text. ENDIF. ENDIF. * get the title row compare with tab structure if need "last row DATA(rowcount) = firstsheet->get_last_row_number( ). DATA(currentrow) = start_row. *get data of excel CASE check_structure. WHEN abap_on. "按照字段对应获取数据 WHILE currentrow <= rowcount. APPEND INITIAL LINE TO pt_tab ASSIGNING FIELD-SYMBOL(<currentrow>). LOOP AT columnfromfile REFERENCE INTO DATA(currentcolumn). cellvalue = firstsheet->get_cell_content( EXPORTING iv_row = currentrow iv_column = currentcolumn->*-column ). ASSIGN COMPONENT currentcolumn->*-columnname OF STRUCTURE <currentrow> TO FIELD-SYMBOL(<cellvalue>). <cellvalue> = cellvalue. ENDLOOP. currentrow = currentrow + 1. ENDWHILE. WHEN OTHERS. "按照顺序获取数据 CLEAR column. WHILE currentrow <= rowcount. APPEND INITIAL LINE TO pt_tab ASSIGNING <currentrow>. DO columncount TIMES. column = column + 1. cellvalue = firstsheet->get_cell_content( EXPORTING iv_row = currentrow iv_column = column ). ASSIGN COMPONENT column OF STRUCTURE <currentrow> TO <cellvalue>. <cellvalue> = cellvalue. ENDDO. CLEAR column. currentrow = currentrow + 1. ENDWHILE. ENDCASE. ENDMETHOD.

结合前2天的随笔,一共给出3种excel导入的方法,掌握应该是第一种最容易掌握,当然第一种缺点也最大。

比较一下三种方法在效率上的区别:导入100条数据测试

1.ALSM_EXCEL_TO_INTERNAL方法:用时7秒

技术图片

 

 2.客制OLE-突破9999行的限制 用时6秒 (其实都是ole 和1 差不多也是正常)

技术图片

 

 3.CL_EHFND_XLSX类 用时2秒

技术图片

 

 由以上可得,多花心思研究下XML方式导入excel,以后就可以不用OLE,又快又舒服。

技术图片

"获取excel

以上是关于2020.02.28 ABAP随笔- EXCEL批导程式3 - CL_EHFND_XLSX类 比较好用快速准确的主要内容,如果未能解决你的问题,请参考以下文章

2020.03.03 ABAP随笔- Excel批量导出6-OLE客制导出

2020.02.27 ABAP随笔- EXCEL批导程式2 - 突破9999行的束缚

2020.05.07 ABAP随笔- ABAP-SM30删除前检查

2020.05.07 ABAP随笔- ABAP-SM30删除前检查

2020.01.11 ABAP随笔SM30常见增强操作-自动带描述等

2020.01.11 ABAP随笔获取标准报表数据(MB52)数据进行客制ALV