SAP日记-ABAP导出EXCEL的两种方式(OLE,DOI)

SAP日记-ABAP导出EXCEL的两种方式(OLE,DOI)
SAP日记-ABAP导出EXCEL的两种方式(OLE,DOI)

SAP日记——ABAP导出EXCEL的两种方法

一、OLE

ABAP通过OLE的方式导出EXCEL,由于数据时一条一条的生成,速度较慢,不适合内表数据较多的场景使用,但是其实现起来比较简单。

REPORT ZTEST1.

TABLES: ZWYM. “自定义的一张表

TYPE-POOLS:SLIS,ole2. “需要用到OLE2

DATA: excel TYPE ole2_object,

workbook TYPE ole2_object,

sheet TYPE ole2_object,

cell TYPE ole2_object.

DATA: application TYPE ole2_object,

book TYPE ole2_object,

books TYPE ole2_object.

DATA: ole_book TYPE ole2_object.

DATA: FILENAME(100) TYPE C VALUE 'D:\data\test.xls'. “定义文件导出的路径

"DATA: GT_ITAB LIKE TABLE OF ZWYM WITH HEADER LINE.

DATA:BEGIN OF GT_ITAB OCCURS 0, “定义内表

INCLUDE STRUCTURE ZWYM.

END OF GT_ITAB.

SELECTION-SCREEN:BEGIN OF BLOCK B1 WITH FRAME TITLE TEXT-001. “查询条件

SELECT-OPTIONS:S_MATNR FOR ZWYM-MATNR.

SELECTION-SCREEN:END OF BLOCK B1.

START-OF-SELECTION.

PERFORM GET_DATA.

END-OF-SELECTION.

PERFORM gen_excel.

FORM GET_DATA.

SELECT * INTO CORRESPONDING FIELDS OF TABLE GT_ITAB FROM ZWYM W HERE MATNR IN S_MATNR.

ENDFORM. “GET_DATA.

FORM gen_excel.

CREATE OBJECT excel 'EXCEL.APPLICATION'.

IF sy-subrc NE 0 .

MESSAGE '不能生成EXCEL对象,检查系统是否安装 MS EXCEL。' TYPE 'E'. STOP.

ENDIF.

SET PROPERTY OF excel 'DisplayAlerts' = 0.

CALL METHOD OF excel 'WORKBOOKS' = workbook .

* Put Excel in background

SET PROPERTY OF excel 'VISIBLE' = 1.

* Create worksheet

SET PROPERTY OF excel 'SheetsInNewWorkbook' = 1.

CALL METHOD OF workbook 'ADD'.

PERFORM gen_item. “此处调用form gen_item 显示EXCEL明细

GET PROPERTY OF excel 'ActiveSheet' = sheet.

FREE OBJECT sheet.

FREE OBJECT workbook.

GET PROPERTY OF excel 'ActiveWorkbook' = workbook.

CALL METHOD OF workbook 'SAVEAS'

EXPORTING

#1 = filename “保存路径

#2 = 1.

FREE OBJECT sheet.

FREE OBJECT workbook.

FREE OBJECT excel.

ENDFORM. "gen_excel

FORM gen_item.

CALL METHOD OF excel 'WORKSHEETS' = sheet.

CALL METHOD OF sheet 'ADD'.

FREE OBJECT sheet.

CALL METHOD OF excel 'WORKSHEETS' = sheet

EXPORTING

#1 = 1.

CALL METHOD OF sheet 'ACTIVATE'.

SET PROPERTY OF sheet 'NAME' = 'btdata'. “导出的EXCEL表单名

FREE OBJECT sheet. "OK

DEFINE c_cell.

call method of excel 'CELLS' = cell “定义在excel的位置 1为行 2为列

EXPORTING

#1 = &1

#2 = &2.

END-OF-DEFINITION.

DEFINE s_cell.

set property of cell &1 = &2. “填充值 1为VALUE 2为填充内容

END-OF-DEFINITION.

