PD4ML – V4 Programmers Manual

User Manual:

Open the PDF directly: View PDF PDF.
Page Count: 24

DownloadPD4ML – V4 Programmers Manual
Open PDF In BrowserView PDF
PD4ML v4 Programmers Manual

H
HO
OM
MEE // PPD
D44M
MLL VV44 PPR
RO
OG
GR
RA
AM
MM
MEER
RSS M
MA
AN
NU
UA
ALL

1. Getting Started #
The major difference with the previous PD4ML versions is that the new API performs the conversion in two phases.
First you need to invoke readHTML() method to read a source document. By default an HTML (styled with CSS) is
expected. However it can be arbitrary XML, where tag nature is specified with CSS display property, e.g. Side content .
After the document is read and parsed you can render and write it as PDF
PDF, PDF/A
PDF/A, RTF or an raster image with
writePDF() or another corresponding method. If you need a conversion result in different formats – invoke
corresponding write*() methods multiple times, there is no need to reread the source HTML.
That’s all you need to know about PD4ML to write your first converter application…

1.

PD4ML pd4ml = new PD4ML();

2.
3.
4.
5.

String html = "TESTHello, World!";
ByteArrayInputStream bais =
new ByteArrayInputStream(html.getBytes());

6.
7.
8.

// read and parse HTML
pd4ml.readHTML(bais);

9.
10.
11.

File pdf = File.createTempFile("result", ".pdf");
FileOutputStream fos = new FileOutputStream(pdf);

12.
13.
14.

// render and write the result as PDF
pd4ml.writePDF(fos);

15.
16.
17.
18.

// alternatively or additionally:
// pd4ml.writeRTF(rtfos, false);
// BufferedImage[] images = pd4ml.renderAsImages();

19.
20.
21.

// open the just-generated PDF with a default PDF viewer
Desktop.getDesktop().open(pdf);

Suggest edit
Last updated on September 4, 2018

2. Obtaining PD4ML #
Since v4 PD4ML is distributed as an universal library, whose features like TTF embedding support or PDF/A output are
activated depending on license key. So binaries for all license types can be obtained from a single location.
Each PD4ML v4.x release is published to our Maven repository . You may either download the library from the
location or, if you use Apache Maven, tune your project build to automatically download the latest library build.

The binaries in the repository are supplied with Javadoc JARs. The most actual Javadoc is always available online.
PD4ML source code licensees also have an access to debugger-friendly library versions with debug info not stripped off.
The library versions and their source code JARs are available from the access-restricted Maven repository .
Nightly builds are available in both repositories as snapshots.
To use PD4ML in Maven environment you’d need to configure something like that:
1. Access to regular binaries
Project pom.xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.

...

com.pd4ml
pd4ml
4.0.0

...
 
pd4ml
https://pd4ml.tech/maven2/

true



2. Access to the binaries with source code
~/.m2/settings.xml
1.
2.
3.
4.
5.


pd4ml-src
login_name_from_license
password_from_license


Of course, it is recommended to store the password in encrypted form there. See Maven documentation how to do
that.
Project pom.xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.

...

com.pd4ml
pd4ml
4.0.0

...

pd4ml-src
https://pd4ml.tech/maven2-src/

true



Suggest edit

Last updated on August 26, 2018

3. Running PD4ML Converter as a standalone application #
PD4ML is not only a software library/component, but also a set of tools, which can be used as standalone applications.
First download the most recent version of PD4ML JAR file from our Maven repository , save it to a directory of your
choice and make sure there is a JRE v1.6+ installed on your workstation/server.
There are two tools available:
Pd4Cmd – command line wrapper of PD4ML API
PD4Browser – GUI viewer/converter

Suggest edit
Last updated on August 27, 2018

3.1. PD4ML as a command-line converter tool #
The command line tool is implemented as com.pd4ml.tools.Pd4Cmd.class . The class is specified as a main class of
the JAR, so it can be executed a simple way:
java -jar pd4ml*.jar
where java*.jar is an actual JAR file name, like pd4ml-4.0.1.jar .
There are four typical usage scenarios:
1. HTML conversion to PDF, RTF or a raster image
2. PDF processing (merging, updating)
3. Reading of document meta information
4. Indexing of TTF fonts

HTML conversion to PDF, RTF or a raster image
HTML-to-PDF conversion with the absolute minimum of parameters

java -Djava.awt.headless=true -Xmx512m -jar pd4ml.jar "http://pd4ml.com" 1200

The command line overrides the default Java memory heap size limit with -Xmx512m
-Xmx512m. Here it is set to 512Mb.
On UNIX platform -Djava.awt.headless=true allows to run the application on non-graphics-enabled servers or from
remote ssh/telnet sessions.

