Send ZIP File Filled with PDF Files in OData, Media Handling in OData
Introduction
Recently I got a request for getting multiple PDFs from the service that was already in use, and I was already using ‘ GET_STREAM ‘ method to return a single PDF. Facing this request, the most quick and usable solution I thought was why not I am adding multiple PDFs into a single ZIP File, and then here we are.
I will be showing you How to create a ZIP File filled with PDFs using OData.
Scenario
We will be using ‘ GET_STREAM ‘ method of OData to get a single ZIP File, filled with PDFs that we will be creating from Adobeform.
Prerequisites:
1. Basic Knowledge about Adobeform2. Basic knowledge about OData3. Basic knowledge about SAP Gateway usage.Step-by-Step Procedure:
1. Creating the Odata Service and Redefining ‘ GET_STREAM ‘ Method.2. Creating a ZIP File and filling it with PDFs.3. Registering the OData Service and testing it from SAP Gateway
STEP 1:
Firstly we need to create our ODATA Service. Go to SEGW and Create an OData project.
Create an ENTITY_TYPE responding your needs. Don’t forget to choose your entity as Media.
Image 1 – Generating Service, Entity Types
Now generate Runtime Artifacts after that to Redefine the ‘ GET_STREAM ‘ method go to DPC_EXT section.
Image 2 – Redefine GET_STREAM Method
STEP 2:
Now lets do what we know best, CODING. To get an easier to read code I prefer using Functions. These are ;
1. ‘ SO_PROFORMA_ZIP ‘ where I create ZIP File and convert it to a xstring variable
2. ‘ SO_GET_PDF_VALUE ‘ where I get PDFs as xstring to add ZIP File
3. ‘ SO_PROFORMA_GET_DATA ‘ where I get my data to fill PDFs
In ‘ SO_GET_PDF_VALUE ‘ Function, I am creating the PDFs and getting their xstring values.
FUNCTION so_get_pdf_value.
*"----------------------------------------------------------------------
*"*"Local Interface:
*" IMPORTING
*" VALUE(IV_VBELN) TYPE VBELN
*" EXPORTING
*" VALUE(EV_VALUE) TYPE FPCONTENT
*"----------------------------------------------------------------------
DATA: ls_printout TYPE so_proforma_st5,
ls_fp_outputparams TYPE sfpoutputparams,
lv_form_name TYPE fpname,
lv_fm_name TYPE rs38l_fnam,
ls_fp_docparams TYPE sfpdocparams,
ls_formoutput TYPE fpformoutput,
ls_result TYPE sfpjoboutput.
" Function where I Get Data to fill my PDF.
CALL FUNCTION 'SO_PROFORMA_GET_DATA'
EXPORTING
iv_vbeln = lv_vbeln
IMPORTING
es_printout = ls_printout.
" Print data
IF sy-cprog EQ 'RS_TESTFRAME_CALL'.
sy-cprog = sy-repid.
ENDIF.
* Do not forget to set your variables ! ! !
ls_fp_outputparams-dest = 'LP01'.
ls_fp_outputparams-getpdf = abap_true.
ls_fp_outputparams-nodialog = abap_true.
lv_form_name = 'SO_AF003'.
CALL FUNCTION 'FP_JOB_OPEN'
CHANGING
ie_outputparams = ls_fp_outputparams
EXCEPTIONS
cancel = 1
usage_error = 2
system_error = 3
internal_error = 4
OTHERS = 5.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
TRY.
CALL FUNCTION 'FP_FUNCTION_MODULE_NAME'
EXPORTING
i_name = lv_form_name
IMPORTING
e_funcname = lv_fm_name.
CATCH cx_fp_api_repository.
CATCH cx_fp_api_internal.
CATCH cx_fp_api_usage.
ENDTRY.
ls_fp_docparams-langu = sy-langu.
IF lv_fm_name IS NOT INITIAL.
CALL FUNCTION lv_fm_name
EXPORTING
/1bcdwb/docparams = ls_fp_docparams
is_general = ls_printout
IMPORTING
/1bcdwb/formoutput = ls_formoutput
EXCEPTIONS
usage_error = 1
system_error = 2
internal_error = 3.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ELSE.
ev_value = ls_formoutput-pdf. " PDF as xstring variable
ENDIF.
ENDIF.
CALL FUNCTION 'FP_JOB_CLOSE'
IMPORTING
e_result = ls_result
EXCEPTIONS
usage_error = 1
system_error = 2
internal_error = 3
OTHERS = 4.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
ENDFUNCTION.
In ‘ SO_PROFORMA_ZIP ‘ Function, I am creating the ZIP FILE filled with PDFs and converting it to xstring variable ( to be able to use it in get_stream method ),
FUNCTION so_proforma_zip.
*"----------------------------------------------------------------------
*"*"Local Interface:
*" IMPORTING
*" VALUE(IV_STRING) TYPE STRING
*" EXPORTING
*" VALUE(EV_ZIPSTRING) TYPE XSTRING
*"----------------------------------------------------------------------
DATA: lo_zip TYPE REF TO cl_abap_zip,
lv_value TYPE fpcontent,
lv_filename TYPE string,
lt_vbeln TYPE TABLE OF vbeln.
SPLIT iv_string AT ',' INTO TABLE lt_vbeln.
CREATE OBJECT lo_zip.
LOOP AT lt_vbeln INTO DATA(lv_vbeln).
CLEAR: lv_filename, lv_value.
lv_filename = |{ lv_vbeln }.pdf|. " Name of the PDF File
CALL FUNCTION 'SO_GET_PDF_VALUE' " Function where I get PDF as xstring value.
EXPORTING
iv_vbeln = lv_vbeln
IMPORTING
ev_value = lv_value.
IF lv_value IS NOT INITIAL.
*Add PDF Files into ZIP File.
lo_zip->add( EXPORTING name = lv_filename
content = lv_value ).
ENDIF.
ENDLOOP.
ev_zipxstring = lo_zip->save( ). " the final ZIP File.
ENDIF.
ENDFUNCTION.
With this we are done with creating PDFs and adding them to ZIP FILE. Now what left is, consuming this ZIP FILE via ‘ GET_STREAM ‘ method of our OData service.
Define your variables as you need, and we are almost done. Do not forget to set mime_type variable as mime_type = ‘application/zip’ , If not you wont be getting any ZIP FILES. ( If you want to you can set several different mime_types like JPEG, PDF …. )
METHOD /iwbep/if_mgw_appl_srv_runtime~get_stream.
CASE iv_entity_set_name.
WHEN 'printSalesSet'.
*In our scenario we are using VBELN numbers seperated by ', ' in a string variable.
DATA(lv_string) = VALUE #( it_key_tab[ 1 ]-value OPTIONAL ). " VBELN numbers seperated via ', '
DATA(stream) = VALUE ty_s_media_resource( mime_type = 'application/zip' ). " Media Source
DATA(filename) ='SalesOrders.zip'.
CALL FUNCTION 'SO_PROFORMA_ZIP' "Function to get ZIP FILE content as a xstring value.
EXPORTING
iv_string = lv_string
IMPORTING
ev_zipxstring = stream-value.
set_header( VALUE #( name = 'Content-Disposition' value = |inline; filename="{ escape( val = filename format = cl_abap_format=>e_url ) }"| ) ).
copy_data_to_ref( EXPORTING is_data = stream CHANGING cr_data = er_stream ).
ENDCASE.
ENDMETHOD.
we are done with coding. now lets get our zip file.
STEP 3:
Go to t-code ‘ /N/IWFND/MAINT_SERVICE ‘ where we activate and maintain services. If you did not activate your service before, click to ‘ Add Service ‘ and activate your service. If you already did it, click ‘ FILTER ‘ and find your service
Image 3 – Maintain Service
Double click your service and go to ‘ SAP Gateway Client ‘ where we will test our ODATA.
Image 4 – SAP Gateway Client
Firstly select your EntitySet which we will be sending request. Fill your variables as responding to your needs and responding how did you set your entity key(s), in my case I will be using VBELN numbers separated by ‘, ‘. Do not forget to add ‘ /$value ‘ to end of your code. Without /$value addition our request wont be reaching ‘ GET_STREAM ‘ method of OData service. If you are done execute your code.
Image 5 – Send a request to service
If you followed the blog well you will be seeing this screen with ~status_code = 200 and ~status_reason = OK. This means our service worked well and we did get our response, which is the ZIP File we created. You can also see your settings from here such as your mime_type which is content_type and your File Name which is ~content_filename.
Image 6 – Receive the response
Now Click ‘ Response in Browser ‘ and select ZIP file. Here it is your ZIP FILE filled with PDFs.
Regards!