본문 바로가기
ABAP/개발Tip

[개발Tip] WebGUI에서 Excel 템플릿의 셀 값 변경 (CL_FDT_XL_SPREADSHEET/ABAP2XLSX)

by name_text 2023. 12. 7.

Excel 템플릿의 셀 값 변경 

CL_FDT_XL_SPREADSHEET

ABAP2XLSX

 

ABAP내에서 Excel OLE를 사용하지 않고 Web Repository Object(SMW0)에 등록한 엑셀 템플릿에 셀 값을 변경하여 다운로드 하는 방법입니다.

 

SAPGUI의 경우 OLE를 사용하면 되지만 WebGUI의 경우에는 브라우저에서 PC의 OLE 오브젝트를 호출할 수 없어서 아래와 같이 XML Reader/Writer기반의 클래스를 사용해야 합니다.

 

더 좋은 방법이 있을것 같긴 하지만 제가 알고 있는 방법은 총 2가지 방법입니다.

ABAP2XLSX이 가장 사용하기 편하고 OLE를 사용할때 처럼 자유롭게 셀 제어가 가능합니다.

CL_FDT_XL_SPREADSHEET도 이름 정의된 셀만 제어할 수 있는 제약사항이 있지만 ABAP2XLSX를 설치하기 어려운 상황에서는 좋은 대안이 될 수 있습니다.

 

#1. CL_FDT_XL_SPREADSHEET 클래스 이용

#2. ABAP2XLSX 클래스 이용 (https://github.com/abap2xlsx)

 

# 소스코드 예시

REPORT YSAND_BOX.

  PARAMETERS: P_OBJ TYPE WWWPARAMS-OBJID OBLIGATORY DEFAULT 'ZTEST111'.
  SELECTION-SCREEN SKIP.
  PARAMETERS: R_FDTXL RADIOBUTTON GROUP RB1,
              R_AB2XL RADIOBUTTON GROUP RB1.

INITIALIZATION.
  %_P_OBJ_%_APP_%-TEXT = 'Web Repository Object'.
  %_R_FDTXL_%_APP_%-TEXT = 'CL_FDT_XL_SPREADSHEET'.
  %_R_AB2XL_%_APP_%-TEXT = 'ABAP2XLSX'.


START-OF-SELECTION.
  "SMW0의 엑셀 양식을 불러온다
  DATA: LT_QUERY_STRING TYPE STANDARD TABLE OF  W3QUERY,
        LT_HTML         TYPE STANDARD TABLE OF  W3HTML,
        LT_MIME         TYPE STANDARD TABLE OF  W3MIME,
        LV_RETURN_CODE  TYPE  W3PARAM-RET_CODE,
        LV_CONTENT_TYPE TYPE  W3PARAM-CONT_TYPE,
        LV_CONTENT_LENGTH TYPE  W3PARAM-CONT_LEN.

  LT_QUERY_STRING = VALUE #( ( NAME = '_OBJECT_ID'  VALUE = P_OBJ ) ).
  CALL FUNCTION 'WWW_GET_MIME_OBJECT'
    TABLES
      QUERY_STRING              = LT_QUERY_STRING
      HTML                      = LT_HTML
      MIME                      = LT_MIME
    CHANGING
      RETURN_CODE               = LV_RETURN_CODE
      CONTENT_TYPE              = LV_CONTENT_TYPE
      CONTENT_LENGTH            = LV_CONTENT_LENGTH
    EXCEPTIONS
      OBJECT_NOT_FOUND          = 1
      PARAMETER_NOT_FOUND       = 2
      OTHERS                    = 3
            .
  IF SY-SUBRC <> 0.
    EXIT.
  ENDIF.
  DATA(LV_XSTRING) = CL_BCS_CONVERT=>SOLIX_TO_XSTRING( LT_MIME ).

  "엑셀 제어
  CASE ABAP_TRUE.
    WHEN R_FDTXL.   "CL_FDT_XL_SPREADSHEET 클래스 사용
* CL_FDT_XL_SPREADSHEET --------------------------------------------------------------------*
      "이름이 지정된 셀만 값 변경 가능
      "Excel Object 생성
      TRY.
        DATA(LO_SPREADSHEET) = NEW CL_FDT_XL_SPREADSHEET( DOCUMENT_NAME = 'TESTDOC'
                                                          XDOCUMENT     = LV_XSTRING ) .
      CATCH CX_FDT_EXCEL_CORE.
        EXIT.
      ENDTRY .

