How to Create a Zip File in ABAP

We generate different kinds of files varying from Excel sheets to Text files based on the data available in SAP. It is very much possible to zip multiple reports within a single zip file and download the zip file from SAP.

In this article we are going to generate a zip file which will contain Material Number (MATNR) and Material Description (MAKTX) in two languages (English and German) in two different files.

SAP has provided the class CL_ABAP_ZIP for reading and writing zip files which we are going to utilize to generate zip file. Following is the sequence of process involved to generate a zip file.

  • Fetch data into internal tables
  • Convert them to xstring.
  • Create object for CL_ABAP_ZIP
  • Use add method to add new files to the zip archive
  • Now, save method returns the final zip file in xstring
  • Convert the xstring to internal table
  • Download it using GUI_DOWNLOAD

And the program is as follows,

report  zfar_zip_download.

data:
      begin of file_stru,
        matnr type matnr,
        maktx type maktx,
      end of file_stru,

      begin of s_matnr,
        matnr type matnr,
      end of s_matnr,

      begin of s_line,
        line type c length 256,
      end of s_line,

      gt_mara_en like standard table of file_stru,
      gt_mara_de like standard table of file_stru,
      gt_matnr like standard table of s_matnr,

      go_zip type ref to cl_abap_zip,

      g_xstr_en type xstring,
      g_xstr_de type xstring,
      g_xstr_zip type xstring.

start-of-selection.

  "Read and prepare data
  perform fetch_data.

  "Create object for CL_ABAP_ZIP
  create object go_zip.

  "Convert itabs to xstring
  perform convert_to_xstring
    tables gt_mara_en
    using  g_xstr_en.

  perform convert_to_xstring
    tables gt_mara_de
    using  g_xstr_de.

  "Add xstring as file content to zip
  go_zip->add(
    exporting
      name = 'en.txt'
      content = g_xstr_en
  ).

  go_zip->add(
    exporting
      name = 'de.txt'
      content = g_xstr_de
  ).

  "Get the xstring for final zip file
  g_xstr_zip = go_zip->save( ).

  "Dowload the xstring received
  "from save method
  perform download_zip_file.

  write 'File Downloaded'.

This process is simple as this, however we will look at the sub routines for more details.

Fetching data in internal tables

First, we are going to read the data for Material Number and Material Description in English and German into internal tables.

form fetch_data.
  data:
        lt_mara_en like standard table of file_stru,
        lt_mara_de like standard table of file_stru,
        s_temp like file_stru.

  "Select thousand materials
  select
    matnr
  from mara
  into table gt_matnr
  up to 1000 rows.

  "Select their english texts
  select
    matnr
    maktx
  from makt
  into table lt_mara_en
  for all entries in gt_matnr
    where matnr eq gt_matnr-matnr
    and spras eq 'E'.

  "Select their german texts
  select
    matnr
    maktx
  from makt
  into table lt_mara_de
  for all entries in gt_matnr
    where matnr eq gt_matnr-matnr
    and spras eq 'D'.

  sort gt_matnr ascending.
  sort gt_mara_en ascending.
  sort gt_mara_de ascending.

  loop at gt_matnr into s_matnr.

    clear s_temp.

    read table lt_mara_en into s_temp
      with key matnr = s_matnr-matnr.

    if sy-subrc eq 0.
      append s_temp to gt_mara_en.
    else.
      s_temp-matnr = s_matnr-matnr.
      append s_temp to gt_mara_en.
    endif.

    clear s_temp.

    read table lt_mara_de into s_temp
      with key matnr = s_matnr-matnr.

    if sy-subrc eq 0.
      append s_temp to gt_mara_de.
    else.
      s_temp-matnr = s_matnr-matnr.
      append s_temp to gt_mara_de.
    endif.

  endloop.

The above code makes sure the data in both languages are exactly same and in same order. If a material does not contain description text in German, the German report will contain only the Material number for that material. The same applies to English report as well.

Converting Internal Table to XSTRING

Though the class CL_ABAP_ZIP makes things simple, it accepts only an xstring as file content. So we have to convert the internal tables to xstring.

form convert_to_xstring
  tables p_tab
  using p_xstr.

  data:
        lt_lines like standard table of s_line.

  loop at p_tab into file_stru.
    s_line-line = file_stru.
    append s_line to lt_lines.
  endloop.

  call function 'SCMS_TEXT_TO_XSTRING'
*   EXPORTING
*     FIRST_LINE       = 0
*     LAST_LINE        = 0
*     MIMETYPE         = ' '
   importing
     buffer           = p_xstr
   tables
     text_tab         = lt_lines
   exceptions
     failed           = 1
     others           = 2
            .
  if sy-subrc <> 0.
    message id sy-msgid type sy-msgty number sy-msgno
            with sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  endif.


endform.                 

p_tab is moved to lt_lines only to make sure that the internal table passed to SCMS_TEXT_TO_XSTRING contains only one column. In case you have to convert a binary internal table to xstring, use the function module SCMS_BINARY_TO_XSTRING.

Creating the Zip File

As shown above, you can use add method to add the xstring data to zip archive as a file. and you can use the save method to get the xstring value of the final zip file.

Converting and Downloading

To download the zip file, we are going to use the Function Module GUI_DOWNLOAD which takes the files content in an internal table as input. Hence, we need to convert the xstring data we got from save method to internal table and then we have to pass it to GUI_DOWNLOAD.

form download_zip_file.

  data:
        l_len type i,
        lt_lines like standard table of s_line.

  call function 'SCMS_XSTRING_TO_BINARY'
    exporting
      buffer                = g_xstr_zip
