ABAPERS, sometimes we could a client requirement of merging multiple adobe forms and displaying it as one single pdf to the end-user.
However, after doing a lot of googling and reading numerous threads, I came across various solutions but some gave output as spool or some merged the forms but didn’t gave user to download the generated pdf into the system with desired location and name.
So, here I’ll provide the complete end-to-end solution with steps as well as the complete code, so that it really helps you. So let’s get started..
STEP 1:
Call function module FP_JOB_OPEN, with below parameters-
Data:ls_fp_outputparams TYPE sfpoutputparams.
ls_fp_outputparams-dest = 'LP01'"Depends on user settings
ls_fp_outputparams-nodialog = abap_true.
ls_fp_outputparams-preview = abap_false.
ls_fp_outputparams-getpdf = 'M'."(Default value = 'X')
ls_fp_outputparams-assemble = 'S'."bigger data
ls_fp_outputparams-bumode = 'M'."This is Bundle Mode
ls_fp_outputparams-reqnew = abap_true.
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.
RETURN.
ENDIF.
*Remember all the values should be passed exactly the same in order to achieve the functionality.
STEP 2:
Get the Adobe Form function Module using FP_FUNCTION_MODULE_NAME and call the generated unction module for your 1st Adobe Form.
Data:lv_fm_inv TYPE rs38l_fnam,
ls_fp_docparams TYPE sfpdocparams,
ls_pdf_file TYPE fpformoutput.
TRY.
CALL FUNCTION 'FP_FUNCTION_MODULE_NAME'
EXPORTING
i_name = 'ZFORM1'
IMPORTING
e_funcname = lv_fm_inv.
CATCH cx_fp_api_repository.
CATCH cx_fp_api_usage.
CATCH cx_fp_api_internal.
ENDTRY.
*&--- Call the generated function module
CALL FUNCTION lv_fm_inv
EXPORTING
/1bcdwb/docparams = ls_fp_docparams
IMPORTING
/1bcdwb/formoutput = ls_pdf_file
EXCEPTIONS
usage_error = 1
system_error = 2
internal_error = 3.
IF sy-subrc <> 0.
* <error handling>
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
RETURN.
ENDIF.
STEP 3:
Repeat Step 2, for 2nd Adobe Form. Call ‘FP_JOB_CLOSE’ to close the spool job.
*&---- Close the spool job
CALL FUNCTION 'FP_JOB_CLOSE'
* IMPORTING
* E_RESULT =
EXCEPTIONS
usage_error = 1
system_error = 2
internal_error = 3
OTHERS = 4.
IF sy-subrc <> 0.
* <error handling>
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
RETURN.
ENDIF.
Note: You can use LOOP..ENDLOOP to call FP_FUNCTION_MODULE_NAME and it’s generated function module if you have more than two adobe forms.
TYPES: BEGIN OF lty_forms,
form TYPE fpname,
END OF lty_forms,
lty_t_forms TYPE STANDARD TABLE OF lty_forms WITH EMPTY KEY..
Data:lt_forms type lty_t_forms.
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 = ls_fp_docparams
iv_final = lwa_final
IMPORTING
/1bcdwb/formoutput =ls_pdf_file
EXCEPTIONS
usage_error = 1
system_error = 2
internal_error = 3
OTHERS = 4.
IF sy-subrc <> 0.
ENDIF.
CLEAR: lwa_forms, lv_fm_name.
ENDLOOP
STEP 4:
Call function module,’ FP_GET_PDF_TABLE’, to merge multiple generated files into a single pdf.
DATA:lt_data TYPE STANDARD TABLE OF tabl1024, "RAWSTRING
lo_pdf_merger TYPE REF TO cl_rspo_pdf_merge,
lt_pdf_table TYPE tfpcontent,
lv_merged_document TYPE xstring,
lv_len TYPE i,
lv_rc TYPE i VALUE 0.
*&&-- Merging different PDF files into one
CREATE OBJECT lo_pdf_merger.
CALL FUNCTION 'FP_GET_PDF_TABLE'
IMPORTING
e_pdf_table = lt_pdf_table.
We will use standard class cl_rspo_pdf_merge methods which can be
reffered from the program:RSPO_TEST_MERGE_PDF_FILES.The same class
can be used to write to a SAP application server.
* Add documents to attribute table of PDF merger
LOOP AT lt_pdf_table 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 ).
CALL FUNCTION 'SCMS_XSTRING_TO_BINARY'
EXPORTING
buffer = lv_merged_document
IMPORTING
output_length = lv_len
TABLES
binary_tab = lt_data.
Step 5:
We will call the method cl_gui_frontend_services=>file_save_dialog, which gives user choice to name and save the pdf at the desired location.
DATA:lv_file TYPE string,
lv_path TYPE string,
lv_file_name TYPE string.
CALL METHOD cl_gui_frontend_services=>file_save_dialog
EXPORTING
window_title = 'Save Form' "You can pass any value as per your choice
default_extension = '.pdf'
default_file_name = 'Invoice.pdf'
prompt_on_overwrite = 'X'
CHANGING
filename = lv_file_name
path = lv_path
fullpath = lv_file
EXCEPTIONS
cntl_error = 1
error_no_gui = 2
not_supported_by_gui = 3
invalid_default_file_name = 4
OTHERS = 5.
IF sy-subrc <> 0.
* Implement suitable error handling here
ENDIF
STEP 6:
Finally,We will call the method cl_gui_frontend_services=>gui_download, for downloading the file and cl_gui_frontend_services=>execute, to automatically open the pdf, after it is downloaded.
DATA:lt_data TYPE STANDARD TABLE OF tabl1024,
lv_file TYPE string,
lv_len TYPE i,
lv_rc TYPE i VALUE 0
CALL METHOD cl_gui_frontend_services=>gui_download
EXPORTING
bin_filesize = lv_len
filename = lv_file
filetype = 'BIN'
CHANGING
data_tab = lt_data
EXCEPTIONS
file_write_error = 1
no_batch = 2
gui_refuse_filetransfer = 3
invalid_type = 4
no_authority = 5
unknown_error = 6
header_not_allowed = 7
separator_not_allowed = 8
filesize_not_allowed = 9
header_too_long = 10
dp_error_create = 11
dp_error_send = 12
dp_error_write = 13
unknown_dp_error = 14
access_denied = 15
dp_out_of_memory = 16
disk_full = 17
dp_timeout = 18
file_not_found = 19
dataprovider_exception = 20
control_flush_error = 21
not_supported_by_gui = 22
error_no_gui = 23
OTHERS = 24.
IF sy-subrc IS NOT INITIAL.
ENDIF.
CALL METHOD cl_gui_frontend_services=>execute
EXPORTING
document = lv_file
synchronous = 'X'
EXCEPTIONS
cntl_error = 1
error_no_gui = 2
bad_parameter = 3
file_not_found = 4
path_not_found = 5
file_extension_unknown = 6
error_execute_failed = 7
synchronous_failed = 8
not_supported_by_gui = 9
OTHERS = 10.
IF sy-subrc IS NOT INITIAL.
ENDIF.
Below I’m also posting the complete code-
DATA: lv_fm_dpr TYPE rs38l_fnam, " CHAR 30 0 Name of Function Module
lv_fm_inv TYPE rs38l_fnam,
ls_fp_docparams TYPE sfpdocparams, " Structure SFPDOCPARAMS Short Description Form Parameters for Form Processing
ls_fp_outputparams TYPE sfpoutputparams, " Structure SFPOUTPUTPARAMS Short Description Form Processing Output Parameter
ls_pdf_file TYPE fpformoutput.
DATA:lt_data TYPE STANDARD TABLE OF tabl1024,
lo_pdf_merger TYPE REF TO cl_rspo_pdf_merge,
lt_pdf_table TYPE tfpcontent,
lv_file TYPE string,
lv_path TYPE string,
lv_file_name TYPE string,
lv_merged_document TYPE xstring,
lv_len TYPE i,
lv_rc TYPE i VALUE 0.
ls_fp_outputparams-dest = 'LP01'. "Depends on user settings
ls_fp_outputparams-nodialog = abap_true.
ls_fp_outputparams-getpdf = 'M'.
ls_fp_outputparams-assemble = 'S'.
ls_fp_outputparams-bumode = 'M'.
ls_fp_outputparams-reqnew = abap_true.
* Sets the output parameters and opens the spool job
CALL FUNCTION 'FP_JOB_OPEN' "& Form Processing: Call Form
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.
RETURN.
ENDIF.
TRY.
CALL FUNCTION 'FP_FUNCTION_MODULE_NAME' "& Form Processing Generation
EXPORTING
i_name = 'ZFORM1'
IMPORTING
e_funcname = lv_fm_inv.
CATCH cx_fp_api_repository.
CATCH cx_fp_api_usage.
CATCH cx_fp_api_internal.
ENDTRY.
**&---- Get the name of the generated function module
TRY.
CALL FUNCTION 'FP_FUNCTION_MODULE_NAME' "& Form Processing Generation
EXPORTING
i_name = 'ZFORM2'
IMPORTING
e_funcname = lv_fm_dpr.
CATCH cx_fp_api_repository.
CATCH cx_fp_api_usage.
CATCH cx_fp_api_internal.
ENDTRY.
* Language and country setting (here US as an example)
ls_fp_docparams-langu = 'E'.
ls_fp_docparams-country = 'US'.
*&--- Call the generated function module
CALL FUNCTION lv_fm_inv
EXPORTING
/1bcdwb/docparams = ls_fp_docparams
IMPORTING
/1bcdwb/formoutput = ls_pdf_file
EXCEPTIONS
usage_error = 1
system_error = 2
internal_error = 3.
IF sy-subrc <> 0.
* <error handling>
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
RETURN.
ENDIF.
*&--- Call the generated function module
CALL FUNCTION lv_fm_dpr
EXPORTING
/1bcdwb/docparams = ls_fp_docparams
IMPORTING
/1bcdwb/formoutput = ls_pdf_file
EXCEPTIONS
usage_error = 1
system_error = 2
internal_error = 3.
IF sy-subrc <> 0.
* <error handling>
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
RETURN.
ENDIF.
*
* ENDLOOP.
*&---- Close the spool job
CALL FUNCTION 'FP_JOB_CLOSE'
* IMPORTING
* E_RESULT =
EXCEPTIONS
usage_error = 1
system_error = 2
internal_error = 3
OTHERS = 4.
IF sy-subrc <> 0.
* <error handling>
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
RETURN.
ENDIF.
*&&-- Merging different PDF files into one
CREATE OBJECT lo_pdf_merger.
CALL FUNCTION 'FP_GET_PDF_TABLE'
IMPORTING
e_pdf_table = lt_pdf_table.
* Add documents to attribute table of PDF merger
LOOP AT lt_pdf_table 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 ).
CALL FUNCTION 'SCMS_XSTRING_TO_BINARY'
EXPORTING
buffer = lv_merged_document
IMPORTING
output_length = lv_len
TABLES
binary_tab = lt_data.
CALL METHOD cl_gui_frontend_services=>file_save_dialog
EXPORTING
window_title = 'Save Form'
default_extension = '.pdf'
default_file_name = 'Invoice.pdf'
prompt_on_overwrite = 'X'
CHANGING
filename = lv_file_name
path = lv_path
fullpath = lv_file
EXCEPTIONS
cntl_error = 1
error_no_gui = 2
not_supported_by_gui = 3
invalid_default_file_name = 4
OTHERS = 5.
IF sy-subrc <> 0.
* Implement suitable error handling here
ENDIF.
CALL METHOD cl_gui_frontend_services=>gui_download
EXPORTING
bin_filesize = lv_len
filename = lv_file
filetype = 'BIN'
CHANGING
data_tab = lt_data
EXCEPTIONS
file_write_error = 1
no_batch = 2
gui_refuse_filetransfer = 3
invalid_type = 4
no_authority = 5
unknown_error = 6
header_not_allowed = 7
separator_not_allowed = 8
filesize_not_allowed = 9
header_too_long = 10
dp_error_create = 11
dp_error_send = 12
dp_error_write = 13
unknown_dp_error = 14
access_denied = 15
dp_out_of_memory = 16
disk_full = 17
dp_timeout = 18
file_not_found = 19
dataprovider_exception = 20
control_flush_error = 21
not_supported_by_gui = 22
error_no_gui = 23
OTHERS = 24.
IF sy-subrc IS NOT INITIAL.
ENDIF.
CALL METHOD cl_gui_frontend_services=>execute
EXPORTING
document = lv_file
synchronous = 'X'
EXCEPTIONS
cntl_error = 1
error_no_gui = 2
bad_parameter = 3
file_not_found = 4
path_not_found = 5
file_extension_unknown = 6
error_execute_failed = 7
synchronous_failed = 8
not_supported_by_gui = 9
OTHERS = 10.
IF sy-subrc IS NOT INITIAL.
ENDIF.
CLEAR:lv_file,lv_len,lv_path,lv_file_name,lt_data.
You can also check this in spool request(SP01) and download it to your system as well.
Source: sap.com
No comments:
Post a Comment