Skip to Content
Technical Articles
Author's profile photo Sugato Biswas

How to merge multiple PDF forms into single one and write in application server

Hello!!!

Today I will try to explain how we can merge multiple PDF forms output into single one and write the same PDF file into application server.

Brief requirement: The real life scenario demanded to send a bundle of different SAP system generated PDF forms to a third party document repository ( has access to the SAP application server ) . The form bundle contains different forms like cover letter, loan agreement, direct debit, third party authorization, terms and condition forms etc.

In the below example we will see how the 5 different PDF forms are getting stitched into one. Here is the sample code of the driver program. Just use it to play and observe the behavior:

 

Code Block 1: Data Declaration. Below 5 constants are the different PDF forms created in the system.

TYPES: BEGIN OF lty_forms,
         form TYPE fpname,
       END OF lty_forms,

       lty_t_forms TYPE STANDARD TABLE OF lty_forms WITH EMPTY KEY.

*&&-- Below are the 5 different Adobe form names created for Contract
CONSTANTS: lc_form_cover       TYPE fpname VALUE 'ZFI_CP_COVER_LETTER',
           lc_form_agreement   TYPE fpname VALUE 'ZFI_CP_LOAN_AGREEMENT',
           lc_form_debit       TYPE fpname VALUE 'ZFI_CP_DIRECT_DEBIT',
           lc_form_third_party TYPE fpname VALUE 'ZFI_CP_THIRD_PARTY',
           lc_form_terms       TYPE fpname VALUE 'ZFI_CP_TERMS_CONDITION'.

DATA: lwa_outputparams   TYPE sfpoutputparams,
      lv_fm_name         TYPE rs38l_fnam,
      lwa_docparams      TYPE sfpdocparams,
      lwa_formoutput     TYPE fpformoutput,
      lt_pdfcontent      TYPE TABLE OF solix,
      lt_formoutput      TYPE tfpcontent,
      lv_merged_document TYPE xstring,
      lv_rc              TYPE i,
      lv_file_name       TYPE string,
      lwa_final          TYPE zsfi_int_sub.

DATA: lo_pdf_merger TYPE REF TO cl_rspo_pdf_merge.​

 

Code Block 2: Populate the multiple form names into internal table and pass desired values to output parameters to trigger the form.

*&&-- Populate the multiple form names into an internal table
DATA(lt_forms) = VALUE lty_t_forms( ( form = lc_form_cover )
                                      ( form = lc_form_agreement )
                                      ( form = lc_form_debit )
                                      ( form = lc_form_third_party )
                                      ( form = lc_form_terms ) ).

lwa_outputparams-nodialog = abap_true.
lwa_outputparams-dest     = 'LOCL'.
lwa_outputparams-getpdf   = 'M'.
lwa_outputparams-bumode   = 'M'.   " Bundle Mode Multiple​

 

Code Block 3: Trigger the 5 forms one by one inside LOOP. The interface import parameters are same for 5 forms. You can mark import parameters in the interface as optional so that different parameters can be used for different forms. Creating single interface will be easier to maintain.

*&---------------------------------------------------------------------*
*& Form Processing: Call Form - Open
*&---------------------------------------------------------------------*
CALL FUNCTION 'FP_JOB_OPEN'
  CHANGING
    ie_outputparams = lwa_outputparams
  EXCEPTIONS
    cancel          = 1
    usage_error     = 2
    system_error    = 3
    internal_error  = 4
    OTHERS          = 5.
IF sy-subrc <> 0.
  " Suitable Error Handling
ENDIF.

LOOP AT lt_forms INTO DATA(lwa_forms).
  TRY.
      CALL FUNCTION 'FP_FUNCTION_MODULE_NAME'
        EXPORTING
          i_name     = lwa_forms-form
        IMPORTING
          e_funcname = lv_fm_name.

    CATCH cx_fp_api.
  ENDTRY.

  CALL FUNCTION lv_fm_name
    EXPORTING
      /1bcdwb/docparams  = lwa_docparams
     iv_final           = lwa_final
    IMPORTING
      /1bcdwb/formoutput = lwa_formoutput
    EXCEPTIONS
      usage_error        = 1
      system_error       = 2
      internal_error     = 3
      OTHERS             = 4.

  IF sy-subrc <> 0.
  ENDIF.

  CLEAR: lwa_forms, lwa_formoutput, lv_fm_name.
