Vánoční nadílka Vánoční nadílka
Vánoční akce! Daruj lepší budoucnost blízkým nebo sobě. Až +50 % zdarma na dárkové poukazy. Více informací

PHP a tvorba PDF dokumentů za pomocí mPDF

PHP Práce se soubory PHP a tvorba PDF dokumentů za pomocí mPDF

ONEbit hosting Unicorn College Tento obsah je dostupný zdarma v rámci projektu IT lidem. Vydávání, hosting a aktualizace umožňují jeho sponzoři.

V tomto tutoriálu popíši jak pomocí PHP a knihovny mPDF vytvářet PDF dokumenty. Velice laicky řečeno vám umožní vzít HTML kód a a vytvořit z něj PDF soubor. Ze zkušeností vím, že ne vše to funguje. Někdy byl problém s HTML nebo CSS, můžete se podívat na tabulku podporovaných tagů. Nicméně se jedná o užitečnou třídu. Můžete s její pomocí snadno vytvářet faktury ve svém e-shopu a další věci, na které se tento formát hodí. (Denní menu v restauraci, ceník služeb atd).

Jednoduchá ukázka

Nyní přistoupíme k samotnému tvoření. Jak je zvykem u nových věcí, začneme i tady s "Hello itnetwork.cz"

  1. Stáhněte si mpdf z webu: http://www.mpdf1.com/mpdf/download. Já jsem stáhl nejnovější Full-instalation v 5.7.
  2. Vytvořte si adresář v rootu vašeho webu. Například: pdf_export a rozbalte do něj složku z archivu.

Nyní už k první ukázce:

<?php
/*Načtení třídy mpdf, pozor na číslo za MPDF - v mém případě 57, ale může se lišit*/
include('MPDF57/mpdf.php');

/*vytvoření objektu*/
$mpdf=new mPDF();

/*Přidání HTML*/
$mpdf->WriteHTML('<p>Hello itnetwork</p>');

/*Výstup*/
$mpdf->Output();
exit;
?>

Výstupem bude zaslání PDF dokumentu prohlížeči. Pokud prohlížeč podporuje zobrazení PDF, tak soubor otevře. Jinak se bude soubor stahovat na disk. Výstup zajišťuje metoda Output(), která po předání určitých parametrů může výstup provádět jinak ale o tom později.

Stylování

Vrátíme se k první ukázce a zkusíme si přidat CSS. CSS musí být vloženo mezi tagy

<style></style>

Externí css soubor nepůjde načíst!

A klidně takto to může vypadat s CSS

<?php
/*Načtení třídy mpdf pozor na číslo za MPDF v mém případě 57 ale může se lišit*/
include('MPDF57/mpdf.php');

/*vytvoření objektu*/
$mpdf=new mPDF();
$css=
"<style>
        .cssTridaProPDF{
                margin-bottom:20px;
                font-weight:bold;
                font-size:34px;
                font-family:sans-serif;
                border-bottom:3px solid #333;
                color:teal;
        }
</style>
";

/*Přidání HTML s se styly v proměné $css*/
$mpdf->WriteHTML("$css<p class='cssTridaProPDF'>Hello itnetwork</p>");

/*Výstup*/
$mpdf->Output();
exit;
?>

Stránkování

Možná přemýšlíte nad tím, co se stane pokud obsah přesáhne stránku. I na toto vývojáři mysleli. Následující příklad ukáže co se stane pokud se pokusíme exportovat velký (dlouhý) obsah.

<?php
/*Načtení třídy mpdf pozor na číslo za MPDF v mém případě 57 ale může se lišit*/
include('MPDF57/mpdf.php');
$mpdf=new mPDF();
for($i=1;$i<=1000;$i++){
        $mpdf->WriteHTML("Řádek číslo: $i <BR>");
}
$mpdf->Output();
?>

Ano, obsah se rozstránkuje sám :). Nicméně spíš budete chtít mít plnou kontrolu na jaké stránce co bude k tomu slouží metoda AddPage().

Následující příklad vytvoří 10 stránek každou pomocí metody AddPage();

<?php
/*Načtení třídy mpdf pozor na číslo za MPDF v mém případě 57 ale může se lišit*/
include('MPDF57/mpdf.php');
$mpdf=new mPDF();
for($i=1;$i<=10;$i++){
        $mpdf->AddPage();
        $mpdf->WriteHTML("<h1>Stránka č.$i <h1>");
        $mpdf->WriteHTML("<p>Lorem ipsum.....<p>");
}
$mpdf->Output();
?>

Vytvoření rozmanitějšího dokumentu

Předešlé ukázky byly jenom takové "hraní". Pojďme nyní vytvořit něco užitečného. Nenapadá mě nic jiného než vygenerování faktury (právě tak jsem se seznámil s mPDF) :).

