Seamless Integration of External PDFs into Existing Output Files

Seamless Integration of External PDFs into Existing Output Files

A practical ABAP guide to merging SAPscript, Smart Forms & Adobe Form output with external PDFs

Business requirements often go beyond standard SAP output. In many scenarios, users need to include additional PDF documents—such as engineering drawings, specifications, or supporting attachments—directly with SAP-generated output.

In this blog, we walk through an ABAP-based approach for attaching external PDFs to output generated from SAPscript, Smart Forms, and Adobe Forms. The objective is to standardize each source as PDF data, merge the documents, and deliver one complete output to end users.

The High-Level Approach

Regardless of the form technology used to produce the original output, the merge process follows the same six logical stages:

  1. Get OTF data from the form
  2. Convert OTF to PDF
  3. Add the PDF Content to the Merge Sequence
  4. Get the external PDF (also as XSTRING)
  5. Merge both PDFs together
  6. Send or store the final merged PDF

Each SAP form technology produces output differently. SAPscript and Smart Forms generate OTF, while Adobe Forms generate PDF directly through Adobe Document Services. To merge documents consistently, every source must ultimately be available as a PDF byte stream, typically handled as XSTRING in ABAP.

StageSAPscript / Smart FormsAdobe Forms
Native outputOTFPDF (direct)
Conversion neededCONVERT_OTF → TLINE → XSTRINGNone — already XSTRING
Key flag/paramTDGETOTF / GETOTF = ‘X’Native via ADS, no flag needed
Merge-ready formatXSTRING (after conversion)XSTRING (as-is)

Let’s Go Through the Steps Involved

1. Getting OTF from each form type

SAPscript :

To enable PDF merging and spool processing, set the SAPscript output interface parameter TDGETOTF to ‘X’. This is done by setting PRINT_OPTS-TDGETOTF = ‘X’ before calling OPEN_FORM, so the form output is generated as OTF data instead of being sent directly to the printer.

After form processing is complete, retrieve the generated OTF data from CLOSE_FORM:

CALL FUNCTION 'CLOSE_FORM'
  IMPORTING
    result  = pr_result
  " Get OTF Data
  TABLES
    otfdata = gt_otf_data.

SmartForms:

For Smart Forms, set the GETOTF flag in the control structure so the output is returned as OTF instead of being printed immediately:

ls_control_param-getotf = 'X'.

Adobe Forms:

Adobe Forms work differently because they generate PDF output natively through Adobe Document Services. There is no OTF conversion step; call the generated function module and read the PDF directly from the output structure:

CALL FUNCTION lv_fm_name
  EXPORTING
    /1bcdwb/docparams  = ls_docparams
  IMPORTING
    /1bcdwb/formoutput = ls_output
lv_pdf = ls_output-pdf.   " Already in PDF format

2. Convert OTF to PDF

Once OTF data has been captured from SAPscript or Smart Forms, convert it into PDF content using the standard function module CONVERT_OTF:

" Convert OTF format to PDF content
CALL FUNCTION 'CONVERT_OTF'
  EXPORTING
    format       = 'PDF'
  IMPORTING
    bin_filesize = lv_binfilesize
    bin_file     = lv_bin_script
  TABLES
    otf          = gt_otf_data   " Input table with OTF format
    lines        = gt_pdf_script.

SmartForms:

For Smart Forms, an additional conversion step may be required to move the binary table into an XSTRING buffer:

" Convert TLINE binary table to XSTRING
CALL FUNCTION 'SCMS_BINARY_TO_XSTRING'
  EXPORTING
    input_length = lv_pdf_size
  IMPORTING
    buffer       = lv_pdf_smartform
  TABLES
    binary_tab   = lt_lines.

3. Add the PDF content to the merge sequence

After the PDF content is available as XSTRING, register it with the merge object using ADD_DOCUMENT. Each call appends one PDF to the merge sequence in the required order:

DATA: lo_pdf_merged TYPE REF TO cl_rspo_pdf_merge.
               lo_pdf_merged->add_document( document = lv_bin_script ).

4. Get the external PDF from the application server

Next, read the external PDF—for example, an engineering drawing—from the application server in binary mode. Once the PDF content is available, add it to the same merge sequence.

DATA: lt_raw_pdfdata TYPE STANDARD TABLE OF x255,
      lt_raw_pdf     TYPE TABLE OF rspolpbi,
      lv_line        TYPE xstring.
OPEN DATASET gv_filename FOR INPUT IN BINARY MODE.
IF sy-subrc IS NOT INITIAL.
  REPLACE '.pdf' IN gv_filename WITH '.PDF'.
  " Read the file from application server (try alt. case)
  OPEN DATASET gv_filename FOR INPUT IN BINARY MODE.