ENDLOOP.

CALL FUNCTION 'FP_JOB_CLOSE'
  EXCEPTIONS
    usage_error    = 1
    system_error   = 2
    internal_error = 3
    OTHERS         = 4.
IF sy-subrc <> 0.
* Implement suitable error handling here
ENDIF.
​

 

Code Block 4: Merge form’s PDF output into one. Internal table LT_FORMOUTPUT will contain 5 rows with PDF data in XSTRING format for 5 different forms.

*&&-- Merging different PDF files into one

CREATE OBJECT lo_pdf_merger.

CALL FUNCTION 'FP_GET_PDF_TABLE'
  IMPORTING
    e_pdf_table = lt_formoutput.

* Add documents to attribute table of PDF merger
LOOP AT lt_formoutput INTO DATA(lwa_form).
  lo_pdf_merger->add_document( lwa_form ).
ENDLOOP.

* Call kernel method to do the merge of the specified files.
lo_pdf_merger->merge_documents( IMPORTING merged_document = lv_merged_document
                                                       rc = lv_rc ).​

 

Code Block 5: Write the PDF file to application directory. The variable LV_MERGED_DOCUMENT contains the merged XSTRING value of those 5 forms.

CONCATENATE 'Loan_Contract' sy-datum sy-uzeit INTO DATA(lv_name) SEPARATED BY '_'.
CONCATENATE lv_name '.pdf' INTO lv_name.

REFRESH: lt_formoutput.
lwa_formoutput-pdf = lv_merged_document.

CALL FUNCTION 'FILE_GET_NAME_USING_PATH'
  EXPORTING
    client                     = sy-mandt
    logical_path               = 'ZFI_CUSTSTMT_PATH'
    file_name                  = lv_name
  IMPORTING
    file_name_with_path        = lv_file_name
  EXCEPTIONS
    path_not_found             = 1
    missing_parameter          = 2
    operating_system_not_found = 3
    file_system_not_found      = 4
    OTHERS                     = 5.
IF sy-subrc <> 0.
* Implement suitable error handling here
ENDIF.

*PDF Upload
IF lwa_formoutput-pdf IS NOT INITIAL.
  lt_pdfcontent = cl_document_bcs=>xstring_to_solix( ip_xstring = lwa_formoutput-pdf ).

  OPEN DATASET lv_file_name FOR OUTPUT IN BINARY MODE .

  IF  sy-subrc = 0.

    LOOP AT lt_pdfcontent INTO DATA(lwa_pdfcontent).
      TRANSFER lwa_pdfcontent-line TO lv_file_name.
    ENDLOOP.

    CLOSE DATASET lv_file_name.

    REFRESH lt_pdfcontent.
  ENDIF.

ENDIF.​

 

OUTPUT:

File has been written in application server successfully. This file can be downloaded in PDF format using CG3Y transaction from application directory for verification. You will not be able to open this PDF file directly from AL11.

 

Note: During the test, it was triggering error/merge failure message at the time of merging. You may need to implement the below OSS note to resolve the error related to class CL_RSPO_PDF_MERGE.

2264208

There is a sample program RSPO_TEST_MERGE_PDF_FILES which contains all the required codes to play around with PDF merging. Just explore this for other merging functionalities.

 

In the above example, we can send the output to the Spool as well. Just pass the below parameters in the code lines of code block 2 , followed by code block 3.

lwa_outputparams-nodialog = abap_true.
lwa_outputparams-device  = 'PRINTER'.
lwa_outputparams-reqnew = abap_true.
lwa_outputparams-dest     = 'LOCL'.
lwa_outputparams-bumode   = 'M'.   " Bundle Mode Multiple

Spool request with single PDF will be generated. For our example, 36 pages have been generated for 5 forms.

Once you open the PDF in spool, you can see the 5 forms. You can check one by one by clicking arrow sign or you can click “Overall View On” to get a merged view.

 

If you want to test the code, just create two dummy PDF forms ( Transaction SFP ) and replace those form names mentioned in the constants.

 

