Přejít k navigační liště

Zdroják » PHP » PHPExcel: tabulky jednoduše

PHPExcel: tabulky jednoduše

Články PHP, Různé

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

Subscribe
Upozornit na
guest
17 Komentářů
Nejstarší
Nejnovější Most Voted
Inline Feedbacks
View all comments
David Grudl

Jen taková zajímavost – mezi přispěvateli do kódu je uveden i Jakub Vrána http://phpexcel.codeplex.com/wikipage?…

Jakub Vrána

To je pravda, napsal jsem načítání a integroval čtení a zápis starších verzí Excelu. Viz také můj starší článek http://php.vrana.cz/…ml-v-php.php

David

Knihovna je skutečně skvělá a není problém vygenerovat téměř cokoliv. Na co však chci upozornit případné zájemce, zápis do XLSX (ostatní jsem nezkoušel) je hodně drahý v případě, že stylujete buňky a provádíte další šílenosti. Další věc, kterou knihovna žere po megabajtech, je operační paměť. Načtení existujícího nebo vytvoření vlastního souboru je opravdu náročné.
Na levném hostingu se vám toto může vymstít.
Myslete na to a řádně testujte.

Je tu velký prostor pro vylepšování knihovny, snad se k tomu někdy někdo dostane.

dc

pouzival som ju v jednom projekte kde som ale potreboval generovat pomerne velke dokumenty (niekolko desiatok zaloziek a kazda obsahovala pomerne vela buniek) a v takom pripade bola tato kniznica skoro nepouzitelna.Bezne phpcko pri generovani zozralo aj cez 256MB ram a viac a tiez doba generovania bola obcas dost dlha. Na male veci je to fajn ale na generovanie vecsich sheetov to nieje moc vhodna kniznica.

roman

Kod tohoto som nevidel, ale neverim na efektivnost objektoveho PHP kodu a mam pocit, ze programator sa zaobera skor cistotou kodu z hladiska POHLADU druheho programatora co to bude citat, ako efektivnostou, co sa nakoniec niekde vypomsti.

xx

vyborny clanok

Ventil

O této knihovně jsem se dozvěděl (a začal ji používat) cca před 2 roky. Nadšeně jsem začal generovat přímo sestavy v XLS, po čase jsem toho nechal – uživatelé portálu si začali zvyšovat nároky a na to tato knihovna opravdu není dělaná. Jak už zde bylo uvedeno, jakmile na list vložíte více buněk, nějaké to formátování (ať to opravdu vypadá jako tabulka) či výpočtů (ať využijete význam souboru XLS) tak se dostanete do takových časových a paměťových nároků, že vás přejde chuť. Před časem jsem si stáhnul aktuální verzi, abych se přesvědčil zda už je na tom lépe

Generování do XLS jsem tak vzdal, tedy až do doby až naleznu vhodnou alternativu. PHPExcel je dobrý počin, ale plusy (featury a možnosti formátu XLS) bohužel narážejí na aktivní a efektivní využití. Pokud potřebujete jednoduché tabulky vystačíte si s formáty HTML či PDF. Pokud potřebujete složitější tabulky, myslím že PHPExcel není zrovna košér řešení :-(

Budu vděčen za jakýkoliv odkaz směřující na alternativu k PHPExcel.

Jiří Kosek
M.

vyzkoušel sem mnoho méně náročných knihoven, ale ani jedna neuměla vygenrovat XLS s češtinou a tím sem skončil

Janci

Ja používam php_writeexcel a so slovenčinou som problém nemal. Takže asi ani so slovenčinou nebude. Stačí skonvertovať text na cp1250.

Janci

Takže ani s češtinou asi nebude – malo byt :)

Murdej

Taky jsem to řešil, nakonec jsem našel způsob jak opatchovat knihovnu z php pear, ale ta zase neumí xlsx.

http://wiki.slfree.net/…do_XLS_v_PHP

michal.kocarek

Možná toto někomu pomůže. Málokdo ví, že Microsoft Office podporuje jako nativní formát také XML/HTML, a to již od verze 2000. Kupříkladu Excel umí otevřít HTML soubor, a data z první tabulky, kterou najde v tomto souboru, převede do buněk a patřičně oformátuje.

Při troše hraní s Content-Type výstupní hlavičkou, a generováním HTML souboru lze vygenerovat relativně jednoduše z PHP jednolistový „excelovský“ soubor.

PS: Nedávno Microsoft zveřejnil kompletní Office HTML/XML referenční manuál. ( ke stažení na http://msdn.microsoft.com/…e.10%29.aspx ) V tomto manuálu jsou popsané veškeré jemnosti Microsoftího HTML, včetně CSS atributů začínajících na -mso-, a jejich vlastností. Lze se zde dozvědět, jak formátovat odrážky pro Word, zalamování textu pro Excel, atp. A to vše lze použít pro vygenerování HTML souboru, který je poté předhozen Officím programům, a správně načten.

Racky

http://dtbaker.com.au/random-bits/php-easily-generate-an-excel-file.html

Samozřejmě OOP je hezké a PHPExcel jistě umožňuje mnohem víc věcí než „mé“ řešení, ale proč to nezkusit..


Jen se nestíhám divit, jak nečitelné Captchy se dají v diskusích vymyslet.

Racky

Dodávám, že pro správnou češtinu je nutno po odeslání headerů dopsat klasicky cca toto:

<!DOCTYPE html PUBLIC „-//W3C//DTD XHTML 1.0 Transitional//EN“ „http://www.w3­.org/TR/xhtml1/­DTD/xhtml1-transitional.dtd“>
<html xmlns=“http:/­/www.w3.org/1999/xhtml“ xml:lang=“en“ lang=“en“>
<head>
<meta http-equiv=“Content-Type“ content=“text/html; charset=utf-8″ />
<meta name=“language“ content=“cs“ />

<title>titulek</ti­tle>
</head>

<body>

Enum a statická analýza kódu

Mám jednu univerzální radu pro začínající programátorty. V učení sice neexistují rychlé zkratky, ovšem tuhle radu můžete snadno začít používat a zrychlit tak tempo učení. Tou tajemnou ingrediencí je statická analýza kódu. Ukážeme si to na příkladu enum.