Vytváření dokumentů PDF v PHP

25. listopadu 2003

Vytváření dokumentů PDF v PHP

Stejně tak jako umí PHP vytvářet grafiku či jiné typy souborů, dokáže to i s formátem PDF. Ukážeme si, jak vytvořit takový jednoduchý vícestránkový PDF dokument s jednoduchým textem a obrázky.

Celkový přehled funkcí naleznete v manuálu ke knihovně pro tvorbu formátu PDF. PHP totiž samo od sebe tvořit PDF neumí, proto si budete muset stáhnout a integrovat podporu tvorby tohoto formátu do svého adresáře s PHP. Knihovnu naleznete na adrese www.pdflib.com. Standardní verze knihovny je licencovaná a tudíž je nutné za ni zaplatit, ovšem vývojáři poskytli i lite verzi, která je zdarma. Pokud už máte staženo a nainstalováno, můžeme začít:

<?php
define („PAGE_WIDTH“, 592);
define („PAGE_HEIGHT“, 842);
define („FONT_SIZE“, 18);
define („INCH“, 72);
$pdf = pdf_new ();    // spuštění nového pdf objektu
pdf_open_file ($pdf, “);   // vytvoření nového prázdného dokumentu
// nepovinné informace
pdf_set_info ($pdf, „Author“, „Jméno Autora“);
pdf_set_info ($pdf, „Title“, „John Winston Lennon“);
// začínáme novou stránku
pdf_begin_page ($pdf, PAGE_WIDTH, PAGE_HEIGHT);
$image = pdf_open_image_file ($pdf, ‚jpeg‘, ‚john.jpg‘);
$image_width = pdf_get_value ($pdf, ‚imagewidth‘, $image);
$image_height = pdf_get_value ($pdf, ‚imageheight‘, $image);
if (($image_width+INCH) > PAGE_WIDTH) {
    $scale = PAGE_WIDTH/($image_width+INCH);
    $x = round ((PAGE_WIDTH-($IMAGE_WIDTH*$scale))/2);
} else {
    $scale = 1;
    $x = round ((PAGE_WIDTH-$image_width)/2);
}
pdf_place_image ($pdf, $image, $x, (PAGE_HEIGHT-$image_height-90), $scale);
pdf_close_image ($pdf, $image);
pdf_setlinewidth ($pdf, 3);
pdf_setcolor ($pdf, ‚both‘, ‚rgb‘, 0.8, 0.8, 0.8, 0);
pdf_circle ($pdf, (round (PAGE_WIDTH/3)*1),(PAGE_HEIGHT-(PAGE_HEIGHT/3)), 18);
pdf_stroke ($pdf);
pdf_circle ($pdf, (round (PAGE_WIDTH/3)*2), (PAGE_HEIGHT-(PAGE_HEIGHT/3)), 18);
pdf_stroke ($pdf);
pdf_arc ($pdf, (PAGE_WIDTH/2), (PAGE_HEIGHT/2), 144, 210, 330);
pdf_stroke ($pdf);
pdf_setlinewidth ($pdf, 1);
$helvetica_bold = pdf_findfont ($pdf, „Helvetica-Bold“, „winansi“);
pdf_setfont ($pdf, $helvetica_bold, 36);
pdf_set_value ($pdf, „textrendering“, 1);
pdf_setcolor ($pdf, ‚both‘, ‚rgb‘, 0.1, 0.1, 1.0, 0.5);
$width = pdf_stringwidth ($pdf, ‚John Winston Lennon‘);
$x = round ((PAGE_WIDTH+$width)/2-390);
pdf_show_xy ($pdf, ‚John Winston Lennon‘, $x+10, (PAGE_HEIGHT-INCH));
pdf_setcolor ($pdf, ‚both‘, ‚rgb‘, 0, 0, 0, 0);
$times = pdf_findfont ($pdf, „Helvetica“, „winansi“);
pdf_setfont ($pdf, $times, FONT_SIZE);
pdf_set_value ($pdf, „textrendering“, 0);
pdf_set_parameter ($pdf, „underline“, „true“);
pdf_show_xy ($pdf, ‚Obsah:‘, INCH, (PAGE_HEIGHT-(INCH*3)));
pdf_set_parameter ($pdf, „underline“, „false“);
$used_height = (INCH*3)+FONT_SIZE;
pdf_set_value ($pdf, „leading“, (FONT_SIZE*2));
pdf_continue_text ($pdf, ‚Úvod‘);
pdf_show ($pdf, ‚………………………………2‘);
$used_height += (FONT_SIZE*3);
pdf_set_value ($pdf, „leading“, (FONT_SIZE*2));
pdf_continue_text ($pdf, ‚Život‘);
pdf_show ($pdf, ‚……………………………….3‘);
$used_height += (FONT_SIZE*3);
pdf_set_value ($pdf, „leading“, (FONT_SIZE*2));
pdf_continue_text ($pdf, ‚Kariéra‘);
pdf_show ($pdf, ‚……………………………4‘);
$used_height += (FONT_SIZE*3);
$times_italic = pdf_findfont ($pdf, „Helvetica-Oblique“, „winansi“);
pdf_setfont ($pdf, $times_italic, 24);
$width = pdf_stringwidth ($pdf, ‚“Chci, aby mě lidi milovali. Chci být milován.“‚);
pdf_show_xy ($pdf, ‚“Chci, aby mě lidi milovali. Chci být milován.“‚, (INCH-15), (PAGE_HEIGHT-(PAGE_HEIGHT/2)-200));
pdf_setlinewidth ($pdf, 1);
pdf_setlinejoin ($pdf, 1);
pdf_rect ($pdf, (INCH/2-10), (INCH/2-10), (PAGE_WIDTH-INCH+20), (PAGE_HEIGHT-INCH+20));
pdf_stroke ($pdf);
pdf_setcolor ($pdf, ‚both‘, ‚rgb‘, 0.1, 0.1, 1.0, 0.5);
pdf_setlinewidth ($pdf, 6);
pdf_setlinecap ($pdf, 1);
pdf_setdash ($pdf, 20, 15);
pdf_moveto ($pdf, INCH, (PAGE_HEIGHT-(PAGE_HEIGHT/2)));
pdf_lineto ($pdf, (PAGE_WIDTH-INCH), (PAGE_HEIGHT-(PAGE_HEIGHT/2)));
pdf_stroke ($pdf);
// ukončení stránky
pdf_end_page ($pdf);
// další stránka úplně stejně…
pdf_begin_page ($pdf, PAGE_WIDTH, PAGE_HEIGHT);
$times = pdf_findfont ($pdf, „Times-Roman“, „winansi“);
pdf_setfont ($pdf, $times, FONT_SIZE);
pdf_set_value ($pdf, „leading“, (FONT_SIZE*2));
$box_height = FONT_SIZE;
$text = „John Winston Lennon se narodil ráno 9.10.1940. Jeho matka se jmenovala Julia Stanley a narodila se 12.3.1914 v Liverpoolu, jeho otcem byl Alfred J. Lennon, lodní stevard. Svatba Alfreda s Julií se uskutečnila 3.12.1938 na liverpoolské radnici. Líbánky strávili v kině a druhý den Alfred odplul do Indie.
   John vyrůstal u Juliiných rodičů na Newcastle Road. Velký vliv na něj měla teta Mary Elizabeth, Mimi, která jej vychovávala v Mendipsu (Menlove Avenue 251)…
