PHPExcel: tabulky jednoduše

Na internetu je nepřeberné množství řešení pro generování dokumentů ve formátu Excel. Leckdy zákazník právě takový export dat požaduje. V tomto článku si ukážeme, jak pracovat s jednou z nejrozsáhlejších knihoven, totiž s knihovnou PHPExcel. Funkčností a možnostmi se blíží téměř samotnému Excelu.

Knihovna PHPExcel vznikla koncem roku 2006 s cílem poskytnout plný OOP přístup pro generování OpenXML dokumentů (tedy souborů s příponou .docx, .xlsx atp.), nicméně dnes umí generovat i jiné formáty: klasický XLS, PDF a dokonce i HTML tabulku. Případů, kdy potřebujeme z aplikace exportovat dokument ve formátu Excel, je nepřeberně. V článku si jako příklad vygenerujeme náš MP3 archiv.

Struktura tabulky

Každá tabulka se skládá ze souboru (tedy objekt PHPExcel) a jednotlivých listů (PHPExcel_Wor­ksheet). Vždy tedy musíme začít vytvořením dokumentu:

    $dokument = new PHPExcel();

Logický předpoklad je samozřejmě začít generovat data, nicméně objektový návrh předpokládá, že listů budeme mít více. Proto musíme vždy vybrat aktuální list a poté nám již nic nebrání v samotném plnění příslušných buněk.

<?php
$dokument->setActiveSheetIndex(0);
// Zde si vyvoláme aktivní list (nastavený nahoře) a vyplníme buňky A1 a A2
$list = $dokument->getActiveSheet();
$list->setCellValue('A1', 'Ahoj');
$list->setCellValue('A2', 'Světe');
?>

Zápis souboru je realizován za pomoci tzv. writerů – sami si tedy vybereme, který chceme použít a soubor uložíme. Zde náš první soubor uložíme v novém XLSX a následně ve starém XLS:

<?php
// Nyní si zavoláme writer pro XLSX a soubor uložíme:
$newExcelWriter = new PHPExcel_Writer_Excel2007($dokument);
$newExcelWriter->save('./ukazka.xlsx');
// A analogicky uděláme to samé pro starý formát:
$oldExcelWriter = new PHPExcel_Writer_Excel5($dokument);
$oldExcelWriter->save('./ukazka.xls');
?>

Chcete se naučit o PHP víc?

Akademie Root.cz pořádá školení Kurz programování v PHP5. Jednodenní kurz programování v PHP 5 je určen všem webovým vývojářům, kteří se chtějí do hloubky seznámit a sžít s programovacím jazykem PHP ve verzi 5. První část kurzu je zaměřena na nový objektový model se všemi jeho vlastnostmi, ošetření chyb pomocí výjimek a efektivní využití těchto konceptů. Druhá část je zaměřena na nové knihovny PHP 5, především pro práci s databázemi, XML a objekty. Pozornost je věnována i zajištění kompatibility s PHP 4, přechodu z této verze a výhledu na PHP 6. Máte zájem o jiné školení? Napište nám!

Knihovnu lze analogicky použít i pro prosté načítání dokumentů (i když ze zkušenosti pro tento účel doporučuji Excel_Reader). Pro načtení dat musíme nejdříve získat buňku samotnou, ze které následně přečteme její aktuální hodnotu:   

echo $list->getCell('A2')->getValue();

Zatím vše vypadá stejně jako ostatní dostupné knihovny, nicméně PHPExcel umí jednu věc, kterou jiné knihovny většinou neumí – stylování jednotlivých buněk. Můžeme tedy definovat barvu pozadí a textu, písmo a jeho velikost, zarovnání buňky i styl okrajů, a to bez větších problémů. Je rovněž možné přidat i obrázky, klikatelné odkazy a spoustu dalšího. Zde však nemáme dostatečný prostor na pokrytí celé knihovny – více je v přiložených ukázkách, místo toho si ukážeme, jak pracovat s okraji:

<?php
$list->getStyle('A1')
     ->getBorders()
     ->getLeft()
     ->setBorderStyle(PHPExcel_Style_Border::BORDER_HAIR);
// A pravý bude tečkovaný
$list->getStyle('A1')
     ->getBorders()
     ->getRight()
     ->setBorderStyle(PHPExcel_Style_Border::BORDER_DOTTED);
?>

Generujeme v praxi

Může se zdát, že zvolený přístup je příliš složitý a osobně s vámi bezvýhradně souhlasím. Uvědomují si to i vývojáři, proto nám připravili dva užitečné způsoby jak styly definovat – nicméně i přesto musíme vybrat příslušnou buňku. Na druhou stranu, selektor pro buňku může být stejný jako pro funkce v excelu:

// Všechny buňky mezi A1 a F56
    $sheet->getStyle('A1:F56')->
    ...
    ->setBorderStyle(...);

Kromě toho můžeme styly definovat z pole:

    $sheet->getStyle('A5')->applyFromArray($pole);