ENDIF.
IF sy-subrc = 0.
DO.
    READ DATASET gv_filename INTO lv_line.
    IF sy-subrc IS NOT INITIAL.
      EXIT.
    ENDIF.
    APPEND lv_line TO lt_raw_pdfdata.
    " Add second PDF: move to the document table
    IF lv_line IS NOT INITIAL.
      lo_pdf_merged->add_document( lv_line ).
    ENDIF.
  ENDDO.
ENDIF.
" Close dataset
CLOSE DATASET gv_filename.

5. Merge the documents

After all PDF sources are added to the merge object, call MERGE_DOCUMENTS to generate one combined PDF:

DATA: lo_pdf_merged TYPE REF TO cl_rspo_pdf_merge.
lo_pdf_merged->merge_documents(
  IMPORTING
    merged_document = DATA(lv_merged_pdf)
    rc       = DATA(rc_code)).

For mass processing, suppress the print dialog so the job can run unattended:

" During mass-processing, no popup for print dialog.
" !! The printer ZPDF is set as a fixed value;
"    for dynamic values, 'dest' must be swapped out !!
DATA(ls_outputparams) = VALUE sfpoutputparams(
  nodialog = abap_true
  dest     = 'ZPDF' ).

6. Generate the external output as PDF

Finally, send the merged PDF to a spool job through Adobe Document Services. Start by opening the job and setting immediate printing if required:

ls_outputparams-reqimm = 'X'.
CALL FUNCTION 'FP_JOB_OPEN'
  CHANGING
    ie_outputparams = ls_outputparams
  EXCEPTIONS
    cancel          = 1
    usage_error     = 2
    system_error    = 3
    internal_error  = 4
    OTHERS          = 5.
lv_copies   = ls_outputparams-copies.
lv_lifetime = ls_outputparams-lifetime.

Then create the spool job from the merged PDF data using ADS_CREATE_PDF_SPOOLJOB.

CALL FUNCTION 'ADS_CREATE_PDF_SPOOLJOB'
  EXPORTING
    dest            = ls_outputparams-dest
    pages           = 100
    pdf_data        = lv_pdf
    name            = ls_outputparams-dataset
    suffix1         = ls_outputparams-suffix1
    suffix2         = ls_outputparams-suffix2
    copies          = lv_copies_ads
    immediate_print = ls_outputparams-reqimm
    auto_delete     = ls_outputparams-reqdel
    titleline       = ls_outputparams-covtitle
    receiver        = ls_outputparams-receiver
    division        = ls_outputparams-division
    authority       = ls_outputparams-authority
    lifetime        = lv_lifetime
  IMPORTING
    spoolid         = lv_spoolid_ads.

After the spool request is created, close the job using FP_JOB_CLOSE.

This approach is technology-agnostic at the merge layer. Whether the original output comes from SAPscript, Smart Forms, or Adobe Forms, the process becomes consistent once each source is available as PDF XSTRING data. From there, use ADD_DOCUMENT for each PDF, MERGE_DOCUMENTS to combine the files, and ADS_CREATE_PDF_SPOOLJOB or another output channel to deliver the final document.

Conclusion

Merging external PDFs into SAP-generated output doesn’t require a different strategy for every form of technology, it requires one consistent target format. Once SAPscript and Smart Forms output is converted from OTF to XSTRING, and Adobe Forms output is used as-is (since it’s already PDF), all three sources speak the same language: PDF byte streams that CL_RSPO_PDF_MERGE can combine through a simple ADD_DOCUMENT / MERGE_DOCUMENTS sequence. This gives you a reusable pattern rather than a one-off solution. That is what makes the approach practical to standardize across multiple forms and reuse on future requirements, rather than building a separate merge process for every form type that comes up.

AUTHOR
Sudha Rani Pathuri
AUTHOR Sudha Rani Pathuri SAP Technical Consultant
Similar Posts
SAP S/4HANA EWM Mobile Execution

SAP S/4HANA EWM Mobile Execution: Fiori Apps vs RF Framework

Choosing between SAP S/4HANA EWM Fiori apps and the RF Framework depends on your warehouse—not a one-size-fits-all answer. This blog breaks down usability, performance, and real-world scenarios to help you select the right mobile execution.
06/24/2026
SAP|Manufacturing|SAP S/4HANA
Performance Optimization Strategies

Performance Optimization Strategies: SAP ABAP ECC vs S/4HANA

Moving from ECC to S/4HANA is not just a technical migration — it demands a fundamental shift in how ABAP developers think about performance. Here's what changes, and how to write code that truly leverages HANA.
07/22/2026
SAP|Manufacturing|SAP S/4HANA