Generátor PDF

(publikováno 06.01.2015) 9 PHP, HTML, CSS

mPDF je generátor napsaný v PHP pro tvorbu PDF dokumentů z HTML a CSS. Proto je tvorba velmi jednoduchá a rychlá. Ukážeme si jednoduché použití, které jsem využil pro tvorbu poukazů.

Generátor PDF

Formát PDF je snad dostatečně známý všem. Je to zkratka Portable document format, vyvinuto společností Adobe. Cílem bylo, aby se na všech zařízeních a platformách zobrazil stejně.

mPDF, tcPDF, fPDF...

Knihoven pro tvorbu PDF dokumentů v PHP je mnoho. Osobně jsem zadal do Google dotaz best PHP PDF generator a hned první odkaz vedl na StackOverflow. Tehdy jsem se rozhodl pro mPDF také pro plnou podporu UTF8 a zůstal u něj. Existují i integrace do Laravelu, použito také při psaní pluginů do WordPressu a dalších.

Článek je kompletně přepsán k 29.9.2019, protože v knihovně byly provedeny velké změny. Migrace u základních řešení je ale velmi jednoduchá.

Jak na to s mPDF

Původní článek popisoval použití knihovny ve verzi 4 a 5. Knihovnu lze od verze 6.1 oficiálně instalovat pomocí composeru. Dále od verze 7 již není možné optimalizovat spouštěcí skript, protože knihovna používá autoload a byla přepracována do namespaců.

composer require mpdf/mpdf

Knihovna je v době psaní článku ve verzi 8 a využívá sémantické verzování. Takže i drobné změny zvyšují majoritní verzi. Základní užití je tak mezi verzí 7 a 8 naprosto totožné.

Tvorba z HTML a CSS

