zoukankan      html  css  js  c++  java
  • (原创)不带模板的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 的实例。

    3.文档接口:I_OI_DOCUMENT_PROXY ,参照这个接口的实例主要用来打开和保存文件,还有创建参照接口I_OI_SPREADSHEET 的实例。

    4.SHEET页接口:I_OI_SPREADSHEET,参照这个接口的实例主要用来在SHEET页层级填充数据,设置格式等。

       最后给出一个简单的DEMO。

    输出目标:

    创建的屏幕100:

    源代码:

    *&---------------------------------------------------------------------*
    *& 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.
  • 相关阅读:
    FreeCAD二次开发-makeChamfer创建倒角
    FreeCAD二次开发-makeFillet创建倒圆
    FreeCAD二次开发-Gui.Selection.getSelectionEx() 遍历选中的对象
    FreeCAD二次开发-Part.Ellipse创建椭圆
    FreeCAD二次开发-Part.makePolygon创建多边形
    FreeCAD二次开发-face.extrude创建拉伸
    FreeCAD二次开发-Part.Face创建面
    FreeCAD二次开发-Part.Shape合并几何元素,生成拓扑形状
    FreeCAD二次开发-Part.LineSegment创建直线
    FreeCAD二次开发-Part.Arc创建圆弧
  • 原文地址:https://www.cnblogs.com/jianglaizhen/p/8779036.html
Copyright © 2011-2022 走看看