* 写标题行

c_cell 1 1. s_cell 'VALUE' '物料号'.

c_cell 1 2. s_cell 'VALUE' '工厂'.

c_cell 1 3. s_cell 'VALUE' '网格值'.

c_cell 1 4. s_cell 'VALUE' '产品名称'.

c_cell 1 5. s_cell 'VALUE' '颜色'.

c_cell 1 6. s_cell 'VALUE' '尺码'.

DATA: line TYPE i VALUE 1.

* 写内容行

LOOP AT GT_ITAB.

line = line + 1.

c_cell line 1. s_cell:'NumberFormatLocal' '@','VALUE' GT _ITAB-matnr.

c_cell line 2. s_cell:'NumberFormatLocal' '@','VALUE' G T_ITAB-werks.

c_cell line 3. s_cell:'NumberFormatLocal' '@','VALUE' G T_ITAB-J_3ASIZE.

c_cell line 4. s_cell 'VALUE' GT_ITAB-MAKTX.

c_cell line 5. s_cell:'NumberFormatLocal' '@','VALUE' G T_ITAB-J_3AKORD1.

c_cell line 6. s_cell:'NumberFormatLocal' '@','VALUE' G T_ITAB-J_3AKORD2.

ENDLOOP.

ENDFORM.

二、DOI

ABAP 通过DOI可以处理对EXCEL有特殊要求格式的需求。DOI的功能很强大,关于OLE 和DOI的区别可以参考https://www.360docs.net/doc/d619079340.html,/ecathy@126/blog/static/1651261562010529103946880/的博客内容。

DOI实现起来分为两步

1.上载EXCEL模板

TCODE:OAOR

下面的可以不用填写

进去之后如下图:左下角点击“创建”选项卡—>“标准文档类型”—> “Table template”

双击“Table template”弹出文旦导航选择文件

之后在主界面左上角3 会显示上载的模板excel模板如下

之后就是代码

以下是网上下载的代码

可以运行(需要在SE51上面创建一个编号100的屏幕屏幕里面建一个CONTAINER,SE41创建STATUS “SA1”)

REPORT ZTEST2.

TABLES: T001.

TYPE-POOLS: SLIS,VRM, SBDST, SOI."引入必要的类型组

CONSTANTS DOCUMENT_NAME(30) VALUE 'temp'."模板名字

CONSTANTS INPLACE VALUE 'X'."控制参数,在GUI中显示Excel

DATA: FLAG .

DATA:CONTAINER TYPE REF TO CL_GUI_CUSTOM_CONTAINER,"容器实例CONTROL TYPE REF TO I_OI_CONTAINER_CONTROL,"控制器实例

DOCUMENT TYPE REF TO I_OI_DOCUMENT_PROXY,"文档操作对象

SPREADSHEET TYPE REF TO I_OI_SPREADSHEET,"分隔符对象

ERROR TYPE REF TO I_OI_ERROR,"错误信息

ERRORS TYPE REF TO I_OI_ERROR OCCURS 0 WITH HEADER LINE."错误信息

* spreadsheet interface structures for Excel data input

DATA: RANGEITEM TYPE SOI_RANGE_ITEM.

DATA: RANGES TYPE SOI_RANGE_LIST.

DATA: EXCEL_INPUT TYPE SOI_GENERIC_TABLE.

DATA: EXCEL_INPUT_WA TYPE SOI_GENERIC_ITEM.

DATA: INITIALIZED(1), RETCODE TYPE SOI_RET_STRING.

DATA: ITEM_URL(256)."存放模板的Url

DATA DOCUMENT_TYPE(80)."文档类型

DATA: EXCEL(80) VALUE 'Excel.Sheet'.

DATA: LINE_COUNT TYPE I,

COLUMN_COUNT TYPE I.

DATA: OK_CODE TYPE SY-UCOMM,

SAVE_OK TYPE SY-UCOMM.

CLASS C_OI_ERRORS DEFINITION LOAD.

