As the PDF format becomes more and more interesting for shop managers, this feature is now available with the IS7 standard product solution.
One of the main targets of the integration was to implement a solution that provides a general PDF generation from any HTML/XHTML source and especially to support the rendering of CMS pagelet entry points.
Portable Document Format | |
Flying Saucer | 3rd-party library that provides PDF rendering with XHTML as input |
Cartridge | Description |
---|---|
bc_pdf | for basic PDF render interfaces and exception class |
ac_pdf_flyingsaucer | to provide specific implementation of an xhtml2pdf renderer as a managed service, contains 3rd-party html2pdf lib |
sld_pdf | to provide a new interaction processor for generating PDF output |
Parameters
PageletEntryPointID | system entrypoint to set that should be rendered and used for PDF generation |
Dictionary | dictionary to set that should be used by the system page rendering process to access required data |
DefaultFileName | the default file name which is provided to the front end user that receives the result of the rendering |
For generating the PDF stream data a new managed service called "XHTML2PDFFlyingSaucerRenderer" is used.
This service adapter implements the following interface:
com.intershop.component.pdf.capi.PDFRenderer
For more information on managed services refer to the corresponding Cookbook - Managed Service Framework.
Since the creation of the PDF simply uses the first PDF renderer service that is available, it is necessary to remove the existing standard service if a custom service should be used with the existing interaction node for PDF creation.
Starting from ICM 11.1.1, the old createPDF
methods are deprecated.
/** * A common interface for pdf renderer that transform a given input into pdf * stream data. */ public interface PDFRenderer { /** * This method transforms content that was given as input stream into a pdf stream that is returned. * The system supports currently only html as input. * * @deprecated Use {@link #createPDF(InputStream, OutputStream)} instead * * @param contentStream input stream with content * @return the created output stream * @throws PDFRenderException */ @Deprecated(forRemoval = true, since = "11.1.1") OutputStream createPDF(final InputStream contentStream) throws PDFRenderException /** * This method transforms content that was given as input stream into a pdf stream. The created pdf is streamed in the given output stream. * The system supports currently only html as input. * * @param inputStream input stream with content * @param outputStream out stream with generated PDF content * @throws PDFRenderException */ void createPDF(InputStream inputStream, OutputStream outputStream) throws PDFRenderException; /** * This method transforms content that was given as a string into a pdf stream that is returned. * stream. The system supports currently only html as input. * * @deprecated Use {@link #createPDF(String, OutputStream)} instead * * @param content The content as String * @return the created output stream * @throws PDFRenderException */ @Deprecated(forRemoval = true, since = "11.1.1") OutputStream createPDF(final String content) throws PDFRenderException /** * This method transforms content that was given as a string into a pdf stream. The created pdf is streamed in the given output stream. * The system supports currently only html as input. * * @param content The content as String * @param outputStream out stream with generated PDF content * @throws PDFRenderException */ void createPDF(String content, OutputStream outputStream) throws PDFRenderException; }
/** * A common interface for configuration tasks of pdf renderer. * * @author Frank E. Hofmann * */ public interface PDFRendererConfig { /** * Add a specific font to the pdf render config. * * @param source * @param encoding * @param family * @param bold * @param italic * @param embedded */ void addFont(final String source, final String encoding, final String family, final boolean bold, final boolean italic, final boolean embedded); /** * Add a given font directory to the pdf render config. * * @param fontDirectory * @param embedded */ void addFontDirectory(final String fontDirectory, final boolean embedded); /** * Set the encryption of the generated pdf. * * @param userPassword * @param ownerPassword * @param allowedPrivileges * @param encryptionType */ void setEncryption(final byte[] userPassword, final byte[] ownerPassword, final int allowedPrivileges, final int encryptionType); /** * Set the pdf version number to be used for the created pdf. * * @param version */ void setVersion(final String version); }
Since the common Intershop template rendering process uses constructs like waInclude, there is a need to change the system to avoid such non-HTML-conform constructs.
It is necessary to create a complete HTML website without any web adapter-related tags because the system is not allowed to create a second request within the current one to resolve such statements.
This will be avoided by using only CMS components and templates that abdicate such remote includes.
A further task is to avoid new HTTP calls by resource loading of the website (ex. all media resources, image includes, CSS).
The solution to this problem is to replace the HTTP URLs by resource URLs that make use of the file protocol instead.
This can be done by creating a callback class which extends the ITextUserAgent
.
public class PDFUserAgentCallback extends ITextUserAgent { @Override public String resolveURI(String uri) { // set Base URL if needed } @Override protected InputStream resolveAndOpenStream(String uri) { //transform uri into desired uri format (file protocol) } } ... //using the callback for resource resolving ITextRenderer renderer = new ITextRenderer(); PDFUserAgentCallback uac = new PDFUserAgentCallback(renderer.getOutputDevice()); uac.setSharedContext(renderer.getSharedContext()); enderer.getSharedContext().setUserAgentCallback(uac);
New fonts can simply be copied into the <IS_SHARE>\system\fontsdirectory so that the PDF service will load them from that location.
It is also possible to embed those fonts into the generated PDF. But always keep in mind that there must be a license for that.
The PDF service embeds font of the fonts directory if the option "embed fonts" of the managed PDF service is selected in the back office.
The current version of the Intershop product is not delivered with Chinese fonts. But there are several fonts available and the integration into the system is pretty simple (as mentioned above), see https://wiki.archlinux.org/index.php/Fonts#Font_packages .
Flow
Call Prefix | |
call ProcessCart-GetCurrentCart | to retrieve basket |
check | if not call ViewPage-Start |
GetPageletEntryPointByID | to get system entrypoint |
KeyMapper | to set DefaultFileName from PageletEntryPoint:ConfigurationParametersAsMap:DefaultFileName:Value |
KeyMapper | Dictionary=CurrentRequest:PipelineDictionary |
Interaction Node | processor: PageEntryPoint2PDFInteractionProcessor that creates the PDF |
The template should be designed using the CMS and Pageletentrypoint.
The shopping cart PDF template must be implemented by the CMS as a page variation so that a shop manager/content manager is able to edit and to customize the Shopping Cart Email template.
This PDF template must have the same localization settings like the shop does have so that the customer (sender) will send the email in the same language the shop has.
It contains 4 sections:
The following settings are available at the system page:
configuration parameter | type | default value | comment |
---|---|---|---|
DefaultFileName | java.lang.String | Shopping_Cart_PrimeTechSpecials.pdf | text-parameter at the system page |
avoid webadapter commands
All used templates and CMS components have to match the criteria mentioned under topic "Rendering Issues"; otherwise, the system can run into a request handler error!
The following application-related shopping cart & checkout settings are available in the Shopping Cart tab on all applications with B2C WebShop as application type.
name | type | default | comment |
---|---|---|---|
Save Cart as PDF | boolean | enabled | pdf button in storefront is only available if this is checked; note that the pdf service must be available too |