org.zefer.pd4ml
to com.pd4ml
. All of this makes newer PD4ML product libraries incompatible with products based on PD4ML v3.
To simplify migration from PD4ML v3 to v4, PD4ML v4 package also includes org.zefer.pd4ml.*
wrapper classes, match PD4ML v3 API. The wrapper classes translate PD4ML v3 API calls to PD4ML v4. This allows to use PD4ML v4 library JAR as a drop-in replacement for pd4ml.jar
of v3 in most use cases.
To unlock more v4 features, it is recommended to switch to the new API using the instructions below. But even if you stay on the wrapper PD4ML v3 API, you always have access to com.pd4ml.PD4ML
instance via org.zefer.pd4ml.PD4ML.pd4mlNew
reference.
1.Applying PD4ML activation code
Software activation is new in PD4ML v4. The activation code enables or disables certain product features, depending on the license you purchased.
To activate the software, you need to either place pd4ml.lic
(a text file with an activation code) in your application’s working directory, or in the root of its classpath.
For example, in the context of a web application, this could be /WEB-INF/classes
(not WEB-INF/lib
). You can also package pd4ml.lic
into your application’s JAR, but you’ll have to experiment with this: the hierarchy of EARs, WARs, JARs, etc. can confuse the PD4ML classloader.
Another approach is to pass the activation code itself or the path to the pd4ml.lic file (or even the URL) directly to the com.pd4ml.PD4ML(String)
constructor or applyLicense()
method.
You can get the activation code or download pd4ml.lic
from https://pd4ml.com/view-my-licenses/
The activation code contains information about the available features, as well as the end date of the maintenance period. The code only activates software versions released before the date. If you apply the code to a version of the software released later, it will watermark the generated documents with a “DEMO MODE” banner, just as if you hadn’t applied any activation at all.
Other reasons for the “DEMO MODE” banner is a corrupted activation code or if PD4ML cannot find/read pd4ml.lic
for some reason. A verbose diagnostics output triggered by pd4ml.setLogLevel(255)
can help to determine what is wrong with the activation.
2.New conversion flow
While PD4ML v3 processes document with a single call pd4ml.render(in, out)
, PD4ML v4 separates the document conversion process into two phases: input document parsing and output document rendering. It allows to collect input document metadata before the output rendering. Or to reuse parsed input document to produce multiple formats: PDF, RTF, raster images.
The example demonstrates a reading of a source document from an HTML string and a writing of a conversion result to a temp file with PD4ML v4 and v3 API.
PD4ML v4 example relies on default settings of PD4ML: output format is A4, 10mm margins etc. PD4ML v3 has different default margins (T,L,B,R): 25pt, 50pt, 25pt, 25pt
PD4ML pd4ml = new PD4ML(); String html = "TEST<pd4ml:page.break><b>Hello, World!</b>"; ByteArrayInputStream bais = new ByteArrayInputStream(html.getBytes()); // read and parse HTML pd4ml.readHTML(bais); File pdf = File.createTempFile("result", ".pdf"); FileOutputStream fos = new FileOutputStream(pdf); // render and write the result as PDF pd4ml.writePDF(fos); // alternatively or additionally: // pd4ml.writeRTF(rtfos, false); // BufferedImage[] images = pd4ml.renderAsImages(); // open the just-generated PDF with a default PDF viewer Desktop.getDesktop().open(pdf);
PD4ML pd4ml = new PD4ML(); String html = "TEST<b>Hello, World!</b>"; StringReader bais = new StringReader(html); File pdf = File.createTempFile("result", ".pdf"); FileOutputStream fos = new FileOutputStream(pdf); // render and write the result as PDF pd4ml.render(bais, fos); // open the just-generated PDF with a default PDF viewer Desktop.getDesktop().open(pdf);
PD4ML v3 specifies the PDF, PDFA, or RTF output document type using the outputFormat()
method. PD4ML v4 has special writing methods for certain types: writePDF(OutputStream os, String pdfFormat)
, writeRTF(OutputStream os)
, renderAsImages()
.
3.PDF document defaults: scale factor, margins, view mode
There are 3 important PD4ML properties, impact resulting PDF page format and layout: pageSize
, pageMargins
, htmlWidth
.
1. pageSize
defines output paper format: A4
, ISOB4
, LETTER
, LEGAL
etc.
For both PD4ML v3 and v4 the default page format is A4
and orientation portrait
.
2. pageMargins
define blank page area width around the page content. The default value for it in PD4ML v4 is new PageMargins(10, 10, 10, 10, Units.MM)
, while in PD4ML v3 it is new Insets(25, 50, 25, 25);
(T,L,B,R in typographical points). So if you’d like to keep the margins as it was in v3, explicitly call pd4ml.setPageMargins(new PageMargins(50, 25, 25, 25, Units.PT));
(L,T,R,B)
3. htmlWidth
default value in PD4ML v3 and in v4 is 640px.
With
htmlWidth=727px
you can achieve 1:1 pixel/point correspondence of 72 DPI resolution. It is calculated from(A4.width - margins.left - margins.right) * PIXELS_PER_POINT
, which is(595pt - (10mm + 10mm) * 2.835pt/mm) * 1.35px/pt
4. Default <body> margin in PD4ML v3 is 8px. Can be applied in PD4ML v4 with pd4ml.addStyle("BODY {margin: 8px}", true);
5. PD4ML v3 default PDF view mode can be set in PD4ML v4 with pd4ml.setParam(Constants.PD4ML_DOCUMENT_VIEW_MODE, "OneColumn");
PD4ML pd4ml = new PD4ML(); pd4ml.setParam(Constants.PD4ML_DOCUMENT_VIEW_MODE, "OneColumn"); pd4ml.setHtmlWidth(640); pd4ml.addStyle("BODY { margin: 8px }", true); pd4ml.setPageSize(PageSize.A4); pd4ml.setPageMargins(new PageMargins(50, 25, 25, 25, Units.PT));
4.PD4ML API calls map
The chart shows the correspondence between PD4ML API calls in v3 and v4. The method names are hyperlinked with matching Javadoc entries.
org.zefer.pd4ml.PD4ML (v3) | com.pd4ml.PD4ML (v4) | Comments | |
---|---|---|---|
addDocumentActionHandler( |
addDocumentActionHandler( |
method defines JavaScript action handler for generated document. | |
addMetadata(String key, String value, boolean hide) |
addMetadata(String key, String value, |
The method defines custom properties for PDF document meta data. | |
|
addStyle(String stylesheet, |
Apply additional stylesheet to the document | |
addStyle(URL stylesheet, boolean overrideDocumentStyles) |
addStyle(URL stylesheet, |
Apply additional stylesheet to the document | |
adjustHtmlWidth() |
adjustHtmlWidth(boolean adjust) |
sets htmlWidth to the most right margin of the HTML block content. | |
changePageOrientation(Dimension d) |
PageSize.rotate() |
rotates given page format by 90 degrees. | |
clearCache() |
The font cache still can be cleared with terminate() ,however a forcing to clear cache is not recommended in general. |
removes all objects (images, CSS, etc) from internal caches. | |
disableHyperlinks() |
enableHyperlinks(boolean enable) |
if enable==false, PD4ML does not generate active hyperlinks in resulting PDF. Default is “true” |
|
enableDebugInfo() |
setLogLevel(int level) |
enables an output of diagnostics messages. | |
enableImgSplit(boolean split) |
By default, image splitting by page break is enabled. It can be disabled with CSS IMG {page-break-inside: avoid}, applied either in input document inline or via addStyle() |
allows to disable image splitting by page breaks. | |
enableRenderingPatch(boolean patch) |
Deprecated in v3; not supported in v4 | ||
enableSmartTableBreaks(boolean enable) |
The feature is disabled by default. It can be controled imput document structure and style. The freature is implicitly enabled if table has a header ( <thead> section or top rows consist of <th> cells only) and TR {page-break-inside: avoid} style applied. |
The method switches on/off the table break feature. This feature protects table rows from being split by page breaks (if possible) and forces the table header to be replicated after each in-table page break. |
|
enableTableBreaks(boolean enable) |
Deprecated in v3; not supported in v4 | ||
fitPageVertically() |
fitPageVertically(int align) |
forces PD4ML to downscale entire HTML layout to fit a single PDF page vertically. |
|
generateMulticolumn(int columns, int span, boolean millimeters) |
generateMulticolumn(int columns, |
switches PD4ML into multicolumn mode | |
generateOutlines( |
generateBookmarksFromAnchors(
|
if triggered, than PD4ML generates PDF bookmarks (aka outlines). | |
generatePdfa(boolean enable) |
PDF/A output can be enebled in writePDF (OutputStream os, where pdfFormat isPDFA |
Forces PD4ML to output PDF compliant with PDF/A specification. | |
generatePdfForms(boolean enable, String useTtfFont) |
generateForms(boolean enable, |
forces PD4ML to convert HTML forms into PDF forms (Acroforms). | |
getCache() |
getCache() |
returns cache object to be “recycled” by another PD4ML instance | |
getLastRenderInfo(String key) |
getLastRenderInfo(String key) |
returns statistics for the last render() call | |
getVersion() |
getVersion() |
getVersion() returns current version number | |
interpolateImages(boolean mode) |
Always “false” | enables or disables image interpolation | |
isDemoMode() |
isDemoMode() |
returns true if the library is used in evaluation mode | |
isPro() |
isPro() |
returns true if it is Pro version of the library | |
merge(InputStream input, int fromPage, int toPage, boolean append) |
merge(PdfDocument pdf, int fromPage, |
Merges conversion result with an already existing PDF document | |
merge(Reader input, int fromPage, int toPage, boolean append) |
merge(PdfDocument pdf, int fromPage, |
Merges conversion result with an already existing PDF document | |
monitorProgress( |
monitorProgressWith( |
conversion progress callback support | |
outputFormat(String format) |
Output format is controlled by chosen write method: writePDF(...) or or
|
||
outputFormat(String format, int width, int height) |
Output format is controlled by chosen write method: writePDF(...) or or
|
||
outputRange(String description) |
outputRange(String description) |
||
overrideDocumentEncoding(String encoding) |
overrideDocumentEncoding(String encoding) |
sets default encoding for URL-addressed HTML documents | |
predictPageHeight(Insets pageInsets, Dimension pageSize, int userSpace) |
predictPageHeight(PageMargins pageMargins, |
predicts page height for given conversion parameters | |
predictScale(Insets pageInsets, Dimension pageSize, int userSpace) |
predictScale(PageMargins pageMargins, |
predicts document HTML-to-PDF mapping scale for given conversion parameters | |
protectPhysicalUnitDimensions() |
protectPhysicalUnitDimensions(boolean |
makes PD4ML to output PDF objects respecting dimensions/font sizes given in “in”, “pt”, “cm” etc. |
|
render(InputStreamReader isr, OutputStream os) |
readHTML(InputStream isr) |
converts input data to PDF | |
render(InputStreamReader isr, OutputStream os, URL base) |
readHTML(InputStream isr, URL base) |
converts input data to PDF. | |
render(String textUrl, OutputStream os) |
readHTML(URL url) + |
input data referred by URL to PDF | |
render(StringReader[] isrs, OutputStream os, URL base) |
Can be achieved by repeating of
|
converts input data to PDF | |
render(StringReader isr, OutputStream os) |
readHTML(InputStream isr) |
converts input data to PDF | |
|
readHTML(InputStream isr, URL base) |
converts input data to PDF | |
render(StringReader isr, OutputStream os, URL base, |
readHTML(InputStream isr, URL base, |
converts input data to PDF | |
render(URL[] urls, OutputStream os) |
Can be achieved by repeating of
and merging of the multiple resulting docs withPdfDocument.mergePDFs(InputStream pdf1, |
converts input data referred by URLs to PDF | |
render(URL url, OutputStream os) |
readHTML(URL url) + |
converts input data referred by URL to PDF | |
renderAsImages(StringReader isr, URL base, int width, int height) |
readHTML(InputStream isr, URL base) or or
|
converts input HTML code to image object(s) | |
renderAsImages(URL url, int width, int height) |
readHTML(URL url) + or or
|
converts URL to image object(s) | |
resetAddedStyles() |
No need in v4 | Reset all styles added with PD4ML.addStyle() | |
setAuthorName(String name) |
setAuthorName(String name) |
sets an author name for the document | |
setCache(PD4Cache cacheWrapper) |
setCache(Object fontCache) |
lets PD4ML to reuse data, cached by another PD4ML instance. | |
setCookie(String name, String value) |
setCookie(String name, String value) |
makes PD4ML to add a cookie with given name and value to each URL connection request |
|
setDefaultTTFs(String serif, String sansserif, String monospace) |
Can be achieved with CSS, e.g by addStyle() |
defines deafult TTF font faces to be used as substritutions for unknown fonts. |
|
setDocumentTitle(String title) |
setDocumentTitle(String title) |
forces to override HTML title | |
setDynamicParams( |
Depending on param type, use one of the methods:
|
||
setHtmlWidth(int width) |
setHtmlWidth(int width) |
defines desired HTML page width in screen pixels. | |
setPageFooter(PD4PageMark mark) |
setPageFooter(String htmlCode, setPageFooter(String htmlCode, |
defines page footer area | |
setPageHeader(PD4PageMark mark) |
setPageHeader(String htmlCode, int heightPx, String scope) |
defines page header area | |
setPageInsets(Insets ii) |
setPageMargins(PageMargins margins)
|
specifies page insets in points | |
setPageInsetsMM(Insets ii) |
setPageMargins(PageMargins margins)
|
specifies page insets in millimeters. | |
setPageSize(Dimension d) |
setPageSize(PageSize d)
|
defines page size in points. | |
setPageSizeMM(Dimension d) |
setPageSize(PageSize d)
|
defines page size in milimeters. | |
setPermissions(String password, int permissions, boolean isStrong) |
setPermissions(String password, |
forces the resulting document to be encrypted with the given password | |
setSessionID(String sessionID) |
setSessionID(String sessionID) |
the method informs PD4ML about current session ID (in web application environments). |
|
translate(int i) |
translateToPt(float mm) |
converts from millimeters to points | |
useAdobeFontMetrics(boolean use) |
Deprecated in v3; not supported in v4 | ||
useHttpRequest( |
useHttpRequest( |
method allows to inform PD4ML about actual HTTP request context (if any). |
|
useServletContext(ServletContext ctx) |
useHttpRequest( |
method allows to inform PD4ML about actual servlet context (if any). | |
useTTF(String pathToFontDirs, boolean embed) |
useTTF(String pathToFontDirs)
|
enables TTF font embedding subsystem. |
6.JSP taglib
Both PD4ML v3 and v4 distributions among other features also include JSP custom tag library. PD4ML JSP custom tags provide a simple mechanism for a converting of HTML or JSP page output into PDF in Web scenarios. In PD4ML v4 the taglib is an integral part of the main library. In PD4ML v3 it comes as a separate pd4ml_tl.jar
.
For backward compatibility with JSP documents created for PD4ML v3, you can use pd4ml_tl.jar
taken from PD4ML v3 distribution together with PD4ML v4.
But if you want to use the latest taglib, you should consider the following.
In PD4ML v4 we changed the taglib structure and removed some redundant wrapper classes. Now we recommend to use pd4tl:
tag prefix instead of previous pd4ml:
in order to distinguish the custom JSP tags from PD4ML proprietary tags (e.g. <pd4ml:page.break>
).
<%@ taglib uri="http://pd4ml.com/tlds/4.0" prefix="pd4tl"%><%@page contentType="text/html; charset=ISO8859_1"%><pd4tl:transform screenWidth="400" pageFormat="A5" pageOrientation="landscape" pageInsets="100,100,100,100,points"> <html> <head> <title>pd4ml test</title> <style type="text/css"> body { color: red; font-family: Tahoma, "Sans-Serif"; font-size: 10pt; } </style> </head> <body> <p> Hello, World! </p> <pd4ml:page.break /> <table style="border: 1px solid gray; border-radius: 5px; background-color: #f8f8f8; color: #000000"> <tr> <td>Hello, New Page!</td> </tr> </table> </body> </html> </pd4tl:transform>
See https://pd4ml.com/support-topics/pd4ml-v4-programmers-manual/#pd4ml-jsp-taglib-and-web-applications for more PD4ML JSP taglib usage hints.