DATA: BEGIN OF ITAB OCCURS 0.

INCLUDE STRUCTURE T001.

DATA: END OF ITAB.

SELECT-OPTIONS BUKRS FOR T001-BUKRS.

START-OF-SELECTION.

PERFORM GETDATA.

CALL SCREEN 100.

*&------------------------------------------------------------

---------*

*& Form getdata

*&------------------------------------------------------------

---------*

* text

*-------------------------------------------------------------

---------*

* --> p1 text

* <-- p2 text

*-------------------------------------------------------------

---------*

FORM GETDATA .

SELECT *

FROM T001

INTO TABLE ITAB

WHERE BUKRS IN BUKRS.

ENDFORM. " getdata

*&------------------------------------------------------------

---------*

*& Module STATUS_0100 OUTPUT

*&------------------------------------------------------------

---------*

* text

*-------------------------------------------------------------

---------*

MODULE STATUS_0100 OUTPUT.

SET PF-STATUS 'SA1'.

IF FLAG = SPACE .

PERFORM CREATE_BASIC_OBJECTS USING '' '' '' '' DOCUMENT_NAME. PERFORM OUTPUT_TO_EXCEL.

ENDIF.

ENDMODULE. "STATUS_0100 OUTPUT

*&---------------------------------------------------------------------*

*& Module USER_COMMAND_0100 INPUT

*&---------------------------------------------------------------------*

* text

*----------------------------------------------------------------------*

MODULE USER_COMMAND_0100 INPUT.

FLAG = 'X'.

SAVE_OK = OK_CODE.

CLEAR OK_CODE.

CASE SAVE_OK.

WHEN 'CANCLE' .

IF NOT DOCUMENT IS INITIAL.

CALL METHOD DOCUMENT->CLOSE_DOCUMENT."关闭文档

FREE DOCUMENT.

ENDIF.

IF NOT CONTROL IS INITIAL.

CALL METHOD CONTROL->DESTROY_CONTROL.

FREE CONTROL.

ENDIF.

LEAVE PROGRAM.

WHEN 'BACK' .

IF NOT DOCUMENT IS INITIAL.

CALL METHOD DOCUMENT->CLOSE_DOCUMENT.

FREE DOCUMENT.

ENDIF.

IF NOT CONTROL IS INITIAL.

CALL METHOD CONTROL->DESTROY_CONTROL.

FREE CONTROL.

ENDIF.

SET SCREEN 0. " quit the program

"set screen 1000.

ENDCASE.

ENDMODULE. " USER_COMMAND_0100 INPUT

*&---------------------------------------------------------------------*

*& Form CREATE_BASIC_OBJECTS

*&---------------------------------------------------------------------*

* text

*----------------------------------------------------------------------*

* -->P_APP_NAME text

* -->P_CLASSNAME text

* -->P_CLASSTYPE text

* -->P_OBJ_KEY text

* -->P_DOCNAME text

*----------------------------------------------------------------------*

FORM CREATE_BASIC_OBJECTS USING P_APP_NAME

P_CLASSNAME

P_CLASSTYPE

P_OBJ_KEY

P_DOCNAME.

CHECK INITIALIZED IS INITIAL.

* 获取SAP DOI的控制器接口

CALL METHOD

C_OI_CONTAINER_CONTROL_CREATOR=>GET_CONTAINER_CONTROL IMPORTING

CONTROL = CONTROL

ERROR = ERROR.

* check no errors occured

CALL METHOD ERROR->RAISE_MESSAGE

EXPORTING

TYPE = 'E'.

"实例化容器实例

CREATE OBJECT CONTAINER

EXPORTING

CONTAINER_NAME = 'CONTAINER'.

DATA L_APP_NAME(200).

IF P_APP_NAME IS INITIAL.

L_APP_NAME = 'TEST'.

ELSE.

L_APP_NAME = P_APP_NAME.

ENDIF.

"初始化控制器的接口

