SAP ABAP 数据填充进EXCEL模板或代码生成EXCEL并维护数据下载到本地

发布于:2023-01-22 ⋅ 阅读:(366) ⋅ 点赞:(0)


需求

在网页应用中利用数据生成excel或填充数据到excel下载到本地(部分代码rept程序应该也是可以用的)


一、针对有EXCEL模板只填充数据的情况

如果我们已有数据需要填充到EXCEL中,并保存到本地,可以使用以下方法
一般模板保存在如下路径(T-CODE:SE80):SAP/PUBLIC/EXCEL TEMPLATE/ZTEST_DEMO.XLSX

如图
在这里插入图片描述
示例代码:

    DATA lv_mime_file TYPE xstring.

    DATA: lv_xdocument TYPE xstring.
    DATA lo_excel_e TYPE REF TO zcx_excel.
    DATA lo_excel_reader TYPE REF TO zif_excel_reader.
    DATA lo_excel_writer TYPE REF TO zif_excel_writer.
    DATA lo_excel TYPE REF TO zcl_excel.
    DATA lo_worksheet TYPE REF TO zcl_excel_worksheet.


    DATA: lt_field_catalog      TYPE zexcel_t_fieldcatalog,
          ls_table_settings     TYPE zexcel_s_table_settings,
          ls_table_settings_out TYPE zexcel_s_table_settings.

*    下载模板
    cl_mime_repository_api=>get_api( )->get(
    EXPORTING        i_url                  =  'SAP/PUBLIC/EXCEL TEMPLATE/ZTEST_DEMO.XLSX'
    IMPORTING        e_content              = lv_mime_file
    EXCEPTIONS OTHERS = 8 ).

    IF sy-subrc <> 0.
      RETURN.
    ELSE.

      CREATE OBJECT lo_excel_reader TYPE zcl_excel_reader_2007.

      TRY.

          lo_excel = lo_excel_reader->load( i_excel2007 = lv_mime_file ).
          IF sy-subrc EQ 0.
            lo_worksheet = lo_excel->get_worksheet_by_name(
              EXPORTING
                ip_sheet_name = '测试模板' ).

            IF is_data-mcost1 IS NOT INITIAL.
              lo_worksheet->set_cell( ip_row = 4 ip_column =  'A' ip_value = is_data-mcost1 ip_abap_type = cl_abap_typedescr=>typekind_string ).
            ENDIF.
            IF is_data-mcost2 IS NOT INITIAL.
              lo_worksheet->set_cell( ip_row = 5 ip_column =  'B' ip_value = is_data-mcost2 ip_abap_type = cl_abap_typedescr=>typekind_string ).
            ENDIF.
            IF is_data-mcost3 IS NOT INITIAL.
              lo_worksheet->set_cell( ip_row = 6 ip_column =  'C' ip_value = is_data-mcost3 ip_abap_type = cl_abap_typedescr=>typekind_string ).
            ENDIF.
            IF is_data-mcost4 IS NOT INITIAL.
              lo_worksheet->set_cell( ip_row = 7 ip_column =  'D' ip_value = is_data-mcost4 ip_abap_type = cl_abap_typedescr=>typekind_string ).
            ENDIF.
            IF is_data-mcost5 IS NOT INITIAL.
              lo_worksheet->set_cell( ip_row = 8 ip_column =  'E' ip_value = is_data-mcost5 ip_abap_type = cl_abap_typedescr=>typekind_string ).
            ENDIF.
            IF is_data-mcost6 IS NOT INITIAL.
              lo_worksheet->set_cell( ip_row = 9 ip_column =  'F' ip_value = is_data-mcost6 ip_abap_type = cl_abap_typedescr=>typekind_string ).
            ENDIF.
            IF is_data-mcost7 IS NOT INITIAL.
              lo_worksheet->set_cell( ip_row = 10 ip_column =  'G' ip_value = is_data-mcost7 ip_abap_type = cl_abap_typedescr=>typekind_string ).
            ENDIF.
            IF is_data-mcost8 IS NOT INITIAL.
              lo_worksheet->set_cell( ip_row = 11 ip_column =  'H' ip_value = is_data-mcost8 ip_abap_type = cl_abap_typedescr=>typekind_string ).
            ENDIF.
            IF is_data-mcost9 IS NOT INITIAL.
              lo_worksheet->set_cell( ip_row = 12 ip_column =  'I' ip_value = is_data-mcost9 ip_abap_type = cl_abap_typedescr=>typekind_string ).
            ENDIF.
            
          ENDIF.

