You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否使用CL_FDT_XL_SPREADSHEET类处理.CSV文件?

问题描述

我有一个维护自定义Z表的程序,目前支持将Z表导出为Excel文件,也能通过.XLSX格式文件刷新更新Z表。现在想让程序同时支持.CSV文件,但在用CL_GUI_FRONTEND_SERVICES=>GUI_UPLOAD获取CSV原始数据后,转换为XSTRING时出现错误。核心疑问是:CL_FDT_XL_SPREADSHEET类是否支持处理.CSV文件,还是仅支持.XLSX?

当前XLSX的上传流程是:用CL_GUI_FRONTEND_SERVICES=>GUI_UPLOAD以BIN格式读取文件,转成XSTRING后传入CL_FDT_XL_SPREADSHEET,调用IF_FDT_DOC_SPREADSHEET~GET_ITAB_FROM_WORKSHEET把数据存入内表,后续用于更新Z表,这个流程完全正常。

原代码

METHOD import_excel_data.

    DATA: lt_xtab TYPE cpt_x255,
          lv_size TYPE i.

    IF i_filetype = abap_true. "******.XLSX UPLOAD*********
      cl_gui_frontend_services=>gui_upload( EXPORTING filename   = i_file
                                                      filetype   = 'BIN'
                                            IMPORTING filelength = lv_size
                                             CHANGING data_tab   = lt_xtab
                                             EXCEPTIONS
                                                      file_open_error = 1
                                                      file_read_error = 2
                                                      error_no_gui            = 3
                                                      not_supported_by_gui    = 4
                                                      OTHERS                  = 5 ).
      IF sy-subrc <> 0.
        RAISE EXCEPTION TYPE zcx_excel_exception EXPORTING i_message = |Invalid File { i_file }| ##no_text.
      ENDIF.
    ELSE."******.CSV UPLOAD*********

      cl_gui_frontend_services=>gui_upload( EXPORTING filename   = i_file
                                                      filetype   = 'ASC'
                                                      has_field_separator = abap_true
                                            IMPORTING filelength = lv_size
                                            CHANGING data_tab   = lt_xtab
                                            EXCEPTIONS
                                                    file_open_error = 1
                                                    file_read_error = 2
                                                    error_no_gui            = 3
                                                    not_supported_by_gui    = 4
                                                    OTHERS                  = 5 ).
      IF sy-subrc <> 0.
        RAISE EXCEPTION TYPE zcx_excel_exception EXPORTING i_message = |Invalid File { i_file }| ##no_text.
      ENDIF.

    ENDIF.

    cl_scp_change_db=>xtab_to_xstr( EXPORTING im_xtab    = lt_xtab
                                              im_size    = lv_size
                                    IMPORTING ex_xstring = DATA(lv_xstring) ).

    DATA(lo_excel) = NEW cl_fdt_xl_spreadsheet( document_name = i_file
                                                xdocument     = lv_xstring ).
    lo_excel->if_fdt_doc_spreadsheet~get_worksheet_names(
      IMPORTING worksheet_names = DATA(lt_worksheets) ).

    rt_table = lo_excel->if_fdt_doc_spreadsheet~get_itab_from_worksheet( lt_worksheets[ 1 ] ).

    IF rt_table IS INITIAL.
      RAISE EXCEPTION TYPE zcx_excel_exception EXPORTING i_message = 'No Data found in Excel File' ##no_text.
    ENDIF.
  ENDMETHOD.
解答

CL_FDT_XL_SPREADSHEET仅支持处理.XLSX格式文件,它是专门针对Office Open XML格式(即XLSX)的解析类,无法识别CSV这种纯文本分隔符格式的文件,这就是你用CSV数据初始化该类后报错的根本原因。

针对CSV文件,不需要绕到XLSX的解析流程,直接通过CL_GUI_FRONTEND_SERVICES=>GUI_UPLOAD读取后即可直接处理:

  1. 处理CSV时,用filetype = 'ASC'并指定has_field_separator = abap_true(默认分隔符为逗号,若使用其他分隔符可额外指定field_separator参数)
  2. 读取后的lt_xtab是每行文本的内表,可直接将其拆分转换为目标结构内表,无需再转XSTRING和调用CL_FDT_XL_SPREADSHEET

