Generátor PDF

Pavel CSS, PHP

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. Proto dnešní návod bude právě o této knihovně.

mPDF is a PHP class which generates PDF files from UTF-8 encoded HTML. It is based on FPDF and HTML2FPDF, with a number of enhancements.

Tvoříme s mPDF

Stáhněte si knihovnu z webu mPDF , uložte ji ke svému projektu a můžeme začít. Základní knihovna má velikost v rozbaleném stavu asi 32MB, z toho ale 4MB jsou příklady a 19MB TTF soubory s fonty.

Optimalizace knihovny

Využití CPU a RAM může být touto knihovnou docela vysoké. Můžeme proto provést optimalizaci spuštěním skriptu compress.php, který je umístěn v hlavní složce knihovny. Zde si vybereme, které funkce budeme a nebudeme využívat.

Tento skript přepíše původní soubor mpdf.php (doporučuji zálohovat). 

Instalace vlastních fontů

Někdy nechceme využívat jen klasických fontů, proto můžeme dodat vlastní. Doporučuji nepoužívat fonty se subsettingem (omezený počet znaků). Zkopírujeme originální TTF soubory do složky mPDF/ttfonts a do souboru config_fonts.php ve složce mPDF upravíme následující kód.

$this->fontdata = array(
    
  "opensans" => array(
      'R' => "OpenSans-Regular.ttf", // řez regular
      'B' => "OpenSans-Bold.ttf", // řez bold
      // další řezy jako I, BI...
    ),
    //zde nechme původní písma
...

Více v dokumentaci k fontům

Práva k zápisu do složek

Knihovna využívá 2 složky k zápisu dočasných souborů. Proto musíme přes chmod pro dané složky povolit zápis. Jde o složky tmp a ttfontdata. Složky lze přemístit v konfiguraci.

Tvorba z HTML a CSS

Nyní přejdeme k samotné tvorbě poukazu. V mém příkladu používám CSS přímo vložené do tagu head, knihovna ale podporuje i odkazy na externí styly.

<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="http://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(
  '', //vytváříme prázdný dokument
  'A4', //velikosti A4
  72, // základní velikost písma
  'OpenSans', //defaultní typ písma
  0,0,0,0,0,0); //margin left,right,top,bottom,header, footer
$mpdf->img_dpi = 300; //obrázky ukládáme s DPI 300
$mpdf->dpi = 96; //dpi dokumentu je 96
$mpdf->WriteHTML("<html>..."); //vložíme HTML k převedení
$mpdf->Output("mujPDFdokument.pdf"); //uložíme

Nyní se nám uloží náš PDF dokument a máme vyhráno. Výše zmíněný kód používám na webu SkiBílá k tvorbě poukazů.

Vzorové si můžete prohlédnout zde: Bílá vzor1, Bílá vzor2, Bílá vzor3, a nově letos i pro SUN Outdoor: SUN vzor1, SUN vzor2

Co ještě mPDF umí a neumí

Začneme tou světlejší stránkou, co umí

  • Kreslit čárové kódy (osobně si je kreslím sám)
  • Využívat CSS přechody a kulaté rohy
  • Záložky, vodoznaky, zaheslovat dokument
  • .. a mnoho dalšího

Chyby, na které jsem narazil

  • Nefungují CSS selektory .trida1.trida2 a .trida1 .trida2
  • Obrázek v pozadí se špatně zobrazí v nativním prohlížeči ve Firefoxu (asi není chyba mPDF)
  • Seznam ostatních chyb naleznete v dokumentaci

Již je ke stáhnutí verze 6.0 ale stable je označena pouze verze 5.7.x. Proto i tento návod nepopisuje novinky ve verzi 6.0

Přidat komentář

Právě odpovídáte na existující komentář. Zrušit

Komentáře

xergic

http://www.kandera.net 6.1.2015 20:56

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

Odpovědět

vv

6.1.2015 21:00

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

Pavel

http://www.kutac.cz/blog/ 6.1.2015 21:59

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 ;)

Jiří

26.9.2016 04:13

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

Odpovědět

Pavel

http://www.kutac.cz/blog/ 7.10.2016 18:52

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 http://www.kutac.cz/...sti-a-balicku-v-php/ a pak žádný include psát nebude ;)

Novinky z blogu

Async / await

Asynchronní programování v Javascriptu bez callbacků a Promise nemusí být nutně sci-fi. Co všechno umí klíčová slova async /...

Další články