쌓고 쌓다

[ABAP] 메일에 Internal Table을 Excel로 첨부하기 본문

SAP/ABAP

[ABAP] 메일에 Internal Table을 Excel로 첨부하기

승민아 2025. 10. 17. 14:25
반응형

 

메일 전송 시 엑셀에 데이터를 원하는 위치에 넣기도 하고

글자 크기, 글자 굵기, 배경색 등을 지정하여 넣길 원했기에

 

OLE 방식을 이용해 메일로 전송하고자 했으나

OLE 방식은 엑셀 파일을 한번 컴퓨터에 저장하고 그 파일에 데이터를 넣거나 꾸미는 과정을 거쳐야 하기에

제외했다.

 

아래의 방법도 CL_SALV_TABLE을 이용한 방법인데

원하는 위치에 데이터를 집어넣어 엑셀을 구성하는 데는 한계가 있다.

 

그래서 로컬 컴퓨터에 저장하지 않고 엑셀 파일에 원하는 위치에 값을 넣는 방법이 존재하는가?

abap2xlsx 방법이 존재한다.

 

크게 이메일에 엑셀 파일을 구성해서 첨부하는 방법은

1. STRING으로 데이터를 넣어 파일 만들기

2. CL_SALV_TABLE로 테이블의 값 파일로 만들기

3. OLE 방식으로 엑셀 파일을 저장하고 조작하고 만들기

4. abap2xlsx 방법으로 만들기

 

섬세하게 엑셀 파일 내용을 구성할 수 있는 것은 1과 3 방법인 것 같다.

 

 

우선 이 글에서는 CL_SALV_TABLE 방식으로 하는 방법이다.

 

Internal Table을 Excel에 옮겨 메일에 첨부하는 방법을 알아보자.

 

위의 사진처럼 테이블에 들어 있는 값들을 가지고

 

위의 형식으로 엑셀에 값을 넣어 이메일로 전송할 수 있다.

 

전체 코드

*&---------------------------------------------------------------------*
*& Report ZS4H086_MAIL_SEND_02
*&---------------------------------------------------------------------*

REPORT ZS4H086_MAIL_SEND_02.

PARAMETERS : PA_MAIL TYPE STRING.

* 메일 변수 설정
DATA: BCS_EXCEPTION      TYPE REF TO CX_BCS,
      ERRORTEXT          TYPE STRING,
      CL_SEND_REQUEST    TYPE REF TO CL_BCS,
      CL_DOCUMENT        TYPE REF TO CL_DOCUMENT_BCS,
      CL_RECIPIENT       TYPE REF TO IF_RECIPIENT_BCS,
      ATTACHMENT_SUBJECT TYPE SOOD-OBJDES,
      MAIL_TITLE         TYPE SO_OBJ_DES,                     " 메일 제목
      LT_MAILTEXT        TYPE SOLI_TAB,                       " 메일 내용
      LS_MAILTEXT        LIKE LINE OF LT_MAILTEXT,
      SEND_TO            TYPE ADR6-SMTP_ADDR,
      SENT               TYPE ABAP_BOOL.

*--------------------------------------------------------------------*
* 메일 작성 - HTML
*--------------------------------------------------------------------*

* 메일 제목
MAIL_TITLE = '테스트 메일 제목'.

*--------------------------------------------------------------------*
* 데이터 세팅 & 첨부파일 넣기
*--------------------------------------------------------------------*

* ALV 타입 및 변수 선언
TYPES : BEGIN OF TY_ALV_DATA,     " ALV DATA
          COL1       TYPE STRING,
          COL2       TYPE I,
          COL3       TYPE EKPO-NETWR,
          COL4       TYPE EKKO-WAERS,
        END OF TY_ALV_DATA.
DATA : LT_ALV_DATA TYPE TABLE OF TY_ALV_DATA,
       LS_ALV_DATA LIKE LINE OF LT_ALV_DATA.

TYPES : BEGIN OF TY_COLUMN,        " ALV COLUMN
          COLUMN_NAME TYPE TEXT30,
          COLUMN_TEXT TYPE TEXT40,
        END OF TY_COLUMN.
DATA : LT_ALV_COLUMN TYPE TABLE OF TY_COLUMN,
       LS_ALV_COLUMN LIKE LINE OF LT_ALV_COLUMN.


* ALV 객체 및 XLSX 변환용 변수
DATA : LO_SALV_TABLE TYPE REF TO CL_SALV_TABLE,
       LV_XSTRING    TYPE XSTRING.

* ALV 데이터 생성
LT_ALV_DATA = VALUE #(
    ( COL1 = 'A' COL2 = 1 COL3 = '1.00' COL4 = 'KRW' ) " 통화 연결하여 값 넣는건 WRITE CURRENCY를 활용하자.
    ( COL1 = 'B' COL2 = 2 COL3 = '2.00' COL4 = 'USD' )
  ).

* ALV 컬럼명 생성
LT_ALV_COLUMN = VALUE #(
    ( COLUMN_NAME = 'COL1' COLUMN_TEXT = '컬럼1' ) " SET_MEDIUM_TEXT에 들어간다.
    ( COLUMN_NAME = 'COL2' COLUMN_TEXT = '컬럼2' )