*     APPEND_TO_TABLE       = ' '
   importing
     output_length         = l_len
    tables
      binary_tab            = lt_lines
            .

  call function 'GUI_DOWNLOAD'
    exporting
      filename   = 'D:/out.zip'
      filetype   = 'BIN'
    importing
      filelength = l_len
    tables
      data_tab   = lt_lines.
  if sy-subrc <> 0.
    message id sy-msgid type sy-msgty number sy-msgno
            with sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  endif.

endform.

And the when the report is run, it produces a zip file with two text documents within it as shown below.

Zip File Output

The complete report is as follows.

report  zfar_zip_download.

data:
      begin of file_stru,
        matnr type matnr,
        maktx type maktx,
      end of file_stru,
      begin of s_matnr,
        matnr type matnr,
      end of s_matnr,
      begin of s_line,
        line type c length 256,
      end of s_line,
      gt_mara_en like standard table of file_stru,
      gt_mara_de like standard table of file_stru,
      gt_matnr like standard table of s_matnr,
      go_zip type ref to cl_abap_zip,
      g_xstr_en type xstring,
      g_xstr_de type xstring,
      g_xstr_zip type xstring.

start-of-selection.

  "Read and prepare data
  perform fetch_data.

  "Create object for CL_ABAP_ZIP
  create object go_zip.

  "Convert itabs to xstring
  perform convert_to_xstring
    tables gt_mara_en
    using  g_xstr_en.

  perform convert_to_xstring
    tables gt_mara_de
    using  g_xstr_de.

  "Add xstring as file content to zip
  go_zip->add(
    exporting
      name = 'en.txt'
      content = g_xstr_en
  ).

  go_zip->add(
    exporting
      name = 'de.txt'
      content = g_xstr_de
  ).

  "Get the xstring for final zip file
  g_xstr_zip = go_zip->save( ).

  "Dowload the xstring received
  "from save method
  perform download_zip_file.

  write 'File Downloaded'.


*&---------------------------------------------------*
*&      Form  fetch_data
*&---------------------------------------------------*
*       text
*----------------------------------------------------*
form fetch_data.
  data:
        lt_mara_en like standard table of file_stru,
        lt_mara_de like standard table of file_stru,
        s_temp like file_stru.

  "Select thousand materials
  select
    matnr
  from mara
  into table gt_matnr
  up to 1000 rows.

  "Select their english texts
  select
    matnr
    maktx
  from makt
  into table lt_mara_en
  for all entries in gt_matnr
    where matnr eq gt_matnr-matnr
    and spras eq 'E'.

  "Select their german texts
  select
    matnr
    maktx
  from makt
  into table lt_mara_de
  for all entries in gt_matnr
    where matnr eq gt_matnr-matnr
    and spras eq 'D'.

  sort gt_matnr ascending.
  sort gt_mara_en ascending.
  sort gt_mara_de ascending.

  loop at gt_matnr into s_matnr.

    clear s_temp.

    read table lt_mara_en into s_temp
      with key matnr = s_matnr-matnr.

    if sy-subrc eq 0.
      append s_temp to gt_mara_en.
    else.
      s_temp-matnr = s_matnr-matnr.
      append s_temp to gt_mara_en.
    endif.

    clear s_temp.

    read table lt_mara_de into s_temp
      with key matnr = s_matnr-matnr.

    if sy-subrc eq 0.
      append s_temp to gt_mara_de.
    else.
      s_temp-matnr = s_matnr-matnr.
      append s_temp to gt_mara_de.
    endif.

  endloop.

endform.                    "fetch_data

*&----------------------------------------------*
*&      Form  convert_to_xstring
*&----------------------------------------------*
*       text
*-----------------------------------------------*
*      -->P_TAB      text
*      -->P_XSTR     text
*-----------------------------------------------*
form convert_to_xstring
  tables p_tab
  using p_xstr.

  data:
        lt_lines like standard table of s_line.

  loop at p_tab into file_stru.
    s_line-line = file_stru.
    append s_line to lt_lines.
  endloop.

  call function 'SCMS_TEXT_TO_XSTRING'
*   EXPORTING
*     FIRST_LINE       = 0
*     LAST_LINE        = 0
*     MIMETYPE         = ' '
   importing
     buffer           = p_xstr
   tables
     text_tab         = lt_lines
   exceptions
     failed           = 1
     others           = 2
            .
  if sy-subrc <> 0.
    message id sy-msgid type sy-msgty number sy-msgno
            with sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  endif.


endform.                    "convert_to_xstring

*&------------------------------------------------*
*&      Form  download_zip_file
*&------------------------------------------------*
*       text
*-------------------------------------------------*
form download_zip_file.

  data:
        l_len type i,
        lt_lines like standard table of s_line.

  call function 'SCMS_XSTRING_TO_BINARY'
    exporting
      buffer                = g_xstr_zip
*     APPEND_TO_TABLE       = ' '
   importing
     output_length         = l_len
    tables
      binary_tab            = lt_lines
            .

  call function 'GUI_DOWNLOAD'
    exporting
      filename   = 'D:/out.zip'
      filetype   = 'BIN'
    importing
      filelength = l_len
    tables
      data_tab   = lt_lines.
  if sy-subrc <> 0.
    message id sy-msgid type sy-msgty number sy-msgno
            with sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  endif.

endform.                    "download_zip_file

Fareez Ahamed

SAP Developer, Full Stack Web Developer, Laravel & Vue.js fanatic