能否使用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读取后即可直接处理:
- 处理CSV时,用
filetype = 'ASC'并指定has_field_separator = abap_true(默认分隔符为逗号,若使用其他分隔符可额外指定field_separator参数) - 读取后的
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
相关产品推荐
相关产品推荐