Jak je zmíněno na začátku, vstupem do mPDF je HTML a CSS na základě kterého je vygenerováno výsledné PDF. V příkladu níže je CSS vloženo přímo do do <head>, ale je možné vložit i odkaz na externí CSS soubor.

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<style type="text/css">
  *{ margin:auto;    padding:0px;  }
  body{color:#303030;font-family:OpenSans;  }
  .bg{position:absolute;    width:800px;  height:377;  }
  .head{font-size:27pt;  padding-top:110px;  padding-left:50px;  position:absolute;  }
  .dedicatione{color:#2e6593;  font-size:13pt;  padding-top:175px;  padding-left:50px;  position:absolute;  width:300px;  }
  .strong{font-weight:bold;  }
  .wrap{position:absolute;  margin-top:270px;  }
  .notes{font-size:8pt;  float:left;  text-align:left;  padding-top:20px;  padding-left:50px;  width:470px;  }
  .barcode{float:right;  width:220px;  height:110px;  margin-right:15px;  }
  .ticket{position:absolute;  margin-top:140px;  padding-left:430px;  font-size:14pt;  width:350px;  }
  .name{color:#2e6593;  font-size:26pt;  }
</style>
</head>
<body>
<div class="bg">
    <img src="https://www.kutac.cz/styles/global/images/poukazNoCompress.jpg" width="800" height="377">
</div>
<div class="wrap">
    <div class="notes">Poukaz lze uplatnit na pokladně č. 1 a 2. Vratná záloha na kartu je 100,- Kč.<br>
        Poukaz lze čerpat pouze do konce zimní sezóny 2014/2015.<br />
        Poukaz lze uplatnit pouze 1x.
    </div>
    <div class="barcode">
        <img src="data:image/png;base64," height="110" width="220">
    </div>
</div>
<div class="ticket">Na permanentku<br>
    <span class="name strong"></span><br>
    v sezóně 2014/2015
</div>
<div class="head strong">Poukaz</div>
<div class="dedicatione strong"></div>
</body>
</html>

A PHP kód

$mpdf = new \Mpdf\Mpdf([
    'mode'              => 'utf-8',
    'format'            => 'A4',
    'margin_left'       => 25,
    'margin_right'      => 25,
    'margin_top'        => 25,
    'margin_bottom'     => 17,
    'margin_header'     => 9,
    'margin_footer'     => 9,
    'tempDir'           => 'framework/cache/pdf', // Určete si vlastní cestu do temp složky
    'dpi'               => 96,
    'img_dpi'           => 96,
    'orientation'       => 'P',
]);

$this->mpdf->SetAuthor('Kutáč.cz'); $this->mpdf->SetCreator('Kutáč.cz'); $this->mpdf->SetDisplayMode('fullpage'); $mpdf->WriteHTML("<html>..."); $mpdf->Output("mujPDFdokument.pdf");

Nastavení je samozřejmě mnoho a dokumentace je popsána velmi kvalitně. Výsledkem je vytvořený PDF soubor. Šablona výše byla použita pro generování vánočních poukazů na webu SkiBílá a vzorový výsledek si lze prohlédnout jak jinak než v PDF formátu. V jiných systémech ale používám také pro generování různých potvrzení a smluv.

Vlastní fonty

Zajímavé a někdy nutné může být přidávání do generovaných PDF souborů vlastní písma. Již není nutné upravovat zdrojové soubory jako v případě verze <7. Vše jde nastavit přes konstruktor. Je ale potřeba prvně získat výchozí hodnoty a ty poté doplnit, jinak dojde k jejich přepsání.

$mpdfConfig = [...]; // Konfigurace jako v příkladu výše

// Je potřeba získat původní konfiguraci a tu rozšířit
$fontDirs = (new \Mpdf\Config\ConfigVariables())->getDefaults()['fontDir'];
$mpdfConfig['fontDir'] = array_merge($fontDirs, ['/absolute/path/to/my/font/folder']);

$fontData = (new \Mpdf\Config\FontVariables())->getDefaults()['fontdata'];
$mpdfConfig['fontdata'] = array_merge($fontData, [
    'opensans' => [
        'R' => 'OpenSans-Normal.ttf',
        'B' => 'OpenSans-Bold.ttf',
    ]
]);

$mpdf = new \Mpdf\Mpdf($mpdfConfig);

Co ještě mPDF umí


Osobní zkušenosti s mPDF či jinou knihovnou můžete sdílet v komentářích

K tomuto článku již není možné přidávat další komentáře

Komentáře

Normálně nepíšu komentáře, když k tomu nemám co říct, ale musím... Ten obrázek se slonem mě fakt pobavil :D

No schválně, Pavle, jak dlouho si ho dělal? :D

Pobavil? Já alespoň vím, že to někdo čte.. :D
No a dnes výjimečně jsem ho dělal asi 15 minut. Nic extra. A rovnou ho použiji i pro další článek ;)

tak ten obrázek se slonem je stažený z phpclasses.org, ale whatever

Myslíš ten obrázek, který je neoficiální logo PHP pod názvem Elephpant? https://bit.ly/2ZeN0tj Jo ten jsem fakt stáhl, ale ani ne z phpclasses.org ale prostě odněkud...

Ahoj, jako amatér doplním, že je ještě potřeba přidat před "$mpdf = new mPDF(" řádek s require mpdf.php

Ahoj,

tento řádek jsem záměrně vynechal, zaprvé je to logické, a za druhé někdo může využívat vlastní autoloader nebo třeba Composer viz můj další článek https://www.kutac.cz/blog/.../composer-reseni-zavislosti-a-balicku-v-php/ a pak žádný include psát nebude ;)

musi to byť len html a css? lebo potreboval by som použiť data z formularu. čiže cez get alebo post natiahnem do premenných data a potom ich script spravi na pdf. bude to ok?

Předem si celé HTML připravíš včetně výpisů proměnných a to pak necháš převést do PDF. PDFko ti určitě nebude vykonávat PHP skripty.

Nejlepší k tomuto úkolu bude použití Output buffering http://php.net/manual/en/book.outcontrol.php