Build your first simple Form Data Provider
For getting started with form development, you only strictly require 4 artifacts:
- Form template
- Service Definition (Service Binding is not necessary!)
- Set of CDS views to model your business data
- ABAP Class to start the process from
Based on this knowledge we can build a simple form output, that will work on virtual data.
Sample location:
For reference, check out the package: ZFDP_SCRATCH This contains:
- Service Definition: ZFDP_SCRATCH_SRVD
- Class: ZCL_FDP_SCRATCH_TEST
That will quickly showcase the FDP data retrieval framework.
Sample Data Model
For this sample we have a flat data service, that only returns the structure of the custom entity (ZCE_FDP_SCRATCH_ROOT):
@EndUserText.label: 'Simple form data provider'
@ObjectModel.leadingEntity.name: 'ZCE_FDP_SCRATCH_ROOT'
define service ZFDP_SCRATCH_SRVD {
expose ZCE_FDP_SCRATCH_ROOT;
}<?xml version="1.0" encoding="utf-8"?>
<Form version="2">
<ZCE_FDP_SCRATCH_ROOT>
<name>CB9980000000</name>
<language>E</language>
<iso>EN</iso>
<userAlias>Initial Admin</userAlias>
<tz>UTC</tz>
<syDate>20251108</syDate>
<syTime>205654</syTime>
<syURL>XXX.ondemand.com</syURL>
</ZCE_FDP_SCRATCH_ROOT>
</Form>@ObjectModel.query.implementedBy: 'ABAP:ZCL_FDP_SCRATCH_IMPL'
@ObjectModel.supportedCapabilities: [ #OUTPUT_FORM_DATA_PROVIDER ]
define custom entity ZCE_FDP_SCRATCH_ROOT {
key name: abap.string( 0 );
language: abap.char( 1 );
iso: abap.char( 2 );
userAlias: abap.string( 0 );
tz: abap.char( 6 );
syDate: abap.char( 8 );
syTime: abap.char( 6 );
syURL: abap.string( 0 );
}"...
INSERT VALUE zce_fdp_scratch_root(
iso = cl_abap_context_info=>get_user_language_iso_format( lv_username )
language = cl_abap_context_info=>get_user_language_abap_format( lv_username )
name = lv_username
tz = cl_abap_context_info=>get_user_time_zone( lv_username )
userAlias = cl_abap_context_info=>get_user_description( lv_username )
syDate = cl_abap_context_info=>get_system_date( )
syTime = cl_abap_context_info=>get_system_time( )
syURL = xco_cp=>current->tenant( )->get_url( xco_cp_tenant=>url_type->ui )->get_host( ) )
INTO TABLE table.
"...TIP
Notice the annotation:
@ObjectModel.supportedCapabilities: [ #OUTPUT_FORM_DATA_PROVIDER ]?
This indicates that this CDS is designed for form output. Please add it to your root cds entity
The custom entity implementation was deliberately shortened, as it contains a lot of boilerplate for implementing a custom entity. This section only highlights the part, where the actual data is injected.
Generate xml data tree from
We can transform the above data model to xml by calling our reuse class. This works by:
- Initialize the reuse class by passing the service definition
- Init the select key object
- Insert the value of your root view key properties
- The process is designed, that using the key object, only a single root entity item shall be returned.
DATA(util) = cl_fp_fdp_services=>get_instance( |ZFDP_SCRATCH_SRVD| ).
DATA(keys) = util->get_keys( ).
keys[ name = 'NAME' ]-value = sy-uname.
" TODO: variable is assigned but never used (ABAP cleaner)
DATA(data) = util->read_to_xml_v2( keys ).TIP
For detailed documentation of our API, see the online help
Generate a PDF docoument
Upload the custom form template
You need to manually upload the form template to the ABAP system.
- Download it here
- In ADT create a new Form object. See also our online help
- Insert the Data Provider Name

- Upload the template

- Save and activate

- Insert the Data Provider Name
Adjust the class
After creating a new form object, it can be used via ABAP reuse class.
DATA(form) = DATA(form) = cl_fp_form_reader=>create_form_reader( CONV #( |ZFORM_FDP_SCRATCH| ) ).
DATA(util) = cl_fp_fdp_services=>get_instance( form->get_fdp_name( ) ).
DATA(keys) = util->get_keys( ).
keys[ name = 'NAME' ]-value = sy-uname.
DATA(xml) = util->read_to_xml_v2( keys ).
cl_fp_ads_util=>render_pdf(
EXPORTING
iv_locale = 'en_US'
iv_xdp_layout = form->get_layout( )
iv_xml_data = xml
is_options = VALUE #(
"0 - only errors <= intended for production
"4 - very detailed trace <= intended for development
trace_level = 4
embed_fonts = form->get_font_embed( ) )
IMPORTING
ev_pdf = DATA(pdf)
ev_trace_string = DATA(logs)
).
"If you want to output pdfs to a UI, convert xstream to base64
DATA(output) = cl_web_http_utility=>encode_x_base64( pdf ).Preview PDF using Previewer.
After implementing the above output, we might face the dilemma, that the generated pdf cannot be easily previewed. To address this issue, the sample repository contains a dedicated tool to display your form development using a custom HTTP service.
Follow the dedicated guide to setup the tool in your system. After setup is finished, you will be able to preview your development easily.