修改后的代码示例

METHOD import_excel_data.
    DATA: lt_xtab TYPE cpt_x255,
          lv_size TYPE i,
          ls_line TYPE string,
          ls_data TYPE <你的目标结构类型>, "替换为实际Z表结构或上传专用结构
          lt_data TYPE STANDARD TABLE OF <你的目标结构类型>.

    IF i_filetype = abap_true. "******.XLSX UPLOAD*********
      cl_gui_frontend_services=>gui_upload( EXPORTING filename   = i_file
                                                      filetype   = 'BIN'
                                            IMPORTING filelength = lv_size
                                             CHANGING data_tab   = lt_xtab
                                             EXCEPTIONS
                                                      file_open_error = 1
                                                      file_read_error = 2
                                                      error_no_gui            = 3
                                                      not_supported_by_gui    = 4
                                                      OTHERS                  = 5 ).
      IF sy-subrc <> 0.
        RAISE EXCEPTION TYPE zcx_excel_exception EXPORTING i_message = |Invalid File { i_file }| ##no_text.
      ENDIF.

      cl_scp_change_db=>xtab_to_xstr( EXPORTING im_xtab    = lt_xtab
                                              im_size    = lv_size
                                    IMPORTING ex_xstring = DATA(lv_xstring) ).

      DATA(lo_excel) = NEW cl_fdt_xl_spreadsheet( document_name = i_file
                                                xdocument     = lv_xstring ).
      lo_excel->if_fdt_doc_spreadsheet~get_worksheet_names(
        IMPORTING worksheet_names = DATA(lt_worksheets) ).

      rt_table = lo_excel->if_fdt_doc_spreadsheet~get_itab_from_worksheet( lt_worksheets[ 1 ] ).

      IF rt_table IS INITIAL.
        RAISE EXCEPTION TYPE zcx_excel_exception EXPORTING i_message = 'No Data found in Excel File' ##no_text.
      ENDIF.
    ELSE."******.CSV UPLOAD*********
      cl_gui_frontend_services=>gui_upload( EXPORTING filename   = i_file
                                                      filetype   = 'ASC'
                                                      has_field_separator = abap_true
                                                      "若CSV使用分号等其他分隔符,添加以下参数
                                                      "field_separator = ';'
                                            IMPORTING filelength = lv_size
                                            CHANGING data_tab   = lt_xtab
                                            EXCEPTIONS
                                                    file_open_error = 1
                                                    file_read_error = 2
                                                    error_no_gui            = 3
                                                    not_supported_by_gui    = 4
                                                    OTHERS                  = 5 ).
      IF sy-subrc <> 0.
        RAISE EXCEPTION TYPE zcx_excel_exception EXPORTING i_message = |Invalid File { i_file }| ##no_text.
      ENDIF.

      "将CSV每行拆分为目标结构字段
      LOOP AT lt_xtab INTO ls_line.
        "跳过表头行(若CSV包含表头,取消下面注释)
        "IF sy-tabix = 1. CONTINUE. ENDIF.
        
        SPLIT ls_line AT ',' INTO ls_data-field1 ls_data-field2 ls_data-field3. "替换为实际字段
        APPEND ls_data TO lt_data.
      ENDLOOP.

      rt_table = lt_data. "将转换后的内表赋值给返回参数

      IF rt_table IS INITIAL.
        RAISE EXCEPTION TYPE zcx_excel_exception EXPORTING i_message = 'No Data found in CSV File' ##no_text.
      ENDIF.
    ENDIF.
  ENDMETHOD.

注意事项

  • 确保CSV的分隔符与代码中指定的一致,默认是逗号,若使用分号或其他符号需在gui_upload中指定field_separator参数
  • 若CSV包含带引号的字段(如字段内容含逗号),需额外处理引号逻辑,避免拆分错误
  • 若CSV有表头行,需添加逻辑跳过第一行再处理数据

内容的提问来源于stack exchange,提问作者Matthew Rook

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 06:50:50