*      "이름이 지정된 Cell 목록
*      LO_SPREADSHEET->IF_FDT_DOC_SPREADSHEET~GET_NAMED_CELLS(
*        importing
*          NAMED_CELLS = DATA(LT_CELLS)
*      ).
*
*      "이름이 지정된 Cell 범위 목록
*      LO_SPREADSHEET->IF_FDT_DOC_SPREADSHEET~GET_NAMED_RANGES(
*        importing
*          NAMED_RANGES = DATA(LT_RANGES)
*      ).

      "엑셀 셀값변경 - 셀이름으로 셀값 변경
      LO_SPREADSHEET->IF_FDT_DOC_SPREADSHEET~SET_NAMED_CELL_VALUE(
          CELL_NAME  = 'CELL1'
          CELL_VALUE = 'TEST CL_FDT_XL_SPREADSHEET' ).

      "엑셀 셀값 변경 - 범위이름으로 셀값 변경
      DATA(LO_RANGE_TAB) = LO_SPREADSHEET->IF_FDT_DOC_SPREADSHEET~GET_NAMED_RANGE_ITAB( 'RANGE1'  ).
      FIELD-SYMBOLS <LFT_RANGE_TAB> TYPE ANY TABLE.
      ASSIGN LO_RANGE_TAB->* TO <LFT_RANGE_TAB>.

      LOOP AT <LFT_RANGE_TAB> ASSIGNING FIELD-SYMBOL(<LFS_RANGE_TAB>).
        ASSIGN COMPONENT 'D' OF STRUCTURE <LFS_RANGE_TAB> TO FIELD-SYMBOL(<LFV>).
        IF <LFV> IS ASSIGNED.
          <LFV> = 'CELL CHANGED'.
        ENDIF.
      ENDLOOP.

      LO_SPREADSHEET->IF_FDT_DOC_SPREADSHEET~SET_NAMED_RANGE_VALUES( RANGE_NAME = 'RANGE1'
                                                                     ITAB       = REF #( <LFT_RANGE_TAB> ) ).

      LV_XSTRING = LO_SPREADSHEET->IF_FDT_DOCUMENT~GET_DOCUMENT( ).
* CL_FDT_XL_SPREADSHEET --------------------------------------------------------------------*

    WHEN R_AB2XL.   "ABAP2XLSX 클래스 사용
* ABAP2XLSX --------------------------------------------------------------------*
      "모든 셀 값 변경 가능
      "Excel Object 생성
      TRY.
        DATA(LO_EXCEL) = NEW ZCL_EXCEL_READER_2007( )->ZIF_EXCEL_READER~LOAD( LV_XSTRING ).
      catch ZCX_EXCEL.
        EXIT.
      ENDTRY.

      "시트 선택
      DATA(LO_SHEET) = LO_EXCEL->GET_ACTIVE_WORKSHEET( ).

      "셀값 변경
      LO_SHEET->SET_CELL( IP_COLUMN            = 'C'
                          IP_ROW               = 7
                          IP_VALUE             = 'TEST ABAP2XLSX' ).

      DATA LV_ROW TYPE I VALUE 10.
      DO 10 TIMES.
        LO_SHEET->SET_CELL( IP_COLUMN            = 'D'
                            IP_ROW               = LV_ROW
                            IP_VALUE             = 'CELL CHANGED' ).
        ADD 1 TO LV_ROW.
      ENDDO.

      LV_XSTRING = NEW ZCL_EXCEL_WRITER_2007( )->ZIF_EXCEL_WRITER~WRITE_FILE( LO_EXCEL ).
* ABAP2XLSX --------------------------------------------------------------------*
  ENDCASE.


  "엑셀 다운로드
  DATA(LT_BINTAB) = CL_BCS_CONVERT=>XSTRING_TO_SOLIX( LV_XSTRING ).

  DATA: LV_FILENAME TYPE STRING,
        LV_PATH     TYPE STRING,
        LV_FULLPATH TYPE STRING.

  CL_GUI_FRONTEND_SERVICES=>FILE_SAVE_DIALOG(
    exporting
      FILE_FILTER               = SWITCH #( SY-LANGU WHEN '3' THEN 'Excel 통합문서 (*.xlsx)|*.xlsx' ELSE 'Excel Workbook (*.xlsx)|*.xlsx' )
    changing
      FILENAME                  = LV_FILENAME
      PATH                      = LV_PATH
      FULLPATH                  = LV_FULLPATH ).

  CHECK LV_FULLPATH IS NOT INITIAL.

  CL_GUI_FRONTEND_SERVICES=>GUI_DOWNLOAD(
    exporting
      BIN_FILESIZE              = XSTRLEN( LV_XSTRING )    " File length for binary files
      FILENAME                  = LV_FULLPATH
      FILETYPE                  = 'BIN'
    changing
      DATA_TAB                  = LT_BINTAB ).

 

 

# CL_FDT_XL_SPREADSHEET 사용을 위해 Excel에 셀 이름 지정

이름이 지정된 셀 또는 범위에 대해서만 값 변경이 가능합니다.

템플릿용 엑셀에 값을 변경할 부분을 "이름 정의"로 셀 이름을 지정해줘야 합니다.

 

댓글