Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
Juwin
Active Contributor
Inspired by: Watermark on all Smartforms

Requirement: Watermark should be included on all Adobe form printouts, without having to individually include them in each form design. This is to identify when the printout is generated from a test/development system, it carries a warning to indicate that it is for non-productive use only.

I haven't tried to use this on interactive Adobe forms, but I believe the same concept should work there too.

First, let's create a test Adobe form with just the Watermark. Few considerations while creating this form:

  1. It can either contain just Text or Image or both. I prefer just Text and I will explain why later.

  2. Justify the content to Top-Left corner. This is to make sure that, the watermark is printed at the same position, whether the actual Adobe form is designed in Portrait or Landscape mode.


Here is my Form. You don't have to activate and transport this Form. It can be deleted after completing all necessary adjustments.


 

Next, download the Form Layout


Open this layout file in a Text processing software - like Notepad++

It should look something like this:


If you had included an image in the form, then the XML file will have the Image data also. This makes the file a little bigger and that's why I suggested to avoid it. But, if you definitely need the Image on the Watermark, then go ahead.


Now, clean-up time, for my 'Text Only' Watermark, this is the portion of the XML that I am interested in. I have deleted other unnecessary elements also below.


After the required cleanup, the final result should look something like this:
<subform h="6.35mm" name="watermark" w="215.9mm">
<bind match="none"/>
<draw h="6.35mm" name="Text1" w="215.9mm">
<ui>
<textEdit/>
</ui>
<value>
<text>This is a watermark text</text>
</value>
<font typeface="Arial"/>
<margin bottomInset="0.5mm" leftInset="0.5mm" rightInset="0.5mm" topInset="0.5mm"/>
</draw>
</subform>

If you wish to, you can skip all of the Form creation/manipulation steps above and just use the XML I have pasted here.

Now, create a Class with the following code. I have modified the Watermark text below directly in the code, just to show that text can be dynamically modified. The constants declared below starting from LC_101... LC_107 is the data from above XML. If you had included an image in the form definition, then the XML code becomes bigger. Here, I am simply checking whether the system is not Production system - you may include any other checks as per your requirements.

The code loads the Form Layout XML document, then traverses through each page, and adds the extra Watermark code in it.
CLASS zclb_adobe_watermark DEFINITION
PUBLIC
FINAL
CREATE PUBLIC .

PUBLIC SECTION.
CLASS-METHODS add_watermark
IMPORTING
VALUE(im_fpname) TYPE fpname
VALUE(im_langu) TYPE sy-langu
CHANGING
VALUE(ch_xftcontent) TYPE fpcontent OPTIONAL
VALUE(ch_xftfile) TYPE fpfile OPTIONAL .

PROTECTED SECTION.

PRIVATE SECTION.
CONSTANTS:
c_001 TYPE c LENGTH 1 VALUE `E` ##NO_TEXT.

CLASS-METHODS find_pagearea
IMPORTING
VALUE(im_page) TYPE REF TO if_ixml_node
RETURNING
VALUE(re_area) TYPE REF TO if_ixml_node_list .
CLASS-METHODS get_form_layout
IMPORTING
VALUE(im_fpname) TYPE fpname
VALUE(im_langu) TYPE sy-langu DEFAULT c_001
RETURNING
VALUE(re_xftcontent) TYPE fpcontent .
ENDCLASS.

CLASS ZCLB_ADOBE_WATERMARK IMPLEMENTATION.
METHOD add_watermark.
CONSTANTS: lc_003 TYPE c LENGTH 3 VALUE `PS1`,
lc_001 TYPE string VALUE 'pageSet',
lc_101 TYPE string VALUE '<subform h="6.35mm" name="WATERMARK" w="215.9mm">',
lc_102 TYPE string VALUE '<bind match="none"/><draw h="6.35mm" name="WatermarkText" w="215.9mm">',
lc_103 TYPE string VALUE '<ui><textEdit/></ui><value>',
lc_104 TYPE string VALUE '<text>DEMO ONLY: This output was generated from a non-productive system (',
lc_105 TYPE string VALUE ')</text></value><font typeface="Arial"/>',
lc_106 TYPE string VALUE '<margin bottomInset="0.5mm" leftInset="0.5mm" rightInset="0.5mm" topInset="0.5mm"/>',
lc_107 TYPE string VALUE '<para hAlign="left"/></draw></subform>'.
DATA: lo_wdocument TYPE REF TO cl_xml_document,
lo_wnodes TYPE REF TO if_ixml_node,
lo_fdocument TYPE REF TO cl_xml_document.
CHECK sy-sysid NE lc_003.

