SAP - 使用CL_FDT_XL_SPREADSHEET将Excel文档导入到内表

使用 CL_FDT_XL_SPREADSHEET 是在ABAP中处理 .xlsx 格式文件的一种标准方法,这个类基于XML技术,能够在服务器端直接解析 Excel 文件,无需前端 Excel 组件。

下面是一个完整的代码示例,演示如何从本地选择 .xlsx 文件,读取其内容,并转换到你指定的内表格式。代码实现了通用性,能够将数据根据目标内表的格式进行导入。Excel 文档的字段结构按顺序,需要与内表的结构相同。

本例假设需要导入会计科目主数据。

abao 复制代码
report zfif001.

types: begin of ty_output,
         company_code      type bukrs,                              " 公司代码
         account_number    type saknr,                              " account number
         chart_of_accounts type ktopl,                              " chart of account
         glaccount_type    type glaccount_coa_data-glaccount_type,  " g/l account type
         ktoks             type glaccount_coa_data-ktoks,           " account group
         txt20             type glaccount_name_data-txt20,
         txt50             type glaccount_name_data-txt50,
         bilkt             type glaccount_coa_data-bilkt,          " 集团科目号
         gr_acc_desc       type string,                            " 集团科目描述
         waers             type glaccount_ccode_data-waers,        " currency
         xsalh             type glaccount_ccode_data-xsalh,        " only local currency
         mwskz             type glaccount_ccode_data-mwskz,        " tax type
         xmwno             type glaccount_ccode_data-xmwno,        " 允许含/不含税过账
         mitkz             type glaccount_ccode_data-mitkz,        " 统驭科目类型
         xopvw             type glaccount_ccode_data-xopvw,        " 未清项目管理
         zuawa             type glaccount_ccode_data-zuawa,        " 排序码
         katyp             type GLACCOUNT_CAREA_DATA-katyp,        " 成本要素类型
         fstag             type glaccount_ccode_data-fstag,        " 字段状态码
         xintb             type glaccount_ccode_data-xintb,        " 只能自动过账
         xmitk             type glaccount_ccode_data-xmitk,        " 统驭科目是否可允许输入
       end of ty_output.


selection-screen begin of block b1 with frame title text-t00.
  parameters:  p_file  type rlgrap-filename.

selection-screen end of block b1.

*selection-screen function key 1.

at selection-screen on value-request for p_file.
  perform frm_get_filepath.

start-of-selection.
  perform frm_excel_to_itab.


**********************************************************************
* 获取上载的文件路径
**********************************************************************
form frm_get_filepath .

  data: lv_action    type i,
        lt_filetable type filetable,
        lv_rc        type i.

  call method cl_gui_frontend_services=>file_open_dialog
    exporting
      window_title      = '选择上载的文件名'
      default_extension = '.xlsx'
      file_filter       = 'Excel文件(*.xlsx)|*.xlsx'
      multiselection    = ''
    changing
      file_table        = lt_filetable
      rc                = lv_rc
    exceptions
      others            = 1.
  if lv_action ne 0.
    message text-m01 type 'S' display like 'E'.
    exit.
  endif.

  read table lt_filetable assigning field-symbol(<ls_file>) index 1.
  p_file = <ls_file>-filename.

endform.

**********************************************************************
* Excel文件导入到内表
**********************************************************************
form frm_excel_to_itab.

* 文件选择相关变量
  data: lv_filename   type string,                       " 文件完整路径
        lv_filelength type i.


* Excel处理相关变量
  data: lt_raw_data       type standard table of raw255,     " 二进制数据表
        lv_xstring        type xstring,                      " XSTRING数据
        lo_excel          type ref to cl_fdt_xl_spreadsheet, " Excel对象
        lt_worksheetnames type table of string,              " 工作表名称表
        lt_data           type ref to data,                  " 动态内表引用
        lx_exception      type ref to cx_fdt_excel_core.     " 异常对象

* 动态处理相关变量
  field-symbols: <dyn_table> type standard table,
                 <dyn_wa>    type any,
                 <dyn_field> type any,
                 <comp>      type any.

* 定义动态内表的结构,用于按列号访问字段
  data: lo_struct type ref to cl_abap_structdescr,
        lt_comp   type cl_abap_structdescr=>component_table.

  data: lt_output     type standard table of ty_output.  " 目标内表
  data: ls_output like line of lt_output.

**----------------------------------------------------------------------
** 1. 上传文件
**----------------------------------------------------------------------
  lv_filename = p_file.

  call method cl_gui_frontend_services=>gui_upload
    exporting
      filename   = lv_filename
      filetype   = 'BIN'   " 对于.xlsx文件,必须使用BIN模式
    importing
      filelength = lv_filelength
    changing
      data_tab   = lt_raw_data
    exceptions
      others     = 1.
  if sy-subrc <> 0.
    message '文件上传失败, 请检查文件是否为打开状态' type 'E'.
  endif.

