SAP DOI 通过ABAP操作Excel 输出Excel报表

什么是DOI

DOI 是Desktop Office Integration的缩写,是 SAP 提供的解决与 Office 集成的技术方案,可以通过ABAP操作Excel表

实现步骤

  • 上传模板
  • 创建动态容器
  • 获得模板链接
  • 打开Excel模板
  • 写入数据

具体ABAP实现

上传模板

类名称:HRFPM_EXCEL_STANDARD

分类类型:OT

对象代码:随便命名,我们这里取名TEST_DOI

image-20230421101625685

在下面点击表模板然后选择本地文件上传就可以了

image-20230421102756156

创建容器

在创建完程序后在资源库浏览器里创建屏幕9001

image-20230421103557694

image-20230421104318226

STATUS_9001 OUTPUT

MODULE STATUS_9001 OUTPUT.
  SET PF-STATUS 'STANDARD'.
  "创建动态容器
  PERFORM FRM_GET_DYNAMIC_CONTAINER.
  PERFORM FRM_CREATE_CONTAINER_CONTROL.
  "获得模板URL
  PERFORM FRM_GET_TEMPLATE_URL.
  "打开excel
  PERFORM FRM_OPEN_EXCEL_DOC.
  "写入数据
  PERFORM FRM_WRITE_DATA_TO_EXCEL.
ENDMODULE.

USER_COMMAND_9001

MODULE USER_COMMAND_9001 INPUT.
  SAVE_OK = OK_CODE.
  CLEAR OK_CODE.
  IF SAVE_OK = '&F03'.
    "释放对象
    PERFORM FRM_RELEASE_OBJECTS.
    LEAVE PROGRAM.
  ENDIF.
ENDMODULE.

FORM FRM_RELEASE_OBJECTS .
  IF GR_DOCUMENT IS NOT INITIAL.
    CALL METHOD GR_DOCUMENT->CLOSE_DOCUMENT.
    FREE GR_DOCUMENT.
  ENDIF.
  IF GR_CONTROL IS NOT INITIAL.
    CALL METHOD GR_CONTROL->DESTROY_CONTROL.
    FREE GR_CONTROL.
  ENDIF.
  IF GR_CONTAINER IS NOT INITIAL.
    CALL METHOD GR_CONTAINER->FREE.
  ENDIF.
ENDFORM.

创建动态容器

FORM FRM_GET_DYNAMIC_CONTAINER .
  CREATE OBJECT GR_SPLITTER
    EXPORTING
      PARENT  = CL_GUI_CONTAINER=>SCREEN0
      ROWS    = 1
      COLUMNS = 1.

  CALL METHOD GR_SPLITTER->SET_BORDER
    EXPORTING
      BORDER = CL_GUI_CFW=>FALSE.

  GR_CONTAINER = GR_SPLITTER->GET_CONTAINER( ROW = 1 COLUMN = 1 ).
ENDFORM.
FORM FRM_CREATE_CONTAINER_CONTROL .
* create container control
  CALL METHOD C_OI_CONTAINER_CONTROL_CREATOR=>GET_CONTAINER_CONTROL
    IMPORTING
      CONTROL = GR_CONTROL.

* initialize control
  CALL METHOD GR_CONTROL->INIT_CONTROL
    EXPORTING
      INPLACE_ENABLED          = 'X '
      INPLACE_SCROLL_DOCUMENTS = 'X'
      REGISTER_ON_CLOSE_EVENT  = 'X'
      REGISTER_ON_CUSTOM_EVENT = 'X'
      R3_APPLICATION_NAME      = 'TEST_DOI'
      PARENT                   = GR_CONTAINER.
ENDFORM.

获取模板链接