Analogicky je možné z pole stejně dobře definovat např. pouze okraje:

    $sheet->getStyle('A5')->getBorders()->applyFromArray($pole);

Pro zevrubný popis možností doporučuji soubor 05featuredemo­.inc.php, který naleznete ve složce Tests v rámci samotné distribuce.V praxi se mi nejvíce osvědčilo zkombinovat funkci čtení a zápisu – pro příklad generování si proto nejdříve vytvoříme prázdný soubor pouze s hlavičkou, samotná data doplníme následně skriptem. Takto si můžeme šablonu pohodlně připravit a v samotném PHP se starat jen o styly, které potřebujeme – například okraje.

V následujícím příkladu máme zdrojový soubor, který obsahuje zdrojové pole (nakonec jde přece jenom o ukázku) a my se soustředíme pouze na to podstatné: samotné načtení a vygenerování databáze MP3. Navíc si ukážeme, jak se nastavují vlastnosti dokumentu.

<?php
// Nejdříve si tedy nastavíme styl, který bude aplikován na plné řádky
$stylOkraj = array(
    'allborders' => array(
        'style' => PHPExcel_Style_Border::BORDER_THIN,
        'color' => array(
            'rgb' => '000000',
        ),
    ),
);

// Teď načteme šablonu a získáme první list
require_once './PHPExcel.php';
require_once './PHPExcel/IOFactory.php';
$dokument = PHPExcel_IOFactory::load('./archiv.sablona.xls');
$dokument->setActiveSheetIndex(0);
$list = $dokument->getActiveSheet();

// Nyní začneme zapisovat / začínáme od třetího řádku, protože
// v prvních dvou již máme hlavičku.
$aktualniRadek = 3;
foreach($archiv as $autor => $alba) {
    // Nastavíme autora do sloupce A (index 0) a aktuálního řádku. Rovnou přidáme i styl s okrajem
    $list->setCellValueByColumnAndRow(0, $aktualniRadek, $autor);
    $list->getStyleByColumnAndRow(0, $aktualniRadek)->getBorders()->applyFromArray($stylOkraj);


    // A zapíšeme všechna alba. Po každém zapsání musíme přičíst aktualní řádek
    // Společně s tím nastavíme okraj buňce s albem.
    foreach($alba as $album => $pisnicky) {
        $list->setCellValueByColumnAndRow(1, $aktualniRadek, $album);
        $list->getStyleByColumnAndRow(1, $aktualniRadek)->getBorders()->applyFromArray($stylOkraj);
        $aktualniRadek++;
    }

    // Nakonec přidáme jednu mezeru
    $aktualniRadek++;
}

// Nastavíme vlastnosti dokumentu:
//  - aktuální datum kdy byl dokument vytvořen (PHPExcel pracuje s tzv. unix timestamp)
//  - jméno autora dokumentu
$vlastnosti = $dokument->getProperties();
$vlastnosti->setCreated(time());
$vlastnosti->setCreator('Pavel Ptáček pro zdrojak.root.cz');

// A soubor uložíme
$writer = PHPExcel_IOFactory::createWriter($dokument, 'Excel5');
$writer->save('./archiv.xls');
?>

Zde si můžete stáhnout uvedený příklad s rozšířenými možnostmi.

Co jsme si neukázali, je například Serialized writer, který umožní celý dokument uložit do souborů, jež můžete načíst kdykoli jindy. Pokud vše zkombinujeme s ostatními způsoby výstupu, můžeme jednoduše vytvořit alternativu ke Google Documents – není problém stejnou tabulku nabídnout v PDF, HTML tabulce (na webu), obou formátech XLS a nakonec vše ukládat v databázi (a vše generovat přes noc).

PHPExcel je tedy knihovnou, která poskytuje příjemný přístup ke generování, ale i načítání prakticky jakýchkoliv tabulek.

Komentáře: 17

Přehled komentářů

David Grudl Zajímavost
Jakub Vrána Re: Zajímavost
Pavel Ptáček Re: Zajímavost
David Pozor na délku provádění skriptu a operační paměť
dc Re: Pozor na délku provádění skriptu a operační paměť
Pavel Ptáček Re: Pozor na délku provádění skriptu a operační paměť
roman Re: Pozor na délku provádění skriptu a operační paměť
xx vyborny clanok
Ventil Nadšení následované zklamáním
Jiří Kosek Re: Nadšení následované zklamáním
M. čeština
Janci Re: čeština
Janci Re: čeština
Murdej Re: čeština
michal.kocarek Export do HTML namísto XLS(X), aneb nativní podpora HTML/XML v Office >= 2000
Racky Jde to i neobjektově, jednodušeji, primitivněji, pomocí headeru a HTML
Racky Re: Jde to i neobjektově, jednodušeji, primitivněji, pomocí headeru a HTML
Zdroj: https://www.zdrojak.cz/?p=3118