„;
while ((pdf_show_boxed ($pdf, $text, INCH, (PAGE_HEIGHT-$used_height-$box_height), (PAGE_WIDTH-(INCH*2)), $box_height-10, „justify“, „blind“)) > 0) {
    $box_height += FONT_SIZE;
}
$remaining_space = PAGE_HEIGHT-($used_height+INCH);
$font_size = FONT_SIZE;
while ($box_height > $remaining_space) {
    $font_size = $font_size-2;
    pdf_setfont ($pdf, $times, $font_size);
   
    $box_height = $font_size;
    while ((pdf_show_boxed ($pdf, $text, INCH, (PAGE_HEIGHT-$used_height-$box_height), (PAGE_WIDTH-(INCH*2)), $box_height-10, „justify“, „blind“)) > 0) {
       $box_height += $font_size;
    }
}
pdf_show_boxed ($pdf, $spam, INCH/2, (PAGE_HEIGHT-$box_height-(INCH/2)), (PAGE_WIDTH-INCH), $box_height, ‚justify‘);
pdf_setlinewidth ($pdf, 1);
pdf_setlinejoin ($pdf, 1);
pdf_rect ($pdf, (INCH/2-10), (INCH/2-10), (PAGE_WIDTH-INCH+20), (PAGE_HEIGHT-INCH+20));
pdf_stroke ($pdf);
// ukončení stránky
pdf_end_page ($pdf);
// zavření dokumentu
pdf_close ($pdf);
// načtení dokumentu do proměnné
$buffer = pdf_get_buffer ($pdf);
// vložení dokumentu do paměti a odeslání ho do prohlížeče
header („Content-type: application/pdf“);
header („Content-Length: „.strlen ($buffer));
header („Content-Disposition: inline;filename=filename.pdf“);
// vypsání dokumentu
echo $buffer;
// odstranění dokumentu z paměti
pdf_delete ($pdf);
?>