http://pd4ml.com" 1200 are HTML source URL and htmlWidth (virtual “browser” frame width) parameters.
Note: on Win32 the URL is enclosed, if needed, to double quotes, on UNIX – to single quotes.
The default PDF document format: A4 / PORTRAIT
In the example 1200px
px width of rendered document will be mapped to 595pt
pt widths of A4 page format.
As long as an output file path omitted, the output is sent to STDOUT and can be piped to another application.

Customized HTML-to-PDF conversion

java -Djava.awt.headless=true -Xmx512m -jar pd4ml.jar "http://pd4ml.com" 1200 LETTER bookmarks HEADINGS -pdfforms -debug -out pd4ml.pdf

In the examples the generated PDF is written to a file, defined with -out parameter. That makes possible to use STDOUT for debug
output (-debug
-debug parameter).
The examples also force PD4ML to produce PDF outlines (bookmarks) from 

-

hierarchy of the document ( bookmarks HEADINGS ) and to convert HTML forms to interactive PDF forms ( -pdfforms ). PDF processing (merging, updating) PDF page removal java -Djava.awt.headless=true -Xmx512m -jar pd4ml.jar -tools file:c:/docs/test.pdf pagerange 2-3,5+ -out c:/docs/newdoc.pdf The call extracts a selected range of document pages and saves them as a new document. PDF documents merge java -Djava.awt.headless=true -Xmx512m -jar pd4ml.jar -tools file:c:/docs/test.pdf -merge file:c:/docs/tomerge.pdf after -out c:/docs/newdoc.pdf Note: -pagerange option is not available by a PDF merge PDF permissions update java -Djava.awt.headless=true -Xmx512m -jar pd4ml.jar -tools file:c:/docs/test.pdf permissions 28 -out c:/docs/newdoc.pdf -permissions 28 is a sum of permissions: AllowDegradedPrint = 4 , AllowModify = 8 and AllowCopy = 16 . See API reference for more details… Reading of document meta information java -Djava.awt.headless=true -Xmx512m -jar pd4ml.jar -tools file:c:/docs/test.pdf printpermissions -printauthor -printtitle -printpagenum The call prints to STDOUT basic PDF info: document permissions (as a hex number), document author, document title, number of document pages (decimal number) Indexing of TTF fonts java -Xmx512m -jar pd4ml.jar -configure.fonts [pd4fonts.properties location] See the command line tool documentation… Suggest edit Last updated on October 27, 2018 3.2. PD4ML as a GUI application # PD4ML library includes a simple GUI tool for HTML document rendering preview and for test conversion to PDF or to RTF. The tool can be activated by a passing -gui parameter to the command line: java -jar pd4ml*.jar -gui where java*.jar is an actual JAR file name, like pd4ml-4.0.1.jar . There is also a “legacy” way to run the GUI converter, kept for backward compatibility with PD4ML versions prior to v4.0.0 java -cp pd4ml*.jar org.zefer.pd4ml.tools.PD4Browser After the first start the GUI tool creates pd4browser.properties file (if no previously created instance found) with the conversion parameter defaults. The file can be customized according your needs in a text editor. In the top section of the application you can find the controls: [•••] – local HTML file open dialog. Accepts .htm(l) and .svg (and .dxl from [GO] – reloads current document and render it in the main application view as an image [PDF] – renders current document as PDF and opens it in default PDF viewer application [RTF] – renders current document as RTF and opens it in default RTF viewer application In the status bar there are: v4 v4.1.0 .1 .0 ) A label with the target page format. The target file format can be changed in pd4browser.properties file or in the source HTML/CSS with @page at-rule A label with the actual htmlWidth conversion parameter value. The value can be changed by a horizontal resizing of the application window. For a fine tuning there are [+ and -] buttons Target page margins. The margins can be changed in pd4browser.properties file or in the source HTML/CSS with @page at-rule. Current page number label with page browse buttons [<< and >>] Mouse position / drag box coordinates A pointing of the mouse over the status bar labels opens a balloon with additional details. A clicking [PDF] button converts current document to PDF and open the resulting file in a separate PDF viewer window: The conversion defaults can be adjusted in pd4browser.properties . The default properties still include some entries, inherited from older PD4ML versions, and not always usable in v4.0.0 . Here we’ll review the important ones. debug.info.enable=0 – logging/debug output verbosity. The value is a bit mask to control logging aspects document.author= – a string to override document author metadata document.title= – a string to override document title metadata insets.bottom=10 – bottom page margin value insets.left=10 – left page margin value insets.right=10 – right page margin value insets.top=10 – top page margin value insets.units=mm – margin value units: mm or pt page.bookmarks.destinations=false – enables a generation of PDF page bookmarks (outlines) from named anchors ( ). Not compatible with page.bookmarks.headings=true page.bookmarks.headings=false – enables a generation of PDF page bookmarks (outlines) from