FORM FRM_GET_TEMPLATE_URL .
  CREATE OBJECT GR_BDS_DOCUMENTS.

  CALL METHOD CL_BDS_DOCUMENT_SET=>GET_INFO
    EXPORTING
      CLASSNAME  = G_CLASSNAME
      CLASSTYPE  = G_CLASSTYPE
      OBJECT_KEY = G_OBJECTKEY
    CHANGING
      COMPONENTS = G_DOC_COMPONENTS
      SIGNATURE  = G_DOC_SIGNATURE.

  CALL METHOD CL_BDS_DOCUMENT_SET=>GET_WITH_URL
    EXPORTING
      CLASSNAME  = G_CLASSNAME
      CLASSTYPE  = G_CLASSTYPE
      OBJECT_KEY = G_OBJECTKEY
    CHANGING
      URIS       = GT_BDS_URIS
      SIGNATURE  = G_DOC_SIGNATURE.

  FREE GR_BDS_DOCUMENTS.

  READ TABLE GT_BDS_URIS INTO GS_BDS_URL INDEX 1.
  G_TEMPLATE_URL = GS_BDS_URL-URI.
ENDFORM.

参数G_CLASSNAME G_CLASSTYPE G_OBJECTKEY对应的所有模板URI都被放在内表GT_BDS_URIS内,上述代码只取了第一个URI,那么如果出现有多个模板的情况应该怎么取到想要的URI呢?

image-20230424112849753

对应的内表GT_BDS_URIS得到的数据如下,可以看到URI字段指向的文件名的被转换了,原本的文件名DOI_TEST.xlsx被改为了DOI_5FTEST.xlsxBS (Company level)变成了BS_20(Company_20level),可能是要把空格去掉,然后连成一个完整的URI字符串

image-20230424113008151

那么当我们要指定读取文件BS (Company level).xlsx的时候需要用到以下代码

DATA:LV_FNAME1 TYPE STRING,
     LV_FNAME2 TYPE STRING.
IF <条件>.
	*自行设置匹配字符串
	LV_FNAME1 = 'BS'.
	LV_FNAME2 = 'Company'.
ENDIF.
*A CS B代表:检查字符串 A 中 是否包含字符串 B
*A CA B代表:检查字符串 A 是否在字符串 B 中存在
*READ TABLE不能使用CS或者CA等关键字 所以只能用LOOP循环 然后等查到数据赋完值之后EXIT跳出循环
LOOP AT GT_BDS_URIS INTO GS_BDS_URL WHERE URI CS LV_FNAME1 AND URI CS LV_FNAME2.
	G_TEMPLATE_URL = GS_BDS_URL-URI.
	CLEAR GS_BDS_URL.
	EXIT.
ENDLOOP.
CLEAR:LV_FNAME1,LV_FNAME2.

打开Excel模板

FORM FRM_OPEN_EXCEL_DOC .
  DATA: AVAILABLE TYPE I.
  CALL METHOD GR_CONTROL->GET_DOCUMENT_PROXY
    EXPORTING
      DOCUMENT_TYPE      = 'Excel.Sheet'
      NO_FLUSH           = 'X'
      REGISTER_CONTAINER = 'X'
    IMPORTING
      DOCUMENT_PROXY     = GR_DOCUMENT.

  CALL METHOD GR_DOCUMENT->OPEN_DOCUMENT
    EXPORTING
      OPEN_INPLACE = 'X'
      DOCUMENT_URL = G_TEMPLATE_URL.

  CALL METHOD GR_DOCUMENT->HAS_SPREADSHEET_INTERFACE
    EXPORTING
      NO_FLUSH     = 'X'
    IMPORTING
      IS_AVAILABLE = AVAILABLE.

  CALL METHOD GR_DOCUMENT->GET_SPREADSHEET_INTERFACE
    EXPORTING
      NO_FLUSH        = 'X'
    IMPORTING
      SHEET_INTERFACE = GR_SPREADSHEET.

  CALL METHOD GR_SPREADSHEET->SELECT_SHEET
    EXPORTING
      NAME     = 'Sheet1'
      NO_FLUSH = 'X'.
ENDFORM.

在选择SHEET这里,如何动态指定其他Sheet页呢?进入接口I_OI_SPREADSHEET浏览它的方法,可以找到其中有一个方法名为GET_SHEET的方法,可以获得所有Sheet页的名字集合内表,点击参数按钮可以查看此方法的参数。

image-20230424135418227

image-20230424135439044

image-20230424135734509

接下来调用该方法

DATA:LT_SHEETS TYPE TABLE OF SOI_SHEETS.
CALL METHOD GR_SPREADSHEET->GET_SHEETS
    IMPORTING
      SHEETS = LT_SHEETS.