Začneme testovacími daty:

<?php
$dodavatel=array(
"firma"=>"ITnetwork Pro Web design",
"adresa"=>"345 Park Ave, San Jose, CA 95110, United States",
"ico"=>"00112233"
);
$odberatel=array(
"firma"=>"Tuning ponorek, s.r.o.",
"adresa"=>"Mesto, ulice 1/3, 12345",
"ico"=>"12345678"
);

$web=array(
"pocet"=>1,
"polozka"=>"Vytvoření webové prezentace",
"cena"=>12000
);
$polozky_k_fakturaci=array($web);
?>

Určitě jste si všimli, že proměnná $polozky_k_fak­turaci je pole polí. To je z důvodu snadného formátování výstupu a výpočtu. Tak, data máme připravená, nyní potřebujeme šablonu. Samozřejmě, že lze použít rozumnější řešení než mít v jednom souboru CSS HTML PHP. Správné řešení by bylo načíst soubory dynamicky za běhu, odkazuji na skvělý seriál http://www.itnetwork.cz/…architektury ,ale to je trošku nad rámec tohoto článku.

Nyní potřebujeme CSS, aby naše faktura nějak vypadala

<style>
        body{
                font-family:sans-serif;
        }
        h1{
                text-align:right;
                margin:0px;
        }
        h2{
                font-weight:normal;
                font-size:23px;
        }
        .dodavatel{
                float:left;
                border:1px solid black;
                width:300px;
                height:300px;
                padding:5px;
        }
        .odberatel{
                float:right;
                border:1px solid black;
                width:300px;
                height:300px;
                padding:5px;
        }
        div p span{
                font-weight:bold;
        }
        table{
                width:100%;
        }
        th{
                text-align:left;
        }
        h3{
                text-align:right;
                margin-top:50px;
        }
</style>

Nezapomeňte celé CSS vepsat pomocí metody WriteHTML(). Tak styly bychom měli. Nyní potřebujeme rozložení (šablonu). Ještě jednou zdůrazňuji, efektivnější je mít vše oddělené.

Nyní zdrojový kód šablony s vepsáním proměnných:

