Skip to Content
Technical Articles
Author's profile photo Abhishek Dalakoti

Preview/Download Fragmented Forms From Fiori List Report (Part -1 )

Introduction / Requirement

There were days where customer requirement was to create ALV reports in GUI and to provide button on top of ALV to print the report data as PDF or to show the details of selected line item.

Now Customers are focusing on application which are more user friendly, responsive instead of old GUI applications/screens.

In this blog, I will be explaining something similar type of requirement where Print functionality (Fragmented Form) on Fiori List report was required.

I have built an application, which allow user to show the PO data in Fiori list report, where user can select a particular line and preview the form (in my case billing document form).

Technical Details

Step 1Creation of Fiori List Report and project in BAS

First step will be creation of CDS view and creating Fiori List report on top of consumption view (I will not go much into details of creating / deploying project in BAS because all that you can explore on your own as there are already lot of blogs for the same).

Preview of list report from ADT


Fiori List Report Preview

Step 2Backend OData Service for PDF data

In the backend we will be creating an OData service which will be used to provide the PDF data (xstring)

a) OData project will be created which will have GetPDFDisplay Entity


OData Service

b) GetPDFDisplay Entity will have Billing document number as a key property.
c) Redefine the method /IWBEP/IF_MGW_APPL_SRV_RUNTIME~GET_STREAM in   DPC_EXT class to get the stream data.


Redefine GET_STREAM method

d) Inside the GET_STREAM method we can write the logic to get the pdf data (we can use                    GET_DOCUMENT () API of class CL_SOMU_FORM_SERVICES to fetch the PDF data for                fragmented forms) by passing the billing document number from the Frontend.

Logic in GET_STREAM method

1) Fetch the incoming billing document number (selected by user from Fiori List report)

2) Prepare the keys for billing doc and master form

3) Call the GET_DOCUMENT API of class CL_SOMU_FORM_SERVICES by passing content and master form keys

4) Prepare the stream data by passing value and mime type and send the response back to UI

Sample code —

  METHOD /iwbep/if_mgw_appl_srv_runtime~get_stream.


    DATA: lt_odatakeys TYPE /iwbep/t_mgw_tech_pairs,
          ls_key       TYPE /iwbep/s_mgw_tech_pair,
          lv_billdoc   TYPE vbeln,
          ls_stream    TYPE ty_s_media_resource.

    DATA: lt_master_keys           TYPE cl_somu_form_services=>ty_gt_key.
    DATA: lv_content               TYPE  xstring.
    DATA: lo_cl_somu_form_services TYPE REF TO cl_somu_form_services,
          lt_keys                  TYPE cl_somu_form_services=>ty_gt_key.


*  Step 1-- "-------------- Fetch the billing document selected by user from frontend-----------------------------

        lt_odatakeys = io_tech_request_context->get_keys( ).
        lv_billdoc  =  VALUE #( lt_odatakeys[ name = lc_entity_name  ]-value OPTIONAL ).

* Step 2 -- " ---------------------------Key Value for the Billing document content form service ---------------------------

        lt_keys =  VALUE #(     ( name = 'BillingDocument'     value = lv_billdoc )
                                ( name = 'SenderCountry'       value = 'DE'            )
                                ( name = 'Language'(040)       value = 'E' ) ) .

*         " --------------------------- Key Value for the master form template service ---------------------------

        lt_master_keys = VALUE #(         ( name = 'PrintFormDerivationRule'            value = 'ZINVOICE_FORM'  )
                                          ( name = 'WatermarkText'                      value = space                       )
                                          ( name = 'LocaleCountry'                      value = 'DE')
                                          ( name = 'LocaleLanguage'                     value = 'E'  )
                                          ( name = 'OutputControlApplicationObjectType' value = 'BILLING_DOCUMENT' )
                                          ( name = 'OutputControlApplicationObject'     value = lv_billdoc  )
                                          ( name = 'OutputRequestItem'                  value = '000001' )
                                          ( name = 'OutputDocumentType'                 value = 'BILLING_DOCUMENT'  )
                                          ( name = 'Recipient'(041)                     value = '00000001003' )
                                          ( name = 'RecipientRole'                      value = 'RE'  )
                                          ( name = 'SenderCountry'                      value = 'DE' )
                                          ( name = 'ReceiverPartnerNumber'              value = '00000001003'  ) ).

