(原創)不帶模板的DOI輸出EXCEL

      前面介紹了OLE輸出EXCEL有個最大的特色就是慢,由於其是基於單元格層次的一個個操做去填充數據,而DOI技術採用面向對象的方法實現,解決了這個問題。至於爲何能解決,有興趣的能夠慢慢研究。工具

      既然是使用面向對象的方法實現,固然離不開類與接口,下面介紹DOI中最經常使用的4種類與接口。字體

1.容器類:目前做者經常使用的兩種類是CL_GUI_CONTAINER和CL_GUI_CUSTOMER_CONTAINER,在不畫屏幕容器,直接使用整個屏幕做爲容器時使用CL_GUI_CONTAINER建立容器實例,在畫屏幕容器時使用CL_GUI_CUSTOM_CONTAINER建立容器實例。優化

2.控制器接口:I_OI_CONTAINER_CONTROL,這個接口的實例主要用來與屏幕容器綁定和建立參照接口I_OI_DOCUMENT_PROXY 的實例。ui

3.文檔接口:I_OI_DOCUMENT_PROXY ,參照這個接口的實例主要用來打開和保存文件,還有建立參照接口I_OI_SPREADSHEET 的實例。spa

4.SHEET頁接口:I_OI_SPREADSHEET,參照這個接口的實例主要用來在SHEET頁層級填充數據,設置格式等。code

   最後給出一個簡單的DEMO。orm

輸出目標:對象

建立的屏幕100:blog

源代碼:接口

*&---------------------------------------------------------------------* *& Report Z15540_DOI1 *&---------------------------------------------------------------------* *& *&---------------------------------------------------------------------*
REPORT Z15540_DOI1. TYPE-POOLS:SOI. "數據定義
DATA:BEGIN OF GS_DATA, WERKS TYPE MARD-WERKS, LGORT TYPE MARD-LGORT, MATNR TYPE MARD-MATNR, MAKTX TYPE MAKT-MAKTX, LABST TYPE MARD-LABST, MEINS TYPE MARA-MEINS, END OF GS_DATA. DATA GT_DATA LIKE TABLE OF GS_DATA. "DOI相關定義
DATA:LCL_CONTAINER  TYPE REF TO CL_GUI_CONTAINER, "容器引用對象
     LCL_CONTROL    TYPE REF TO I_OI_CONTAINER_CONTROL, "容器控制器引用對象
     LCL_DOCUMENT   TYPE REF TO I_OI_DOCUMENT_PROXY, "對應EXCEL文檔層次引用對象
     LCL_SHEET      TYPE REF TO I_OI_SPREADSHEET. "對應SHEET層次操做的接口引用對象

START-OF-SELECTION. CALL SCREEN 100. *&---------------------------------------------------------------------* *& Form FRM_CONTAINER *&---------------------------------------------------------------------* *& text *&---------------------------------------------------------------------* *& --> p1 text *& <-- p2 text *&---------------------------------------------------------------------*
FORM FRM_CONTAINER . "將CL_GUI_CONTAINER的靜態屬性SCREEN0付給LCL_CONTAINER,至關於以當前系統顯示的整個屏幕建立一個容器實例,該例中則以屏幕100建立實例
  LCL_CONTAINER = CL_GUI_CONTAINER=>SCREEN0. ENDFORM. *&---------------------------------------------------------------------* *& Form FRM_CONTAINER_CONTROL *&---------------------------------------------------------------------* *& text *&---------------------------------------------------------------------* *& --> p1 text *& <-- p2 text *&---------------------------------------------------------------------*
FORM FRM_CONTAINER_CONTROL . "實例化容器控制器
  CALL METHOD C_OI_CONTAINER_CONTROL_CREATOR=>GET_CONTAINER_CONTROL IMPORTING
      CONTROL = LCL_CONTROL. "綁定容器與容器控制器,並初始化控制器設定
  CALL METHOD LCL_CONTROL->INIT_CONTROL EXPORTING
* DYNPRO_NR = SY-DYNNR * GUI_CONTAINER = ' '
      INPLACE_ENABLED          = 'X' "EXCEL可嵌入容器 * INPLACE_MODE = 0 * INPLACE_RESIZE_DOCUMENTS = ' '
      INPLACE_SCROLL_DOCUMENTS = 'X' "可滾動 * INPLACE_SHOW_TOOLBARS = 'X' "是否展現工具欄以上 * NO_FLUSH = 'X' * PARENT_ID = cl_gui_cfw=>dynpro_0
      R3_APPLICATION_NAME      = 'DOI TEST' REGISTER_ON_CLOSE_EVENT = 'X' "註冊關閉事件
      REGISTER_ON_CUSTOM_EVENT = 'X' "註冊定製事件 * REP_ID = SY-REPID * SHELL_STYLE = 1384185856
      PARENT                   = LCL_CONTAINER * NAME = * AUTOALIGN = 'x' * IMPORTING * ERROR = * RETCODE =
    EXCEPTIONS JAVABEANNOTSUPPORTED = 1 OTHERS = 2. IF SY-SUBRC <> 0. * Implement suitable error handling here
  ENDIF. ENDFORM. *&---------------------------------------------------------------------* *& Form FRM_CREATE_EXCEL *&---------------------------------------------------------------------* *& text *&---------------------------------------------------------------------* *& --> p1 text *& <-- p2 text *&---------------------------------------------------------------------*