Jak už jsem napsal, vytvoříme si takový ukázkový dokument. Jako zde to může být například kniha o Johnu Lennonovi, tedy její dvě úvodní stránky.

Pro začátek bude potřeba definovat čtyři důležité konstanty. Dvě první definují velikost stránky. Já jsem zvolil 592 postscriptových bodů šířku a 842 postscriptových bodů výšku, což představuje standardní formát A4. Dál můžete volit z těchto standardních formátů:

Formát Šířka Výška
Letter 612 792
Legal 612 1008
A0 2380 3368
A1 1684 2380
A2 1190 1684
A3 842 1190
A4 595 842
A5 421 595
A6 297 421

Následuje definice výchozí velikosti písma, no a nakonec konstanta INCH o velikosti jednoho palce jako pomocník při odsazení textu od okraje a podobně. Nyní vytvoříme počáteční objekt $pdf pdf_new (). Když už je objekt vytvořen, musíme jej v pdf otevřít funkcí pdf_open_file ($pdf, název souboru). Chcete-li však dokument vytvořit jen v paměti a poté ho odeslat prohlížeči a okamžitě zobrazit, název souboru zadávat nemusíte. Teď je vhodné vložit pár informací o dokumentu: pdf_set_info ($pdf, vlastnost, popis) – takto vždy vložíte informace, jaké budete chtít, ovšem fungovat to bude i bez toho. Teď následuje funkce pdf_create_page ($pdf, šířka int, výška int). Touto funkcí musí začínat každá nova stránka a teprve za ní mohou být definovány vlastnosti a prvky jedné stránky. Normálně bych asi měl postupovat od vytvoření prázdné stránky, pak bych měl popsat vkládání textu, kreslení a vkládání obrázků, ovšem budu to brát podle toho, jak jde kód… začínáme vložením obrázku.

Vložení obrázku

Nejprve je nutné obrázek otevřít funkcí pdf_open_image_file ($pdf, formát, cesta), přičemž výchozí adresář pro cestu nebude adresář, v němž se nachází stránka, ale adresář serveru. Mezi použitelné formáty obrázku zde patří: JPEG, GIF, PNG, TIFF, částečně i BMP a snad taky CCITT a RAW. Teď, protože bychom byli neradi, kdyby se nám veliký obrázek zobrazil přes okraje stránky, zjistíme pomocí funkce pdf_get_value ($pdf, parametr, obrázek) šířku a výšku obrázku, jejž chceme zobrazit. Pro zjištění šířky je to parametr imagewidth, pro výšku imageheight. Nyní, když jsme zjistili, jak je obrázek veliký, můžeme zajistit, aby se nám daným způsobem na stránce zobrazil. Podmínka nám opatří tyto situace: bude-li obrázek větší, proměnná $scale (měřítko) se nastaví na příslušnou hodnotu a na příslušnou hodnotu se také nastaví souřadnice x. Pokud je obrázek v normě stránky, nic se nestane – měřítko zůstane na hodnotě jedna a nastaví se souřadnice x. Po vyhodnocení podmínky již můžeme obrázek připlácnout na stránku. K tomu poslouží funkce pdf_place_image ($pdf, obrázek, souřadnice x, souřadnice y, měřítko). Místo, kde bude obrázek zobrazen tedy určíme souřadnicí x a y ve funkci, no a měřítko slouží ke změně velikosti obrázku oproti výchozí hodnotě. Ovšem pozor! Nulový souřadnicový bod je v levém dolním rohu, nikoli v levém horním, tudíž pokud nastavíte souřadnice na 100 a 100 bodů, obrázek a i jakýkoli jiný objekt, protože tento nulový souřadnicový bod v levém dolním rohu platí naprosto pro všechno, bude 100 bodů od spodu a 100 bodů z leva. Obrázek se nám tedy ukázal a teď ho jen funkcí pdf_close_image ($pdf, obrázek) zavřeme.