$mpdf=new mPDF();
$mpdf->WriteHTML($css); //Načtení CSS
$mpdf->WriteHTML("
<h1>Faktura číslo: 4647</h1>
<hr>
<div style='width:100%'>
        <div class='dodavatel'>
                <h2>Dodavatel</h2>
                <p>
                        <span>Obchodní název:</span>
                        $dodavatel[firma]
                </p>
                <p>
                        <span>Adresa:</span>
                        $dodavatel[adresa]
                </p>
                <p>
                        <span>IČO:</span>
                        $dodavatel[ico]
                </p>
        </div>
        <div class='odberatel'>
                <h2>Odběratel</h2>
                <p>
                        <span>Obchodní název:</span>
                        $odberatel[firma]
                </p>
                <p>
                        <span>Adresa:</span>
                        $odberatel[adresa]
                </p>
                <p>
                        <span>IČO:</span>
                        $odberatel[ico]
                </p>
        </div>
</div>
<hr>
<table>
<tr>
        <td>Datum vystavení</td>
        <td>11.11.2014</td>
        <td>Datum splatnosti</td>
        <td>12.12.2014</td>
</tr>
</table>
<hr>
<h2>Položky:</h2>
<table border='1' cellspacing='0' cellpadding='2'>
        <tr>
                <th>Množství</th>
                <th>Název</th>
                <th>Cena</th>
        </tr>
");
$cena_celkem=0;
foreach($polozky_k_fakturaci AS $polozka){
        $mpdf->WriteHTML("
        <tr>
                <td>$polozka[pocet] x</td>
                <td>$polozka[polozka]</td>
                <td>$polozka[cena],- CZK</td>
        </tr>
        ");
        $cena_celkem+=$polozka['cena'];
}
$mpdf->WriteHTML("</table>");
$mpdf->WriteHTML("<h3>Celkem $cena_celkem,- CZK</h3>");

A na závěr vypsání výstupu.

$mpdf->Output();

Výstup dokumentu

Metoda Output() nám zajišťuje výstup. Zatím se nám zobrazoval v prohlížeči. Samozřejmě jen pokud prohlížeč podporuje PDF. Podíváme se na to, jaké parametry můžeme dát do metody Output().

$mpdf->Output('NasSoubor.pdf','F');
// soubor se uloží na serveru první parametr:NasSoubor.pdf může obsahovat i cestu např: PDF_doc/NasSoubor.pdf
$mpdf->Output('NasSoubor.pdf','I');
// pošle dokument prohlížečí pokud je dostupný plugin soubour se zobrazí, pokud ne soubor se stáhne
$mpdf->Output('NasSoubor.pdf','D');
// Vynutí stažení souboru

Závěr

Nepochybně se mnou souhlasíte, že použité CSS lze napsat lépe. Bohužel nějaké CSS atributy nefungují tak, jak jsme zvyklí.

Po stažení třídy z webu mPDF a otevření adresáře MPDF57 se nelekněte. Je zde mnoho adresářů a souborů jako jsou fonty nebo příklady. MPDF má kvalitní online dokumentaci na :Dokumentace .

Dovedu si představit využití mPDF na vyvoření katalogu E-Shopu nebo klidně publikaci knihy. Je to můj první normální článek zde na ITnetwork, tak doufám, že jsem vás nezklamal. Pokud jsem něco důležitého opomněl nebo chybí to, co vás zajímá, napište do zpráv nebo pod článek komentář a rád informace doplním.


 

Stáhnout

Staženo 667x (12.22 MB)
Aplikace je včetně zdrojových kódů v jazyce php

 

 

Článek pro vás napsal jan.vencl
Avatar
Jak se ti líbí článek?
10 hlasů
Autor se věnuje webovým technologiím, financím a ekonomii. Zajímá se převážně o informační systémy a v současné době studuje VŠFS obor bankovnictví.
Miniatura
Všechny články v sekci
Práce se soubory v PHP
Miniatura
Následující článek
PHP: Databáze INIFILE
Aktivity (2)

 

 

Komentáře
Zobrazit starší komentáře (4)

Avatar
Václav Šámal:14.8.2015 13:48

Zdravím, zkoušel někdo v mPDF aby se obsah v DIVu nezalomil na novou stránku uprostřed DIVu ale v případě, že se již na stránku nevejde, vytiskne se celý na novou stránku. V praxi to znamená, že mám sadu záznamů uzavřené v DIVech a každý jednotlivý záznam se nesmí rozdělit na dvě stránky. page-break-inside:avoid nefunguje, google nic rozumného nanevrhne. Děkuji za rady.

 
Odpovědět  +1 14.8.2015 13:48
Avatar
jan
Člen
Avatar
jan:29.3.2016 16:48

načtení externího css:

$stylesheet = file_get_contents('style.css');
$mpdf->WriteHTML($stylesheet);
 
Odpovědět 29.3.2016 16:48
Avatar
Ondřej Pech
Člen
Avatar
Ondřej Pech:29.4.2016 7:07

Takže na používání stylů z fw bootstrap můžu asi zapomenout, že?

 
Odpovědět 29.4.2016 7:07
Avatar
urso
Člen
Avatar
urso:19.8.2016 13:34

Ahoj, bohužel mi mPDF neformátuje dobře plovoucí okna, ukládá je pod sebe místo vedle sebe.

Odpovědět 19.8.2016 13:34
Ne estas pano sen laboro!
Avatar
Šimon Rataj
Člen
Avatar
Odpovídá na jan
Šimon Rataj:19.12.2017 18:47

Spíše

$mpdf->WriteHTML("<style type=\"text/css\">" . $stylesheet . "</style>");
 
Odpovědět 19.12.2017 18:47
Avatar
Šimon Rataj
Člen
Avatar
Šimon Rataj:19.12.2017 18:49

pošle dokument prohlížečí pokud je dostupný plugin soubour se zobrazí, pokud ne soubor se stáhne

 
Odpovědět 19.12.2017 18:49
Avatar
arnost99
Člen
Avatar
arnost99:4. února 22:22

Čistě náhodou někdo nevíte, jak vyřešit to, že mi vypsání PDF automaticky ukončí skript? (jakýkoliv output)... Mám po vytvoření PDF nastaveníé přesměrování s flash message, ale zbytek toho skriptu se nevykoná...

 
Odpovědět 4. února 22:22
Avatar
Jarda Pytlíček:24. srpna 15:24

díky, moc pomohlo. cením ukázku v zipu!

 
Odpovědět 24. srpna 15:24
Avatar
albertpatera
Redaktor
Avatar
albertpatera:10. října 11:29

Ahoj,

neexistuje nějaká mPDF metoda, která by ""spojila" tří stránkový dokument na jednu stránku (ze tří stránek bude jedna).

Díky za odpověď ;-)
vycházel jsem z dokumentace na gitHubu i zde na ITnetwork :-)

 
Odpovědět 10. října 11:29
Avatar
Roman Mik
Člen
Avatar
Roman Mik:4. listopadu 22:39

vsetko je OK ale posledne dva priklady uz niesu vyesportovatelne pise Error
aj ked som zalatal mpdf xampp mi to nevie zrobit.
ak by ste mali aktualnu funcnu mpdf verziu rad si ju stiahnem
nakolko uz ani stranka vyrobcu nieje dostupna

 
Odpovědět 4. listopadu 22:39
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 10 zpráv z 14. Zobrazit vše