CALL METHOD CONTROL->INIT_CONTROL

EXPORTING

R3_APPLICATION_NAME = L_APP_NAME

INPLACE_ENABLED = INPLACE

INPLACE_SCROLL_DOCUMENTS = 'X'

PARENT = CONTAINER

REGISTER_ON_CLOSE_EVENT = 'X'

REGISTER_ON_CUSTOM_EVENT = 'X'

NO_FLUSH = 'X'

IMPORTING

ERROR = ERRORS.

* save error object in collection

APPEND ERRORS.

CLEAR ITEM_URL.

"定义BDS实例变量,用于设置文档信息

DATA: BDS_INSTANCE TYPE REF TO CL_BDS_DOCUMENT_SET.

DATA: DOC_SIGNATURE TYPE SBDST_SIGNATURE,

WA_DOC_SIGNATURE LIKE LINE OF DOC_SIGNATURE,

DOC_COMPONENTS TYPE SBDST_COMPONENTS,

DOC_URIS TYPE SBDST_URI,

WA_DOC_URIS LIKE LINE OF DOC_URIS.

*以下三个值为Tcode:OAOR里面新建模板文件的参数

DATA: DOC_CLASSNAME TYPE SBDST_CLASSNAME VALUE 'HRFPM_EXCEL_ST ANDARD',

DOC_CLASSTYPE TYPE SBDST_CLASSTYPE VALUE 'OT',

DOC_OBJECT_KEY TYPE SBDST_OBJECT_KEY VALUE 'TEMP'.

WA_DOC_SIGNATURE-PROP_NAME = 'DESCRIPTION'.

DOCUMENT_TYPE = EXCEL.

WA_DOC_SIGNATURE-PROP_VALUE = P_DOCNAME."赋给文档名字

APPEND WA_DOC_SIGNATURE TO DOC_SIGNATURE."DOC_SIGNATURE存储了文档信息

CREATE OBJECT BDS_INSTANCE.

CALL METHOD BDS_INSTANCE->GET_INFO"获取文档信息

EXPORTING

CLASSNAME = DOC_CLASSNAME

CLASSTYPE = DOC_CLASSTYPE

OBJECT_KEY = DOC_OBJECT_KEY

CHANGING

COMPONENTS = DOC_COMPONENTS

SIGNATURE = DOC_SIGNATURE.

CALL METHOD BDS_INSTANCE->GET_WITH_URL"获取文档的url地址放到DOC_URIS中

EXPORTING

CLASSNAME = DOC_CLASSNAME

CLASSTYPE = DOC_CLASSTYPE

OBJECT_KEY = DOC_OBJECT_KEY

CHANGING

URIS = DOC_URIS

SIGNATURE = DOC_SIGNATURE.

FREE BDS_INSTANCE."释放该对象

READ TABLE DOC_URIS INTO WA_DOC_URIS INDEX 1.

ITEM_URL = WA_DOC_URIS-URI."获取对象的地址

* 告诉SAP DOI容器开辟一个Excel策略

CALL METHOD CONTROL->GET_DOCUMENT_PROXY EXPORTING

DOCUMENT_TYPE = 'Excel.Sheet'

NO_FLUSH = 'X'

IMPORTING

DOCUMENT_PROXY = DOCUMENT

ERROR = ERRORS.

APPEND ERRORS.

* 根据模板地址打开Excel文件

CALL METHOD DOCUMENT->OPEN_DOCUMENT

EXPORTING

OPEN_INPLACE = INPLACE

DOCUMENT_URL = ITEM_URL.

DATA: HAS TYPE I.

CALL METHOD DOCUMENT->HAS_SPREADSHEET_INTERFACE EXPORTING

NO_FLUSH = ''

IMPORTING

IS_AVAILABLE = HAS

ERROR = ERRORS.

APPEND ERRORS.

"获取模板文档的表格分割器接口给SPREADSHEET

CALL METHOD DOCUMENT->GET_SPREADSHEET_INTERFACE EXPORTING

NO_FLUSH = ' '

IMPORTING

SHEET_INTERFACE = SPREADSHEET

ERROR = ERRORS.

APPEND ERRORS.

*激活第一个sheet

CALL METHOD SPREADSHEET->SELECT_SHEET EXPORTING

NAME = '表整理'

* NO_FLUSH = ' '

IMPORTING

ERROR = ERRORS.

* RETCODE =

.

APPEND ERRORS.

" LOOP AT ERRORS.

" CALL METHOD ERRORS->RAISE_MESSAGE

" EXPORTING

" TYPE = 'E'.

"ENDLOOP.

FREE ERRORS.

INITIALIZED = 'X'.

ENDFORM. "CREATE_BASIC_OBJECTS

*&---------------------------------------------------------------------*

*& Form output_to_excel

*&---------------------------------------------------------------------*

* fill the EXCEL sheet

*----------------------------------------------------------------------*

FORM OUTPUT_TO_EXCEL.

DATA NUM TYPE I VALUE 0.

LOOP AT ITAB.

NUM = SY-TABIX + 2.

PERFORM FILL_CELL USING NUM 1 ITAB-BUKRS."行列值

PERFORM FILL_CELL USING NUM 2 ITAB-SPRAS.

PERFORM FILL_CELL USING NUM 3 ITAB-BUTXT.

ENDLOOP.

ENDFORM. "output_to_excel

*&---------------------------------------------------------------------*

*& Form FILL_CELL

*&---------------------------------------------------------------------*

* text

*----------------------------------------------------------------------*

* -->I text

* -->J text

* -->VAL text

*----------------------------------------------------------------------*

FORM FILL_CELL USING I J VAL.

DATA: COLUMNS_NUMBER TYPE I,

ROWS_NUMBER TYPE I.

COLUMNS_NUMBER = 1.

ROWS_NUMBER = 1.

CALL METHOD SPREADSHEET->INSERT_RANGE_DIM

EXPORTING

NAME = 'cell'

NO_FLUSH = 'X'

TOP = I

LEFT = J

ROWS = ROWS_NUMBER

COLUMNS = COLUMNS_NUMBER

IMPORTING

ERROR = ERRORS.

APPEND ERRORS.

REFRESH: RANGES, EXCEL_INPUT.

RANGEITEM-NAME = 'cell'.

RANGEITEM-COLUMNS = 1.

RANGEITEM-ROWS = 1.

APPEND RANGEITEM TO RANGES.

EXCEL_INPUT_WA-COLUMN = 1.

EXCEL_INPUT_WA-ROW = 1.

EXCEL_INPUT_WA-VALUE = VAL.

APPEND EXCEL_INPUT_WA TO EXCEL_INPUT.

* set data

CALL METHOD SPREADSHEET->SET_RANGES_DATA

EXPORTING

RANGES = RANGES

CONTENTS = EXCEL_INPUT

NO_FLUSH = 'X'

IMPORTING

ERROR = ERRORS.

APPEND ERRORS.

CALL METHOD SPREADSHEET->FIT_WIDEST

EXPORTING

NAME = SPACE

NO_FLUSH = 'X'.

REFRESH: RANGES, EXCEL_INPUT.

ENDFORM. "fill_cell

最后显示结果

相关参考:

1.https://www.360docs.net/doc/d619079340.html,/s/blog_4d1570de0100rsxp.html

2.https://www.360docs.net/doc/d619079340.html,/link?url=SrSs_HPDwgVDw4l7p_YoO21bEymUKxDxQlxQ59

M80QWj6P4-OyJtEHhGB-0hxahXI8HiL_OKTi6gDfK1uHiSRstKwPHDYbsobyt7dZQGdU e

3 https://www.360docs.net/doc/d619079340.html,/uid-9308264-id-2005222.html

4 https://www.360docs.net/doc/d619079340.html,/VerySky/articles/3040097.html

相关主题
相关文档
最新文档