Kreslení kruhu

Nakreslení takového kruhu nebo čáry taky není zrovna jednoduchá věc. Nejprve samozřejmě musíme vždy určit parametry objektu dřív, než ho budeme kreslit. Jako první je dobré nastavit, jakou bude mít nakreslená čára (kruh) tloušťku. K tomu je určena funkce pdf_setlinewidth ($pdf, tloušťka int). Platí, stejně jako ostatní parametrové funkce pro netextové objekty, pro všechno – čáry, kruhy, čtverce,… Pak můžeme nastavit barvu čáry, pdf_setcolor ($pdf, ‚both‘, ‚rgb‘, červená int, zelená int, modrá int, 0). Hodnota rgb se však neudává od 0 do 255, ale v rozmezí mezi 0 a 1, takže si to musíte přepočítat. Základní nastavení máme, můžeme nakreslit kroužek. Funkce pdf_circle ($pdf, souřadnice x, souřadnice y, poloměr) vykreslí kruh se středem v souřadnici xy a poloměrem poloměr. Ovšem, napsal jsem, že vykreslí, avšak ona jen vykreslí – ukáže cestu, takže sama tato funkce ještě kruh nezobrazí. Pro konečné viditelné vykreslení vytvořené cesty máme funkci pdf_stroke ($pdf). Ta viditelně vykreslí podle zadaných parametrů poslední vytvořený objekt.

Kreslení části kruhu

Pokud už jsme někdy předtím, tedy konkrétně u předešlých dvou kruhů, nastavili nějaké parametry, budou platit i nadále. Teď už tedy jen funkcí pdf_arc ($pdf, souřadnice x, souřadnice y, poloměr, počáteční_úhel int, koncový_úhel int) vykreslíme cestu pro část kruhu a funkcí pdf_stroke ($pdf) ho opět zviditelníme. Tento necelý kruh bude vykreslen s poloměrem poloměr, se středem v souřadnicích xy a začínat bude na počátečním úhlu, končit na koncovém úhlu.

Používání True-Type fontů

Vždy je jako první nutné zvolit si písmo. To pak platí do té doby, než ho opět změníte. Ovšem dřív než tak můžeme učinit, musí být funkcí pdf_findfont ($pdf, název písma, kódování) nejdříve písmo vyhledáno v seznamu a poté být výsledek funkce uložen do proměnné, s níž se bude dál pracovat. Do parametrů funkce tedy zadáte název nějakého systémového písma a druh kódování. Kódování je několik druhů: winansi – pro Windows, macroman – pro Macintosh, builtin – je obsahem přímo fontů, host – kódování podle systému a pak je ještě pár druhů kódování, ale troufal bych si říct, že ty už nikdo nevyužije. Nyní už tedy může být vyhledané písmo určeno jako aktivní funkcí pdf_setfont ($pdf, písmo, velikost int). Pokud máme nastaven font, můžeme přistoupit k definování vlastností. Pdf_set_value ($pdf, vlastnost, hodnota) – touto funkcí je přistupováno k většině vlastností textu. Vlastností může být například textrendering, jenž určuje, jakým způsobem bude písmo vykresleno. Výchozí hodnotou je 0, vykreslení výplně, jednička je pro vykreslení obrysu, dvojka pro vykreslení obrysu i výplně a trojka pro neviditelné vykreslení. Jsou i další hodnoty, ale tyto základní, myslím, dostačují. Další možností manipulace s textem je funkce pdf_set_parameter ($pdf, parametr, hodnota). Parametrem může být například podtrhnutí – underline s hodnotou true nebo false, ovšem nikoli tučný text či kurzíva – tyto vlastnosti textu jsou určené přímo výběrem písma, například, chci font Helvetica, ale tučné, musím nastavit font Helvetica-Bold nebo pro kurzíva Helvetica-Oblique. Dalším důležitým parametrem je leading. Jeho hodnota bude při použití funkce pdf_continue_text ($pdf, text), jež zobrazí další text jako pokračování předtím použitých souřadnic, jednoduše řečeno, mezera mezi řádky. Avšak vložit do dokumentu text opět není jen tak, neboť ten se sám od sebe na konci řádku ani nikdy jindy zalamovat nebude a pojede si klidně dál. Pokud ale víme, že by text neměl být delší než řádek, můžeme ho jen tak plácnout. K tomu poslouží funkce pdf_show_xy ($pdf, text, souřadnice x, souřadnice y). Myslím, že je docela jasná. Bude zobrazen text v kolonce text a začínat bude na souřadnicích xy.

