📜 ⬆️ ⬇️

Software generation of PDF forms on ABAP or how to get rid of problems with SPOOL

How it all began


The specifics of the company in which I work, implies close contact and cooperation with our clients. One of these business processes is sending out various documents both by mail and on paper to our not favorite mail in envelopes. Standard functionality that allows you to generate printable PDF forms and print them or publish somewhere in binary form uses background tasks and SPOOL print data.
At first everything was fine, the data was formed, the customers were satisfied. But at one moment everything was covered with a “copper basin”, the volumes of the printed plates were significantly increased, and SPOOL began to “become infected”, which led to terrible brakes of the entire server part. I want to tell about one of the ways to solve this problem in this article.

Go


As is usually the case, first of all, everyone runs with similar problems to the basists, who are responsible for running the server side and optimizing a heap of various settings in the configuration files. What is the result: a lot of SAP Notes was read, forums were studied, then changes of parameters began, something gave a small performance boost, somewhere in the opposite. But in the end result, the desired effect was not received. Of course, the pressure of management and dissatisfied customers increased, since the formation of documents took more and more time and there was no question of any customer focus, which adversely affected the company's prestige. As a result, it was decided to try to deal with the problem at the program level.
Enough preludes, let's move on to the technical side of the issue.

Base code analysis


At first, I decided to figure out how the standard functionality for generating PDF forms still works, as a result of Drill down, I came across a package of SAFP , which opened my eyes to everything that happens and it seems the floor of the matter has already been decided. After analyzing the examples of programs, I found out that the following main tasks arose for me:
  1. Create an XFT form file;
  2. Generate an XFD file containing the data;
  3. Get a binary file and a PDL file that the printer understands;

Create an XFT Form File


There were two solutions for me, either to create this file myself and store it somewhere on the application server, which would be unwise from the point of view of support and updating, or not to invent a bicycle and immediately receive a link to a ready-made form that is convenient to edit and test through an SFP transaction. Let's take the path of least resistance:
DATA: l_xdp TYPE fpwbformname VALUE 'ZTEST', "   l_xft TYPE string, "       l_except TYPE REF TO cx_fp_api_repository. "    TRY. cl_fp_wb_helper=>form_layout_exists( i_name = l_xdp ). CATCH cx_fp_api_usage. "#EC NO_HANDLER CATCH cx_fp_api_repository INTO l_except. IF l_except->textid = cx_fp_api_repository=>object_already_exists. l_xft = cl_fp_wb_helper=>form_layout_url( i_name = l_xdp i_dest_path = 'X' ). ELSE. MESSAGE ID 'FPRUNX' TYPE 'E' NUMBER '050' WITH sy-langu. ENDIF. ENDTRY. 

Here we check if there is a form in the system with the given name and if we get a positive answer, then we read the path to this form.

Generating an XFD file containing data


Generating a PDF file is still half the battle. We need to fill it with data, in order to do this we need to generate a file with XFD data, which is a regular xml file. The best solution for me was to use transformations. So let's get started.
How can we find out how the file should look like after transformation, so that it can be successfully applied to our form? It is very simple to do this, go to the SFP transaction, open the form we need and enable debugging, as shown in the figures below:
Form debug mode
We select in the form Settings

')
Next, set the debug mode, it will allow us after the output of the printed form to get the files in the attachment


We launch the printed form for a test and get the necessary files in the PDF attachment, we are interested in XFD.xml


So, we have received the data file for the printed form, now it will not be difficult for us to create a transformation and call it further:
 CALL TRANSFORMATION ztest_trans SOURCE is_data = it_data RESULT XML xstr. 

Get a binary file and a PDL file that the printer understands


So, we have everything necessary to form a printed form. The truth is there is one nuance. In nature, as it turned out, there are various types of printers, some are color, others are not. For a certain group of printers, so-called XSD templates are used, which are used to generate PDF files. More details about their types and classification are written here .
We will use hppcl5c.xdc, as it is ideally suited for our task, including allowing it to print on a color printer. What we got:
Some code
 DATA: l_fp TYPE REF TO if_fp, l_pdfobj TYPE REF TO if_fp_pdf_object, pdfresult TYPE xstring, pdlresult TYPE xstring. *  ADS- MOVE cl_fp=>get_ads_connection( ) TO l_dest. *  FP reference l_fp = cl_fp=>get_reference( ). TRY. *   PDF l_pdfobj = l_fp->create_pdf_object( connection = l_dest ). *   ,     l_pdfobj->set_template( xftfile = l_xft ). *     l_pdfobj->set_data( formdata = l_xfd ). *   PDF  PDF *       ,       l_pdfobj->set_task_renderpdf( ). *   PDF  PDL  CALL METHOD l_pdfobj->set_task_renderpdl EXPORTING pdltype = 'pcl' pdlfile = '' xdcname = 'hppcl5c.xdc'. DATA: form TYPE string. form = i_fpwbformname. l_pdfobj->set_application_form_identity( application = 'SAFP' form = form ). *   ,  ADS TRY. l_pdfobj->execute( ). CATCH cx_fp_runtime_internal cx_fp_runtime_system cx_fp_runtime_usage. "#EC NO_HANDLER ENDTRY. *     XSTRING l_pdfobj->get_pdf( IMPORTING pdfdata = pdfresult ). CALL METHOD l_pdfobj->get_pdl IMPORTING pdldata = pdlresult. ENDTRY. 


Results


As a result, after applying this approach, it was possible to completely eliminate SPOOL as such in the chain. This allowed us to create fairly large volumes of print forms in the background without loading the server, currently about 5000 documents in 3 hours. It is worth noting that this approach also allows you to perform other operations with PDF, such as a digital signature on the server side. You can learn more about the examples in the package I mentioned above in the SAFP article.

Source: https://habr.com/ru/post/201280/


All Articles