Recently I was approached by a client that was concerned about the length of time it would take for their K2 SmartForm to generate a PDF of their form which had multiple tabs and lots of controls.
The Save as PDF feature available out of the box with K2 SmartForms is a nice feature, but also very limited in that it basically just does a snapshot of your form in the browser, similar to if you used the Print feature in your browser. There are several limitations including how it handles page breaks especially in this case where the form is very long. When using the PDF feature on the SmartForm, K2 will automatically create page breaks for each of the tabs.
I will discuss a trick I found using CSS and a literal control later to help with page breaks, but the main concern of the client was how long it took to generate this PDF which was attached to an email and sent as part of the workflow.
There are two options available for handling long running tasks in K2 when using the Save As PDF feature:
- Utilize the "Save As PDF Async" method which allows the process to run in the background with out causing the user to think their browser has locked up or is frozen.
- Move the logic to create the PDF using a K2 system control, "PDF Converter.Create PDF From URL" SmartObject event in the K2 BlackPearl workflow in the activity.
We tried the first option initially which solved one of the issues of preventing the browser from appearing locked up while the PDF was generated since the method was running asynchronously in the background. However, the client had no visual indicator like a spinner or 'Please Wait' dialog to understand something was still processing.
To overcome this limitation, I was able to utilize the K2 HTML literal control and adding this control to the form, I specified a link reference to the Bootstrap CSS file from a public CDN. The next step was to add a Label control to the form that would provide the message to the user that the PDF was being generated. By adding the CSS class to our label from bootstrap (class="alert alert-info") we were able to provide a nicely styled progress dialog to the end users.
The final step of this process was to finalize the rules in the form, so that when the Save As PDF Async method started, we would disable the view, which provided a watermark layer over the form, show our progress label and added the method when the PDF Async was complete to change the label that it was complete and close or redirect the form at that point.
While this first approach prevented the lock up of the browser and provided a message to the users, it ultimately didn't solve the problem of the performance issues, so we proceeded to move the entire logic from the K2 SmartForm to the K2 Blackpearl workflow using events in the K2 Studio designer.
After the form was submitted, we added a rule to start the workflow. In the workflow, we added an activity that would handle the processing of the PDF and send an email confirmation with it attached. This included adding an event to the activity calling the "PDF Converter.Create PDF From URL" SmartObject passing in all the required parameters it required including the URL to the form and then the email activity would send this PDF as an attachment.
One thing to note about generating the PDF from the workflow is that you don't have the active context of the user submitted form as you did when using the SmartForm rules. In order to generate the PDF showing the data entered in the form, you must create a different form/view or add a different state that will accept a parameter to load the saved data in the form and present it in read-only format using data labels, basically creating a nice printer-friendly SmartForm with the loaded data and this is the URL you supply as the parameter in the 'Create PDF from URL' SmartObject.
I promised earlier to show you a CSS trick for handling page breaks when generating the PDF. In order to accomplish this you will need to add an HTML Literal control or add a Label control to the view where you would like the page break to occur and check to the box for 'Literal'. Then you add this HTML code to the control and it will provide the necessary page breaks at the location of the control.
Hopefully this article will help you when working with the K2 PDF feature and long running processes that could be moved to a workflow event.