This is a TYPO3 CMS extension that provides various Fluid ViewHelpers to generate PDF documents.
Using the ViewHelpers from this extension you can make any Fluid template into a PDF document.
The extension pdfviewhelpers is using TCPDF and FPDI for the PDF generation.
Key features
ViewHelpers to render text and lists
ViewHelper to render images (supporting FAL and image processing)
ViewHelpers to repeatedly render header and footer
ViewHelper to render HTML / rich-text content
ViewHelper to avoid page breaks inside
ViewHelpers to create a multi column layout
ViewHelpers to create a table of content
Load existing PDF documents as template
Define and apply different text types easily
Fully customizable by writing your own ViewHelpers
Supports batch creation of PDFs
Supported output destinations: string, inline, download and file
Usable both in frontend and backend
Rich inheritance based TypoScript settings
Rich API documentation with lots of examples
Configuration Reference
Technical information: Installation, TypoScript Reference, Caching as well as advanced customization.
Install the extension using the extension manager and include the static TypoScript template of the extension.
TypoScript Reference
Settings inheritance
To avoid redundancy there is an inheritance structure within the settings. There are basically three levels top down:
plugin.tx_pdfviewhelpers.settings.document|page|generalText: The top level are global settings for document, page and generalText (all textual output).
plugin.tx_pdfviewhelpers.settings.headline|text|list: Headline, text and list inherit settings from generalText. All the settings from generalText may be overwritten here with specific settings.
Fluid ViewHelper attributes: The bottom level are Fluid ViewHelper attributes. All TypoScript settings may be overwritten using Fluid ViewHelper attributes with the same name. e.g:
Decides which PHP class should be used as TCPDF object. You can easily provide your own class in order to render custom header and footers or to customize TCPDF in any way.
Your provided class must inherit from Bithost\Pdfviewhelpers\Model\BasePDF.
Decides whether the PHP method exit is called after the PDF content has been sent to the browser.
This might solve issues when additional content is echoed and appended to the PDF document. However it might also lead to other unexpected behaviour so be careful.
Decides whether to subset the used fonts or not. When this is set to true it is not possible to edit the generated PDF
if the font is not present in the users system, but the file size gets smaller.
Path to directory where font files of custom fonts should be stored. This folder can safely be deleted and will automatically be re/created if it does not exist.
The TCPDF output path of the document. If you are saving the file to filesystem this is a relative path from the
webroot directory e.g. fileadmin/pdfviewhelpers/projectXY.pdf.
If you are sending it inline or as file download it is simply the name of the document e.g. projectXY.pdf.
The name of the hyphen file used for the automatic hyphenation. This needs to be set according to the language of your document.
All possible values can be found in the directory pdfviewhelpers/Resources/Private/Hyphenation/.
Example values are: hyph-de-1996.tex, hyph-en-gb.tex, hyph-nl.tex, hyph-fr.tex
Defines the format of the current page. Possible values are e.g. A0 - A12, to see all possible values you have to check \TCPDF_STATIC::$page_formats. You can also provide numeric values as fluid array e.g. {0:210,1:75} to set unusual page sizes.
A boolean value indicating whether to use TCPDF's automatic hyphenation or not. You can also add soft hyphens yourself to your text with "­".
If you use automatic hyphenation please make sure that you configure "config.hyphenFile" to match your language.
The fontStyle this individual bookmark. Also see See generalText.
Header and Footer
It is possible to render header and footer for each page using the header and footer ViewHelpers. You can define
document wide headers and overwrite them on page level if desired. It is possible to use the MultiColumnViewHelper
in the header and footer sections. However it is recommended to use absolute positioning using the posY attribute as
in the Basic Usage example for performance reasons.
Please also see the ViewHelper documentation as well as the example of header and footer usage.
In addition to using these ViewHelpers you may provide your own PDF class and
overwrite the methods Header / Footer or basePdfHeader / basePdfFooter. Overwriting Header / Footer
disables the usage of the header and footer ViewHelpers completely. Overwriting basePdfHeader / basePdfFooter
allows to use the header and footer ViewHelpers while also be able to define custom headers in the PDF class.
Text Types
It is possible to define multiple default text styles and then apply them to a ViewHelper using the type attribute.
This is for instance useful if you have different types of headlines. It is possible to define types for the
TextViewHelper, HeadlineViewHelper and ListViewHelper. In addition you can define types in the generalText section,
these types are available for all ViewHelpers mentioned.
Text types take part in the settings inheritance, with the following priority (higher priority overwrites lower priority):
<pdf:headline type="h1">Rendered as h1</pdf:headline>
<pdf:headline type="h2">Rendered as h2</pdf:headline>
<pdf:headline type="h3">Rendered as h3</pdf:headline>
Copied!
Extend Existing PDFs
It is possible to use existing PDFs as template and extend the PDF where needed. You can either load the template PDF
within the TypoScript settings or within the Fluid template itself.
Adding custom fonts is as easy as providing the path to the TTF file within your TypoScript settings.
The name of the font is automatically generated by TCPDF using the font file name. Only the characters a-z, 0-9 and _ are allowed and words like
bold, oblique, italic or regular are replaced by b, o, i or [empty].
Example: ROBOTObold.ttf becomes robotob
Please note that the TypoScript key you use is not the font name, the font name is generated only based on the font file name!
TypoScript
plugin.tx_pdfviewhelpers.settings.config.fonts {
addTTFFont {
roboto {
path = EXT:pdfviewhelpers/Resources/Public/Examples/FullFeatureShowCase/Roboto.ttf
# Font type. Leave empty for autodetect mode. Valid values are: TrueTypeUnicode, TrueType, Type1, CID0JP = CID-0 Japanese, CID0KR = CID-0 Korean, CID0CS = CID-0 Chinese Simplified, CID0CT = CID-0 Chinese Traditional.# type = TrueTypeUnicode# Name of the encoding table to use. Leave empty for default mode. Omit this parameter for TrueType Unicode and symbolic fonts like Symbol or ZapfDingBats.# enc =# Unsigned 32-bit integer containing flags specifying various characteristics of the font (PDF32000:2008 - 9.8.2 Font Descriptor Flags): +1 for fixed font; +4 for symbol or +32 for non-symbol; +64 for italic. Fixed and Italic mode are generally autodetected so you have to set it to 32 = non-symbolic font (default) or 4 = symbolic font.# flags =
}
opensans {
path = EXT:pdfviewhelpers/Resources/Public/Examples/FullFeatureShowCase/OpenSans.ttf
}
}
}
Copied!
TCPDF fonts
TCPDF comes already with the following fonts installed: courier, helvetica, symbol, times and zapfdingbats
Limitations
TCPDF does not support OpenType fonts with CFF data. If your font can not be added, please try to convert it to TTF, there are a couple of free online converters available.
Advanced Customization
To completely customize the PDF creation you have the options to write your own ViewHelper or provide your own PDF class.
If you feel like your custom ViewHelper might be useful for everybody, feel free to create a pull request!
Create your own ViewHelper
Creating your own ViewHelper might be necessary if you need access to a TCPDF method that is not yet available through the implemented ViewHelpers
or if you have a complex layout to realise.
When writing your own ViewHelper you have the options to extend AbstractContentElementViewHelper or AbstractPDFViewHelper. If your ViewHelper
will add some content to the PDF (e.g. TextViewHelper or LineViewHelper), you should extend AbstractContentElementViewHelper
in order to inherit its position properties and allow the header and footer ViewHelpers to work properly.
If your ViewHelper does not add content (e.g. GetPosXViewHelper or PageBreakViewHelper) you can directly extend AbstractPDFViewHelper.
Within your ViewHelper you have full access to the public API of TCPDF using $this->getPDF(). Please see the TCPDF examples in order to see what
you can do with it: https://tcpdf.org/examples/
The following example shows a ViewHelper that could be used to render a TCPDF barcode.
PHP
<?phpnamespaceVendor\YourExtension\ViewHelpers;
/***
*
* This file is part of the "PDF ViewHelpers" Extension for TYPO3 CMS.
*
* (c) 2016 Markus Mächler <markus.maechler@bithost.ch>, Bithost GmbH
* Esteban Gehring <esteban.gehring@bithost.ch>, Bithost GmbH
*
* All rights reserved
*
* This script is part of the TYPO3 project. The TYPO3 project is
* free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* The GNU General Public License can be found at
* http://www.gnu.org/copyleft/gpl.html.
*
* This script is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* This copyright notice MUST APPEAR in all copies of the script!
***/useBithost\Pdfviewhelpers\ViewHelpers\AbstractContentElementViewHelper;
/**
* BarcodeViewHelper
*
* @author Markus Mächler <markus.maechler@bithost.ch>, Esteban Gehring <esteban.gehring@bithost.ch>
*/classBarcodeViewHelperextendsAbstractContentElementViewHelper{
/**
* @param string $title
* @param string $code
* @param string $type
*
* @return void
*/publicfunctionrender($title, $code, $type){
$style = [
'position' => '',
'align' => 'C',
'stretch' => FALSE,
'fitwidth' => TRUE,
'cellfitalign' => '',
'border' => TRUE,
'hpadding' => 'auto',
'vpadding' => 'auto',
'fgcolor' => [0,0,0],
'bgcolor' => FALSE,
'text' => TRUE,
'font' => 'helvetica',
'fontsize' => 8,
'stretchtext' => 4
];
$this->getPDF()->SetFontSize($this->settings['generalText']['fontSize']);
$this->getPDF()->Cell(0, 0, $title, 0, 1);
$this->getPDF()->write1DBarcode($code, $type, '', '', '', 18, 0.4, $style, 'N');
}
}
You can provide your own PDF class in the TypoScript settings in order to customize its behaviour as you want.
Your own PDF class is required to extend Bithost\Pdfviewhelpers\Model\BasePDF.
TypoScript
plugin.tx_pdfviewhelpers.settings {
config {
class = Vendor\YourExtension\Model\MyPDF
}
}
Copied!
PHP
<?phpnamespaceVendor\YourExtension\Model;
/***
*
* This file is part of the "PDF ViewHelpers" Extension for TYPO3 CMS.
*
* (c) 2016 Markus Mächler <markus.maechler@bithost.ch>, Bithost GmbH
* Esteban Gehring <esteban.gehring@bithost.ch>, Bithost GmbH
*
* All rights reserved
*
* This script is part of the TYPO3 project. The TYPO3 project is
* free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* The GNU General Public License can be found at
* http://www.gnu.org/copyleft/gpl.html.
*
* This script is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* This copyright notice MUST APPEAR in all copies of the script!
***/useTYPO3\CMS\Core\Utility\ExtensionManagementUtility;
/**
* MyPDF
*
* @author Markus Mächler <markus.maechler@bithost.ch>, Esteban Gehring <esteban.gehring@bithost.ch>
*/classMyPDFextends \Bithost\Pdfviewhelpers\Model\BasePDF{
/**
* @return void
*/publicfunction__construct($orientation='P', $unit='mm', $format='A4', $unicode=true, $encoding='UTF-8', $diskcache=false, $pdfa=false){
$myFormat = 'A3';
parent::__construct($orientation, $unit, $myFormat, $unicode, $encoding, $diskcache, $pdfa);
}
/**
* @return void
*/publicfunctionbasePdfHeader(){
$extPath = ExtensionManagementUtility::extPath('pdfviewhelpers');
$address = "Bithost GmbH \nMilchubckstrasse 83 \nCH-8057 Zürich \n\nhallo@bithost.ch \n044 585 28 20 \n\nwww.bithost.ch";
$this->SetTextColor(140, 140, 140);
$this->SetFontSize(11);
$this->Image($extPath . 'Resources/Public/Examples/BasicUsage/logo.png', 15, 15, 56, 24, '', '', '', FALSE, 300, '', FALSE, FALSE, 0, FALSE, FALSE, FALSE, FALSE);
$this->MultiCell(null, null, $address, 0, 'R', FALSE, 1, 0, 45, TRUE, 0, FALSE, TRUE, 0, 'T', FALSE);
}
/**
* @return void
*/publicfunctionbasePdfFooter(){
$this->SetY(-20);
$this->SetDrawColor(140, 140, 140);
$this->Line(15, $this->y, $this->w - 15, $this->y);
$this->SetY(-17);
$this->SetTextColor(140, 140, 140);
$this->SetFontSize(11);
$this->Cell($this->w - 15, 10, 'Page '.$this->getAliasNumPage() . ' of '.$this->getAliasNbPages(), 0, false, 'C', 0, '', 1, false, 'T', 'M');
}
}
Copied!
Caching
The extension pdfviewhelpers does not provide any caching mechanism for the generated PDF documents. In fact caching
is disabled by default because it makes not much sense to save a PDF document to the TYPO3 frontend cache.
Since generating PDF documents is quite time consuming you should implement your own caching strategy by saving
the generated PDF files to the filesystem and only generate them when necessary.
It is not possible to cache the Fluid template parsing when using the MultiColumnViewHelper because it implements the ChildNodeAccessInterface.
This may lead to a significant loss in performance for that view.
EXT:news integration
The extension pdfviewhelpers ships with a PDF template for EXT:news. You can use the default template provided or customize it in any way.
Enable default template
To enable the default template you have to include the static TypoScript template pdfviewhelpers - EXT:news.
All the TypoScript settings that are needed are limited to the special page type 28032013. In order to link to the PDF view
you have to include this page type in the link generation:
<n:link newsItem="{newsItem}" settings="{settings}" title="{newsItem.title}" configuration="{additionalParams: '&type=28032013'}">
Download as PDF
</n:link>
Copied!
Customising the PDF
Most of the typography aspects can be changed solely through TypoScript configuration by changing the existing text types (see also text types).
Please make sure that all your configuration is limited to the page type 28032013.
If you need to change the layout or extend the header and footer content, you can provide your own Fluid template
that is located in EXT:yourext/Resources/Private/Templates/Extensions/News/Templates/News/Detail.html:
These ViewHelpers can be used to set header and footer for pages. Thereby they are always applied to one of the following scopes:
document: The header and footer are applied to all the pages.
thisPage: The header and footer are only applied to the first page they are set on.
thisPageIncludingPageBreaks The header and footer are only applied to the page they are set on including sub pages triggered by an auto page break or the PageBreakViewHelper.
The scope is implicitly set depending on where you place the ViewHelpers. ViewHelpers that are descendants of the DocumentViewHelper have as
default scope document applied. ViewHelpers that are descendants of the PageViewHelper have as default scope thisPageIncludingPageBreaks applied.
It is also possible to set the scope explicitly using the scope ViewHelper attribute.
ViewHelpers that are defined within a PageViewHelper may overwrite ViewHelpers that are defined on document level. Please see the examples section
for an extended example of the header and footer usage.
</pdf:header>
<pdf:footer posY="-15">
<pdf:text>Footer with default scope thisPageIncludingPageBreaks</pdf:text>
</pdf:footer>
<pdf:text>Content goes here</pdf:text>
</pdf:page>
</pdf:document>
AvoidPageBreakInsideViewHelper
This ViewHelper may wrap any composition of other ViewHelpers. It tries its best to avoid a page break within its children elements.
Note that this ViewHelper needs to render its children two times to determine whether a page break is needed or not.
This has a negative impact on the performance as well as might create other undesired side effects.
<pdf:document>
<pdf:page>
<pdf:headline>Welcome to the extension pdfviewhelpers</pdf:headline>
<pdf:text>Lorem ipsum.</pdf:text>
<pdf:avoidPageBreakInside>
<pdf:headline>Some more information</pdf:headline>
<pdf:multiColumn>
<pdf:column>
<pdf:text>Lorem ipsum.</pdf:text>
</pdf:column>
<pdf:column>
<pdf:image src="EXT:pdfviewhelpers/Resources/Public/Examples/BasicUsage/Bithost.jpg"/>
<pdf:text padding="{top: 1}" color="#8C8C8C">Esteban Gehring, Markus Mächler</pdf:text>
</pdf:column>
</pdf:multiColumn>
</pdf:avoidPageBreakInside>
</pdf:page>
</pdf:document>
Copied!
MultiColumnViewHelper / ColumnViewHelper
These ViewHelpers have to be used together in order to generate a multi column layout. By default all columns are of equal width.
It is however possible to specify the width of a column with an absolute or percentage value. In addition it possible to set a padding value for each column.
Important: The parsing of the Fluid template can not be cached when these ViewHelpers are used. This can lead to a significant loss in performance.
Rendering text using the settings for text.
It is possible to easily define different default styles and apply them using the type attribute, see chapter Text Types.
Rendering text using the settings for headlines.
It is possible to easily define different default styles and apply them using the type attribute, see chapter Text Types.
Text rendered with a HeadlineViewHelper can be added to the table of content automatically by setting plugin.tx_pdfviewhelpers.settings.headline.addToTableOfContent = 1.
Rendering a list given as a one dimensional array.
It is possible to easily define different default styles and apply them using the type attribute, see chapter Text Types.
Basic Usage
<pdf:list listElements="{0: 'Full Stack Application Development', 1: 'Modernizing, Refactoring and Migrating Applications', 2: 'Active Collaboration in an existing Team', 3: 'Consulting and Support for IT Projects'}"/>
listElements="{0: 'Full Stack Application Development', 1: 'Modernizing, Refactoring and Migrating Applications', 2: 'Active Collaboration in an existing Team', 3: 'Consulting and Support for IT Projects'}"
/>
HtmlViewHelper
Rendering any html content using TCPDF's method writeHTML. The default text settings are those from generalText.
It is possible to include a css style tag and also inline styles. This ViewHelper is especially useful for rendering Rich Text.
Please note that the use of CSS within a style tag can lead to parsing issues with Fluid, use an external style sheet in that case.
<h1>Some html headline</h1>
<p style="color: #3a718a;">Lorem ipsum</p>
{someAdditionalRichText}
</pdf:html>
ImageViewHelper
This ViewHelper renders an image given as src. As src argument you may provide a valid TYPO3 path or an object implementing TYPO3 FAL FileInterface (e.g. File or FileReference).
The Image ViewHelper supports image processing using the processingInstructions attribute.
The attribute value is directly passed to ImageService->applyProcessingInstructions, thus it supports all configurations supported by this method.
There is no need to set the crop or cropVariant in the processingInstructions in case you use the default crop of a file object.
Adds a line break of given height, this can be used to add margin between elements.
<pdf:lineBreak height="10" />
Copied!
Graphics LineViewHelper
This ViewHelper allows to render a simple line. By default it renders a horizontal line matching the current page width.
It is however also possible to specify start and end point of the line explicitly.
Please see https://tcpdf.org/examples/example_012/ to find out what values can be used on the style attribute.
These ViewHelpers return alias strings to the current page number as well as the total number of pages. Please note
that they do not return an integer value, but a string that is replaced by the correct number at the end of the PDF
generation. This may lead to alignment errors when trying to align text including these ViewHelpers right or centered.
These ViewHelpers provide the possibility to read the current position within the PDF document.
<pdf:text>This text will be rendered at position x={pdf:getPosX()} and y={pdf:getPosY()}</pdf:text>
Copied!
It is possible to use these ViewHelpers to position elements relatively when used together with a math ViewHelper.
The following example requires the extension vhs to be installed.
The TableOfContentViewHelper allows to render a table of content when placed inside a PageViewHelper. The HtmlBookmarkTemplateViewHelper allows to style the content table entries using HTML.
Text rendered with a HeadlineViewHelper can be added to the table of content automatically by setting plugin.tx_pdfviewhelpers.settings.headline.addToTableOfContent = 1.
Additionally it is possible to use the BookmarkViewHelper to add entries to the table of content.
Note that the TableOfContentViewHelper should be placed on the last page of the document, using the page attribute it can be moved to the front.
Please see the examples section for an extended example of the table of content usage.
IMPORTANT NOTICE: Please note that TCPDF does not produce valid PDF documents when bookmarks are used.
Although most PDF viewers are still able to render the document you might run into validity troubles using these ViewHelpers.
Regular Mode
<pdf:page tableOfContentPage="1">
<pdf:tableOfContent />
</pdf:page>
HTML Mode
In HTML mode the variables #TOC_DESCRIPTION# and #TOC_PAGE_NUMBER# get replaced with the bookmark title and the page number respectively.
This ViewHelper allows to set a custom bookmark that will add an entry to the table of content.
Text rendered with a HeadlineViewHelper can be added to the table of content automatically by setting plugin.tx_pdfviewhelpers.settings.headline.addToTableOfContent = 1.
IMPORTANT NOTICE: Please note that TCPDF does not produce valid PDF documents when bookmarks are used.
Although most PDF viewers are still able to render the document you might run into validity troubles using these ViewHelpers.
There are examples being shipped with this extension, you will find the code in Resources/Public/Examples.
Be aware that the static TypoScript template must be included for the examples to work!
pdfpage = PAGE
pdfpage {
10 = FLUIDTEMPLATE
10 {
file = EXT:pdfviewhelpers/Resources/Public/Examples/BasicUsage/Template.html
}
# ensure there is no other output apart from the pdf# take a look at the generated pdf file (end!) in a text editor to verify there is no other output# like warnings, error messages or html code
config {
disableAllHeaderCode = 1
xhtml_cleaning = 0
admPanel = 0
}
}
plugin.tx_pdfviewhelpers.settings {
config {
language = eng
}
document {
title = Bithost document
subject = Autogenerated PDF, By Bithost GmbH
author = Bithost GmbH
keywords = Example, Test, Just to show how it works
creator = TYPO3 EXT:pdfviewhelpers
outputPath = bithost_example.pdf
}
header {
posY = 15
}
footer {
posY = -15
}
text {
paragraphSpacing = 0
}
page {
margin {
top = 65
bottom = 25
}
}
graphics {
line {
padding {
top = 0
bottom = 1.5
}
}
}
}
module.tx_pdfviewhelpers < plugin.tx_pdfviewhelpers
pdfpage = PAGE
pdfpage {
10 = FLUIDTEMPLATE
10 {
file = EXT:pdfviewhelpers/Resources/Public/Examples/HeaderAndFooter/Template.html
}
# ensure there is no other output apart from the pdf# take a look at the generated pdf file (end!) in a text editor to verify there is no other output# like warnings, error messages or html code
config {
disableAllHeaderCode = 1
xhtml_cleaning = 0
admPanel = 0
}
}
plugin.tx_pdfviewhelpers.settings {
page {
autoPageBreak = 1
margin {
top = 25
bottom = 25
}
}
header {
posY = 10
}
footer {
posY = -15
}
}
module.tx_pdfviewhelpers < plugin.tx_pdfviewhelpers
There is the possibility to load existing PDF documents and use them as template. Under the hood pdfviewhelpers
uses FPDI to import PDF documents as template. You must include the static TypoScript template of the extension
in order to make this example work.
TypoScript
pdfpage = PAGE
pdfpage {
10 = FLUIDTEMPLATE
10 {
file = EXT:pdfviewhelpers/Resources/Public/Examples/ExtendExistingPDFs/Template.html
}
# ensure there is no other output apart from the pdf# take a look at the generated pdf file (end!) in a text editor to verify there is no other output# like warnings, error messages or html code
config {
disableAllHeaderCode = 1
xhtml_cleaning = 0
admPanel = 0
}
}
Copied!
Fluid Template
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers"
xmlns:pdf="http://typo3.org/ns/Bithost/Pdfviewhelpers/ViewHelpers"
xsi:schemaLocation="http://typo3.org/ns/Bithost/Pdfviewhelpers/ViewHelpers https://pdfviewhelpers.bithost.ch/schema/3.0.xsd"
data-namespace-typo3-fluid="true">
<pdf:documentsourceFile="EXT:pdfviewhelpers/Resources/Public/Examples/ExtendExistingPDFs/pdf_template.pdf">
<pdf:pageimportPage="1" margin="{top: 80, right: 20, bottom: 40, left: 20}">
<pdf:headline>Hereisyourheader</pdf:headline>
<pdf:text>Loremipsumdolorsitamet, consetetursadipscingelitr, seddiamnonumyeirmodtemporinvidunt.</pdf:text>
<pdf:htmlautoHyphenation="1">
<h1style="font-weight: normal; font-size: 16px;">Here is the HTML header</h1>
<p>Lorem ipsum dolor sit amet, consetetur
sadipscingelitrseddiamnonumyeirmodtemporinviduntutlaboreetdoloremagnaaliquyameratseddiam
voluptua. At vero eos et dolores et ea rebum. Stet
clita kasd gubergren, no sea takimata sanctus est
Lorem ipsum dolor sit amet. Lorem ipsum dolor sit
diam nonumy eirmod tempor invidunt ut labore et
dolore magna aliquyam erat, sed diam voluptua. At
vero eos et accusam et justo duo dolores et ea
rebum. Stet clita kasd gubergren est Lorem ipsum
dolor sit amet.</p>
<p>Lorem ipsum dolor sit amet, consetetur sadipscing
elitr, sed diam nonumy eirmod tempor invidunt ut
labore et dolore magna aliquyam erat, sed diam
voluptua. At vero eos et dolores et ea rebum. Stet
clita kasd gubergren, no sea takimata sanctus est
Lorem ipsum dolor sit amet. Lorem ipsum dolor sit
diam nonumy eirmod tempor invidunt ut labore et
dolore magna aliquyam erat, sed diam voluptua. At
vero eos et accusam et justo duo dolores et ea
rebum. Stet clita kasd gubergren est Lorem ipsum
dolor sit amet.</p>
</pdf:html>
</pdf:page>
</pdf:document>
</html>
Copied!
PDF Output
|
Table Of Content
IMPORTANT NOTICE: Please note that TCPDF does not produce valid PDF documents when bookmarks are used.
Although most PDF viewers are still able to render the document you might run into validity troubles using these ViewHelpers.
TypoScript
pdfpage = PAGE
pdfpage {
10 = FLUIDTEMPLATE
10 {
file = EXT:pdfviewhelpers/Resources/Public/Examples/TableOfContent/Template.html
}
# ensure there is no other output apart from the pdf# take a look at the generated pdf file (end!) in a text editor to verify there is no other output# like warnings, error messages or html code
config {
disableAllHeaderCode = 1
xhtml_cleaning = 0
admPanel = 0
}
}
plugin.tx_pdfviewhelpers.settings {
headline {
addToTableOfContent = 1
}
}
module.tx_pdfviewhelpers < plugin.tx_pdfviewhelpers
This example is showing some of the features of the extension pdfviewhelpers including typography, custom fonts, header and footer, lists, images, html, layout and settings inheritance.
TypoScript
pdfpage = PAGE
pdfpage {
10 = FLUIDTEMPLATE
10 {
file = EXT:pdfviewhelpers/Resources/Public/Examples/FullFeatureShowCase/Template.html
}
# ensure there is no other output apart from the pdf# take a look at the generated pdf file (end!) in a text editor to verify there is no other output# like warnings, error messages or html code
config {
disableAllHeaderCode = 1
xhtml_cleaning = 0
admPanel = 0
}
}
plugin.tx_pdfviewhelpers.settings {
config {
class = Bithost\Pdfviewhelpers\Model\FullFeatureShowCasejpgQuality = 80
fonts{
addTTFFont {
roboto {
path = EXT:pdfviewhelpers/Resources/Public/Examples/FullFeatureShowCase/Roboto.ttf
}
opensans {
path = EXT:pdfviewhelpers/Resources/Public/Examples/FullFeatureShowCase/OpenSans.ttf
}
}
}
}
document {
title = Full Feature Show Case Title
subject = No Subject
keywords = full, feature, show, case
outputDestination = inline
outputPath = fullfeatureshowcase.pdf
}
header {
posY = 10
}
page {
margin {
top = 25
right = 15
bottom = 25
left = 15
}
}
generalText {
color = #555
}
text {
types {
header {
color = #8C8C8C
}
quote {
fontStyle = italic
alignment = center
padding {
top = 10
right = 50
bottom = 10
left = 50
}
}
}
}
headline {
fontFamily = courier
fontStyle = bold
types {
h1 {
fontSize = 28
color = #ff642c
}
h2 {
fontSize = 22
color = #ff642c
}
h3 {
fontSize = 14
fontFamily = helvetica
fontStyle = bold
}
}
}
list {
color = #000
fontStyle = bold
bulletColor = #BEDB39
padding {
left = 2
}
}
}
module.tx_pdfviewhelpers < plugin.tx_pdfviewhelpers
Copied!
PHP
<?phpnamespaceBithost\Pdfviewhelpers\Model;
/***
*
* This file is part of the "PDF ViewHelpers" Extension for TYPO3 CMS.
*
* (c) 2016 Markus Mächler <markus.maechler@bithost.ch>, Bithost GmbH
* Esteban Gehring <esteban.gehring@bithost.ch>, Bithost GmbH
*
* All rights reserved
*
* This script is part of the TYPO3 project. The TYPO3 project is
* free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* The GNU General Public License can be found at
* http://www.gnu.org/copyleft/gpl.html.
*
* This script is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* This copyright notice MUST APPEAR in all copies of the script!
***//**
* FullFeatureShowCase
*
* @author Markus Mächler <markus.maechler@bithost.ch>, Esteban Gehring <esteban.gehring@bithost.ch>
*/classFullFeatureShowCaseextendsBasePDF{
/**
* @return void
*/publicfunctionbasePdfHeader(){
}
/**
* @return void
*/publicfunctionbasePdfFooter(){
$this->SetY(-20);
$this->SetDrawColor(140, 140, 140);
$this->Line(15, $this->y, $this->w - 15, $this->y);
$this->SetY(-17);
$this->SetTextColor(140, 140, 140);
$this->SetFontSize(11);
$this->Cell($this->w - 15, 10, 'Page ' . $this->getAliasNumPage() . ' of ' . $this->getAliasNbPages(), 0, false, 'C', 0, '', 1, false, 'T', 'M');
}
}
Copied!
Fluid Template
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers"
xmlns:pdf="http://typo3.org/ns/Bithost/Pdfviewhelpers/ViewHelpers"
xsi:schemaLocation="http://typo3.org/ns/Bithost/Pdfviewhelpers/ViewHelpers https://pdfviewhelpers.bithost.ch/schema/3.0.xsd"
data-namespace-typo3-fluid="true">
<pdf:documentoutputPath="overwritten_name.pdf" title="FullFeatureShowCase">
<pdf:header>
<pdf:texttype="header">BithostGmbH - Milchbuckstrasse 83 CH-8057 Zürich</pdf:text>
<pdf:texttype="header" posY="10" alignment="right">hallo@bithost.ch - www.bithost.ch</pdf:text>
<pdf:graphics.linestyle="{color: '#8C8C8C'}"/>
</pdf:header>
<pdf:page>
<pdf:headlinefontSize="20">FullFeatureShowCase</pdf:headline>
<pdf:text>Showingsomefeaturesofpdfviewhelpers.</pdf:text>
<pdf:headline>Typography</pdf:headline>
<pdf:textfontStyle="bold">Boldtext</pdf:text>
<pdf:textfontStyle="italic">Italictext</pdf:text>
<pdf:textfontStyle="underline">Underlinedtext</pdf:text>
<pdf:textcolor="#ff642c">Coloredtext</pdf:text>
<pdf:textalignment="left">AlignmentLeft</pdf:text>
<pdf:textalignment="center">AlignmentCenter</pdf:text>
<pdf:textalignment="right">AlignmentRight</pdf:text>
<pdf:textcolor="#ff642c" padding="{top:6, right:80, bottom:6, left:20}">
Textwithspecialpadding. Loremipsumdolorsitamet, consetetursadipscingelitr, seddiamnonumyeirmodtemporinviduntutlaboreetdoloremagnaaliquyamerat, seddiamvoluptua. Atveroeosetdoloresetearebum.
</pdf:text>
<pdf:multiColumn>
<pdf:column>
<pdf:text>
Textwithnormalparagraphspacing.
Shownhere.
</pdf:text>
</pdf:column>
<pdf:column>
<pdf:textparagraphSpacing="2">
Textwithextendedparagraphspacing.
Shownhere.
</pdf:text>
</pdf:column>
<pdf:column>
<pdf:textparagraphSpacing="4">
Textwithevenmoreextendedparagraphspacing.
Shownhere.
</pdf:text>
</pdf:column>
</pdf:multiColumn>
<pdf:multiColumn>
<pdf:column>
<pdf:textautoHyphenation="0" padding="{right: 2}">
ThisisalongtextWITHOUTautomatichyphenationbeingactivated.
</pdf:text>
</pdf:column>
<pdf:column>
<pdf:textautoHyphenation="1" padding="{left: 2}">
ThisisalongtextWITHautomatichyphenationbeingactivated.
</pdf:text>
</pdf:column>
</pdf:multiColumn>
<pdf:textlineHeight="2" characterSpacing="1.5">
ThistexthasincreasedlineHeightaswellasincreasedcharacterSpacing.
</pdf:text>
<pdf:headline>Customfonts</pdf:headline>
<pdf:textfontFamily="opensans">CustomfontOpenSansautomaticallyconvertedfromTTFfile.</pdf:text>
<pdf:textfontFamily="roboto">CustomfontRobotoautomaticallyconvertedfromTTFfile.</pdf:text>
<pdf:textfontFamily="roboto" color="#ff642c">CustomfontRobotoevencolored!</pdf:text>
<pdf:pageBreak />
<pdf:headline>Styledlists</pdf:headline>
<pdf:listpadding="{left: 1.75}"
bulletSize="2.5"
bulletImageSrc="EXT:pdfviewhelpers/Resources/Public/Examples/FullFeatureShowCase/bullet_image.png"
listElements="{0: 'FullStackApplicationDevelopment', 1: 'Modernizing, RefactoringandMigratingApplications', 2: 'ActiveCollaborationinanexistingTeam', 3: 'ConsultingandSupportforITProjects'}" />
<pdf:listbulletSize="2"
bulletColor="#ff642c"
fontStyle="italic"
listElements="{0: 'Loremipsum', 1: 'dolorsit', 2: 'Loremdipsum', 3: 'dolorsitamet'}" />
<pdf:headline>Texttypes</pdf:headline>
<pdf:text>Itispossibletocreateanarbitraryamountofdefaulttextsettingsandeasilyapplythemusingthetypeattribute.</pdf:text>
<pdf:headlinetype="h1">Thisisah1headline</pdf:headline>
<pdf:headlinetype="h2">Thisisah2headline</pdf:headline>
<pdf:headlinetype="h3">Thisisah3headline</pdf:headline>
<pdf:texttype="quote">Thiscouldbeaquotestyle. Loremipsumdolorsitamet, consetetursadipscingelitr, seddiamnonumyeirmodtemporinviduntutlaboreetdoloremagnaaliquyamerat, seddiamvoluptua.</pdf:text>
</pdf:page>
<pdf:pageorientation="landscape" format="A4" margin="{top: 15}">
<pdf:headerscope="thisPage">
<pdf:texttype="header">Onlythispagewillhaveadifferentheader</pdf:text>
</pdf:header>
<pdf:multiColumn>
<pdf:columnwidth="50%">
<pdf:headline>Imagesindifferentsizes</pdf:headline>
<pdf:imagesrc="EXT:pdfviewhelpers/Resources/Public/Examples/FullFeatureShowCase/Bithost.jpg" width="100" link="https://www.bithost.ch" />
<pdf:imagesrc="EXT:pdfviewhelpers/Resources/Public/Examples/FullFeatureShowCase/Bithost.jpg" width="70" link="https://www.bithost.ch" />
<pdf:imagesrc="EXT:pdfviewhelpers/Resources/Public/Examples/FullFeatureShowCase/Bithost.jpg" width="50" link="https://www.bithost.ch" />
</pdf:column>
<pdf:columnwidth="50%">
<pdf:headline>Imageswithdifferentalignment</pdf:headline>
<pdf:imagesrc="EXT:pdfviewhelpers/Resources/Public/Examples/FullFeatureShowCase/Bithost.jpg" width="50%" alignment="left" />
<pdf:imagesrc="EXT:pdfviewhelpers/Resources/Public/Examples/FullFeatureShowCase/Bithost.jpg" width="50%" alignment="center" />
<pdf:imagesrc="EXT:pdfviewhelpers/Resources/Public/Examples/FullFeatureShowCase/Bithost.jpg" width="50%" alignment="right" />
</pdf:column>
</pdf:multiColumn>
</pdf:page>
<pdf:page>
<pdf:headline>HTMLcontentbeingstyledexternally</pdf:headline>
<pdf:htmlstyleSheet="EXT:pdfviewhelpers/Resources/Public/Examples/FullFeatureShowCase/styles.css">
<h1>Headline 1</h1>
<h2>Headline 2</h2>
<h3>Headline 3</h3>
<ahref="https://www.bithost.ch">ALinktoclick</a>
<p>Loremipsumdolorsitamet, consetetursadipscingelitr, seddiamnonumyeirmodtemporinviduntutlaboreetdoloremagnaaliquyamerat, seddiamvoluptua.</p>
<p>Loremipsumdolorsitamet, consetetursadipscingelitr, seddiamnonumyeirmodtemporinviduntutlaboreetdoloremagnaaliquyamerat, seddiamvoluptua.</p>
<h3style="color: #333;">Table</h3>
<table cellpadding="4" cellspacing="4">
<thead>
<tr>
<th>Head 1</th>
<th>Head 2</th>
<th>Head 3</th>
</tr>
</thead>
<tbody>
<tr>
<td>Content 1</td>
<td>Content 2</td>
<td>Content 3</td>
</tr>
<tr>
<td>More Content 1</td>
<td>More Content 2</td>
<td>More Content 3</td>
</tr>
<tr>
<td>Content 1</td>
<td>Content 2</td>
<td>Content 3</td>
</tr>
</tbody>
</table>
</pdf:html>
<pdf:headline>Position ViewHelpers</pdf:headline>
<pdf:text>This text will be rendered at position x={pdf:getPosX()} and y={pdf:getPosY()}</pdf:text>
<pdf:headline>PageNumber ViewHelpers</pdf:headline>
<pdf:text>We are on page {pdf:getPageNumberAlias()} of {pdf:getTotalNumberOfPagesAlias()} pages.</pdf:text>
<pdf:avoidPageBreakInside>
<pdf:headline>Avoid page break inside</pdf:headline>
<pdf:text>EXT:pdfviewhelpers tries to avoid page breaks inside ViewHelpers that are wrapped with an AvoidPageBreakInsideViewHelper.</pdf:text>
<pdf:text>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</pdf:text>
<pdf:text>That is why all these elements are rendered on the next page.</pdf:text>
</pdf:avoidPageBreakInside>
</pdf:page>
</pdf:document>
</html>
Copied!
PDF Output
|
|
|
|
|
PDF/A Show Case
Intro
Its's possible to render the output as a valid PDF/A document.
TypoScript
Be sure to disable all header data, to ensure that all HTML header output is disabled. Some variables on page properties are used to fill the meta data.
The most important setting is plugin.tx_pdfviewhelpers.settings.document.pdfa = 1 to enable PDF/A mode.
pdfpage = PAGE
pdfpage {
config {
disableAllHeaderCode = 1
xhtml_cleaning = 0
admPanel = 0
}
10 = FLUIDTEMPLATE
10 {
file = EXT:pdfviewhelpers/Resources/Public/Examples/PdfaShowCase/Template.html
variables {
fileTitle = TEXT
fileTitle {
field = title
wrap = |.pdf
}
docTitle = TEXT
docTitle {
field = title
wrap = |
}
docAuthor = TEXT
docAuthor {
field = author
wrap = |
}
docDate = TEXT
docDate {
field = starttime
date = d.m.Y
wrap = |
}
docAbstract = TEXT
docAbstract {
field = abstract
wrap = |
}
docKeywords = TEXT
docKeywords {
field = keywords
wrap = |
}
}
}
}
plugin.tx_pdfviewhelpers.settings {
config {
class = Bithost\Pdfviewhelpers\Model\PdfaShowCasejpgQuality = 80
fonts{
addTTFFont {
roboto {
path = EXT:pdfviewhelpers/Resources/Public/Examples/FullFeatureShowCase/Roboto.ttf
}
opensans {
path = EXT:pdfviewhelpers/Resources/Public/Examples/FullFeatureShowCase/OpenSans.ttf
}
}
}
}
document {
title = PDFa Show Case Title
subject = No Subject
keywords = full, feature, show, case
outputDestination = I
outputPath = pdfa.pdf
pdfa = 1
}
page {
margin {
top = 20
right = 15
bottom = 20
left = 15
}
}
generalText {
color = #555
}
headline {
fontFamily = courier
fontStyle = B
}
list {
color = #555
fontStyle = I
bulletColor = #555
}
}
module.tx_pdfviewhelpers < plugin.tx_pdfviewhelpers
It is possible to render a PDF document as standalone view. That is especially useful if you want to attach the document to an email or you want to generate multiple PDFs in one request.
PHP
<?php
$standaloneView = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Fluid\View\StandaloneView::class);
$templatePath = \TYPO3\CMS\Core\Utility\GeneralUtility::getFileAbsFileName('EXT:pdfviewhelpers/Resources/Public/Examples/BasicUsage/Template.html');
$standaloneView->setFormat('html');
$standaloneView->setTemplatePathAndFilename($templatePath);
$standaloneView->assignMultiple(['someVariable' => 'someValue']);
$pdf = $standaloneView->render(); //return pdf as string, or simply save to file system
Please look carefully at the examples being shipped with this extension, you will find the code in Resources/Public/Examples.
Be aware that the static TypoScript template must be included for the examples to work!
Typical Problems
Headers already sent
Sometimes the following error message is found in the php log or in the output:
Warning:
PHP Warning: Cannot modify header information - headers already sent by...
Copied!
This usually occurs when there has already been sent content to the output buffer before the pdf fluid template is rendered.
Since we need to set some headers in order to allow the browser to interpret the content as pdf file for inline display / download,
pdfviewhelpers need to be able to set headers, and this can only be done if there was no output at all on that page before the pdf is rendered.
PDF does not validate
Sometimes, the generated pdf does not correctly validate e.g. in https://www.pdf-online.com/osa/validate.aspx
If this is the case, check the generated file in a text editor, especially the end of the file.
Ensure there is no content after the %%EOF.
If you want to have a valid PDF/A document, validate the xml in the metadata in the
Also ensure you have disabled all html header output:
pdfpage = PAGE
pdfpage {
10 = FLUIDTEMPLATE
10 {
file = EXT:pdfviewhelpers/Resources/Public/Examples/BasicUsage/Template.html
}
# ensure there is no other output apart from the pdf# take a look at the generated pdf file (end!) in a text editor to verify there is no other output# like warnings, error messages or html code
config {
disableAllHeaderCode = 1
xhtml_cleaning = 0
admPanel = 0
}
}
Copied!
pdfviewhelpers can not be installed via TER
The extension pdfviewhelpers is quite big compared to other extensions, as it ships with the entire TCPDF in order to be easily installable via TER.
The size EXT:pdfviewhelpers might be an issue if your memory_limit or max_execution_time is quite low, try increasing these values.
The following chapter provides guides to upgrade from one major version to the next major version. This includes only
breaking changes, for a complete changelog please see https://github.com/bithost-gmbh/pdfviewhelpers/blob/master/CHANGELOG.md .
If there is something missing in one of these guides please tell us via mail, a GitHub issue or even better a pull request!
The classes EmptyFPDI and EmptyTCPDF have been replaced by BasePDF. If you have any TypoScript configuration or PHP Code using these
classes you should replace them by Bithost\Pdfviewhelpers\Model\BasePDF. The class BasePDF offers the same functionality as the other classes before
while adding the possibility to use header and footer ViewHelpers.
Provided class must inherit from BasePDF
The PDF class you can provide in plugin.tx_pdfviewhelpers.settings.config.class is now required to inherit from Bithost\Pdfviewhelpers\Model\BasePDF.
Removed example class BithostTCPDF
The example class BithostTCPDF has been removed without a replacement.
Please extend BasePDF, and see the basic usage example on how to render a similar header.
Introduces ValidationService
All utility methods that start with isValid have been moved to a separate class ValidationService.
If you implemented custom ViewHelpers you have to change these method calls.
Renamed page.margins to page.margin
The TypoScript setting plugin.tx_pdfviewhelpers.settings.page.margins has been renamed to plugin.tx_pdfviewhelpers.settings.page.margin.
Also the Fluid PageViewHelper attribute has been renamed from page.margins to page.margin.
Changed default value of page.autoPageBreak
The option plugin.tx_pdfviewhelpers.settings.page.autoPageBreak is now enabled by default.
Moved settings from config to document
The settings plugin.tx_pdfviewhelpers.settings.config.language and plugin.tx_pdfviewhelpers.settings.config.hyphenFile have been moved to plugin.tx_pdfviewhelpers.settings.document.language
and plugin.tx_pdfviewhelpers.settings.document.hyphenFile. That allows to set this values in the Fluid template and thus allows to create documents of different languages in a batch process.
Upgrading from 2.x.x to 3.x.x
Removed TCPDF and FPDI libraries from source code
The libraries TCPDF and FPDI have been removed from Resources\Private\PHP for composer installations.
In case you are referencing paths in that folder, you might have to change them to the vendor folder.
Removed classes EmptyFPDI and EmptyTCPDF
The deprecated classes PDF Bithost\Pdfviewhelpers\Model\EmptyFPDI and Bithost\Pdfviewhelpers\Model\EmptyTCPDF have been removed.
Please use Bithost\Pdfviewhelpers\Model\BasePDF as an alternative.
Type hints and strict typing
The PHP files now use strict types and have been extended with type hinting.
This might require changes to classes that inherit or use classes from this extension.
pdfviewhelpers - EXT:news
The TypoScript template pdfviewhelpers - EXT:news does no longer copy the plugin settings to module.tx_pdfviewhelpers
and the page config has been moved from config to pageNewsPDF.config.
TypoScript file extensions
All TypoScript file extensions have been changed from .txt to .typoscript.
ImageViewHelper processingInstructions merging
The processingInstructions from TypoScript settings and the Fluid template are now merged instead of overwritten.
This might lead to TypoScript settings being applied unexpectedly depending on your usage.
Donate
With the extension pdfviewhelpers we try to take the pain out of creating PDF documents.
We aim at providing the best service possible by constantly improving the extension and responding fast to bug reports.
We do this fully free of cost, mostly because we love to code and share. However we are still human and have human needs like food, shelter and beer.
So if you feel like this extension was useful to you and saved you and your business some precious time, please consider making a donation to support its maintenance and further development.