*   컬럼3, 컬럼4를 설정해주지 않으면 Element 필드 라벨의 값이 자동으로 들어간다.
  ).

* ALV 객체를 생성하기
TRY.
    " ALV 객체 생성 (데이터와 함께)
    CL_SALV_TABLE=>FACTORY(
      IMPORTING
        R_SALV_TABLE = LO_SALV_TABLE
      CHANGING
        T_TABLE      = LT_ALV_DATA
    ).

  CATCH CX_SALV_MSG.
    MESSAGE 'ALV 객체 생성 실패' TYPE 'E'.
    RETURN.
ENDTRY.


* ALV 컬럼 설정
LOOP AT LT_ALV_COLUMN ASSIGNING FIELD-SYMBOL(<FS_ALV_COLUMN>).
* SALV에서 COLUMN_NAME과 일치하는 컬럼 찾고
  DATA(LO_COLUMN) = LO_SALV_TABLE->GET_COLUMNS( )->GET_COLUMN( <FS_ALV_COLUMN>-COLUMN_NAME ).

* 헤더 텍스트 설정
  LO_COLUMN->SET_LONG_TEXT( <FS_ALV_COLUMN>-COLUMN_TEXT ).
  LO_COLUMN->SET_MEDIUM_TEXT( CONV #( <FS_ALV_COLUMN>-COLUMN_TEXT ) ).
  LO_COLUMN->SET_SHORT_TEXT( CONV #( <FS_ALV_COLUMN>-COLUMN_TEXT ) ).
ENDLOOP.

DATA(LT_FCAT) = CL_SALV_CONTROLLER_METADATA=>GET_LVC_FIELDCATALOG(
                  R_COLUMNS      = LO_SALV_TABLE->GET_COLUMNS( )      " 컬럼 정보
                  R_AGGREGATIONS = LO_SALV_TABLE->GET_AGGREGATIONS( ) " 합계나 소계 같은 집계 정보도 포함
                ).

* internal Table 데이터 Xlsx(Binary Data)로 변환
CL_SALV_BS_LEX=>EXPORT_FROM_RESULT_DATA_TABLE(
  EXPORTING
    IS_FORMAT                     = IF_SALV_BS_LEX_FORMAT=>MC_FORMAT_XLSX
    IR_RESULT_DATA_TABLE          = CL_SALV_EX_UTIL=>FACTORY_RESULT_DATA_TABLE(
                                      R_DATA                 = REF #( LT_ALV_DATA )
                                      T_FIELDCATALOG         = LT_FCAT
                                    )
  IMPORTING
    ER_RESULT_FILE                = LV_XSTRING
).

*--------------------------------------------------------------------*
* 메일 전송
*--------------------------------------------------------------------*
TRY.

* BCS(Business Communication Services)
    CL_SEND_REQUEST = CL_BCS=>CREATE_PERSISTENT( ).                            " 빈 메일 요청 생성(요청 오브젝트 생성)

* 문서 생성
    CL_DOCUMENT = CL_DOCUMENT_BCS=>CREATE_DOCUMENT( I_TYPE    = 'HTM'          " HTML 타입
                                                    I_TEXT    = LT_MAILTEXT    " 메일 글
                                                    I_SUBJECT = MAIL_TITLE ).  " 메일 타이틀

*   XSTRING 데이터 첨부
    CL_DOCUMENT->ADD_ATTACHMENT(
      EXPORTING
        I_ATTACHMENT_TYPE     = 'XLS'
        I_ATTACHMENT_SUBJECT  = 'ALV엑셀파일'
        I_ATTACHMENT_SIZE     = CONV #( XSTRLEN( LV_XSTRING ) )
        I_ATT_CONTENT_HEX     = CL_BCS_CONVERT=>XSTRING_TO_SOLIX( IV_XSTRING = LV_XSTRING )
    ).

*   빈 메일 요청에 문서 추가
    CL_SEND_REQUEST->SET_DOCUMENT( CL_DOCUMENT ).

    SEND_TO = PA_MAIL. " 수신자

    CL_RECIPIENT = CL_CAM_ADDRESS_BCS=>CREATE_INTERNET_ADDRESS( SEND_TO ). " 이메일 주소 문자열을 기반으로 생성된 수신자 객체
    CL_SEND_REQUEST->ADD_RECIPIENT( CL_RECIPIENT ).
    CL_SEND_REQUEST->SET_SEND_IMMEDIATELY( 'X' ). " 즉시 전송

    SENT = CL_SEND_REQUEST->SEND( I_WITH_ERROR_SCREEN = 'X' ).

    IF SENT = ABAP_TRUE. " 성공메시지
      COMMIT WORK.
      MESSAGE |{ PA_MAIL }로 발송 되었습니다.| TYPE 'S'.
    ELSE.
      ROLLBACK WORK.
    ENDIF.

  CATCH CX_BCS INTO BCS_EXCEPTION. " 에러 메시지 출력
    ERRORTEXT = BCS_EXCEPTION->IF_MESSAGE~GET_TEXT( ).
    MESSAGE ERRORTEXT TYPE 'I'.

ENDTRY.

 

반응형