*----------------------------------------------------------------------
* 2. 将二进制表转换为XSTRING
*----------------------------------------------------------------------
  call function 'SCMS_BINARY_TO_XSTRING'
    exporting
      input_length = lv_filelength
    importing
      buffer       = lv_xstring
    tables
      binary_tab   = lt_raw_data
    exceptions
      failed       = 1
      others       = 2.
  if sy-subrc <> 0.
    message '数据转换失败' type 'E'.
  endif.

*----------------------------------------------------------------------
* 3. 实例化 CL_FDT_XL_SPREADSHEET 类
*----------------------------------------------------------------------
  try.
      lo_excel = new #( document_name = lv_filename
                        xdocument     = lv_xstring ).
    catch cx_fdt_excel_core into lx_exception.
      message lx_exception->get_text( ) type 'E'.
  endtry.

*----------------------------------------------------------------------
* 4. 获取工作表名称
*----------------------------------------------------------------------
  lo_excel->if_fdt_doc_spreadsheet~get_worksheet_names(
      importing
          worksheet_names = lt_worksheetnames ).

  if lt_worksheetnames is initial.
    message 'Excel文件中没有工作表' type 'E'.
  endif.

*----------------------------------------------------------------------
* 5. 读取工作表数据到动态内表
*----------------------------------------------------------------------
  try.
      lt_data = lo_excel->if_fdt_doc_spreadsheet~get_itab_from_worksheet(
           lt_worksheetnames[ 1 ] ).
    catch cx_fdt_excel_core into lx_exception.
      message lx_exception->get_text( ) type 'E'.
  endtry.

*----------------------------------------------------------------------
* 6. 转换为指定格式内表
*----------------------------------------------------------------------
* 将动态引用分配给字段符号
  assign lt_data->* to <dyn_table>.

* 获取目标内表的结构描述
  clear ls_output.
  lo_struct ?= cl_abap_typedescr=>describe_by_data( ls_output ).
  lt_comp = lo_struct->get_components( ).

* 循环处理动态内表中的每一行(从第二行开始)
  loop at <dyn_table> assigning <dyn_wa> from 2 .
    clear ls_output.

    " 内循环:将动态行的每个字段映射到 ls_output 的对应字段
    do lines( lt_comp ) times.
      data(lv_index) = sy-index. " 当前列号(从1开始)

      " 获取动态行的当前列的值
      assign component lv_index of structure <dyn_wa> to <dyn_field>.
      if sy-subrc <> 0.
        continue.
      endif.

      " 获取目标结构 ls_output 的第 lv_index 个字段
      read table lt_comp into data(ls_comp) index lv_index.
      if sy-subrc = 0.
        assign component ls_comp-name of structure ls_output to <comp>.
        if sy-subrc = 0.
          <comp> = <dyn_field>. " 将Excel单元格的值赋给目标字段
        endif.
      endif.
    enddo.

    append ls_output to lt_output. " 将转换后的行追加到目标内表
  endloop.

  cl_demo_output=>display( lt_output ).
endform.

使用说明

文件格式限制:该类只支持 .xlsx 格式,不支持旧的 .xls 。

SAP官方立场:这个类最初是为 BRFplus 设计的,虽然可以用于读取 Excel,但SAP官方并不推荐在自定义程序中作为首选方案,未来版本可能会有变更 。

性能考量:对于非常大的数据集(如超过15万行),该类性能可能不佳,甚至报错 。

替代方案:如果需要更强大、更稳定的 Excel 处理功能,可以考虑开源的 abap2xlsx 框架 。

相关推荐
雨天行舟4 天前
abap调用deepseek接口 v3.0
http·ai·sap·abap·聊天·deepseek
stone08236 天前
SAP FICO程序 - 会计科目余额报表
sap
Henry-SAP7 天前
ERP(SAP) MRP 业务视角全局流程解析
人工智能·sap·软件需求·erp·sap pp
小羔羊的官方学习账号9 天前
SAP中工单控制关键配置点
sap·pp
SAP_奥维奥科技9 天前
奥维奥助力花园乳业数字化转型落地 以SAP B1破解全产业链管理难题
sap·sap管理系统·sap business one·sap管理系统软件·sap实施服务商
sinat_375112269 天前
ME_PROCESS_PO_CUST增强check
sap·abap·增强
Seele_101813 天前
RAP - 报表示例
sap·abap
SAP_奥维奥科技13 天前
破局传统制造,赋能智能转型——机加工企业智能工厂升级实施方案重磅出炉
sap·智能制造·sap管理系统·sap管理系统软件·sap实施服务商推荐
SAP_奥维奥科技14 天前
如何选择适合自己企业的SAP实施服务商?
sap