TRY.
CREATE OBJECT: lo_wdocument, lo_fdocument.
lo_fdocument->parse_xstring( get_form_layout( im_fpname = im_fpname im_langu = im_langu ) ).
lo_wdocument->parse_string(
lc_101 && lc_102 && lc_103 && lc_104 && sy-sysid && sy-mandt && lc_105 && lc_106 && lc_107 ).

DATA(lo_pagenode) = lo_fdocument->find_node( lc_001 ).
DATA(lo_pages) = find_pagearea( lo_pagenode ).

DO lo_pages->get_length( ) TIMES.
DATA(lo_page) = lo_pages->get_item( sy-index - 1 ).
lo_page->append_child( lo_wdocument->get_first_node( )->clone( ) ).
ENDDO.

lo_fdocument->render_2_xstring( IMPORTING stream = ch_xftcontent ).
IF ch_xftcontent IS NOT INITIAL.
CLEAR: ch_xftfile.
ENDIF.
CATCH cx_root.
ENDTRY.
ENDMETHOD.

METHOD find_pagearea.
CONSTANTS: lc_002 TYPE string VALUE 'pageArea'.
CHECK im_page->num_children( ) > 0.
TRY.
DATA(lo_children) = im_page->get_children( ).
DO lo_children->get_length( ) TIMES.
DATA(lo_child) = lo_children->get_item( sy-index - 1 ).
IF lo_child->get_name( ) = lc_002 .
re_area = lo_children.
ELSE.
re_area = find_pagearea( lo_child ).
ENDIF.
IF re_area IS NOT INITIAL.
EXIT.
ENDIF.
ENDDO.
CATCH cx_root.
ENDTRY.
ENDMETHOD.

METHOD get_form_layout.
CONSTANTS: lc_005 TYPE c LENGTH 1 VALUE `D`.
DATA: lo_wb_form TYPE REF TO if_fp_wb_form,
lo_form TYPE REF TO if_fp_form,
lo_layout TYPE REF TO if_fp_layout,
lv_layout_xml TYPE xstring,
lo_ixml TYPE REF TO if_ixml,
lo_stream_factory TYPE REF TO if_ixml_stream_factory,
lo_stream TYPE REF TO if_ixml_istream,
lo_parser TYPE REF TO if_ixml_parser.

lo_ixml = cl_ixml=>create( ).
TRY.
lo_wb_form = cl_fp_wb_form=>load(
i_name = im_fpname
i_mode = if_fp_wb_object=>c_mode_read
i_language = im_langu
i_suppress_language_check = abap_true ).
CATCH cx_fp_api.
RETURN.
ENDTRY.
lo_form ?= lo_wb_form->get_object( ).
lo_layout = lo_form->get_layout( ).
lv_layout_xml = lo_layout->get_layout_data( ).

IF lv_layout_xml IS INITIAL.
TRY.
lo_wb_form = cl_fp_wb_form=>load(
i_name = im_fpname
i_mode = if_fp_wb_object=>c_mode_read
i_language = lc_005
i_suppress_language_check = abap_true ).
CATCH cx_fp_api.
RETURN.
ENDTRY.
lo_form ?= lo_wb_form->get_object( ).
lo_layout = lo_form->get_layout( ).
lv_layout_xml = lo_layout->get_layout_data( ).
ENDIF.

IF lv_layout_xml IS NOT INITIAL.
re_xftcontent = lv_layout_xml.
ENDIF.
ENDMETHOD.
ENDCLASS.

Now, create 3 Implicit Enhancement implementations at the following locations

Program SAPLFPCOMP -> Subroutine SET_DOCUMENT_PARAMETERS -> End of Subroutine
  zclb_adobe_watermark=>add_watermark( exporting im_fpname     = p_docpar-formname
im_langu = p_document-spoolprev-reqlangu
changing ch_xftcontent = p_document-xft
ch_xftfile = p_document-xftfile ).

Program SAPLFPCOMP -> Subroutine LOAD_TEMPLATE -> End of Subroutine
  zclb_adobe_watermark=>add_watermark( exporting im_fpname     = p_formname
im_langu = p_langu
changing ch_xftcontent = p_xft ).

Program SAPLFPCOMP -> Subroutine BIN_GET_SPOOL_PREVIEW -> End of Subroutine
  zclb_adobe_watermark=>add_watermark( exporting im_fpname     = p_spoolprev-formname
im_langu = p_spoolprev-langu
changing ch_xftfile = p_spoolprev-formurl ).

After activating this, when you create a new Adobe form print-preview/ printout or view any spool request, it should show you a Watermark message on the output as per your design.

Preview:


Spool output:


 
1 Comment
Labels in this area