-

hierachy. Not compatible with page.bookmarks.destinations=true page.format=A4 – specified target page format (e.g. A6 , LETTER ) page.hyperlinks=true – enables a conversion of HTML hyperlinks to active PDF hyperlinks page.orientation=false – by true rotates given target page format to 90 degrees (e.g. portrait to landscape) pdf.forms.enable=false – enabled a conversion of HTML forms to submittable native PDF forms. pdf.pdfa=false – enables PDF/A output pdf.protect.pud=false – forces PD4ML to keep HTML object sizes given in physical units (mm, pt, in etc) in resulting PDF, independently on HTML-to-PDF scale factor proxy.host= – proxy host address (if needed) proxy.port=0 – proxy port (if needed) style.add= – CSS style string to be applied to loaded documents ttf.fonts.default.monospace= – default monospaced font. Not recommended, use CSS style for that instead ttf.fonts.default.sansserif= – default Sans Serif font. Not recommended, use CSS style for that instead ttf.fonts.default.serif= – default Serif font. Not recommended, use CSS style for that instead ttf.fonts.dir= – location of TTF fonts dir directory with pd4fonts.properties index file userSpace.adjustToContent=false – if true , forces PD4ML to set htmlWidth value to the measured width of the HTML content. Suggest edit Last updated on October 28, 2018 4. PD4ML Java API # API Documentation Each release of PD4ML comes with actual JavaDocs. When you use Maven for dependency management, your IDE will automatically download the JavaDocs JARs and when you hover on a PD4ML class or method, show you the corresponding documentation. For reference we also publish the API documentation online so you can link to it from emails or websites: https://pd4ml.tech/javadoc/com/pd4ml/PD4ML.html Pre-Requisites The following are the pre-requisites needed to use the PD4ML Java API library: * JDK installed on your PC * Apache Maven build automation tool * Eclipse installed on your PC (While Eclipse is not compulsory it is highly recommended) * PD4ML Java API can be downloaded from our website directly (or let Maven do that automatically) * PD4ML evaluation license Developing your first application Creating blank Maven Java project As a good starting point we recommend to create a blank Java project as described in the tutorial: https://maven.apache.org/guides/getting-started/maven-in-five-minutes.html After you’ve got the example application to run, let’s add to it PD4ML. First add PD4ML library dependency to project’s pom.xml . See lines 17-22 below: 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 4.0.0 com.mycompany.app test-pd4ml jar 1.0-SNAPSHOT test-pd4ml http://maven.apache.org junit junit 3.8.1 test com.pd4ml pd4ml [1.0.0,) org.apache.maven.plugins maven-compiler-plugin 3.1 1.7 1.7 pd4ml https://pd4ml.tech/maven2/ true In order to resolve the dependency, add a location of PD4ML repository. The right location for the repository address is $HOME/.m2/settings.xml (See Maven documentation). We’ll keep the example configuration simpler and add the repository info to pom.xml , despite it is not a recommended practice. See lines 37-45 in the example above. If you own PD4ML license with product source code access, use https://pd4ml.tech/maven2-src/ as the repository URL. You would also need to configure the repository access credentials (login/password pair) obtained from the license email. Also for runtime environment simplicity we’ll add the example PD4ML API calls to the application test suite. A typical test case class looks like the example: 1. 2. 3. 4. public class AppTest extends TestCase { public AppTest(String testName) { super(testName); } 5. public static Test suite() { return new TestSuite(AppTest.class); } 6. 7. 8. 9. public void testApp() { } 10. 11. 12. } We are going to extend testApp() method with PD4ML usage example code. Creating a PD4ML object When writing an application with PD4ML API, the very first thing to do is to create the PD4ML object: 1. 2. 3. 4. 5. try { PD4ML pd4ml = new PD4ML(); } catch (Exception e) { e.printStackTrace(); } The constructor in the example has no parameters and it expects to find license pd4ml.lic file in the working dir of the application or in the root folder of the classpath or of pd4ml*.jar . Alternatively you may pass to PD4ML constructor a string with a serial number (obtained from the license email) or a string with an URL of an alternative pd4ml.lic location. Where to obtain pd4ml.lic ? Download it from your license page or save the serial number from the license email to a text file and name the file pd4ml.lic Reading HTML After you’ve got an instance of PD4ML you can read and parse a source HTML document with one of a variety of readHTML() methods. In the example it reads from a prepared input stream. But it can also read from an arbitrary URL. 1. 2. 3. String html = "Hello, World!"; ByteArrayInputStream bais = new ByteArrayInputStream(html.getBytes()); 4. 5. 6. // read and parse HTML pd4ml.readHTML(bais); If you want to point the converter to a font directory or to apply an additional style, headers, footers, watermarks etc – the corresponding API calls need to be performed before readHTML() Writing target format A parsed source document can be rendered as a sequence of images, PDF or RTF documents. Here it writes a PDF: 1. 2. File pdf = File.createTempFile("result", ".pdf"); FileOutputStream fos = new FileOutputStream(pdf); 3. 4. 5. // render and write the result as PDF pd4ml.writePDF(fos); Launching default document viewer (optional) It is rarely needed in real-life applications, but very handy in our case: lookup for a default viewer and launch it for just generated PDF. 1. 2. // open the just-generated PDF with a default PDF viewer Desktop.getDesktop().open(pdf); It looks for a viewer, associated with given file extension. For PDF it launches Adobe Reader (or similar). If we write to a file with .rtf extension it likely launches MS Word or WordPad First PD4ML application complete The application, in its entirety, is as follows: 1. package com.mycompany.app; 2. 3. 4. 5. 6. import import import import java.awt.Desktop; java.io.ByteArrayInputStream; java.io.File; java.io.FileOutputStream; 7. 8. import com.pd4ml.PD4ML; 9. 10. 11. 12. import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; 13. 14. 15. 16. 17. public class AppTest extends TestCase { public AppTest(String testName) { super(testName); } 18. 19. 20. 21. public static Test suite() { return new TestSuite(AppTest.class); } 22. 23. 24. 25. public void testApp() { try { PD4ML pd4ml = new PD4ML(); 26. 27. 28. 29. String html = "Hello, World!"; ByteArrayInputStream bais = new ByteArrayInputStream(html.getBytes()); 30. 31. 32. // read and parse HTML pd4ml.readHTML(bais); 33. 34. File pdf = File.createTempFile("result", ".pdf"); FileOutputStream fos = new FileOutputStream(pdf); 35. 36. // render and write the result as PDF pd4ml.writePDF(fos); 37. 38. 39. // alternatively or additionally: // pd4ml.writeRTF(rtfos, false); // BufferedImage[] images = pd4ml.renderAsImages(); 40. 41. 42. 43. // open the just-generated PDF with a default PDF viewer Desktop.getDesktop().open(pdf); 44. 45. 46. } catch (Exception e) { e.printStackTrace(); } 47. 48. 49. } 50. 51. } Running the application Now we are ready to run the demo application. Go to the Maven project root (where pom.xml is) and execute the command line: 1. mvn test The test target builds the projects and runs its test suite. As our example code is implemented as a test case, it will be executed. If you did everything correct you’ll see a PDF viewer window with a generated PDF file in it: The document is minimalistic and built using PD4ML defaults: A4 page format, 10mm margins, 727px htmlWidth, no TTF fonts. 727px are calculated from (A4.width - margins.left - margins.right) * PIXELS_PER_POINT , which is (595pt - (10mm + 10mm) * 2.835pt/mm) * 1.35px/pt Customizing the conversion PDF page format and content scaling There are 3 important PD4ML properties, impact resulting PDF page format and layout: pageSize , pageMargins , htmlWidth . pageSize defines output paper format: A4 , ISOB4 , LETTER , LEGAL etc. Corresponding constants are defined in java.pd4ml.Constants class, but you may define any non-standard page dimension with, for instance, new com.pd4ml.PageSize(400,400) (by default the dimensions are in typographic points) and pass it to pd4ml.setPageSize() method. Default page format is A4 , orientation portrait . PDF file format does not explicitly specifies on meta level if a particular page is landscape landscape– or portrait portrait-oriented. If a page has its width greater than height – it is landscape, otherwise it is portrait. com.pd4ml.PageSize implements a page rotation by a simple swapping of page height and width. pageMargins define blank page area width around the page content. The default value for it new PageMargins(10, 10, 10, 10, Units.MM) The page margins can be additionally increased by HTML document margins (e.g. ). The HTML document margins have some specifics, when converted to PDF: the top margin is applied to the top of the document (in other words, on the first page only), the bottom margin on the last page only. Document with no margins: htmlWidth value defines "virtual web browser" frame width (in screen pixels), and by default for A4 it is 727px (to keep 1:1 scale factor by 72dpi). PD4ML renders source HTML page using htmlWidth parameter and maps the resulting layout to the efficient PDF page width (which is pageFormat.width - pageMargins.left - pageMargins.right ). That makes HTML-to-PDF scale factor computed like that: scale = (pageFormat.width - pageInsets.left - pageInsets.right) / htmlWidth From the above it is obvious, that an increasing of htmlWidth makes the resulting document content appears smaller. Examples: htmlWidth = 920 htmlWidth = 1320 Defining page header and footer setPageHeader() and setPageFooter() methods are used to define page headers/footers using HTML as a layout definition. Optional scope parameter allows to apply particular header or footer to a specified range of pages. The HTML code may include the placeholders: $[page] – to be substituted with current page number; $[total] – total number of pages; $[title] – document title as defined in HTML tag or overridden with setDocumentTitle() API call. 1. 2. 3. // define page header for the first page 30px high pd4ml.setPageHeader("$[title]", 30, "1"); 4. 5. // define page footer for the first page pd4ml.setPageFooter("Total pages: $[total]", 30, "1"); 6. 7. 8. // define page header for the second page pd4ml.setPageHeader("<b>$[title]</b> $[page]/$[total]", 30, "2+"); 9. 10. 11. // define page footer for the second page pd4ml.setPageFooter("<div style='width: 100%; text-align: right'>Page: $[page]</div>", 30, "2+"); E003SetPageHeaderFooter.java Protecting resulting document setPermissions() method allows to apply the standard PDF security options: define a document password or restrict particular document actions (like a hi-res print). See a list of applicable permission flags ( Allow* and DefaultPermissions ). It is possible to define a positive list of permissions: 1. pd4ml.setPermissions(null, Constants.AllowAnnotate | Constants.AllowDegradedPrint); or to disable only selected ones: 1. pd4ml.setPermissions(null, Constants.DefaultPermissions ^ Constants.AllowModify); 1. // protect the document with "test" password. No permission restrictions applied pd4ml.setPermissions("test", Constants.DefaultPermissions); 2. E009SetDocumentPassword.java Reading resources from non-standard sources If some HTML resources like images or stylesheets are not accessible with the standard methods (file read, HTTP(S), etc), you may define your own resource reading “driver”. First, define a resource addressing syntax, that matches your needs. For example <a src="database:table=pictures;id=4711"> Second, implement a resource loader, which knows what to do with “database:table=pictures;id=4711” URI. The loader has to be derived from com.pd4ml.ResourceProvider class and to implement two methods: boolean canLoad(String resource, FileCache cache) to test if it can read the URL; BufferedInputStream getResourceAsStream(String resource, FileCache cache) to actually read the resource bytes. 1. public class DummyProvider extends ResourceProvider { 2. 3. public final static String PROTOCOL = "dummy"; 4. 5. 6. 7. 8. 9. @Override public BufferedInputStream getResourceAsStream(String resource, FileCache cache) throws IOException { if (!resource.toLowerCase().startsWith(PROTOCOL)) { return null; } 10. 11. // interpret the "resource" parameter according to your protocol (e.g. as a key to a database record etc) 12. // in the example we simply dump the resource parameter string String buf = "[" + resource.substring(PROTOCOL.length()+1) + "]"; ByteArrayInputStream baos = new ByteArrayInputStream(buf.getBytes()); return new BufferedInputStream(baos); 13. 14. 15. 16. } 17. 18. @Override public boolean canLoad(String resource, FileCache cache) { if (resource.toLowerCase().startsWith(PROTOCOL)) { return true; } return false; } 19. 20. 21. 22. 23. 24. 25. 26. } 27. 28. pd4ml.addCustomResourceProvider("advanced.DummyProvider"); A005AddCustomResourceLoader.java Suggest edit Last updated on November 10, 2018 5. PD4ML JSP taglib and Web applications # Using PD4ML custom tags in JSP PD4ML distribution among other features also includes 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. PD4ML JSP taglib deployment PD4ML tag library classes and the tag library descriptor (TLD) are packaged together in PD4ML JAR file. To make the classes and the TLD accessible for your Web application, you only need to copy pd4ml*.jar library to the lib directory WEBINF/lib Using <pd4tl:transform> tag Once PD4ML custom tags are deployed, its actions can be called from your HTML using an XML syntax. First, reference a JAR file containing a tag library from your JSP: <%@ taglib uri="http://pd4ml.com/tlds/4.0" prefix="pd4tl" %> The uri attribute is a unique TLD identifier. It does not point to an existing Web document, but refers to pd4tl.tld file, packaged to pd4ml*.jar and registered there under the same uri identifier. In PD4ML v4.0.0 we changed the taglib structure and removed some 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> ). Next, you need to surround your HTML or JSP content with <pd4tl:transform> and </pd4tl:transform> tags. That’s it: 1. 2. 3. <%@ taglib uri="http://pd4ml.com/tlds/4.0" prefix="pd4tl"%><%@page contentType="text/html; charset=ISO8859_1"%><pd4tl:transform 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. screenWidth="400" pageFormat="A5" pageOrientation="landscape" pageInsets="100,100,100,100,points"> <html> <head> <title>pd4ml test