*           导出文件
          CREATE OBJECT lo_excel_writer TYPE zcl_excel_writer_2007.
          lv_xdocument = lo_excel_writer->write_file( lo_excel ).

        CATCH zcx_excel INTO lo_excel_e.

      ENDTRY.

      cl_wd_runtime_services=>attach_file_to_response(
      i_filename      = '模板.xlsx'                  "可自定义文件名
*        i_content       = lv_mime_file
      i_content       = lv_xdocument
      i_mime_type     = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
      i_in_new_window = abap_false
      i_inplace       = abap_false
      ).
    ENDIF.

如果出现调用Excel.Application报错,请按文章最后传送门方法检查office是否正确配置

2022.08.11更新
上面下载的方法针对与网页应用(fpm)
如果是REPORT程序,应该用以下方法:


  DATA: lv_path TYPE string,
        t_rawdata   TYPE solix_tab,
        bytecount TYPE I.
        
  t_rawdata = cl_bcs_convert=>xstring_to_solix( iv_xstring  = lv_xdocument ).
  bytecount = xstrlen( lv_xdocument ).

  CONCATENATE lv_path TEXT '.XLSX' INTO lv_path.
* Get trailing blank
  cl_gui_frontend_services=>gui_download( EXPORTING bin_filesize = bytecount
    filename     = lv_path
    filetype     = 'BIN'
  CHANGING data_tab     = t_rawdata ).

二、没有模板需要凭空生成Excel的情况

如果需要把大量数据整理后转化为excel传向OA

这里面有三个参数 IS_HEADER和IT_DATA都是FIELD-SYMBOL,IV_ATTACHNAME是自定义要保存的EXCEL名字,IS_HEADER是excel的第一行,列名,IT_DATA为数据,做成function的好处是可以复用,不必每次都去新建相应结构
举例:
在这里插入图片描述
代码:

FUNCTION z_convert_data_to_excel.
*"----------------------------------------------------------------------
*"*"本地接口:
*"  IMPORTING
*"     REFERENCE(IS_HEADER) TYPE  ANY OPTIONAL
*"     REFERENCE(IV_ATTACHNAME) TYPE  STRING
*"  TABLES
*"      IT_DATA TYPE  STANDARD TABLE
*"----------------------------------------------------------------------

  DATA: excel  TYPE REF TO zcl_excel,          reader            TYPE REF TO zif_excel_reader.
  DATA: worksheet         TYPE REF TO zcl_excel_worksheet,
        highest_column    TYPE        zexcel_cell_column,
        highest_row       TYPE        int4,
        column            TYPE        zexcel_cell_column VALUE 1,
        col_str           TYPE        zexcel_cell_column_alpha,
        row               TYPE        int4               VALUE 1,
        value             TYPE        zexcel_cell_value,
        lv_highest_column TYPE        string,
        dref              TYPE REF TO data,
        lv_highest_row    TYPE        string,
        lv_error_flag     TYPE        sap_bool,
        lo_excel_writer   TYPE REF TO zif_excel_writer,
        lv_file           TYPE        xstring.

  DATA: ex TYPE REF TO cx_root.

  DATA:lv_xdocument TYPE xstring.
  DATA:itab_type   TYPE REF TO cl_abap_tabledescr,
       struct_type TYPE REF TO cl_abap_structdescr,
       elem_type   TYPE REF TO cl_abap_elemdescr,
       comp_tab    TYPE        cl_abap_structdescr=>component_table,
       comp_fld    TYPE        cl_abap_structdescr=>component,
       column_num  TYPE        i,
       row_num     TYPE        i,
       tcolumn     TYPE        string,
       lv_str      TYPE        string.

  FIELD-SYMBOLS : <lt_outtab> TYPE ANY TABLE,
                  <ls_outtab> TYPE            any,
                  <l_fld>     TYPE            any.

  TRY.
      itab_type ?= cl_abap_typedescr=>describe_by_data( it_data[] ).
      struct_type ?= itab_type->get_table_line_type( ).
      comp_tab = struct_type->get_components( ).

      DESCRIBE TABLE comp_tab LINES highest_column.

      CREATE DATA dref TYPE HANDLE struct_type.
      ASSIGN dref->* TO <ls_outtab>.

*     start excel data set
      CREATE OBJECT reader TYPE zcl_excel_reader_2007.