READ TABLE LT_SHEETS INTO DATA(LS_SHEET) INDEX 2.
IF SY-SUBRC EQ 0.
  CALL METHOD GR_SPREADSHEET->SELECT_SHEET
  	EXPORTING
      NAME     = LS_SHEET-SHEET_NAME
      NO_FLUSH = 'X'.
	CLEAR LS_SHEET.
	REFRESH LT_SHEETS.
ENDIF.

写入数据

FORM FRM_WRITE_DATA_TO_EXCEL .
  TYPES: BEGIN OF TY_DATA,
    COL TYPE I,
    ROW TYPE I,
    VALUE TYPE STRING.
  TYPES END OF TY_DATA.
  DATA:LS_DATA TYPE TY_DATA.
  DATA:LT_DATA TYPE TABLE OF TY_DATA.
  LS_DATA = VALUE #( COL = 1 ROW = 1 VALUE = 'DOI_TEST' ).
  APPEND LS_DATA TO LT_DATA.
  CLEAR LS_DATA.
  LS_DATA = VALUE #( COL = 1 ROW = 1 VALUE = '-LE0N' ).
  APPEND LS_DATA TO LT_DATA.
  CLEAR LS_DATA.
  LS_DATA = VALUE #( COL = 1 ROW = 1 VALUE = SY-TIMLO ).
  APPEND LS_DATA TO LT_DATA.
  CLEAR LS_DATA.
  LOOP AT LT_DATA INTO LS_DATA.
    PERFORM FRM_WRITE_CELL USING LS_DATA-ROW LS_DATA-COL LS_DATA-VALUE .
  ENDLOOP.
ENDFORM.
FORM FRM_WRITE_CELL USING P_ROW
                              P_COL P_VALUE.

* DEFINE INTERNAL TABLE FOR RANGES AND CONTENTS PARAMETERS
  DATA: LT_RANGES    TYPE SOI_RANGE_LIST,
        LS_RANGEITEM TYPE SOI_RANGE_ITEM,
        LT_CONTENTS  TYPE SOI_GENERIC_TABLE,
        LS_CONTENT   TYPE SOI_GENERIC_ITEM.
  DATA:LT_CONT TYPE SOI_GENERIC_TABLE.
  DATA:LV_ROW TYPE I,
       LV_COL TYPE I.
  LV_ROW = P_ROW.
  LV_COL = P_COL.
* populate ranges
  CLEAR LS_RANGEITEM.
  CLEAR LT_RANGES[].
  LS_RANGEITEM-NAME = 'CELL' .
  LS_RANGEITEM-COLUMNS = 1.
  LS_RANGEITEM-ROWS = 1.
  LS_RANGEITEM-CODE = 4.
  APPEND LS_RANGEITEM TO LT_RANGES.

  "Get data from cell
  CALL METHOD GR_SPREADSHEET->GET_RANGES_DATA
    IMPORTING
      CONTENTS = LT_CONT
      ERROR    = GT_ERROR
    CHANGING
      RANGES   = LT_RANGES.
* populate contents
  CLEAR LS_CONTENT.
  CLEAR LT_CONTENTS[].
  LS_CONTENT-COLUMN = 1.
  LS_CONTENT-ROW = 1.
  LS_CONTENT-VALUE = P_VALUE.
  CONDENSE LS_CONTENT-VALUE NO-GAPS.
  APPEND LS_CONTENT TO LT_CONTENTS.

  CALL METHOD GR_SPREADSHEET->INSERT_RANGE_DIM
    EXPORTING
      NAME     = 'CELL'
      NO_FLUSH = ''
      TOP      = LV_ROW
      LEFT     = LV_COL
      ROWS     = 1
      COLUMNS  = 1
    IMPORTING
      ERROR    = GT_ERROR.
  LOOP AT GT_ERROR.
    CALL METHOD GT_ERROR->RAISE_MESSAGE
      EXPORTING
        TYPE = 'E'.
  ENDLOOP.
  FREE GT_ERROR.

  CALL FUNCTION 'CLOI_PUT_SIGN_IN_FRONT' "负号前置函数 1000- -> -1000
    CHANGING
      VALUE = LS_CONTENT-VALUE.
  CALL METHOD GR_SPREADSHEET->SET_RANGES_DATA
    EXPORTING
      RANGES   = LT_RANGES
      CONTENTS = LT_CONTENTS
      NO_FLUSH = 'X'.