Hello, World!

Hello, New Page!
Comments: Line 1. Make sure there is no whitespaces before the directive start (before <%@ ). The taglib is intended to return a PDF (binary) file. Any content or whitespace (incl. new line characters) before implicitly switches HTTP output to text mode and prefixes the PDF bytes with unexpected characters. As the last resort PD4ML taglib tries to reset such undesired content (if any), but it is not possible in all environments and java.lang.IllegalStateException: getOutputStream() has already been called for this response is thrown. Other symptoms of the undesired content are either corrupted PDF, or PDF, which is always being reindexed when opened by a PDF Viewer. Line 2 and 3 No characters or whitespaces between tags or directives allowed (See %><% and %> <%@page contentType="text/html; charset=ISO8859_1"%> pd4ml test Hello, World! Defining PDF document footer (or header) with JSP custom tag. Since PD4ML v4.0.0 a dedicated header/footer JSP custom tags are not supported anymore. Instead of it use PD4ML proprietary and tags (they take effect not only in JSP context, but also in regular HTML). Identically you may define a watermark with tag. 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. <%@ taglib uri="http://pd4ml.com/tlds/4.0" prefix="pd4tl"%><%@page contentType="text/html; charset=ISO8859_1"%> Page title. $[title] Visible only on the first page Page $[page] of $[total] Page 1 Page 2 Comments: Line 13 Page header definition, whose scope is limited only by the first page. $[title] placeholder is to be substituted with a title value taken from HTML’s > tag. Line 14. Page footer definition to be applied to all pages (as there is no scope attribute). Placeholder $[page] and $[total] to be substituted with the current page number and total number of pages correspondingly. How to add dynamic data (like current date) to PDF header or footer It is JSP. Forget about PDF and do it you would normally do it in a regular JSP: 1. 2. 3. 4. <% String template = getFormattedDate() ; %> <pd4ml:page.footer height=30><span style="color: tomato"><%=template%></span>, page $[page]</pd4ml:page.footer> Temporary saving generated PDF to hard drive. With <pd4tl:savefile> tag you have a possibility to store just generated PDF to a hard drive (on server side) and redirect user’s browser to read the PDF as a static document or to redirect the request to another URL for PDF postprocessing. Note: the tag should be nested to <pd4ml:transform> and have no body. Usage 1. 1. 2. 3. 4. 5. <pd4ml:savefile uri="/WEB/savefile/saved/" dir="D:/spool/generated_pdfs" redirect="pdf" debug="false"/> The tag above forces PD4ML to save the generated PDF to D:/spool/generated_pdfs with an autogenerated name. It is expected, that local directory D:/spool/generated_pdfs corresponds to URL http://yourserver.com/WEB/savefile/saved/ (as given in uri attribute) After generation PD4ML will send to client’s browser a redirect command with URL like that: http://yourserver.com/WEB/savefile/saved/generated_name.pdf Usage 2. 1. 2. 3. 4. <pd4ml:savefile dir="D:/spool/generated_pdfs" redirect="/mywebapp/send_pdf_by_email.jsp" debug="false"/> The tag above forces PD4ML to save the generated PDF to D:/spool/generated_pdfs with an autogenerated name. After that it forwards to /mywebapp/send_pdf_by_email.jsp with a parameter filename=<pdfname> . So send_pdf_by_email.jsp can read file name with String fileName = request.getParameter("filename"); build the full path String path = "D:/spool/generated_pdfs" + "/" + fileName; read the just-generated PDF file and perform post-processing or other actions (like a sending of the PDF by email). In both cases above you can predefine PDF file name with name attribute. If a file with the name is already exists in D:/spool/generated_pdfs , then the new file name is appended with an auto-incremented numeric value. Using PD4ML custom tags with Struts or with any other J2EE UI frameworks, if JSP taglib integration is problematic The specifics of many UI frameworks (like Struts Struts) is that in some cases they take control and open output stream in text mode before PD4ML-enabled JSP page is loaded. On the other hand PD4ML needs an exclusive control over the output stream: it outputs binary data and any other output writers can corrupt it. In order to solve the problem there are workarounds. As described in the above chapter, a just generated PDF can be temporally stored to the hard drive and the current HTTP request can be forwarded to the new static PDF. Alternatively PD4ML transformer JSP pages can be deployed to a separate web application outside of the framework (e.g. Struts) context. It can be even the same web application, but the PD4ML-enabled JSP pages should be out of control of the Struts dispatching servlet. (Can be achieved by web.xml settings). For our example the separate Web application is associated with name separate_web_app . Create a dedicated PD4ML transformer JSP page transformer.jsp in separate_web_app like the following. 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. <%@ 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="15,15,15,15,points" enableImageSplit="false" inline="true" fileName="myreport.pdf" url="http://mainserver/struts/report.jsp"> <pd4ml:footer titleTemplate="$[title]" pageNumberTemplate="page $[page] of $[total]" titleAlignment="left" pageNumberAlignment="right" fontSize="12" areaHeight="14"/> </pd4ml:transform> Replace url attribute value of <pd4ml:transform> with the actual URL of your Struts (JSP) page, that should be converted to PDF. Because of url attribute presence (line 11), the HTML content of transformer.jsp is ignored completely. But as usually: it should be no any whitespace character before <pd4ml:transform> tag. At this point you can access the transformer.jsp and force PDF conversion of the specified source. However in most of the cases a session ID ( JSESSIONID ) propagation is important for proper Struts (or other JSP-based frameworks) functionality. If the url attribute of <pd4ml:transform> is set, then PD4ML takes its value and appends to it JSESSIONID parameter. The value for the parameter it takes from HTTP request variable pd4session A request for PDF generation from Struts context can look like that: 1. 2. 3. 4. <% response.sendRedirect("/separate_web_app/transformer.jsp?pd4session=" + session.getId() ); %> Suggest edit Last updated on November 4, 2018 6. PD4ML and IBM Notes/Domino # v3.x.x v4.1.0 PD4ML can be used to convert IBM Notes documents to PDF (as well as to RTF or to a raster image) a variety of ways. The most straightforward method is to capture HTML documents, returned by Notes Domino via HTTP: an URL like one of the following is to be passed to render() method of PD4ML. http://Host/Database/PageUNID?OpenPage (i.e. http://www.acme.com/discussion.nsf/35AE8FBFA573336A852563D100741784?OpenPage) http://Host/Database/View/DocumentUniversalID?OpenDocument (http://www.acme.com/leads.nsf/By+Rep/35AE8FBFA573336A852563D100741784?OpenDocument) http://Host/Database/FormUniversalID?ReadForm (http://www.acme.com/products.nsf/625E6111C597A11B852563DD00724CC2?ReadForm) More IBM Notes URL syntax info… If you run JSP infrastructure on IBM Domino server, another online method of PDF generation would be to use PD4ML JSP custom tag library (TODO) . If an online document generation method (involving HTTP, JSP etc) is undesired, there is a possibility to generate PDF documents from their XML representations (so called DXL). DXL is an adaptation of XML used to describe, in detail, the structure and data contained in a Domino database. It describes data and design elements such as views, forms, and documents and provides a basis for importing or exporting XML representations of data to and from a Domino/Notes application. Schematically a process of Notes document conversion to PDF can be seen like that: Products Licenses Support Try Free Buy Now [ ] All conversion steps can be implemented at once as a IBM Lotus Notes Java agent, or can be implemented as two-step batch: DXL export request followed by a conversion with Pd4Cmd command-line tool java -Djava.awt.headless=true -Xmx512m -jar pd4ml.jar test.dxl 1200 -xsl notesdefault The command line overrides the default Java memory heap size limit with -Xmx512m . Here it is set to 512Mb. On UNIX platform -Djava.awt.headless=true allows to run the application on non-graphics-enabled servers or from remote ssh/telnet sessions. test.dxl 1200 are DXL location and htmlWidth (virtual “browser” frame width) parameters. On Win32 the path is enclosed, if needed, to double quotes, on UNIX – to single quotes. -xsl notesdefault applies XSL stylesheet to the input document. In the case it refers to the built-in default DXL-toHTML XSL, but it can be an URI of an arbitrary external stylesheet. The default PDF document format: A4 / PORTRAIT In the example 1200px px width of rendered document will be mapped to 595pt pt widths of A4 page format. As long as an output file path omitted, the output is sent to STDOUT STDOUTand can be piped to another application. See more command line arguments… PD4ML as Notes Agent… Suggest edit Last updated on November 4, 2018 7. Usage Examples # Go to Usage Examples section… Suggest edit Last updated on September 4, 2018 </pre><hr>Source Exif Data: <br /><pre>File Type : PDF File Type Extension : pdf MIME Type : application/pdf Linearized : No Page Count : 24 PDF Version : 1.4 Title : PD4ML – PD4ML v4 Programmers Manual Author : igor Subject : Producer : macOS Version 10.14 (Build 18A391) Quartz PDFContext Creator : Safari Create Date : 2019:01:16 19:58:15Z Modify Date : 2019:01:16 19:58:15Z Apple Keywords : </pre> <small>EXIF Metadata provided by <a href="https://exif.tools/">EXIF.tools</a></small> <div id="ezoic-pub-ad-placeholder-110"> <script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script> <!-- usermanual link ad --> <ins class="adsbygoogle" style="display:block" data-ad-client="ca-pub-0545639743190253" data-ad-slot="6172135303" data-ad-format="link"></ins> <script> (adsbygoogle = window.adsbygoogle || []).push({}); </script> </div> </div> <div id="catlinks" class="catlinks catlinks-allhidden" data-mw="interface"></div> <div class="visualClear"></div> </div> </div> <div id="mw-navigation"> <h2>Navigation menu</h2> <div id="mw-head"> <div id="p-personal" role="navigation" class="" aria-labelledby="p-personal-label"> <!-- <div id="p-search" role="search"> <form action="https://usermanual.wiki/search.php" id="searchform"> <div id="simpleSearch"> <input type="search" name="search" placeholder="Search UserManual.wiki" title="Search UserManual.wiki [ctrl-option-f]" accesskey="f" id="searchInput" tabindex="1" autocomplete="off"><input type="hidden" value="Special:Search" name="title"><input type="submit" name="go" value="Go" title="Find a User Manual" id="searchButton" class="searchButton"> </div> </form> </div>--> <ul> <li id="pt-mycontris"><a href="https://usermanual.wiki/upload" title="Upload User Manual" accesskey="y">Upload a User Manual</a></li> </ul> </div> <div id="left-navigation"> <div id="p-namespaces" role="navigation" class="vectorTabs" aria-labelledby="p-namespaces-label"> <h3 id="p-namespaces-label">Versions of this User Manual:</h3> <ul> <li id="ca-nstab-main"><span><a href="https://usermanual.wiki/Document/PD4ML20E2809320PD4ML20v420Programmers20Manual.1678052226" title="User Manual Wiki" accesskey="c">Wiki Guide</a></span></li> <li id="ca-nstab-main"><span><a href="https://usermanual.wiki/Document/PD4ML20E2809320PD4ML20v420Programmers20Manual.1678052226/html" title="HTML" accesskey="c">HTML</a></span></li> <li id="ca-nstab-main"><span><a href="https://usermanual.wiki/Document/PD4ML20E2809320PD4ML20v420Programmers20Manual.1678052226/amp" title="Mobile AMP" accesskey="c">Mobile</a></span></li> <li id="ca-nstab-main" class="selected" ><span><a href="https://usermanual.wiki/Document/PD4ML20E2809320PD4ML20v420Programmers20Manual.1678052226/help" title="Discussion / FAQ / Help" accesskey="c">Download & Help</a></span></li> </ul> </div> </div> <div id="right-navigation"> <div id="p-views" role="navigation" class="vectorTabs" aria-labelledby="p-views-label"> <h3 id="p-views-label">Views</h3> <ul> <li id="ca-view"><span><a href="#">User Manual</a></span></li> <li class="selected" id="ca-edit"><span><a href="https://usermanual.wiki/Document/PD4ML20E2809320PD4ML20v420Programmers20Manual.1678052226/help" title="Ask a question" accesskey="e">Discussion / Help</a></span></li> </ul> </div> </div> </div> <div id="mw-panel"> <div id="p-logo" role="banner"><a class="mw-wiki-logo" href="https://usermanual.wiki/Main_Page" title="Visit the main page"></a></div> <div class="portal" role="navigation" id="p-navigation" aria-labelledby="p-navigation-label"> <h3 id="p-navigation-label">Navigation</h3> </div> <div class="portal" role="navigation" id="p-tb" aria-labelledby="p-tb-label"> </div> </div> </div> <div id="footer" role="contentinfo"> <ul id="footer-info"> <li id="footer-info-lastmod">© 2024 UserManual.wiki</li> </ul> <ul id="footer-places"> <li id="footer-places-privacy"><a href="https://usermanual.wiki/ContactUs" title="UserManual.wiki:Contact Us">Contact Us</a></li> <li id="footer-places-about"><a href="https://usermanual.wiki/DMCA" title="UserManual.wiki:DMCA">DMCA</a></li> </ul> <ul id="footer-icons" class="noprint"> <li id="footer-poweredbyico"> </li> </ul> </div> </div></body></html>