FORM FRM_CREATE_EXCEL . "實例化LCL_DOCUMENT
  CALL METHOD LCL_CONTROL->GET_DOCUMENT_PROXY EXPORTING
* DOCUMENT_FORMAT = 'NATIVE'
      DOCUMENT_TYPE  = 'EXCEL.SHEET' "應用類型
      NO_FLUSH       = 'X'
* REGISTER_CONTAINER = ' '
    IMPORTING DOCUMENT_PROXY = LCL_DOCUMENT * ERROR = * RETCODE =
 . "建立EXCEL文件
  CALL METHOD LCL_DOCUMENT->CREATE_DOCUMENT EXPORTING
* CREATE_VIEW_DATA = ' '
      DOCUMENT_TITLE = 'DOI TEST'
* NO_FLUSH = 'X'
      OPEN_INPLACE   = 'X' "嵌入顯示 * OPEN_READONLY = 'X' "只讀 * ONSAVE_MACRO = 'X' * STARTUP_MACRO = 'X' * IMPORTING * ERROR = * RETCODE =
 . ENDFORM. *&---------------------------------------------------------------------* *& Form FRM_SET_DATA *&---------------------------------------------------------------------* *& text *&---------------------------------------------------------------------* *& --> p1 text *& <-- p2 text *&---------------------------------------------------------------------*
FORM FRM_SET_DATA . DATA LV_ROW TYPE I."填充數據的行數
  DATA:LS_RANGE       TYPE SOI_RANGE_ITEM, LT_RANGE TYPE TABLE OF SOI_RANGE_ITEM, "爲SET_RANGE_DATA方法標明填充數據的範圍名及其行列數
       LS_CONTENT     TYPE SOI_GENERIC_ITEM, LT_CONTENT TYPE TABLE OF SOI_GENERIC_ITEM, "爲SET_RANGE_DATA方法提供填充數據
       LS_FORMATTABLE TYPE  SOI_FORMAT_ITEM, "設置範圍格式
       LT_FORMATTABLE TYPE TABLE OF SOI_FORMAT_ITEM. "設置範圍格式

  DATA LV_COUNT_ROW TYPE I."當前行
  DATA LV_LABST TYPE C LENGTH 18. FIELD-SYMBOLS:<FS_DATA_FILED>, <FS_CONTENT_FIELD>. SELECT MARD~WERKS, MARD~LGORT, MARD~MATNR, MAKT~MAKTX, MARD~LABST, MARA~MEINS INTO TABLE @GT_DATA UP TO 200 ROWS FROM MARD INNER JOIN MARA ON MARD~MATNR = MARA~MATNR LEFT OUTER JOIN MAKT ON MARD~MATNR = MAKT~MATNR WHERE MAKT~SPRAS = @SY-LANGU. DESCRIBE TABLE GT_DATA LINES LV_ROW."填充數據行數

  DATA A1 TYPE I. CALL METHOD LCL_DOCUMENT->HAS_SPREADSHEET_INTERFACE EXPORTING NO_FLUSH = 'X'
    IMPORTING
* ERROR =
      IS_AVAILABLE = A1 * RETCODE =
 . "實例化SHEET對象
  CALL METHOD LCL_DOCUMENT->GET_SPREADSHEET_INTERFACE EXPORTING NO_FLUSH = 'X'
    IMPORTING
* ERROR =
      SHEET_INTERFACE = LCL_SHEET * RETCODE =
 . "選中SHEET1
  CALL METHOD LCL_SHEET->SELECT_SHEET EXPORTING NAME = 'Sheet1' NO_FLUSH = 'X'
* IMPORTING * ERROR = * RETCODE =
 . *CALL METHOD LCL_SHEET->GET_ACTIVE_SHEET * EXPORTING * NO_FLUSH = 'X' ** IMPORTING ** SHEETNAME = ** ERROR = ** RETCODE = * .
  "建立一個左上角爲第一行第一列,共計6列200行,名叫RANGE1的範圍對象
  CALL METHOD LCL_SHEET->INSERT_RANGE_DIM EXPORTING NO_FLUSH = 'X' NAME = 'RANGE1'
      LEFT     = 1 TOP = 1 ROWS = LV_ROW COLUMNS = 6