*  该方法可以通过设置范围LT_RANGES获得指定范围内CELL的值 LT_CONT
*  我在项目上遇到写入没报错 但是没有成功写入到Excel表内的情况 
*  就可以用这个方法检查是否成功写入 没成功就可以设置条件重新执行写入 直到成功写入
*  CALL METHOD GR_SPREADSHEET->GET_RANGES_DATA 
*    IMPORTING
*      CONTENTS = LT_CONT
*      ERROR    = GT_ERROR
*    CHANGING
*      RANGES   = LT_RANGES.
ENDFORM.

完整代码

*&---------------------------------------------------------------------*
*& Report ZDOI_TEST
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT ZDOI_TEST.
INCLUDE ZDOI_TEST_TOP.
INCLUDE ZDOI_TEST_FUNC.
INITIALIZATION.
  G_CLASSNAME = 'HRFPM_EXCEL_STANDARD'.
  G_CLASSTYPE = 'OT'.
  G_OBJECTKEY = 'TEST_DOI'.
START-OF-SELECTION.
  PERFORM FRM_GET_DATA.
  CALL SCREEN 9001.
*&---------------------------------------------------------------------*
*& 包含               ZDOI_TEST_TOP
*&---------------------------------------------------------------------*
DATA: GR_CUSTOM_CONTAINER TYPE REF TO CL_GUI_CUSTOM_CONTAINER.
DATA: GR_CONTAINER   TYPE REF TO CL_GUI_CONTAINER,
      GR_CONTROL     TYPE REF TO I_OI_CONTAINER_CONTROL,
      GR_DOCUMENT    TYPE REF TO I_OI_DOCUMENT_PROXY,
      GR_SPREADSHEET TYPE REF TO I_OI_SPREADSHEET.

* business document system
DATA: GR_BDS_DOCUMENTS TYPE REF TO CL_BDS_DOCUMENT_SET,
      G_CLASSNAME      TYPE SBDST_CLASSNAME,
      G_CLASSTYPE      TYPE SBDST_CLASSTYPE,
      G_OBJECTKEY      TYPE SBDST_OBJECT_KEY,
      G_DOC_COMPONENTS TYPE SBDST_COMPONENTS,
      G_DOC_SIGNATURE  TYPE SBDST_SIGNATURE.
DATA: GR_SPLITTER TYPE REF TO CL_GUI_SPLITTER_CONTAINER.
DATA:GV_FLAG TYPE C.
* template url
DATA: GT_BDS_URIS         TYPE SBDST_URI,
      GS_BDS_URL          LIKE LINE OF GT_BDS_URIS,
      G_TEMPLATE_URL(256) TYPE C.

DATA: OK_CODE TYPE SY-UCOMM,
      SAVE_OK LIKE OK_CODE.

* Required for writing data to Excel
DATA: GT_RANGES   TYPE SOI_RANGE_LIST,
      GS_RANGE    TYPE SOI_RANGE_ITEM,
      GT_CONTENTS TYPE SOI_GENERIC_TABLE,
      GS_CONTENT  TYPE SOI_GENERIC_ITEM.

DATA: GS_ERROR TYPE REF TO I_OI_ERROR,
      GT_ERROR TYPE REF TO I_OI_ERROR OCCURS 0 WITH HEADER LINE.


SELECTION-SCREEN BEGIN OF BLOCK BLK01 WITH FRAME TITLE TEXT-001.
PARAMETERS:P_GJAHR LIKE BKPF-GJAHR DEFAULT  SY-DATUM+0(4),
           P_MONAT LIKE BKPF-MONAT DEFAULT SY-DATUM+4(2).
SELECTION-SCREEN END OF BLOCK BLK01.
*&---------------------------------------------------------------------*
*& 包含               ZDOI_TEST_FUNC
*&---------------------------------------------------------------------*
*&---------------------------------------------------------------------*
*& Form FRM_GET_DATA
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM FRM_GET_DATA .