Co když ale potřebujeme zapsat delší text? Pak nejdříve využijeme funkci pdf_show_boxed ($pdf, text, souřadnice x, souřadnice y, šířka boxu, výška boxu, zarovnání). Ta zobrazí daný text v boxu na souřadnicích xy se zarovnáním vlevo – left, vpravo – right, na střed – center, nebo do bloku – justify. Velikost boxu pak bude samozřejmě taková, jakou ji nastavíme v kolonkách šířka boxu a výška boxu.

Kreslení čar

Funkcí pdf_setlinecap ($pdf, hodnota int) nastavíme vlastnost čáry, zda bude její konec hranatý (0), nebo kulatý (1).Chceme-li vytvořit přerušovanou čáru, postačí funkce pdf_setdash ($pdf, šířka, výška). Ta udělá z obyčejné čáry čáru přerušovanou. Funkcí pdf_moveto ($pdf, souřadnice x, souřadnice y) přesuneme pomyslný kurzor na určenou polohu a nyní už zbývá jen krůček k vytvoření čáry v podobě funkce pdf_lineto ($pdf, souřadnice x, souřadnice y), jež vytvoří cestu pro čáru z pozice pomyslného kurzoru do pozice určené v této funkci. Pak už jen zbývá cestu viditelně vykreslit funkcí pdf_stroke ($pdf).

Kreslení čtverců a obdélníků

I zde se samozřejmě dají použít všechny vlastnosti čáry, které jsem popsal, snad vše jen doplním jen o funkci pdf_setlinejoin ($pdf, hodnota int). Funkcí bude ovlivněno spojení dvou cest – zda bude spoj kulatý, vlnitý či zkosený. No a čtverec či obdélník se vykreslí funkcí pdf_ rect ($pdf, souřadnice x, souřadnice y, šířka, výška) – objekt bude vykreslen na souřadnicích xy v dané šířce a výšce. Teď už zbývá znova jen zviditelnit objekt funkcí pdf_stroke ($pdf).

Stránku máme hotovou a stejně tak, jako jsme ji funkcí začali, tak ji musíme i funkcí zakončit – pdf_end_page ($pdf). Chcete-li vytvořit novou stránku, pokračujete úplně stejně – funkcí pdf_begin_page ($pdf…) začnete, nadefinujete obsah a ukončíte funkcí pdf_end_page ($pdf). Pokud jsme se stránkami skončili, je nutné dokument zavřít. K tomu poslouží funkce pdf_close ($pdf). Pokud jste nezadali žádné jméno souboru a chcete tedy stránku vložit do paměti a hned ji zobrazit, následuje nyní nahrání dokumentu do proměnné $buffer funkcí pdf_get_buffer ($pdf) a za pomoci příslušných header řádků dokument odešleme do prohlížeče a nakonec zobrazíme příkazem echo $buffer.

Teď zbývá pouze dokument odstranit z paměti funkcí pdf_delete ($pdf) a je hotovo. Nyní byste měli dokázat vytvořit jednoduchý vícestránkový PDF dokument.

Starší komentáře ke článku

Pokud máte zájem o starší komentáře k tomuto článku, naleznete je zde.

Štítky: Články

Mohlo by vás také zajímat

Nejnovější

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *