Advanced Dynamic PDF Generation Techniques
You can use CSS and HTML to customize the layout of your PDF and generate complex, pixel-perfect documents. We've included some of the most common tips and tricks and CSS references below. For a complete list of the
On This Page
- Editing the CSS
- Prince User Guide Links, supports CSS selectors & Advanced Options
- Controlling Page Breaks
- Widows & Orphans
- Page Numbering
- Repeating Table Headers and Footers Across Pages
- Changing the Header/Footer on the First Page of the PDF
- Adding Table of Contents and Bookmarks
- Linking From a Page to Another
- Including a SVG Checkbox (using SVG)
Paged Media Resource
Most of the tips and tricks here are based on the paged media CSS spec.For more paged media layout tips and tricks we highly recommend this article "Paged Media Tips and Tricks for Page Layout"Editing the CSS
You can edit the documents CSS by following these steps:
- Click the Edit Document Body button to open the editor
- Click the Source button in the tool bar to switch to source code mode
- Add or edit an existing <style> tag in the document header to add your own CSS
Prince User Guide Links, supports CSS selectors & Advanced Options
Under the hood Logiforms uses the PrinceXML rendering engine. Below are links to the PrinceXML user guide for a more detailed breakdown of supported CSS selectors and prince specific formatting options:
Controlling Page Breaks
You can use the wildcard menu to insert the pageBreak wildcard or use the following CSS/markup:
<div style="page-break-after:always"></div>
You can use this CSS to force a page-break every-time an h1
(heading) tag is encountered:
h1 { page-break-before: always }
page-break-before is used to force a page break immediately before an h1
element, New chapters are often started on the recto pages in text books, this is usually the right page:
h1 { page-break-before: right }
The property page-break-after may also be used to force a page break after an element, In addition to these forced page break, you can also use the any of the @paged CSS rules to apply breaking rules to elements to ensure that the page breaks in the correct location.
For example, if you do not want a table to break across pages, you can wrap the table in a div that uses this pagebreak CSS :
<div style="page-break-inside: avoid;"> <!-- your table here --> </div>
or
<table style="page-break-inside: avoid;"> ... </table>
Note that If a rule cannot be satisfied (e.g. a <div style="page-break-inside: avoid;"> spans three pages), the rule is simply dropped as if it never existed.
So far we have discussed forcing a page break, however suppressing page breaks is also important. For example, it is poor style to have a page break between a header and the first paragraph of a section. Therefore, the default stylesheet will use the page-break-after property to suppress page breaks immediately after headers:
h1, h2, h3, h4, h5, h6 { page-break-after: avoid }
If a heading occurs at the bottom of a page, it may be moved to the next page to keep it with the content that follows it, usually a paragraph.
Widows & Orphans
Just as breaking a page between a heading and the first paragraph below the heading can look bad, breaking the page after only one or two lines of a paragraph also looks bad. These stray lines are called orphans. The minimum number of orphans to allow can be specified with the orphans property (the default is 1).
p { orphans: 2 }
Likewise the minimum number of lines to move to a new page (widows) can be specified with the widows property (the default is 1).
p { widows: 2 }
It can be easy to confuse widows and orphans. However a mnemonic device can help: "An orphan is alone from the beginning [of the paragraph]; a widow is alone at the end [of the paragraph]". (Source Widows and orphans — Wikipedia).
Page Numbering
Page numbering can be inserted into the header or footer by using the following markup:
Page <span id="pagenumber"> </span> of <span id="pagecount"> </span>
Repeating Table Headers and Footers Across Pages
Add this to your CSS to repeat table headers and footers (THEAD and TFOOT GROUPS (Table Specifications)) across pages:
table{ -fs-table-paginate: paginate; border-spacing: 0; }
Changing the Header/Footer on the First Page of the PDF
You can change the header and footer displayed on the first page by adding some new elements to the markup and adding some corresponding CSS.
Add the following CSS to the document:
<style> @page :first { @bottom-right { content: element(firstPageFooter); } @top-left{ content: element(firstPageHeader); } } </style>
And the following markup anywhere in the document body:
<div id="firstPageFooter" style="position: running(firstPageFooter);"> <div class="footerContent">Your First Page Foooter Content Here</div> </div> <div id="firstPageHeader" style="position: running(firstPageHeader);"> <div class="headerContent">Your First Page Header Content Here</div> </div>
Adding Table of Contents and Bookmarks
Using Table of Contents
Adding Table of Contents in your PDF is as easy as having a similar HTML structure as the code below. Notice the style tag is necessary in the <head> section of your document as it styles the TOC list. Then in the <body> section of your document, you will have a list of Content titles which are just <a> links to anchors in your document. Each heading(h2, h3, h4) is forced to start a new page by the the CSS statement: h2, h3, h4 { page-break-before: always; }
<html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>TOC Demo</title> <style type="text/css" media="print"> .toc a::after { content: leader('.') target-counter(attr(href), page); } h2, h3, h4 { page-break-before: always; } </style> </head> <body> <h1>TOC Demo</h1> <b>Contents</b> <ol class="toc"> <li><a href="#xil_1">Document History</a></li> <li><a href="#xil_2">An Introduction to Prince</a> <ol> <li><a href="#xil_3">What it is</a></li> <li><a href="#xil_4">What it does</a></li> <li><a href="#xil_5">What you can do with it</a></li> <li><a href="#xil_6">Where the Prince is a Pauper (what it can't do)</a></li> <li><a href="#xil_7">License and Dependencies</a></li> <li><a href="#xil_8">Requirements for Running and Using Prince</a></li> <li><a href="#set_classpath">Setting your Classpath</a></li> <li><a href="#xil_9">Sample Applications</a> <ol> <li><a href="#xil_10">The Browser</a></li> <li><a href="#xil_11">The About Box</a></li> <li><a href="#xil_12">DocBook</a></li> <li><a href="#xil_13">SVG</a></li> </ol> </li> </ol> </li> </ol> <h2 id="xil_1">Document History</h2> <h2 id="xil_2">An Introduction to Prince</h2> <h3 id="xil_3">What it is</h3> <h3 id="xil_4">What it does</h3> <h3 id="xil_5">What you can do with it</h3> <h3 id="xil_6">Where the Prince is a Pauper (what it can't do)</h3> <h3 id="xil_7">License and Dependencies</h3> <h3 id="xil_8">Requirements for Running and Using Prince</h3> <h3 id="set_classpath">Setting your Classpath</h3> <h3 id="xil_9">Sample Applications</h3> <h4 id="xil_10">The Browser</h4> <h4 id="xil_11">The About Box</h4> <h4 id="xil_12">DocBook</h4> <h4 id="xil_13">SVG</h4> </body> </html>
The appearance of the PDF generated by this bare code above is shown below:
Using Bookmarks
Observe the code block below at it shows the basic structure you will have in your PDF. In the <head> section of your document, a parent <bookmarks> tag is added, and under it, you just need <bookmark> tags with attributes: name and href which just refers to an achor(<a name="section_1">Some Text</a>) in the <body> of the document. I you need nesting, then see the first <bookmark> block and do it similarly. Take note of the scheme used in the <body> wherein each section anchor is wrapped with <div style="page-break-before: always;"> so that it always occupy the top of a new page.
<html xmlns="http://www.w3.org/1999/xhtml"> <head> <bookmarks> <bookmark name="Section 1" href="#section_1"> <bookmark name="Section 1.1" href="#section_11"></bookmark> <bookmark name="Section 1.2" href="#section_12"></bookmark> </bookmark> <bookmark name="Section 2" href="#section_2"></bookmark> <bookmark name="Section 2" href="#section_3"></bookmark> </bookmarks> </head> <body> <div style="page-break-before: always;"> <a name="section_1"><strong>Section 1</strong></a> </div> <div style="page-break-before: always;"> <a name="section_11">Section 1.1</a> </div> <div style="page-break-before: always;"> <a name="section_12">Section 1.1.2</a> </div> <div style="page-break-before: always;"> <a name="section_2"><strong>Section 2</strong></a> </div> <div style="page-break-before: always;"> <a name="section_3"><strong>Section 3</strong></a> </div> </body> </html>
Screenshot below shows how it appears in Adobe Acrobat XI Pro.
For more information on usng bookmarks,
Linking From a Page to Another
You can link to any anchor in the PDF, not just using bookmarks as described above. You would insert an anchor at the section/page you want to jump to:
<a name="myAnchor"></a>
And then link to that anchor from anywhere else within the PDF:
<a href="#myAnchor">Jump to Section XYZ</a>
Including a SVG Checkbox (using SVG)
SVG (Scalable Vector Graphics) can be included in your dynamic PDFs following the guidelines found here.
SVG must be inserted into the SOURCE code view of the PDF Editor
When inserting SVG into the Dynamic PDF Editor, make sure to click the Source button in the editor toolbar before pasting the SVG code.The below SVG markup can be used to show a checkbox in a check and unchecked state within a Dynamic PDF (note, you must be using the Prince rendering engine in order to us SVG).
SVG for a Checked Checkbox
<svg enable-background="new 0 0 24 24" height="24px" id="Layer_1" version="1.1" viewbox="0 0 24 24" width="24px" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <g> <path d="M23.414,0.586c-0.781-0.781-2.047-0.781-2.828,0L11,10.171L7.414,6.586c-0.78-0.781-2.048-0.781-2.828,0 c-0.781,0.781-0.781,2.047,0,2.828l5,5C9.976,14.805,10.488,15,11,15s1.024-0.195,1.414-0.586l11-11 C24.195,2.633,24.195,1.367,23.414,0.586z"> </path> <path d="M21,10c-0.553,0-1,0.448-1,1v7c0,1.103-0.897,2-2,2H4c-1.103,0-2-0.897-2-2V4c0-1.103,0.897-2,2-2h11c0.553,0,1-0.448,1-1 s-0.447-1-1-1H4C1.8,0,0,1.8,0,4v14c0,2.2,1.8,4,4,4h14c2.2,0,4-1.8,4-4v-7C22,10.448,21.553,10,21,10z"> </path> </g> </svg>
SVG for an unchecked Checkbox
<svg enable-background="new 0 0 24 24" height="24px" id="Layer_1" version="1.1" viewbox="0 0 24 24" width="24px" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <g> <path d="M18,0H4C1.8,0,0,1.8,0,4v14c0,2.2,1.8,4,4,4h14c2.2,0,4-1.8,4-4V4C22,1.8,20.2,0,18,0z M20,18c0,1.103-0.897,2-2,2H4 c-1.103,0-2-0.897-2-2V4c0-1.103,0.897-2,2-2h14c1.103,0,2,0.897,2,2V18z"> </path> </g> </svg>
0 Comments