ENDFORM.
*&---------------------------------------------------------------------*
*& Module STATUS_9001 OUTPUT
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
MODULE STATUS_9001 OUTPUT.
  SET PF-STATUS 'STANDARD'
  ."创建动态容器
  PERFORM FRM_GET_DYNAMIC_CONTAINER.
  PERFORM FRM_CREATE_CONTAINER_CONTROL.
  "获得模板URL
  PERFORM FRM_GET_TEMPLATE_URL.
  "打开excel
  PERFORM FRM_OPEN_EXCEL_DOC.
  "写入数据
  PERFORM FRM_WRITE_DATA_TO_EXCEL.
ENDMODULE.
*&---------------------------------------------------------------------*
*&      Module  USER_COMMAND_9001  INPUT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
MODULE USER_COMMAND_9001 INPUT.
  SAVE_OK = OK_CODE.
  CLEAR OK_CODE.

  IF SAVE_OK = '&F03'.
    "释放
    PERFORM FRM_RELEASE_OBJECTS.
    LEAVE PROGRAM.
  ENDIF.
ENDMODULE.
*&---------------------------------------------------------------------*
*& Form FRM_GET_DYNAMIC_CONTAINER
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM FRM_GET_DYNAMIC_CONTAINER .
  CREATE OBJECT GR_SPLITTER
    EXPORTING
      PARENT  = CL_GUI_CONTAINER=>SCREEN0
      ROWS    = 1
      COLUMNS = 1.

  CALL METHOD GR_SPLITTER->SET_BORDER
    EXPORTING
      BORDER = CL_GUI_CFW=>FALSE.

  GR_CONTAINER = GR_SPLITTER->GET_CONTAINER( ROW = 1 COLUMN = 1 ).
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_CREATE_CONTAINER_CONTROL
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM FRM_CREATE_CONTAINER_CONTROL .
* create container control
  CALL METHOD C_OI_CONTAINER_CONTROL_CREATOR=>GET_CONTAINER_CONTROL
    IMPORTING
      CONTROL = GR_CONTROL.