* UPDATING = -1 * SHEETNAME = '' * IMPORTING * ERROR = * RETCODE =
 . LT_RANGE = VALUE #( ( NAME = 'RANGE1' ROWS = LV_ROW COLUMNS = '6' ) ). LOOP AT GT_DATA INTO GS_DATA. LV_COUNT_ROW = SY-TABIX. DO 6 TIMES. ASSIGN COMPONENT SY-INDEX OF STRUCTURE GS_DATA TO <FS_DATA_FILED>. LS_CONTENT-ROW = LV_COUNT_ROW. LS_CONTENT-COLUMN = SY-INDEX. IF SY-INDEX = 5. LV_LABST = <FS_DATA_FILED>. CONDENSE LV_LABST NO-GAPS. LS_CONTENT-VALUE = LV_LABST. ELSE. LS_CONTENT-VALUE = <FS_DATA_FILED>. ENDIF. APPEND LS_CONTENT TO LT_CONTENT. CLEAR LS_CONTENT. ENDDO. CLEAR GS_DATA. ENDLOOP. "填充數據
  CALL METHOD LCL_SHEET->SET_RANGES_DATA EXPORTING NO_FLUSH = 'X'
      RANGES   = LT_RANGE CONTENTS = LT_CONTENT * UPDATING = -1 * RANGESDEF = * IMPORTING * ERROR = * RETCODE =
 . "設置範圍字體格式
  LT_FORMATTABLE = VALUE #( ( NAME = 'RANGE1' SIZE = 11 BOLD = 1 ALIGN = 1 ) )."RANGE1字體大小11 加粗 水平居中
  CALL METHOD LCL_SHEET->SET_RANGES_FORMAT EXPORTING FORMATTABLE = LT_FORMATTABLE NO_FLUSH = 'X'
* UPDATING = -1 * IMPORTING * ERROR = * RETCODE =
 . "設置範圍邊框格式
  CALL METHOD LCL_SHEET->SET_FRAME EXPORTING RANGENAME = 'RANGE1' TYP = '127'
      COLOR     = 1
* NO_FLUSH = ' ' * IMPORTING * ERROR = * RETCODE =
 . "設置列自動優化
  CALL METHOD LCL_SHEET->FIT_WIDEST EXPORTING NO_FLUSH = 'X' NAME = 'RANGE1'
* IMPORTING * ERROR = * RETCODE =
 . "更改SHEET名稱
  CALL METHOD LCL_SHEET->SET_SHEET_NAME EXPORTING NEWNAME = '可用庫存清單' OLDNAME = 'Sheet1' NO_FLUSH = 'X'
* IMPORTING * ERROR = * RETCODE =
 . "保存文件(該方法會自動默認保存到c盤用戶文件下的文檔文件夾中)
  CALL METHOD LCL_DOCUMENT->SAVE_AS EXPORTING FILE_NAME = '可用庫存清單' NO_FLUSH = 'X'
* PROMPT_USER = ' ' * IMPORTING * ERROR = * RETCODE =
 . ENDFORM. *&---------------------------------------------------------------------* *& Module STATUS_0100 OUTPUT *&---------------------------------------------------------------------* *& *&---------------------------------------------------------------------*
MODULE STATUS_0100 OUTPUT. SET PF-STATUS 'STANDARD'. SET TITLEBAR 'DOI TEST'. "實例化容器
  PERFORM FRM_CONTAINER. "建立容器控制器
  PERFORM FRM_CONTAINER_CONTROL. "建立EXCEL文檔
  PERFORM FRM_CREATE_EXCEL. "填充數據
  PERFORM FRM_SET_DATA. ENDMODULE. *&---------------------------------------------------------------------* *& Module USER_COMMAND_0100 INPUT *&---------------------------------------------------------------------* * text *----------------------------------------------------------------------*
MODULE USER_COMMAND_0100 INPUT. "退出時釋放實例。
  IF LCL_DOCUMENT IS NOT INITIAL. CALL METHOD LCL_DOCUMENT->CLOSE_DOCUMENT. ENDIF. IF LCL_CONTAINER IS NOT INITIAL. CALL METHOD LCL_CONTAINER->FREE. ENDIF. IF LCL_CONTROL IS NOT INITIAL. CALL METHOD LCL_CONTROL->DESTROY_CONTROL. FREE LCL_CONTROL. ENDIF. LEAVE PROGRAM. ENDMODULE.
相關文章
相關標籤/搜索