Thanks for reading the blog post and please let me know your feedback!!

 

Cheers !!,

Sugato

Assigned Tags

      20 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Gustavo Vazquez
      Gustavo Vazquez

      Nice blog !!!!!!

      Author's profile photo Sugato Biswas
      Sugato Biswas
      Blog Post Author

      Thanks Gustavo..

      Author's profile photo Somnath Paul
      Somnath Paul

      Thank Sugata!! Nice blog.

      Author's profile photo Sugato Biswas
      Sugato Biswas
      Blog Post Author

      Thanks Somnath

      Author's profile photo Shibojyoti Banerjee
      Shibojyoti Banerjee

      Very helpful.

      Author's profile photo Sugato Biswas
      Sugato Biswas
      Blog Post Author

      Thanks Shibojyoti

      Author's profile photo Amith Poojary
      Amith Poojary

      Thanks for the detailed blog Sugato ..

      Author's profile photo Sugato Biswas
      Sugato Biswas
      Blog Post Author

      Thanks Amith

       

      Author's profile photo Joachim Rees
      Joachim Rees

      Thanks for showing us a way in ABAP!
      If you ever have/want to do that (merge PDF-Files into a singel one) on your PC (or maybe on your server as well), I can really recommend PDFsam -> PDF Split And Merge

      https://pdfsam.org/

      I find it really helpfull!

      best
      Joachim

      Author's profile photo Sugato Biswas
      Sugato Biswas
      Blog Post Author

      Thanks Joachim

      Author's profile photo Akshay Jain
      Akshay Jain

      Good one Sugato:) Keep Blogging!!

      Author's profile photo Francisco Javier Kurtz Lamata
      Francisco Javier Kurtz Lamata

      Thanks for the information. Very helpful post!

       

      Francisco.

      Author's profile photo seokyeon Hong
      seokyeon Hong

      Really Awesome.... I always tried to make forms by looping that throw to interface multiple key in sfp..

       

      Thanks.

      Author's profile photo Dinesh Kumar
      Dinesh Kumar

      Sugato Biswas :  Hi Sugato, my requirement is that I need to print PO form (From ME21/22/23N) along with this I need to merge the Terms & Conditions( Stored on AL11).

       

      The terms & conditions are being read from AL11 and these are in Xstring format.

       

      I am able to merge these documents and send it over an email as a single attachment.

       

      But what the requirement is that both these need to be displayed together when user clicks on Print Preview. AL11 T&C and PO form should be displayed as merged document together.

       

      How can i achieve this?

       

      Thanks,

      Dinesh

      Author's profile photo Prakash Mani
      Prakash Mani

      Nice and detailed program on how to use!!

      Author's profile photo Ray Mannion
      Ray Mannion

      You've saved my life with this!! I was tasked with capturing many spools into a single PDF file and I had tried so many different options without success. Your code and post were very easy to read. Well done!

      Author's profile photo MANIKANDAN RAJASEKARAN
      MANIKANDAN RAJASEKARAN

      Hi Sugato Biswas ,

      I tried and coded as you specified. In debugging I can see the data determined in lt_formoutput (but 2 entries of same values). I also updated into the server file but it has written as 2 separate forms only  when I call the pdf-obj value using the custom program to display the form.

      Can you help pls?

      lt_formoutput
      Author's profile photo MANIKANDAN RAJASEKARAN
      MANIKANDAN RAJASEKARAN

      Hi  Sugato Biswas ,

      I followed the standard program RSPO_TEST_MERGE_PDF_FILES and I can able to view that my 2 Forms are merged into a single PDF Form. Thanks for your awesome blog and KT here.

      I also need your help, how to manage the page form as it is displaying as Page 1 of 1 for 2 pages.

      It suppose to be corrected and write with page count correctly.

      Please help.

      Thanks.

      Author's profile photo Tharindu Jayawardana
      Tharindu Jayawardana

      Thanks alot for the Blog post!

      I'm trying the same thing, however my page numbering restarts everytime a new document is merged.

      Is it possible to get the total count of pages within content (e.g. 1 of 9)

      Author's profile photo Jill Michael
      Jill Michael

      Hi .To borrow a Chinese saying to praise you.

      "真牛逼!"