* initialize control
  CALL METHOD GR_CONTROL->INIT_CONTROL
    EXPORTING
      INPLACE_ENABLED          = 'X '
      INPLACE_SCROLL_DOCUMENTS = 'X'
      REGISTER_ON_CLOSE_EVENT  = 'X'
      REGISTER_ON_CUSTOM_EVENT = 'X'
      R3_APPLICATION_NAME      = 'TEST_DOI'
      PARENT                   = GR_CONTAINER.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_GET_TEMPLATE_URL
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM FRM_GET_TEMPLATE_URL .
  CREATE OBJECT GR_BDS_DOCUMENTS.

  CALL METHOD CL_BDS_DOCUMENT_SET=>GET_INFO
    EXPORTING
      CLASSNAME  = G_CLASSNAME
      CLASSTYPE  = G_CLASSTYPE
      OBJECT_KEY = G_OBJECTKEY
    CHANGING
      COMPONENTS = G_DOC_COMPONENTS
      SIGNATURE  = G_DOC_SIGNATURE.

  CALL METHOD CL_BDS_DOCUMENT_SET=>GET_WITH_URL
    EXPORTING
      CLASSNAME  = G_CLASSNAME
      CLASSTYPE  = G_CLASSTYPE
      OBJECT_KEY = G_OBJECTKEY
    CHANGING
      URIS       = GT_BDS_URIS
      SIGNATURE  = G_DOC_SIGNATURE.

  FREE GR_BDS_DOCUMENTS.

  READ TABLE GT_BDS_URIS INTO GS_BDS_URL INDEX 1.
  G_TEMPLATE_URL = GS_BDS_URL-URI.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_OPEN_EXCEL_DOC
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM FRM_OPEN_EXCEL_DOC .
  DATA: AVAILABLE TYPE I.
  CALL METHOD GR_CONTROL->GET_DOCUMENT_PROXY
    EXPORTING
      DOCUMENT_TYPE      = 'Excel.Sheet'
      NO_FLUSH           = 'X'
      REGISTER_CONTAINER = 'X'
    IMPORTING
      DOCUMENT_PROXY     = GR_DOCUMENT.

  CALL METHOD GR_DOCUMENT->OPEN_DOCUMENT
    EXPORTING
      OPEN_INPLACE = 'X'
      DOCUMENT_URL = G_TEMPLATE_URL.

  CALL METHOD GR_DOCUMENT->HAS_SPREADSHEET_INTERFACE
    EXPORTING
      NO_FLUSH     = 'X'
    IMPORTING
      IS_AVAILABLE = AVAILABLE.

  CALL METHOD GR_DOCUMENT->GET_SPREADSHEET_INTERFACE
    EXPORTING
      NO_FLUSH        = 'X'
    IMPORTING
      SHEET_INTERFACE = GR_SPREADSHEET.

  CALL METHOD GR_SPREADSHEET->SELECT_SHEET
    EXPORTING
      NAME     = 'Sheet1'
      NO_FLUSH = 'X'.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_RELEASE_OBJECTS
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM FRM_RELEASE_OBJECTS .
  IF NOT GR_DOCUMENT IS INITIAL.
    CALL METHOD GR_DOCUMENT->CLOSE_DOCUMENT.
    FREE GR_DOCUMENT.
  ENDIF.

  IF NOT GR_CONTROL IS INITIAL.
    CALL METHOD GR_CONTROL->DESTROY_CONTROL.
    FREE GR_CONTROL.
  ENDIF.

  IF GR_CONTAINER IS NOT INITIAL.
    CALL METHOD GR_CONTAINER->FREE.
  ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_WRITE_DATA_TO_EXCEL
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM FRM_WRITE_DATA_TO_EXCEL .
  TYPES: BEGIN OF TY_DATA,
           COL   TYPE I,
           ROW   TYPE I,
           VALUE TYPE STRING.
  TYPES END OF TY_DATA.
  DATA:LS_DATA TYPE TY_DATA.
  DATA:LT_DATA TYPE TABLE OF TY_DATA.
  REFRESH LT_DATA.
  LS_DATA = VALUE #( COL = 1 ROW = 1 VALUE = 'DOI_TEST' ).
  APPEND LS_DATA TO LT_DATA.
  CLEAR LS_DATA.
  LS_DATA = VALUE #( COL = 1 ROW = 2 VALUE = SY-TIMLO ).
  APPEND LS_DATA TO LT_DATA.
  CLEAR LS_DATA.
  WHILE GV_FLAG IS INITIAL.
    CLEAR GV_FLAG.
    LOOP AT LT_DATA INTO LS_DATA.
      PERFORM FRM_WRITE_CELL USING LS_DATA-ROW LS_DATA-COL LS_DATA-VALUE .
      IF GV_FLAG = 'X'.
        MESSAGE 'Rewriting...' TYPE 'W'.
        EXIT.
      ENDIF.
    ENDLOOP.

  ENDWHILE.


ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_WRITE_CELL
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*&      --> P_ROW
*&      --> P_COL
*&      --> P_VALUE
*&      --> P_FX
*&---------------------------------------------------------------------*
FORM FRM_WRITE_CELL USING P_ROW
                              P_COL P_VALUE.

* DEFINE INTERNAL TABLE FOR RANGES AND CONTENTS PARAMETERS
  DATA: LT_RANGES    TYPE SOI_RANGE_LIST,
        LS_RANGEITEM TYPE SOI_RANGE_ITEM,
        LT_CONTENTS  TYPE SOI_GENERIC_TABLE,
        LS_CONTENT   TYPE SOI_GENERIC_ITEM.
  DATA:LT_CONT TYPE SOI_GENERIC_TABLE.
  DATA:LV_ROW TYPE I,
       LV_COL TYPE I.
  LV_ROW = P_ROW.
  LV_COL = P_COL.
* populate ranges
  CLEAR LS_RANGEITEM.
  CLEAR LT_RANGES[].
  LS_RANGEITEM-NAME = 'CELL' .
  LS_RANGEITEM-COLUMNS = 1.
  LS_RANGEITEM-ROWS = 1.
  LS_RANGEITEM-CODE = 4.
  APPEND LS_RANGEITEM TO LT_RANGES.

  "Get data from cell
  CALL METHOD GR_SPREADSHEET->GET_RANGES_DATA
    IMPORTING
      CONTENTS = LT_CONT
      ERROR    = GT_ERROR
    CHANGING
      RANGES   = LT_RANGES.