*  Step3 --" --------------------------- Call GET_DOCUMENT API ---------------------------

        lo_cl_somu_form_services = cl_somu_form_services=>get_instance( ).

            lo_cl_somu_form_services->get_document( EXPORTING iv_master_form_name  = 'ZZ1_OTC_INVOICE_MASTER_A4'
                                                              iv_form_name         = 'ZZ1_OTC_INVOICE_OUTPUT'
                                                              it_key               = lt_keys
                                                              it_master_key        = lt_master_keys
                                                              iv_form_language     = 'E'
                                                              iv_form_country      = 'DE'
                                                    IMPORTING ev_content           = lv_content

"            --------------------------- Set the Header  ---------------------------*
              DATA(lv_name) = |inline; filename={ 'Billing Document  ' && lv_billdoc && '.pdf' };| .
              DATA(ls_header) = VALUE ihttpnvp( name  = 'Content-Disposition'
                                                value = lv_name

              set_header( is_header = ls_header ).

"            --------------------------- Set the stream data   ---------------------------*
              ls_stream-value     = lv_content.
              ls_stream-mime_type = 'application/pdf'.

          CATCH cx_somu_error INTO DATA(lr_root).
            MESSAGE lr_root->get_text( ) TYPE 'E'.

     "Step 4----------------------------- Send the stream data to frontend  ---------------------------*
        copy_data_to_ref( EXPORTING
                            is_data = ls_stream
                            cr_data = er_stream ).

      CATCH /iwbep/cx_mgw_busi_exception .

      CATCH /iwbep/cx_mgw_tech_exception .



Test the service in gateway.


Test Service

*Note – This approach can also be used with adobe forms*

Step 3 Frontend (Extension in BAS)

Extension in BAS

Apart from default data source, we must define additional data source for the backend OData service which we have created in gateway builder in step 2, under the “dataSources” section of manifest file for fetching PDF data (xstring).



Define data source in manifest

This OData data source should be mapped to a UI5 model in manifest file under “models” section.



Using Guided development, button will be added which will add the required information in manifest file and create controller.js file with function.

Steps –

1) Right click on the project and open guided development


Guided Development

In Guided development we have different options to perform extension on Fiori report.
For our requirement we will select 1st option, add a custom action to a page using extension.

In this step, we will create a controller extension to define a handler function for the custom action button.
If a controller extension is already available for a page, we can copy the code and use it.

Click on create button to create the controller.js file.

Step 2 – Update the manifest file.

In this step, we will add the extension settings of the custom action to the manifest.

After clicking on insert snippet, manifest file will be updated with required information.

"extends": {
            "extensions": {
                "sap.ui.controllerExtensions": {
                    "sap.suite.ui.generic.template.ListReport.view.ListReport": {
                        "controllerName": "xx.sellbuybackreport.ext.controller.ListReportExt",
                        "": {
                            "ZC_OTC_SELLBUYBACK_DETAILS": {
                                "EntitySet": "ZC_OTC_SELLBUYBACK_DETAILS",
                                "Actions": {
                                        "onPrint": {
                                        "id": "printID",
                                        "text": "Print Preview",
                                        "press": "onPrintPreview",
                                        "requiresSelection": true


Once we preview the application, we can see the Print Preview button in the toolbar section of report.


Report Preview

Now we have to plug in the code in button method which was created via guided development in controller.js file.
Explanation of controller code

1) Create object of PDF Viewer and add it to current view

2) Get selected billing document number

3) Use createKey method to create the key by passing the billing document number if billing document is present for the selected line.

4) Create the final URL, the service URL + the OData entity set which will return the PDF with a $Value parameter.
Set this URL to the PDFViewer Object along with the title of PDF, In the end open the PDF Viewer

  onPrintPreview: function(oEvent) {
            var opdfViewer = new PDFViewer();
            //get selected line index
          var selectedIndex = this.getView().byId('xx.sellbuybackreport::sap.suite.ui.generic.template.ListReport.view.ListReport::ZC_OTC_SELLBUYBACK_DETAILS--GridTable')
          .getAggregation("plugins")[0].getSelectedIndex() ;

          // get billing document  from selected index
           var vSelectedBillDoc =  this.getView().byId('xx.sellbuybackreport::sap.suite.ui.generic.template.ListReport.view.ListReport::ZC_OTC_SELLBUYBACK_DETAILS--GridTable').

            if (vSelectedBillDoc !== '') {
            // create the path for OData Get_stream call
                const path = this.getView().getModel("oERPSOModel").createKey("/GetPDFDisplaySet", {
                    // Key(s) and value(s) of that entity set
                    "BillingDoc": vSelectedBillDoc,
                var sServiceURL = this.getView().getModel("oERPSOModel").sServiceUrl;
       //   Create the final URL
                var sSource = sServiceURL + path + "/$value";   
                opdfViewer.setTitle("Billing Document ");
       // Opne the PDF Viewer

            } else {
          // If billing doc is not present for selected line     
                sap.m.MessageBox.error("Billing Document doesn't exists");




Let’s test the code …

Select a line where billing document exists and click on print preview to show the form in preview mode. User can download this form by clicking download.


Print Preview of Billing Document

Below backend call was made on click of Print button to fetch the PDF data .
“/sap/opu/odata/sap/ZGW_OTC_SELLBUYBACK_SRV/GetPDFDisplaySet (‘94000058’)/$value”

That’s the end of the topic, I appreciate that you have gone through the concept. This was one such requirement where extension is required on top of Fiori list report.

In the 2nd part of the blog, I will be explaining how we can switch/ convert SEGW project to Unmanaged query (Custom CDS view) to make the solution as cloud ready.

Part-2- Preview/Download Fragmented Forms from Fiori List Report (Part -2) | SAP Blogs

Assigned Tags

      You must be Logged on to comment or reply to a post.
      Author's profile photo Ila Tyagi
      Ila Tyagi

      Thanks for sharing!

      Very Explanatory.

      Author's profile photo Anjali Singh
      Anjali Singh

      Well Explained blog.

      Author's profile photo Rahul Ranjan
      Rahul Ranjan

      Very well documented and explained.

      Author's profile photo Ketan Agarwal
      Ketan Agarwal

      Thanks for Sharing!


      Very detailed explanation!

      Author's profile photo Pratham Kapoor
      Pratham Kapoor

      Thanks for detailed document.

      Author's profile photo Harish Bhatt
      Harish Bhatt

      Nice Blog, precisely explained.

      Author's profile photo Nishu Bajpai
      Nishu Bajpai

      Very Well Explained!!

      Author's profile photo Rohit Patil
      Rohit Patil

      Thanks for sharing!

      Author's profile photo Satyam Raj
      Satyam Raj

      Thanks Abhishek! This is exactly what I was looking for, saved me a lot of time.