Pdf and graphic files generator library written in php

Related tags

PDF PHPPdf
Overview

Information

Build Status

Examples

Sample documents are in the "examples" directory. "index.php" file is the web interface to browse examples, "cli.php" is a console interface. Via the web interface, the documents are available in pdf and jpeg format (the jpeg format requires Imagick).

Documentation

Table of contents

  1. Introduction
  2. Installation
  3. Symfony2 bundle
  4. FAQ
  5. Document parsing and creating pdf file
  6. Basic document structure
  7. Inheritance
  8. Stylesheet structure
  9. Palette of colors
  10. Standard tags
  11. Attributes
  12. Complex attributes
  13. Units
  14. Barcodes
  15. Charts
  16. Hyperlinks
  17. Bookmarks
  18. Sticky notes
  19. Repetitive headers and footers
  20. Watermarks
  21. Page numbering
  22. Using the pdf document as a template
  23. Separate page on columns
  24. Breaking pages and columns
  25. Metadata
  26. Configuration
  27. Markdown support
  28. [Image generation engine] (#image-generation)
  29. Known limitations
  30. TODO - plans
  31. Technical requirements

Introduction

PHPPdf is library that transforms an XML document to a PDF document or graphics files. The XML source document is similar to HTML, but there are lots of differences in names and properties of attributes, properties of tags, and there are a lot of not standard tags, not all tags from html are supported, stylesheet is described in an xml document, not in css.

Assumption of this library is not HTML -> PDF / JPEG / PNG, but XML -> PDF / JPEG / PNG transformation. Some tags and attributes are the same as in HTML in order decrease the learning curve of this library.

Installation

PHPPdf is available at packagist.org, so you can use composer to download this library and all dependencies.

(add to require section in your composer.json file)

    "psliwa/php-pdf": "*"

You should choose last stable version (or wildcard of stable version), wildcard char ("*") is only an example.

If you want to use as features as barcodes or image generation, you should add extra dependencies:

    "zendframework/zend-barcode": ">=2.0.0,<2.4",
    "zendframework/zend-validator": ">=2.0.0,<2.4",
    "imagine/Imagine": ">=0.2.0,<0.6.0"

Symfony2 bundle

There is a Symfony2 bundle which integrates this library with the Symfony2 framework.

FAQ

Diacritical marks are not displayed, what should I do?

You should set a font that supports the encoding that you are using, and set this encoding as "encoding" attribute for "page" and/or "dynamic-page" tags. PHPPdf provides some free fonts that support utf-8 encoding, for example, DejaVuSans. The "Font" example shows how to change the font type by using a stylesheet.

You can also add custom fonts, in order that you should prepare xml config file and configure Facade object as shown below:

    <!-- xml config file code -->
    <fonts>
        <font name="DejaVuSans">
            <normal src="%resources%/fonts/DejaVuSans/normal.ttf" /><!-- "%resources%" will be replaced by path to PHPPdf/Resources directory -->
            <bold src="%resources%/fonts/DejaVuSans/bold.ttf" />
            <italic src="%resources%/fonts/DejaVuSans/oblique.ttf" />
            <bold-italic src="%resources%/fonts/DejaVuSans/bold+oblique.ttf" />
            <light src="%resources%/fonts/DejaVuSans/light.ttf" />
            <light-italic src="%resources%/fonts/DejaVuSans/light+oblique.ttf" />
        </font>
    </fonts>
//php code
$loader = new PHPPdf\Core\Configuration\LoaderImpl();
$loader->setFontFile(/* path to fonts configuration file */);
$builder = PHPPdf\Core\FacadeBuilder::create($loader);
$facade = $builder->build();
<!-- xml document code -->
<pdf>
    <dynamic-page encoding="UTF-8" font-type="DejaVuSans">
    </dynamic-page>
</pdf>

You can find more datails in the Configuration section.

Generating of a simple pdf file with png images takes a lot of time and memory, what should I do?

PHPPdf uses the Zend_Pdf library that poorly supports png files without compression. You should compress the png files.

How can I change the page size/orientation?

To set the page dimensions you use the "page-size" attribute of the page or dynamic-page tags.

The value syntax of this attribute is "width:height".

There are however standard predefined values:

  • A format: from 4A0 to A10
  • B format: from B0 to B10
  • C format: from C0 to C10
  • US sizes: legal and letter

All formats are supported in portrait and lanscape.

Example:

<page page-size="100:50">text</page>
<page page-size="a4">text</page>
<page page-size="letter-landscape">text</page>

Document parsing and creating a pdf file

The simplest way of using the library is:

//register the PHPPdf and vendor (Zend_Pdf and other dependencies) autoloaders
require_once 'PHPPdf/Autoloader.php';
PHPPdf\Autoloader::register();
PHPPdf\Autoloader::register('/path/to/library/lib/vendor/Zend/library');

//if you want to generate graphic files
PHPPdf\Autoloader::register('sciezka/do/biblioteki/lib/vendor/Imagine/lib');

$facade = new PHPPdf\Core\Facade(new PHPPdf\Core\Configuration\Loader());

//$documentXml and $stylesheetXml are strings contains XML documents, $stylesheetXml is optional
$content = $facade->render($documentXml, $stylesheetXml);

header('Content-Type: application/pdf');
echo $content;

Basic document structure

The library bases pages on an XML format similar to HTML, but this format isn't HTML - some tags are diffrent, interpretation of some attributes is not the as same as in the HTML and CSS standards, adding attributes is also different.

A simple document has following structure:

<pdf>
    <dynamic-page>
        <h1>Header</h1>
        <p>paragraph</p>
        <div color="red">Layer</div>
        <table>
            <tr>
                <td>Column</td>
                <td>Column</td>
            </tr>
        </table>
    </dynamic-page>
</pdf>

Adding a DOCTYPE declaration is strongly recommended in order to replace html entities on values:

    <!DOCTYPE pdf SYSTEM "%resources%/dtd/doctype.dtd">

The root name of a document must be "pdf". The "dynamic-page" tag is an auto breakable page. The "page" tag is an alternative, and represents only a single, no breakable page.

The way of attribute setting is different than in HTML.

In order to set a background and border you need to use complex attributes, where first part of attribute name is a complex attribute type, and the second part is the property of this attribute.

Complex attribute parts are separated by a dot (".").

An another way of setting complex attributes is by using the "complex-attribute" tag.

Example:

<pdf>
    <dynamic-page>
        <div color="red" border.color="black" background.color="pink">
            This text is red on pink backgroun into black border
        </div>
    </dynamic-page>
</pdf>

Alternative syntax ("stylesheet" tag):

<pdf>
    <dynamic-page>
        <div>
            <stylesheet>
                <attribute color="red" />
                <complex-attribute name="border" color="black" />
                <complex-attribute name="background" color="pink" />
            </stylesheet>
            This text is red on pink backgroun into black border
        </div>
    </dynamic-page>
</pdf>

Attributes can by set as XML attributes, directly after a tag name or by using the mentioned "stylesheet" tag. The HTML "style" attribute does not exist the PHPPdf XML dialect.

The library is very strict in respecting the corectness of tags and attributes. If an unexisted tag or attribute is detected, the document parser will stop and throw an exception.

Inheritance

The "id" attribute has an different usage than in HTML. The id attribute is used to identify tags when using inheritance.

The "name" attribute can also be used as an alias to "id".

An id must by unique throughout the document, otherwise a parsing error is thrown.

Example:

<pdf>
    <dynamic-page>
        <div id="layer-1" color="red" font-type="judson" font-size="16px">
            <stylesheet>
                <complex-attribute name="border" color="green" />
            </stylesheet>
            Layer 1
        </div>
        <div extends="layer-1">
            Layer 2 inherits style (type, simple and complex attributes) from layer 1)
        </div>
    </dynamic-page>
</pdf>

The Second layer inherits all attributes (simple and complex), and also those from external stylesheets.

Priorites in attributes setting:

  1. Stylesheet tag directly in an element tag
  2. Attributes directly after a tag name (XML attributes)
  3. Attributes from external stylesheets
  4. Inherited attributes from a parent tag

Example:

<pdf>
    <page>
        <div id="1" color="#cccccc" height="100px" text-align="right">
        </div>
        <div extends="1" color="#aaaaaa" height="150px">
            <stylesheet>
                <attribute name="height" value="200px" />
            </stylesheet>
        </div>
    </page>
</pdf>

The second "div" will now have the following attributes:

  • text-align: right
  • color: #aaaaaa
  • height: 200px

Stylesheet structure

Stylesheets are defined in external files, stylesheet short and long declarations of attributes are supported.

Syntax of the stylesheet:

Short style:

<stylesheet>
    <!-- style attributes are embeded as xml attributes, class attribute has the same meaning as in HTML/CSS -->
    <div class="class" font-size="12px" color="gray" background.color="yellow">
        <!-- nested element, equivalent CSS selector syntax: "div.class p" -->
        <p margin="10px 15px">
        </p>
    </div>

    <!-- equivalent CSS selector syntax: ".another-class", "any" tag is wildcard (mean any tag) -->
    <any class="another-class" text-align="right">
    </any>

    <h2 class="header">
        <span font-size="9px">
        </span>
        
        <div font-style="bold">
        </div>
    </h2>
</stylesheet>

Long style:

<stylesheet>
    <div class="class">
        <!-- simple and complex attributes are nested in "div.class" selector path -->
        <attribute name="font-size" value="12px" />
        <attribute name="color" value="grey" />
        <!-- equivalent of background.color attribute -->
        <complex-attribute name="background" color="yellow" />

        <!-- another nested element, equivalent CSS selector syntax: "div.class p" -->
        <p>
            <attribute name="margin" value="10px 15px" />
        </p>
    </div>

    <!-- equivalent CSS selector syntax: ".another-class", "any" tag is wildcard (mean any tag) -->
    <any class="another-class">
        <attribute name="text-align" value="right" />
    </any>

    <h2 class="header">
        <span>
            <attribute name="font-size" value="9px" />
        </span>
        <div>
            <attribute name="font-style" value="bold" />
        </div>
    </h2>
</stylesheet>

Palette of colors

PHPPdf supports color palettes, - mapping of logical names to real colors.

Color palettes gives you the opportunity to create or overwrite default named colors. By default, PHPPdf supports named colors from the W3C standard (for example "black" = "#000000").

You can use a palette for the DRY principle, because information about used colors will be kept in one place. And you can also generate one document with different palettes.

Example:

<!-- colors.xml file -->
<colors>
    <color name="header-color" hex="#333333" />
    <color name="line-color" hex="#eeeeee" />
</colors>

<!-- stylesheet.xml file -->
<h2 color="header-color" />
<hr background-color="line-color" />
<table>
    <td border-color="line-color" />