*      excel = reader->load( lv_xstring ).
      CREATE OBJECT excel.

      worksheet = excel->get_active_worksheet( ).

      row_num = 1.
      IF is_header IS NOT INITIAL.
        column_num = 1.
        WHILE column_num <= highest_column.
          ASSIGN COMPONENT column_num OF STRUCTURE is_header TO <l_fld>.
          CALL FUNCTION 'ZCONVERT_NUMBER_EXCEL_COLUMN'
            EXPORTING
              number = column_num
            IMPORTING
              column = tcolumn.
          lv_str = <l_fld>.
          IF lv_str IS NOT INITIAL.
            worksheet->set_cell( ip_column = tcolumn ip_row = row_num ip_value = lv_str ).
          ENDIF.
          column_num = column_num + 1.
        ENDWHILE.
        row_num = row_num + 1.
      ENDIF.
      LOOP AT it_data ASSIGNING <ls_outtab>.
        column_num = 1.
        WHILE column_num <= highest_column.
          ASSIGN COMPONENT column_num OF STRUCTURE <ls_outtab> TO <l_fld>.
          CALL FUNCTION 'ZCONVERT_NUMBER_EXCEL_COLUMN'
            EXPORTING
              number = column_num
            IMPORTING
              column = tcolumn.
          lv_str = <l_fld>.
          IF lv_str IS NOT INITIAL.
            worksheet->set_cell( ip_column = tcolumn ip_row = row_num ip_value = lv_str ).
          ENDIF.
          column_num = column_num + 1.
        ENDWHILE.
        row_num = row_num + 1.
      ENDLOOP.
      CREATE OBJECT lo_excel_writer TYPE zcl_excel_writer_2007.
      lv_xdocument = lo_excel_writer->write_file( excel ).

    CATCH zcx_excel INTO ex.    " Exceptions for ABAP2XLSX
      EXIT.
  ENDTRY.
  
      cl_wd_runtime_services=>attach_file_to_response(
      i_filename      = IV_ATTACHNAME && '.XLSX'                  "可自定义文件名
*        i_content       = lv_mime_file
      i_content       = lv_xdocument
      i_mime_type     = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
      i_in_new_window = abap_false
      i_inplace       = abap_false
      ).

ENDFUNCTION.

*用到的function
FUNCTION zconvert_number_excel_column.
*"----------------------------------------------------------------------
*"*"本地接口:
*"  IMPORTING
*"     REFERENCE(NUMBER) TYPE  I
*"  EXPORTING
*"     REFERENCE(COLUMN) TYPE  STRING
*"----------------------------------------------------------------------

  CLEAR column.

  CALL FUNCTION 'ZCONVERT_GET_DATA'
    EXPORTING
      input  = number
    CHANGING
      output = column.

ENDFUNCTION.

FUNCTION zconvert_get_data.
*"----------------------------------------------------------------------
*"*"本地接口:
*"  IMPORTING
*"     REFERENCE(INPUT) TYPE  I
*"  CHANGING
*"     REFERENCE(OUTPUT) TYPE  STRING
*"----------------------------------------------------------------------

  DATA lv_div TYPE i.
  DATA lv_rem TYPE i.
  CHECK input GT 0.
  lv_div = input DIV 26.
  lv_rem = input MOD 26.

  IF lv_rem IS INITIAL.
    lv_rem = 26.
    SUBTRACT 1 FROM lv_div.
  ENDIF.
  SUBTRACT 1 FROM lv_rem.
  CONCATENATE sy-abcde+lv_rem(1) output INTO output.
  CALL FUNCTION 'ZCONVERT_GET_DATA'
    EXPORTING
      input  = lv_div
    CHANGING
      output = output.

ENDFUNCTION.

三、检查Excel是否正确安装

  1. 这里有个老哥写的很详细了:传送门
  2. 如果还是不行,那就完全卸载(一定要完全卸载,网上都有工具)并重装office,即可修复,亲测可行,我之前也遇到过

四、如果系统中没有ZCL_EXCEL**的帮助类

开源项目下载导入即可,什么?你不知道ABAPGIT?
读到这里你就必须得去abapgit的开源项目看看了,开源项目里面也有很多处理excel的例子,让你发现新大陆,哈哈~
这里有直达=======>ABAPGIT传送门


总结

这篇文章主要针对网页上处理EXCEL,但也不止于此,还有很多处理,比如涉及宏,手动设置超链接等,以后有时间再补充到本栏。
REPORT程序处理/下载EXCEL我看网上很多,这里没必要多写了
希望对你有所帮助,如果有错误请大胆指出,大家互相进步

本文含有隐藏内容,请 开通VIP 后查看