* populate contents
  CLEAR LS_CONTENT.
  CLEAR LT_CONTENTS[].
  LS_CONTENT-COLUMN = 1.
  LS_CONTENT-ROW = 1.
  LS_CONTENT-VALUE = P_VALUE.
  CONDENSE LS_CONTENT-VALUE NO-GAPS.
  APPEND LS_CONTENT TO LT_CONTENTS.



  CALL METHOD GR_SPREADSHEET->INSERT_RANGE_DIM
    EXPORTING
      NAME     = 'CELL'
      NO_FLUSH = ''
      TOP      = LV_ROW
      LEFT     = LV_COL
      ROWS     = 1
      COLUMNS  = 1
    IMPORTING
      ERROR    = GT_ERROR.
  LOOP AT GT_ERROR.
    CALL METHOD GT_ERROR->RAISE_MESSAGE
      EXPORTING
        TYPE = 'E'.
  ENDLOOP.
  FREE GT_ERROR.

  CALL METHOD GR_SPREADSHEET->SET_RANGES_DATA
    EXPORTING
      RANGES   = LT_RANGES
      CONTENTS = LT_CONTENTS
      NO_FLUSH = 'X'.
  CALL METHOD GR_SPREADSHEET->GET_RANGES_DATA
    IMPORTING
      CONTENTS = LT_CONT
      ERROR    = GT_ERROR
    CHANGING
      RANGES   = LT_RANGES.
  IF LT_CONT IS NOT INITIAL .
    GV_FLAG = 'X'.
    REFRESH LT_CONT.
  ENDIF.
ENDFORM.

参考文档:
ABAP DOI详解(1)

ABAP DOI详解(2)

ABAP DOI详解(3)

ABAP DOI 技术

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ABAP是一种SAP系统的编程语言SAP DOI(Document Object Infrastructure)是SAP系统的一个组件,用于处理文档对象。其中,I_OI_SPREADSHEET接口可用于读取和写入Excel电子表格数据。 以下是使用I_OI_SPREADSHEET接口读取Excel数据的简单示例: ``` DATA: lr_spreadsheet TYPE REF TO i_oi_spreadsheet, lr_worksheet TYPE REF TO i_oi_spreadsheet_worksheet, lr_cell TYPE REF TO i_oi_spreadsheet_cell, lv_value TYPE string. * 创建电子表格对象 CREATE OBJECT lr_spreadsheet TYPE cl_oi_spreadsheet. * 打开Excel文件 lr_spreadsheet->open_file( 'C:\data\example.xlsx' ). * 获取第一个工作表 lr_worksheet = lr_spreadsheet->get_worksheet( 1 ). * 逐个读取单元格数据 DO 10 TIMES. lr_cell = lr_worksheet->get_cell( sy-index, 1 ). IF lr_cell IS BOUND. lv_value = lr_cell->get_value( ). WRITE: / lv_value. ENDIF. ENDDO. ``` 以上代码会逐行读取Excel文件的第一个工作表的第一列数据,并输出到屏幕上。 如果希望写入Excel数据,可以使用类似以下的代码: ``` DATA: lr_spreadsheet TYPE REF TO i_oi_spreadsheet, lr_worksheet TYPE REF TO i_oi_spreadsheet_worksheet, lr_cell TYPE REF TO i_oi_spreadsheet_cell. * 创建电子表格对象 CREATE OBJECT lr_spreadsheet TYPE cl_oi_spreadsheet. * 打开Excel文件 lr_spreadsheet->open_file( 'C:\data\example.xlsx' ). * 获取第一个工作表 lr_worksheet = lr_spreadsheet->get_worksheet( 1 ). * 写入数据到单元格 lr_cell = lr_worksheet->get_cell( 1, 1 ). IF lr_cell IS BOUND. lr_cell->set_value( 'Hello World!' ). ENDIF. * 保存Excel文件 lr_spreadsheet->save( ). ``` 以上代码会将字符串“Hello World!”写入Excel文件的第一个工作表的第一个单元格,并保存文件。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值