Praktická ukázka vytvoření dokumentu aplikace Excel 2007 pomocí tříd PHPExcel využívajících výhod otevřenosti formátu Open XML.
Kancelářský balík Microsoft Office 2007 nepřinesl pouze revoluční změny vzhledu a ovládání, ale také nový datový formát Open XML. Díky otevřenosti a řádnému zdokumentování nového formátu vznikly nástroje, které nám umožňují snadnější práci s dokumenty balíku Office i v jiných aplikacích. Jedním nástrojem je i třída PHPExcel zastřešující export a import dat mezi PHP aplikacemi a soubory tabulkového procesoru Excel 2007.
Open XML
Open XML je formát určený pro uchování a výměnu elektronických dokumentů. Specifikace formátu vznikla v dílnách Microsoftu, který jeho podporu implementoval do kancelářského balíku Microsoft Office 2007. Open XML byl doposud standardizován Ecma International, v prosinci 2006. Kompletní dokumentaci Office Open XML formátu naleznete na webových stránkách Ecma International.
Jakýkoliv Office Open XML soubor je obyčejný zip archiv obsahující převážně textové XML soubory. Součástí archivu mohou být i binární data v podobě grafických či multimediálních formátů (BMP, GIF, JPG, …). Pro použití Office Open XML souborů ve starších kancelářských aplikacích Microsoft Office 2000, XP a 2003 je třeba nainstalovat balík zpětné kompatibility Microsoft Office Compatibility Pack.
PHP a Open XML
Díky existenci neustále vyvíjených tříd PHPExcel, určených pro skriptovací jazyk PHP, máme možnost vytváření a čtení Open XML spreadsheet (Excel) dokumentů přímo z PHP aplikací. Nejnovější verzi PHPExcel včetně dokumentace můžete stahovat ze stránek CodePlex. Abyste mohli PHPExcel využít, je třeba přítomnost PHP, minimálně ve verzi 5.2, spolu s aktivovaným rozšířením php_zip.dll.
Bližší informace o instalaci serveru a nastavení PHP naleznete v článku Instalace nejnovější verze Apache 2, PHP 5 a MySQL 5 krok za krokem.
Pro samotné testování budete potřebovat aplikaci Excel 2007, kterou si můžete bezplatně stáhnout ze stránek Microsoftu (v rámci Office 2007). Jedná se o zkušební verzi funkční po dobu 60 dní.
Ukázka použití PHPExcel
V následující části si ukážeme, jak se generuje text, mění font a provádějí základní matematické operace s dokumenty Excel 2007. Kvůli přehlednosti kódu jsou vkládaná data uložena přímo ve zdrojovém php souboru, nikoli v databázi, jak je u běžných aplikací zvykem.
Pakliže jste si doposud nestáhli třídy PHPExcel, tak je stáhněte. Stažený archiv rozbalte do adresáře phpexcel, který umístěte někam na server. V adresáři si vytvořte soubor seznam-zbozi.php, který je třeba ukládat v kódování UTF-8.
Vložení hlaviček
Kvůli nastavení kódování a zakázání cachování je třeba na začátku souboru vložit několik hlaviček. Bližší informace o hlavičkách naleznete v oficiální dokumentaci jazyka PHP.
<?php
header("Content-Type: text/html; charset=UTF-8");
header("Expires: Sat, 01 Jan 2000 00:00:00 GMT");
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: nocache");
header("Content-Description: File Transfer");
session_cache_limiter("must-revalidate");
Nastavení cesty a vložení souborů
Abyste nebyli nuceni vkládat všechny třídy, tak pomocí ini_set nastavíme adresář explicitně. Díky funkci ini_get('include_path') se použije současné nastavení cesty, včetně nového ./Classes/, které značí adresář Classes v aktuálním adresáři. Pokud jste si php soubor vytvořili na jiném místě než v adresáři phpexcel, je třeba korektně nastavit adresu k adresáři Classes. Následuje vložení dvou php souborů a vytvoření objektu PHPExcel.
/* Nastavení cesty ke třídám PHPExcel */
ini_set('include_path', ini_get('include_path').';./Classes/');
/* Vložení potřebných tříd pro práci a tvorbu souboru */
include 'PHPExcel.php';
include 'PHPExcel/Writer/Excel2007.php';
/* Vytvoření PHPExcel objektu */
$objPHPExcel = new PHPExcel();
Metadata
Objekt již máme vytvořen, můžeme tedy přistoupit k vytváření samotného dokumentu. Pomocí metod nastavíme metadata souboru, což je jméno autora, titulek, předmět, popis, klíčová slova a kategorie.
/* Nastavení metadat - autor, název, popis, ... */
$objPHPExcel->getProperties()->setCreator("Zdeněk Večeřa");
$objPHPExcel->getProperties()->setLastModifiedBy("Zdeněk Večeřa");
$objPHPExcel->getProperties()->setTitle("Seznam zboží");
$objPHPExcel->getProperties()->setSubject("Office 2007, Open XML a PHPExcel");
$objPHPExcel->getProperties()->setDescription("Tvorba Excel dokumentu z PHP aplikace.");
$objPHPExcel->getProperties()->setKeywords("Zboží, Office 2007");
$objPHPExcel->getProperties()->setCategory("Zboží");
Vkládáme data
Pomocí metody setActiveSheetIndex zvolíme list, který chceme, aby byl při prvním otevření souboru aktivní. Následuje již samotný zápis dat do jednotlivých buněk. První parametr metody SetCellValue označuje buňku a druhý vkládanou hodnotu. Lze zapisovat obyčejný řetězec (obklopený uvozovkami), číselné a logické hodnoty (true a false). Můžete také použít například matematické funkce (SUM, …), které se zapisují jako řetězec (vkládají se mezi uvozovky).
/* Nastavení listu, který bude aktivní po otevření souboru */
$objPHPExcel->setActiveSheetIndex(0);
/* Vložení hodnot */
$objPHPExcel->getActiveSheet()->SetCellValue('A1', 'Zboží');
$objPHPExcel->getActiveSheet()->SetCellValue('B1', 'Ks');
$objPHPExcel->getActiveSheet()->SetCellValue('C1', 'Cena/Ks');
$objPHPExcel->getActiveSheet()->SetCellValue('D1', 'DPH [%]');
$objPHPExcel->getActiveSheet()->SetCellValue('E1', 'Celkem [Kč]');
$objPHPExcel->getActiveSheet()->SetCellValue('A2', 'Microsoft Natural Ergonomic Keyboard 4000 CZ, USB');
$objPHPExcel->getActiveSheet()->SetCellValue('B2', 1);
$objPHPExcel->getActiveSheet()->SetCellValue('C2', 1019.00);
$objPHPExcel->getActiveSheet()->SetCellValue('D2', 19.00);
$objPHPExcel->getActiveSheet()->SetCellValue('E2', '=(((C2/100)*D2)+C2)*B2');
$objPHPExcel->getActiveSheet()->SetCellValue('A3', 'Logitech MX 1000 Laser, PS/2+USB');
$objPHPExcel->getActiveSheet()->SetCellValue('B3', 1);
$objPHPExcel->getActiveSheet()->SetCellValue('C3', 1326.00);
$objPHPExcel->getActiveSheet()->SetCellValue('D3', 19.00);
$objPHPExcel->getActiveSheet()->SetCellValue('E3', '=(((C3/100)*D3)+C3)*B3');
$objPHPExcel->getActiveSheet()->SetCellValue('A4', 'DVD-R Verbatim 16x spindl po 10ks');
$objPHPExcel->getActiveSheet()->SetCellValue('B4', 3);
$objPHPExcel->getActiveSheet()->SetCellValue('C4', 148.00);
$objPHPExcel->getActiveSheet()->SetCellValue('D4', 19.00);
$objPHPExcel->getActiveSheet()->SetCellValue('E4', '=(((C4/100)*D4)+C4)*B4');
$objPHPExcel->getActiveSheet()->SetCellValue('A5', 'DVD-RAM Verbatim 4,7GB, 5x');
$objPHPExcel->getActiveSheet()->SetCellValue('B5', 10);
$objPHPExcel->getActiveSheet()->SetCellValue('C5', 64.00);
$objPHPExcel->getActiveSheet()->SetCellValue('D5', 19.00);
$objPHPExcel->getActiveSheet()->SetCellValue('E5', '=(((C5/100)*D5)+C5)*B5');
$objPHPExcel->getActiveSheet()->SetCellValue('E6', '=SUM(E2:E5)');
Fonty, šířky sloupců a zarovnání
Následujícím kódem nastavíme šesti buňkám tučný font.
/* Nastavení fontů */
$objPHPExcel->getActiveSheet()->getStyle('A1')->getFont()->setBold(true);
$objPHPExcel->getActiveSheet()->getStyle('B1')->getFont()->setBold(true);
$objPHPExcel->getActiveSheet()->getStyle('C1')->getFont()->setBold(true);
$objPHPExcel->getActiveSheet()->getStyle('D1')->getFont()->setBold(true);
$objPHPExcel->getActiveSheet()->getStyle('E1')->getFont()->setBold(true);
$objPHPExcel->getActiveSheet()->getStyle('E6')->getFont()->setBold(true);
Protože jsme vložili delší text, musíme i patřičně upravit šířku sloupců, která se udává ve znacích.
/* Nastavení šířky sloupců */
$objPHPExcel->getActiveSheet()->getColumnDimension('A')->setWidth(43);
$objPHPExcel->getActiveSheet()->getColumnDimension('B')->setWidth(6);
$objPHPExcel->getActiveSheet()->getColumnDimension('C')->setWidth(9);
$objPHPExcel->getActiveSheet()->getColumnDimension('D')->setWidth(8);
$objPHPExcel->getActiveSheet()->getColumnDimension('E')->setWidth(11);
A konečně, provedeme i samotné zarovnání textů. Opět jsme se zaměřili na první řádek tabulky, kde první tři buňky zarovnáváme na střed, a následující dvě buňky k levému, resp. k pravém okraji.
/* Zarovnání prvních řádků */
$objPHPExcel->getActiveSheet()->getStyle('A1')->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
$objPHPExcel->getActiveSheet()->getStyle('B1')->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
$objPHPExcel->getActiveSheet()->getStyle('C1')->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
$objPHPExcel->getActiveSheet()->getStyle('D1')->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_LEFT);
$objPHPExcel->getActiveSheet()->getStyle('E1')->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_RIGHT);
Speciální text
Pokud si nevystačíme s obyčejným textem, je třeba přistoupit k vytvoření objektu PHPExcel_RichText, který nám umožní prakticky libovolnou manipulaci s textem (tučný, kurzíva, velikost, barva, …). Při vytváření objektu určíme buňku, do které chceme zapisovat. Metodami nastavíme text a jeho vlastnosti.
/* Vložení speciálního textu do buňky A8 */
$objRichText = new PHPExcel_RichText( $objPHPExcel->getActiveSheet()->getCell('A8') );
// obyčejný text
$objRichText->createText('Text může být obyčejný, ');
// kurzívou
$objPayable = $objRichText->createTextRun('kurzívou ');
$objPayable->getFont()->setItalic(true);
// obyčejný text
$objRichText->createText('nebo ');
// tučně
$objPayable = $objRichText->createTextRun('tučný');
$objPayable->getFont()->setBold(true);
// obyčejný text
$objRichText->createText('.');
/* Vložení textu do buňky A9 */
$objRichText = new PHPExcel_RichText( $objPHPExcel->getActiveSheet()->getCell('A9') );
$objPayable = $objRichText->createTextRun('Lze měnit i jeho velikost a barvu.');
// červenou barvou
$objPayable->getFont()->setColor( new PHPExcel_Style_Color( PHPExcel_Style_Color::COLOR_RED ) );
// velikost fontu 25
$objPayable->getFont()->setSize(18);
Jméno listu a uložení
Ještě bychom měli nastavit nějaký popisek listu, do kterého jsme prováděli zápis. Poté již stačí vytvořit samotný objekt pro zápis do souboru a uložit ho pod zadaným názvem. Má-li váš adresář právo pro zápis, vytvoří se nový soubor seznam-zbozi.xlsx, který lze otevřít aplikací Microsoft Office 2007.
/* Nastavení jména listu */
$objPHPExcel->getActiveSheet()->setTitle('Přehled zboží');
/* Uložení souboru Excel 2007 */
$objWriter = new PHPExcel_Writer_Excel2007($objPHPExcel);
$objWriter->save("seznam-zbozi.xlsx");
echo "Soubor vytvořen.";
?>
Jak to vypadá?
Výsledek vidíte na obrázku výše. Zdrojový php soubor včetně xlsx vygenerovaného dokumentu si můžete stáhnout zde.