PDF exporting gone wild
Did you ever have the need to export your crosstab data in a shiny enterprise ready reporting manner? At this point in time there are a couple of options. I listed them in a short overview regarding pdf functionality below. The succeeding paragraphs describe an approach, how to overcome their shortages and produce a best of breed pdf, I implemented recently.
- SAP BusinessObjects Crystal Reports
- Well proven in the SAP community [+]
- BO server dependent (BI platform) [–]
- But extra cost [–]
- Third party SDK extensions
- Client-side only exporting (easy, no security issues) [+]
- Available from DS12 and upwards [+]
- Proprietary extra server component needed [–]
- Special crosstab setup to make it work (+several scripting customizations), e.g. crosstab data loading mechanism to have all query data in the browser for the SDK component to grab [–]
- Very flexible but heavy CSS knowledge needed to make it “shiny” [–]
- Extra cost [–]
- DS15 standard component
- Integrated and no extra cost [+]
- Not flexible enough yet (gui only and almost no scripting capabilities), SAP promised according to the road map to improve it to a certain extent by 1.6 in November [–]
- Current version far from being “shiny” at all [–]
- Only Available from DS15 upwards
- Community SDK PDF component
- Integrated and no extra cost [+]
- Available from DS13 upwards [+]
- More flexible scripting options than standard component though [+]
- Suffers from similar problems like the standard component [–]
However, none of those options offer you the capability to play with the result set and the data breakdown outside the BEx query result view options in a reasonable way or even not at all. I recently faced the challenge to mix attributes/characteristics and key figures on the same breakdown on the pdf export. In order to get this done with the options described above, you would need the query to do it or put some heavy customization into one of the SDK components. Unfortunately this kind of functionality is no longer supported since the BEx query version upgrade from 3.x (see http://scn.sap.com/docs/DOC-54701).
Luckily I have an easy, tightly integrated and already successfully implemented approach for you guys. Let me briefly describe how it works before we go more into the technical details. The actual data crunching happens on the ABAP backend using either:
- The function module ‘RRW3_GET_QUERY_VIEW_DATA’ (See http://wiki.scn.sap.com/wiki/display/BI/Expose+BI+Query+as+RESTful+Service) or
- SAP Easy Queries (See http://scn.sap.com/people/uwe.fischer/blog/2011/12/12/easy-queries-on-sap-netweaver-bw)
The result is than passed to the SAP Adobe pdf module. This module does the magic to fulfill the described task to mix all sorts of dimensions because the BEx query restrictions no longer apply. That way we were able to bring the characteristics into the key figure dimension again. There is some coding effort though to design, style the pdf and bring the data into it. But as you can imagine, controlling all of this and customizing it to your every need is highly beneficial. At this point the only additional thing you need, is a SDK component that identifies the query you want to export and passes that information to your ABAP backend.
Now you legitimately wonder how does this ABAP coding integrate with DesignStudio. I developed a SDK component that exposes web service calling functionality and events using the HTTP verbs GET and POST to DesignStudio scripting. The actual call is performed asynchronously by jQuery with AJAX which is standard best practice on the web. Just define the mime type of your HTTP response to be application/pdf and either save it using frameworks like FileSaver.js or open a new tab and use your preferred browser’s pdf plugin to display it right away. Let me say that there is one pitfall to this. Your DesignStudio app runs on the SAP java stack and all of your data resides on the SAP ABAP stack, which means you are going to encounter cross-origin security issues due to the same origin policy trying to perform an AJAX call from another domain. This topic is already discussed in depth so I will only mention a couple of example sources for further reading.
- Cross-Origin Resource Sharing (CORS)
I would recommend choosing the CORS setup over JSONP in a production environment for security reasons and compliance with the standard web protocols but I like JSONP for development and debugging purposes because of its ease of use.
As a good starting point you can check out my DesignStudio community SDK team mate Karol Kalisz’s component PostResponseParser:
I also plan on publishing a new component under the community SDK’s utils section for standard web service communication so that you can build upon the component even easier in the near future.
So there is only one missing piece in the setup. How does the ABAP stack receives the call from the DesignStudio SDK component? There are several options but I like to mention two that appeared easiest and most straight forward to me. Cesar Martin’s approach offers much more HTTP functionality and methods out of the box but the SAP standard WebRFC function module is setup much quicker.
SAP standard WebRFC
Cesar Martin’s HTTP class
Cesar published his implementation of the SAP standard web interfaces here https://github.com/cesar-sap/abap_fm_json. His article on that matter is also worth reading http://scn.sap.com/community/abap/connectivity/blog/2013/03/05/json-adapter-for-abap-function-modules. You are once again ready to fire a test call from DesignStudio.
Figure: PDF exporting SDK extension UML structure and deployment diagram
Technical query name and BEx variable values are passed using the HTTP payload or the standard query string. Of course you will need to define a REST interface upfront for both components to be able to exchange data with each other.
One last thing I like to mention is that DesignStudio offers a scripting function to identify the query on both the frontend and the backend.
That way you can find out the BEx query’s technical name to use with the function module ‘RRW3_GET_QUERY_VIEW_DATA’ or the corresponding Easy Query. There are a lot of more useful attributes hidden within the getInfo() method, for example to learn more about the last modified date of a datasource or the underlying info provider.
To put it into a nutshell: Once setup, exporting arbitrary queries in the most flexible and “shiniest” manner with DesignStudio no matter the release version (DS12+, because at least SDK is needed), really is a walk in the park.
Thanks for reading. Follow up questions as well as your comments are most welcome as usual.