</table>

<!-- document.xml file -->
<pdf>
    <page>
        <h2>Header</h2>
        <hr />
        <table>
            <tr>
                <td>Data</td>
                <td>Data</td>
            </tr>
        </table>
    </page>
</pdf>
    //php code
    use PHPPdf\DataSource\DataSource;
    
    $facade = ...;

    $content = $facade->render(
        DataSource::fromFile(__DIR__.'/document.xml'),
        DataSource::fromFile(__DIR__.'/stylesheet.xml'),
        DataSource::fromFile(__DIR__.'/colors.xml')
    );

Standard tags

The library supports primary HTML tags: div, p, table, tr, td, b, strong, span, a, h1, h2, h3, h4, h5, img, br, ul, li

In addition there are also not standard tags:

  • dynamic-page - auto breakable page
  • page - single page with fixed size
  • elastic-page - single page that accommodates its height to its children as same as another tags (for example "div"). Header, footer, watermark, template-document attribute do not work with this tag. Useful especially in graphic files generation (image engine).
  • page-break, column-break, break - breaks page or column, this tag must be direct child of "dynamic-page" or "column-layout"!
  • column-layout - separate workspace on columns, additional attributes: number-of-columns, margin-between-columns, equals-columns
  • barcode - more information in barcode chapter
  • circle - element that border and backgroud are in circle shape. Additional attributes: radius (it overwrites width and height attributes)
  • pie-chart - element that can be used to draw simple pie chart (more information in charts chapter.

There are tags that are only bags for attributes, a set of tags etc:

  • stylesheet - stylesheet for parent
  • attribute - simple attribute declaration, direct child of "stylesheet" tag. Required attributes of this element: name - attribute name, value - attribute value
  • complex-attribute - complex attribute declaration, direct child of "stylesheet" tag. Required attributes of this element: name - complex attribute name
  • placeholders - defines placeholders for parent tag. Children tags of placeholder are specyfic for every parent tag. It should be first tag in parent
  • metadata - defines metadata of pdf document, direct child of document root
  • behaviours - defines behaviours for a parent tag. Supported behaviours: href, ref, bookmark, note (action as same as for attributes with as same as name)

Attributes

  • width and height: rigidly sets height and width, supported units are described in separate section. Relative values in percent are supported.
  • max-width, max-height: sets max sizes of elements
  • margin (margin-top, margin-bottom, margin-left, margin-right): margin similar to margin from HTML/CSS. Margins of simblings are pooled. For side margins possible is "auto" value, it works similar as in HTML/CSS.
  • padding (padding-top, padding-bottom, padding-left, padding-right): works similiar as in HTML/CSS
  • font-type - font name must occurs in fonts.xml config file, otherwise exception will be thrown
  • font-size - file size in points, there are no any unit
  • font-style - allowed values: normal, bold, italic, bold-italic, light, light-italic
  • color - text color. HTML/CSS style values are supported
  • breakable - if true, element is able to be broken in several pages. Default value for most tags is true..
  • float - works similar but not the same as in HTML/CSS. Allowed values: left|none|right, default none
  • line-height - works similar as in HTML/CSS. Default value: 1.2*font-size
  • text-align - works as same as in HTML/CSS. Allowed values: left|center|right|justify, default left.
  • text-decoration - allowed values: none, underline, overline, line-through
  • break - breaks page or column in the end of the owner of this attribute. Owner of this attribute must by directly child of dynamic-page or column-layout tag!
  • colspan, rowspan - works similar as in HTML (TODO: rowspan isn't implemented yet)
  • href - external url where element should linking
  • ref - id of element where owner should linking
  • bookmark - create bookmark with given title associated with the tag
  • note - create sticky note associated with tag
  • dump - allowed values: true or false. Create sticky note with debug informations (attributes, position etc.)
  • rotate - angle of element rotation. This attribute isn't fully implemented, works corectly for watermarks (see "Watermarks" section). Possible values: XXdeg (in degrees), XX (in radians), diagonally, -diagonally.
  • alpha - possible values: from 0 to 1. Transparency for element and his children.
  • line-break - line break (true or false), by default set on true only for "br" tag
  • style - as same as in html, this attribute can be used to set another attributes, for example: style="width: 100px; height: 200px; margin: 20px 0;". Every attribute must be finished by ";" char, even the last.
  • ignore-error (only for img tag) - ignore file loading error or throw exception? False by default, that means exception will be thrown.
  • keep-ratio (only for img tag) - keeps ratio by cutting fragment of image even if ratio of setted dimension is not the same as ratio of original source image. False by default.
  • position - the same as in html. Allowed values: static (default), relative, absolute
  • left and top - the same as in html, works with position relative or absolute. Right and bottom is not supported.

Complex attributes

Complex attributes can be set by notation "attributeName.attributeProperty" or "attributeName-attributeProperty"

For example: border.color="black" or border-color="black"

  • border:

    • color: border color
    • style: posible values: solid (solid line), dotted (predefined dotted line) or any definition in the form of integers separated by space
    • type: which edges will be shown - default "top+bottom+left+right" (all edges). "none" value is possible (it disable border)
    • size: border size
    • radius: corner rounding in units of length (attention: if this parameter is set, type paramete will be ignored, rounded border always will be full - this will be fixed in future)
    • position: border translation relative to original position. Positive values extends border, negative values decrases border. Owing to manipulation of this parameter, you can obtain complex pattern as border if you add another borders with different styles and positions.
  • background:

    • color: background color
    • image: background image
    • repeat: way of image repeating (none|x|y|all)
    • radius: rounding background corners in units of length (for now only works with color background)
    • use-real-dimension: attribute only used by page (or dynamic-page). True for filling also margins, false in otherwise.
    • image-width: custom width of background image, percentage values are allowed
    • image-height: custom height of background image, percentage values are allowed
    • position-x: horizontal position for image of background, allowed values: left, center, right or numeric value (default: left)
    • position-y: vertical position for image of background, allowed values: top, center, bottom or numeric value (default: top)

It is possible to add several complex attributes in the same type (for instance 3 different borders).

You can achieve that by using the "stylesheet" tag instead of the short notation.

<pdf>
    <dynamic-page>
        <div>
            <stylesheet>
                <!-- Top and bootom edges are red, side edges are yellow-gray --> 
                <complex-attribute name="border" color="red" type="top+bottom" />
                <complex-attribute id="borderLeftAndRight" name="border" color="yellow" type="left+right" size="4px" />
                <complex-attribute id="outerBorderLeftAndRight" name="border" color="gray" type="left+right" size="2px" position="1px" />
            </stylesheet>
        </div>
    </dynamic-page>
</pdf>

In this example, the second border has a "borderLeftAndRight" indentifie, if this border had no id, the attributes from second border would be merged with the attributes from first border.

Remeber the default identifier "id" is as same as the "name" attribute. The "id" attributes for complex attributes has nothing to do with the "id" attribute of tags (used in inheritance).

It is possible to create complex borders the same as in the previous example (outerBorderLeftAndRight).

Units

Supported units for numerical attributes:

  • in (inches)
  • cm (centimeters)
  • mm (milimeters)
  • pt (points)
  • pc (pica)*
  • px (pixels)
    • % (percent - only for width and height).

Currently unsupported units are: em and ex

When the unit is missing (for example: font-size="10"), then the default unit is points (pt). 1pt = 1/72 inch

Barcodes

Barcodes are supported by the <barcode> tag.

PHPPdf uses the Zend\Barcode library in order to generate barcodes.

Example:

<pdf>
    <dynamic-page>
        <barcode type="code128" code="PHPPdf" />
    </dynamic-page>
</pdf>

<barcode> tag supports the most of standard attributes and has some other attributes:

  • type - typ of barcode, supported values: code128, code25, code25interleaved, code39, ean13, ean2, ean5, ean8, identcode, itf14, leitcode, planet, postnet, royalmail, upca, upce
  • draw-code - equivalent of drawCode option from Zend\Barcode
  • bar-height - equivalent of barHeight option from Zend\Barcode
  • with-checksum - equivalent of withChecksum option from Zend\Barcode
  • with-checksum-in-text - equivalent of withChecksumInText option from Zend\Barcode
  • bar-thin-width - equivalent of barThinWidth option from Zend\Barcode
  • bar-thick-width - equivalent of barThickWidth option from Zend\Barcode
  • rotate - equivalent of orientation option from Zend\Barcode

You can find the description of these options and there default values in the Zend\Barcode documentation.

In order to render textual barcodes, you can't use to following embeded pdf fonts: courier, times-roman and helvetica. This will soon be fixed.

Charts

PHPPdf supports drawing simple charts.

For now there is only support for s simple pie chart.

Example:

<pdf>
    <dynamic-page>
        <pie-chart radius="200px" chart-values="10|20|30|40" chart-colors="black|red|green|blue"></pie-chart>
    </dynamic-page>
</pdf>

The <pie-chart> tag has three extra attributes:

  • radius - radius of the chart
  • chart-values - values of the chart, together they must be summing to 100. Each value must be separated by "|".
  • chart-colors - colors of each value. Each color must be separated by "|".

Hyperlinks

The library supports external and internal hyperlinks.

External hyperlinks link to url's, while internal links link to other tags inside the pdf document.

Example:

<pdf>
    <dynamic-page>
        <a href="http://google.com">go to google.com</a>
        <br />
        <a ref="some-id">go to another tag</a>
        <a href="#some-id">go to another tag</a> <!-- anchor style ref -->
        <page-break />
        <p id="some-id">Yep, this is another tag! ;)</p>
    </dynamic-page>
</pdf>

Every element has a "href" and "ref" attribute, even div. You can't nest elements inside an "a" tag.

If you want to use img elements as a link, you should use the href (external link) or ref (internal link) attribute directly in img tag.

Bookmarks

The preferred way of creating bookmarks is by using the "behaviours" tag.

This doesn't restrict the structure of the document, the owner of a parent bookmark doesn't have to be a parent of a child's bookmark owner.

Example:

<pdf>
    <dynamic-page>
	    <div>
	        <behaviours>
	            <bookmark id="1">parent bookmark</bookmark>
	        </behaviours>
	        Some content
	    </div>
	    <div>
	        <behaviours>
	            <bookmark parentId="1">children bookmark</bookmark>
	        </behaviours>
	        Some another content
	    </div>
	    <div>
	        <behaviours>
	            <bookmark parentId="1">another children bookmark</bookmark>
	        </behaviours>
	        Some another content
	    </div>
	    <div>
	        <behaviours>
	            <bookmark>another parent bookmark</bookmark>
	        </behaviours>
	       Some content
	    </div>
	</dynamic-page>
</pdf>

A shortcut for the "bookmark" behaviour is the "bookmark" attribute, if you assign some value to this attribute, bookmarks that refers to this tag will be automatically created.

The bookmark of a parent tag is also the parent of a children's bookmarks.

Example:

<pdf>
    <dynamic-page>
	    <div bookmark="parent bookmark">
	        Some content
	        <div bookmark="children bookmark">
	            Some another content
	        </div>
	        <div bookmark="another children bookmark">
	            Some another content
	        </div>
	    </div>
	    <div bookmark="another parent bookmark">
	       Some content
	    </div>
	</dynamic-page>
</pdf>

The above structures (both examples) will create this bookmarks structure:

  • parent bookmark
    • children bookmark
    • another children bookmark
  • another parent bookmark

Sticky notes

Sticky notes can be created by using the "note" attribute.

Example:

<pdf>
    <dynamic-page>
        <div note="note text"></div>
    </dynamic-page>
</pdf>

The XML parser normalizes values of attributes, wich results ignoring new line characters.

If you want to add a note with new line characters, you should use this syntax:

<pdf>
    <dynamic-page>
        <div>
            <behaviours>
                <note>note text</note>
            </behaviours>
        </div>
    </dynamic-page>
</pdf>

Repetitive headers and footers

"placeholders" can be used in for adding a repetitive header or/and footer.

Some elements have special "placeholders": page has header and footer, table also has header and footer (TODO: not implemented yet) etc.

<pdf>
    <dynamic-page>
        <placeholders>
            <header>
                <div height="50px" width="100%">
                    Header
                </div>
            </header>
            <footer>
                <div height="50px" width="100%">
                    Footer
                </div>
            </footer>
        </placeholders>
    </dynamic-page>
</pdf>

Header and footer need to have a height attribute set. This height is pooled with page top and bottom margins.

Workspace is the page size reduced by page margins and placeholders (footer and header) height.

Watermarks

Page can have a "watermark" placeholder.

The watermark may be set on block's and container elements, for instance: div, p, h1 (no span, plain text or img).

If you want to use an image as a watermark, you should wrap the img tag in a div.

Example:

<pdf>
    <dynamic-page>
        <placeholders>
            <watermark>
                <!-- rotate can have absolute values (45deg - in degrees, 0.123 - in radians) or relative values ("diagonally" and "-diagonally" - angle between diagonal and base side of the page) -->
                <div rotate="diagonally" alpha="0.1">
                    <img src="path/to/image.png" />
                </div>
            </watermark>
        </placeholders>
    </dynamic-page>
</pdf>

Page numbering

There are two tags that can be used to show page information in a footer, header or watermark: page-info and page-number.

This element only works with dynamic-page, not single pages. Page-info shows the current and total page number, page-number shows only the current page number.

Attributes of this tags:

  • format - format of output string that will be used as argument of sprintf function. Default values: "%s." for page-number, "%s / %s" for page-info.
  • offset - value that will be added to current page number and total page number. Usefull if you want to count pages from a diffrent value than zero. Default: 0.

Example:

<pdf>
    <dynamic-page>
        <placeholders>
            <header>
                <div height="20px">
                    <page-info format="page %s for %s" />

                    <!-- when we would like to number from 2 -->
                    <page-info offset="1" format="page %s for %s" />

                    <!-- when we would like to display only current page number -->
                    <page-info format="%1$s." />
                    <!-- or -->
                    <page-number />

                    <!-- when we would like to display only total pages number -->
                    <page-info format="%2$s pages" />
                </div>
            </header>
        </placeholders>
        Some text
    </dynamic-page>
</pdf>

Using a pdf document as a template

The "page" and "dynamic-page" tags can have a "document-template" attribute, that allows you to use an external pdf document as a template.

For the "page" tag, the page's template will be the first page of an external document.

For the "dynamic-page" tag, the template for each page will be the corresponding page of an external document.

Example:

<pdf>
    <dynamic-page document-template="path/to/file.pdf">
        <div>Some content</div>
    </dynamic-page>
</pdf>

Separate page on columns

Page can be separated on columns:

<pdf>
    <dynamic-page>
        <column-layout>
            <div width="100%" height="2500px" background.color="green">
            </div>
        </column-layout>
    </dynamic-page>
</pdf>

The above XML describes several pages of the pdf document, with green rectangles separated on two columns.

The "column-layout" tag has three additional parameters: number-of-columns, margin-between-columns and equals-columns.

Default values for this attributes are 2, 10 and false respectlivy. If the equals-columns attribute is set, columns will have more or less equals height.

Breaking pages and columns

Page and column may by manually broken using one of these tags: page-break, column-break, break.

All these tags are the same. These tags need to be direct children of the breaking element (dynamic-page or column-layout).

If you want to avoid automatic page or column break on certain tags, you should set the "breakable" attribute of this tag to "off.

Example:

<pdf>
    <dynamic-page>
        <div breakable="false">this div won't be automatically broken</div>
    </dynamic-page>
</pdf>

Metadata

Metadata can be added by attributes at the document's root.

Supported metadata is: Creator, Keywords, Subject, Author, Title, ModDate, CreationDate and Trapped.

** These attribute names are case sensitive. **

Example:

<pdf Author="Piotr Sliwa" Title="Test document">
    <!-- some other elements -->
</pdf>

Configuration

The library has four primary config files that allow you to adopt the library for specyfic needs and extending.

  • complex-attributes.xml - declarations of complex attributes classes to logical names that identify attribute in whole library.
  • nodes.xml - definitions of allowed tags in xml document with default attributes and formatting objects.
  • fonts.xml - definitions of fonts and assigning them to logical names that identify font in whole library.
  • colors.xml - palette of colors definitions

In order to change default the config files, you must pass to Facade constructor configured Loader object:

    $loader = new PHPPdf\Core\Configuration\LoaderImpl(
        '/path/to/file/nodes.xml',
        '/path/to/file/enhancements.xml',
        '/path/to/file/fonts.xml',
        '/path/to/file/colors.xml'
    );
    
    $facade = new PHPPdf\Core\Facade($loader);

If you want to change only one config file, you should use LoaderImpl::set* method:

$loader = new PHPPdf\Core\Configuration\LoaderImpl();
$loader->setFontFile(
'/path/to/file/fonts.xml'); //there are setFontFile, setNodeFile, setComplexAttributeFile and setColorFile methods
$facade = new PHPPdf\Core\Facade($loader);

FacadeBuilder can be uset to build and configure Facade. FacadeBuilder is able to configure cache, rendering engine and document parser.

$builder = PHPPdf\Core\FacadeBuilder::create(/* you can pass specyfic configuration loader object */)
                                        ->setCache('File', array('cache_dir' => './cache'))
                                        ->setUseCacheForStylesheetConstraint(true); //stylesheets will be also use cache

$facade = $builder->build();

Markdown support

Library supports basic (official) markdown syntax. To convert markdown document to pdf, you should configure Facade object by MarkdownDocumentParser. You also might to use FacadeBuilder to do this for you.

Example:

$facade = PHPPdf\Core\FacadeBuilder::create()
                                   ->setDocumentParserType(PHPPdf\Core\FacadeBuilder::PARSER_MARKDOWN)
                                   ->setMarkdownStylesheetFilepath(/** optionaly path to stylesheet in xml format */)
                                   ->build();

By default, in markdown pdf document, helvetica font is used. If you want to use utf-8 characters or customize a pdf document, you should provide your own stylesheet by using the FacadeBuilder::setMarkdownStylesheetFilepath method.

The stylesheet structure has been described in the stylesheet chapter. By default the stylesheet is empty, if you want to set another font type, the stylesheet should look like this:

<stylesheet>
    <any font-type="DejaVuSans" />
</stylesheet>

Internally the MarkdownDocumentParser converts a markdown document to html (via the PHP markdown library), then converts html to xml, and at last xml to a pdf document.

Be aware of that, if you in a markdown document use raw html that will be incompatible with the xml syntax of PHPPdf (for example unexistend attributes or tags), the parser will throw an exception then.

Not all tags used in the markdown implementation are propertly supported by PHPPdf, for example "pre" and "code" tags.
For now "pre" tag is an alias for "div", and "code" tag is an alias for "span", be aware of that.

Image generation engine

PHPPdf is able to generate image (jpg or png) files insted of a pdf document. To achieve that, you must configure the FacadeBuilder, example:

$facade = PHPPdf\Core\FacadeBuilder::create()
                                   ->setEngineType('image')
                                   ->build();

//render method returns array of images' sources, one pdf page is generated to single image file 
$images = $facade->render(...);

By default the GD library is used to render an image.

But you can also use Imagick, which offers a better quality, so it is recommended that if you have the opportiunity to install Imagick on your server. To switch the graphic library, you must configure the FacadeBuilder object using the setEngineOptions method:

$builder = ...;
$builder->setEngineOptions(array(
    'engine' => 'imagick',
    'format' => 'png',//png, jpeg or wbmp
    'quality' => 60,//int from 0 to 100
));

Supported graphic libraries are: GD (default), imagick, gmagick. PHPPdf uses the Imagine library as an interface for graphics file generation.

Known limitations

Below is a list of known limitations of the current version of the library:

  • there no way to inject an image into a text with floating - will be introduced in the next releases
  • partial support for float attribute within table element (floats might work improperly within a table)
  • vertical-align attribute works improperly if in element with this attribute set, are more than one element
  • border doesn't change dimensions of the element (while in HTML they do)
  • png files (expecially without compression) are inefficient. png files with high compression (compression level 6 or higher) or jpeg should be used instead
  • not all tags are propertly supported, for example the "pre" tag is an alias to "div" and the "code" tag is an alias for "span"
  • nesting of linear tags (text, span, code, page-info, page-number, a, b, i, em) is not properly supported. If one linear tag contains another, only text within this tags is merged, styles are taken from the most outher linear tag.

TODO - plans

  • automatic generating of "table of contents"
  • improve table, header and footer for table, rowspan. Fix calculation of cell's min height when colspan is used.
  • support for simple bar and pie charts

Technical requirements

This library works with php 5.3 and up.

Comments
  • Zend Framework

    Zend Framework

    Why Zend 1.11 is used but not Zend 2? Why Zend is included inside PHPPdf's package? (if PHPPdf is included inside a Symfony 2 application which already included Zend Framework, there is a problem...)

    opened by hlecorche 12
  • header + footer and templates are incompatible

    header + footer and templates are incompatible

    When I try to display a header and a footer over a template, it does not work.

    The header and the footer space are reserved but the their content are not displayed. But the page content is.

    When I remove the template, the header and footer contents are displayed along with the page content.

    opened by aledeg 8
  • Problem with pdf size

    Problem with pdf size

    There is some problem with innormal file size of generated pdfs.

    <page encoding="UTF-8" font-type="DejaVuSans">
    

    One-page pdf with no image will be ~700-800 kb Its normal?

    opened by i4got10 8
  • Text from page above runs into <header> placeholder on page below.

    Text from page above runs into
    placeholder on page below.

    I am using the dynamic-page tag and have a header placeholder that I want to appear on all pages. Unfortunately, if the content on the page runs across two pages, instead of skipping over the header area, the text runs through it, so I have the header content showing with the over-running page content written over the top.

    How can I prevent this?

    opened by Tocacar 7
  • Text-align justify seems not working

    Text-align justify seems not working

    Hi,

    The text-align attribute seems not working. My text is moving well for the RIGHT, LEFT and CENTER values, but doesn't expand for the JUSTIFY.

    Any ideas please ?

    Thanks.

    opened by pierre-b 6
  • Added a reset for the Engine's internal images array

    Added a reset for the Engine's internal images array

    The engine currently keeps a hash of path => data presumably to allow optimizing for header/footer images on multilpe pages.

    We are using the PHPdf library with the Symfony Bundle. We wrote a console command that runs forever, and generates single-page PDF's in a loop. Each page has a QR code, which get generated on disk in the same loop cycle.

    With the current Engine, we have two options, both problematic:

    • If we use the same filename for the QR code images, only the first image wll ever be loaded from disk
    • If we use different filenames for the QR code images, all images will remain in the Engine memory and never be cleared.

    This patch simply clears the internal Images array on reset().

    opened by ramondelafuente 5
  • Footer content not cleared mulitple documents

    Footer content not cleared mulitple documents

    I'm using a single php process to generate multiple PDF documents with different footer content. It seems that the footer content from the first document is not cleared when the script generates the next document. The content appears behind the footer of the second document and so forth. When I have ten documents, the footer of the 10th document has 10 layers of content in it's footer.

    This proplem only appears on a dynamic-page, with a single page with fixed size the issue doesn't occur.

    opened by vinniecent 5
  • image can't be initialized

    image can't be initialized

    Hello,

    I am experiencing some problems when using the images. In fact, when I try to upload pictures from "https://chart.googleapis.com/chart" I'm always getting an "xxx The image can not be initialized."   This only happens on the server in my localhost it works correctly.

    My document looks like this:

    <img

    src="https://chart.googleapis.com/chart?cht=bvo&chs=500x200&chd=t1:80,85,88,90,95|78,83,86,88,93|82,87,90,92,97&chco=74bb7e|74bb7e|74bb7e|74bb7e|74bb7e,16359a,698cff&chf=bg,s,65432100&chl=80|85|88|90|95&chtt=%&chtt=%25&chts=000000,12,center&chxt=x&chxt=x,y" /> PDF captures localhost and server operation

    localhost: pdf-localhost

    server pdf-server-error

    Help me please.

    opened by edosgn 5
  • Fix non-explicit dependencies

    Fix non-explicit dependencies

    Hello @psliwa

    I'm getting this error today

    Problem 1
        - zendframework/zend-cache 2.3.x-dev requires zendframework/zend-eventmanager == 2.3.9999999.9999999-dev -> no matching package found.
        - zendframework/zend-cache 2.3.x-dev requires zendframework/zend-eventmanager == 2.3.9999999.9999999-dev -> no matching package found.
        - Installation request for zendframework/zend-cache 2.3.x-dev -> satisfiable by zendframework/zend-cache[2.3.x-dev]
    

    Previous composer.json will fail (started from 2014-08-12 11:58 UTC) on anyone project that require this library with minimum stability dev since zendframework/zend-eventmanager doesn't have 2.3-dev branch.

    opened by toopay 4
  • UTF-8

    UTF-8

    Hi,

    When creating bookmarks and setting

    <dynamic-page encoding="UTF-8" font-type="judson">
    

    the bookmarks are incorrectly encoded

    screenshot

    Thanks in advance

    opened by smasala1 4
  • Problem with some characters

    Problem with some characters

    I am unable to render "à" characters. The character is not in the source pdf. If I write directly in the pdf with text editor as vim, it works.

    It's quite strange as "á" works.

    opened by lucasfilippi 4
  • Project maintenance

    Project maintenance

    Hi,

    I'm creating this issue just to inform that - on my repository fork those who are still interested in using this project will soon find an updated version. As this project is used widely in my projects, I needed to pull up some dependencies. Code base requires min PHP8

    If anyone is interested, the early version should show at the beginning of january.

    opened by Armstrong1992 0
  • Avoid E_NOTICE and E_WARNING in PHP 7.1

    Avoid E_NOTICE and E_WARNING in PHP 7.1

    Since PHP 7.1, E_NOTICE and E_WARNING are produced if unexpected characters are found when implicitly converting a string to value. Columns with relative width now produce errors when used in arithmetic operations. A workaround is to explicitly cast string to value before doing arithmetic operations.

    See https://wiki.php.net/rfc/invalid_strings_in_arithmetic

    opened by olivier-idlab 0
  • Support APCu cache implementation.

    Support APCu cache implementation.

    For PHP 5.6+ and 7 that use Opcache and APCu as a replacement for APC

    NOTICE: PHP message: PHP Fatal error:  Uncaught Zend\Cache\Exception\ExtensionNotLoadedException: Missing ext/apc in /var/www/html/vendor/zendframework/zend-cache/src/Storage/Adapter/Apc.php:48
    
    opened by ambroisemaupate 0
Owner
Piotr Śliwa
Piotr Śliwa
Gravity PDF is a GPLv2-licensed WordPress plugin that allows you to automatically generate, email and download PDF documents using Gravity Forms.

Gravity PDF Gravity PDF is a GPLv2-licensed WordPress plugin that allows you to automatically generate, email and download PDF documents using the pop

Gravity PDF 90 Nov 14, 2022
PHP library generating PDF files from UTF-8 encoded HTML

mPDF is a PHP library which generates PDF files from UTF-8 encoded HTML. It is based on FPDF and HTML2FPDF (see CREDITS), with a number of enhancement

null 3.8k Jan 2, 2023
Sign PDF files with valid x509 certificate

Sign PDF files with valid x509 certificate Require this package in your composer.json and update composer. This will download the package and the depe

Lucas Nepomuceno 175 Jan 2, 2023
A Laravel package for creating PDF files using LaTeX

LaraTeX A laravel package to generate PDFs using LaTeX · Report Bug · Request Feature For better visualization you can find a small Demo and the HTML

Ismael Wismann 67 Dec 28, 2022
Simple wrapper package around MPDF's setProtection method that allows you to set password on PDF files

Laravel PDF Protect (fork) Simple wrapper package around MPDF's setProtection method that allows you to set password on PDF files. Installation You ca

Raphael Planer 2 Jan 23, 2022
Offers tools for creating pdf files.

baldeweg/pdf-bundle Offers tools for creating pdf files. Getting Started composer req baldeweg/pdf-bundle Activate the bundle in your config/bundles.p

André Baldeweg 0 Oct 13, 2022
Official clone of PHP library to generate PDF documents and barcodes

TCPDF PHP PDF Library Please consider supporting this project by making a donation via PayPal category Library author Nicola Asuni [email protected] co

Tecnick.com LTD 3.6k Jan 6, 2023
Official clone of PHP library to generate PDF documents and barcodes

TCPDF PHP PDF Library Please consider supporting this project by making a donation via PayPal category Library author Nicola Asuni [email protected] co

Tecnick.com LTD 3.6k Dec 26, 2022
PHP library allowing thumbnail, snapshot or PDF generation from a url or a html page. Wrapper for wkhtmltopdf/wkhtmltoimage

Snappy Snappy is a PHP library allowing thumbnail, snapshot or PDF generation from a url or a html page. It uses the excellent webkit-based wkhtmltopd

KNP Labs 4.1k Dec 30, 2022
TCPDF - PHP PDF Library - https://tcpdf.org

tc-lib-pdf PHP PDF Library UNDER DEVELOPMENT (NOT READY) UPDATE: CURRENTLY ALL THE DEPENDENCY LIBRARIES ARE ALMOST COMPLETE BUT THE CORE LIBRARY STILL

Tecnick.com LTD 1.3k Dec 30, 2022
PdfParser, a standalone PHP library, provides various tools to extract data from a PDF file.

PdfParser Pdf Parser, a standalone PHP library, provides various tools to extract data from a PDF file. Website : https://www.pdfparser.org Test the A

Sebastien MALOT 1.9k Jan 2, 2023
PHP library allowing PDF generation or snapshot from an URL or an HTML page. Wrapper for Kozea/WeasyPrint

PhpWeasyPrint PhpWeasyPrint is a PHP library allowing PDF generation from an URL or an HTML page. It's a wrapper for WeasyPrint, a smart solution help

Pontedilana 23 Oct 28, 2022
PHP library allowing thumbnail, snapshot or PDF generation from a url or a html page.

Snappy Snappy is a PHP library allowing thumbnail, snapshot or PDF generation from a url or a html page. It uses the excellent webkit-based wkhtmltopd

KNP Labs 4.1k Dec 30, 2022
A PHP tool that helps you write eBooks in markdown and convert to PDF.

Artwork by Eric L. Barnes and Caneco from Laravel News ❤️ . This PHP tool helps you write eBooks in markdown. Run ibis build and an eBook will be gene

Mohamed Said 1.6k Jan 2, 2023
FPDI is a collection of PHP classes facilitating developers to read pages from existing PDF documents and use them as templates in FPDF.

FPDI - Free PDF Document Importer ❗ This document refers to FPDI 2. Version 1 is deprecated and development is discontinued. ❗ FPDI is a collection of

Setasign 821 Jan 4, 2023
A PDF conversion and form utility based on pdftk

php-pdftk A PDF conversion and form utility based on pdftk. Features php-pdftk brings the full power of pdftk to PHP - and more. Fill forms, either fr

Michael Härtl 800 Jan 9, 2023
HTML to PDF converter for PHP

Dompdf Dompdf is an HTML to PDF converter At its heart, dompdf is (mostly) a CSS 2.1 compliant HTML layout and rendering engine written in PHP. It is

null 9.3k Jan 1, 2023
Generate simple PDF invoices with PHP

InvoiScript Generate simple PDF invoices with PHP. Installation Run: composer require mzur/invoiscript Usage Example use Mzur\InvoiScript\Invoice; re

Martin Zurowietz 16 Aug 24, 2022
Convert HTML to PDF using Webkit (QtWebKit)

wkhtmltopdf and wkhtmltoimage wkhtmltopdf and wkhtmltoimage are command line tools to render HTML into PDF and various image formats using the QT Webk

wkhtmltopdf 13k Jan 4, 2023