Generowanie plików RTF i PDF
Rozwiązania w języku PHP do eksportu dokumentów w popularnych formatach tekstowych.
26 Maj 2010
Autor: Joachim Kret / Weeby.pl
DomPdf
DomPdf w w stosunku do innych darmowych bibliotek generujących dokumenty w formacie Pdf charakteryzuje się:
- możliwością konwersji dokumentów HTML w wersji 4.0,
- wsparciem dla selektorów oraz właściwości CSS w wersji 2.1,
- obsługą obrazów w formacie: png, gif i jpeg,
- możliwością generowania rozbudowanych i złożonych tabel,
- niezależnością – do jej implementacji nie potrzebujemy żadnych zewnętrznych bibliotek.
Dzięki wsparciu standardów Html i CSS, jesteśmy w stanie wygenerować dokument Pdf nie różniący się znacząco od wyglądu strony internetowej. Dlatego jeżeli potrzebujemy darmowej, wygodnej i szybkiej w obsłudze biblioteki generującej dokumenty na podstawie stron Html biblioteka DomPdf w całości spełni te oczekiwania. Aktualną wersję biblioteki możemy pobrać ze strony głównej programu: http://www.digitaljunkies.ca/dompdf/, bądź ze strony: http://code.google.com/p/dompdf/.
Instalacja i konfiguracja
Opis instalacji, a także konfiguracji biblioteki DomPdf został przedstawiony w oparciu o Zend Framework w wersji 1.10.0.
Aby zainstalować bibliotekę DomPdf należy najpierw pobrać z oficjalnej strony internetowej najnowszą, lub stabilną wersję. Po pobraniu i rozpakowaniu archiwum, przenosimy folder biblioteki do folderu library naszego projektu w Zend Framework. Teraz tylko należy dołączyć do projektu skopiowaną bibliotekę poprzez dodanie wpisu w pliku konfiguracyjnym – application.ini w sekcji production:
includePaths.dompdf = APPLICATION_PATH "/../library/dompdf"
informującego Zend Framework o ścieżce dostępu do biblioteki oraz dodać do autoloadera klasy Zend_Loader_Autoloader klasę dompdf_config.inc.php włączającą wszystkie pliki biblioteki DomPdf. W tym celu w kontrolerze, bądź modelu klasy wywołujemy następujący kod:
require_once 'dompdf_config.inc.php';
$autoloader = Zend_Loader_Autoloader::getInstance();
$autoloader->pushAutoloader('DOMPDF_autoload');
Po wykonaniu powyższych czynności musimy jeszcze zadbać o poprawne konwertowanie polskich znaków, w tym celu należy utworzyć tablicę asocjacyjną zawierające dwa klucze ‘encoding’ i ‘differences’. Pierwszy klucz może przechowywać jedną z następujących wartości: ‘none’, ‘WinAnsiEncoding’, ‘MacRomanEncoding’ bądź ‘MacExpertEncoding’ informując DomPdf o sposobie kodowania znaków, natomiast klucz ‘differences’ przechowuje tablicę mapującą zdefiniowane kody znaków ASCII na określoną nazwę w Unicode. Wszystkie kody ASCII i opowiadające im nazwy w Unicode dla znaków kodowanych w Windows-1250 znajdziemy na stronie Microsoftu w bazie MSDN pod adresem: http://msdn.microsoft.com/pl-pl/goglobal/(…), lub na stronie wikipedii dotyczącej kodowania znaków w Windows-1250: http://en.wikipedia.org/wiki/Windows-1250.
Przykładowa tablica asocjacyjna dla kodowania znaków w Windows 1250 będzie wyglądać następująco:
$enc = 'WinAnsiEncoding';
$diff = array(
131 => '.notdef',
136 => '.notdef',
140 => 'Sacute',
141 => 'Tcaron',
143 => 'Zacute',
152 => '.notdef',
156 => 'sacute',
157 => 'tcaron',
159 => 'zacute',
161 => 'caron',
162 => 'breve',
163 => 'Lslash',
165 => 'Aogonek',
// ...
);
$encoding = array('encoding' => $enc, 'differences' => $diff);
Niestety w bibliotece DomPdf nie istnieje publiczna funkcja mogąca przyjąć jako parametr tablicę asocjacyjną definiującą różnicę w kodowaniu znaków. Standardowo konwersja ta zachodzi po wywołaniu funkcji render(), której zadaniem jest sformatowanie kodu Html, obrazów i tabel do dokumentu w formacie Pdf. Dlatego musimy wymusić dodanie tablicy poprzez dołączenie jej do ciała funkcji selectFont(), odpowiedzialnej za wybranie i kodowanie czcionek. Metoda ta znajduje się w ciele klasy class.pdf.php w folderze /lib biblioteki DomPdf. Po wykonaniu powyższych czynności możemy generować pliki Pdf wraz z obsługą polskich czcionek.
Przykład użycia
Po skonfigurowaniu biblioteki do pracy w naszym projekcie, możemy rozpocząć pracę z DOMPDF. Jej obsługa jest bardzo prosta, gdyż sprowadza się tylko do wykonania kilku linijek kodu:
$pdf = new DOMPDF();
$pdf->set_paper('a4', 'portrait');
//load content
$pdf->load_html(iconv('UTF-8', 'Windows-1250', $html));
//render
$pdf->render();
//save document
file_put_contents("test.pdf", $pdf->output());
Najpierw tworzymy nową instancję klasy DomPdf oraz ustawiamy rozmiar dokumentu. Następnie za pomocą funkcji load_html() dołączamy do dokumentu kod Html, który został skonwertowany z kodowania UTF-8 do formatu Windows-1250. Po wykonaniu konwersji i dodaniu treści wiadomości wywołujemy funkcję render(), a kod wyjściowy zapisujemy za pomocą funkcji file_put_content(), bądź jeśli chcemy wysłać plik do okna przeglądarki – poprzez stream(„test.pdf”). Więcej przykładów użycia biblioteki znajdziemy na oficjalnej stronie projektu w zakładce „usage”, gdzie dodatkowo opisano pomocnicze funkcje wspomagające operacje rysowania w dokumentach Pdf.

Przykładowy plik Pdf wygenerowany przy pomocy biblioteki DomPdf.
PHPRtfLite
PHPRtfLite to mała, dostępna na licencji LGPL i stosunkowo nowa biblioteka generująca pliki w formacie Rtf. Cechą główną biblioteki jest podział formatowanego tekstu na sekcje, dzięki którym formatujemy interesujący nas wybrany fragment tekstu ustalając jego czcionkę, rozmiar oraz kolor. Dodatkowo biblioteka wspiera generowanie teksu ze znacznikami Html, które wpływają na wygląd czcionki: pogrubienie, kursywa, podkreślenie, wielkość oraz kolor. Możemy także dodać obsługę innych znaczników poprzez zdefiniowanie nowych reguł w klasie Container.php (znajdującej się w folderze /libPHPrtfLite biblioteki) w funkcji writeText(). Charakteryzuje się także możliwością ustalenia formatowania dokumentu pod względem rozmiaru i szerokości marginesów, osadzania obrazów (foramty .jpg i .png), wyrównania tekstu, formatowania nagłówka oraz stopki, a także wsparciem dla kodowania UTF-8. Aktualną wersję biblioteki możemy pobrać ze strony głównej projektu w zakładce download: http://www.phprtf.com/index.php/download/.
instalacja i konfiguracja
Instalacja biblioteki w projekcie Zend Framework przebiega standardowo – po pobraniu i rozpakowaniu archiwum kopiujemy folder /lib do folderu /library naszego projektu zmieniając przy okazji nazwę folderu biblioteki na /RtfLite. Następnie informujemy Zend Framework o włączeniu do projektu nowej biblioteki poprzez dodanie nowego wpisu w pliku application.ini:
includePaths.PHPrtfLite = APPLICATION_PATH "/../library/RtfLite"
Biblioteka posiada także własny autoloader klas, dzięki któremu nie jesteśmy zmuszani do załączania kolejnych klas potrzebnych w naszym projekcie. Aby dodać automatyczne ładowanie plików biblioteki wywołujemy poniższy kod:
require_once 'PHPRtfLite.php'; PHPRtfLite::registerAutoloader();
Po zarejestrowaniu klasy autoloadera jesteśmy gotowi do korzystania z możliwości generowania dokumentów Rtf przy użyciu biblioteki PHPRtfLite.
Funkcjonalność
Definiowanie czcionek – aby zdefiniować nową czcionkę należy utworzyć nowy obiekt typu PHPRtfLite_Font jako jego parametry podając kolejno rozmiar czcionki, nazwę czcionki oraz jej kolor w postaci liczby szesnastkowej:
$fontLink = new PHPRtfLite_Font(10, 'Helvetica', '#0000ff');
Formatowanie paragrafów – do formatowania paragrafów służy klasa PHPRtfLite_ParFormat(), która jako parametr wywołania przyjmuje format wyrównania tekstu. Po utworzeniu nowego obiektu klasy uzyskujemy dostęp do metod odpowiadających za formatowanie tekstu paragrafu:
$parPhp = new PHPRtfLite_ParFormat();
$parPhp->setIndentLeft(5);
$parPhp->setIndentRight(5);
$parPhp->setIndentFirstLine(3);
$parPhp->setTextAlignment('justify');
Wywołanie funkcji setIndentLeft() oraz setIndentRight() padając jako parametr liczbę 5 oznacza sformatowanie paragrafu jako 5 cm wcięcia z jego lewej jak i prawej strony. Następna funkcja tworzy 3 cm akapit pierwszej linii, po czym następuje wyjustowanie całego paragrafu przy pomocy metody setTextAligmrent() .
Tworzenie sekcji – aby stworzyć nową sekcję należy wywołać metodę kasy PHPRtfLite – addSection(). Funkcja w miejscu wywołania zwraca nam nowy obiekt typu PHPRtfLite_Container_Section, który posłuży nam do sformatowania tekstu i dodania nowej treści do dokumentu Rtf.
$sect = $rtf->addSection(); $sect->writeText($text, $fontLink, $parPhp, false);
Funkcja writeText() klasy PHPRtfLite_Container dodaje nową sekcję tekstu do dokumentu, jako parametry wywołania przyjmuje formatowany tekst, obiekt klasy PHPRtfLite_Font przechowujący dane dotyczące czcionki, obiekt PHPRtfLite_ParFormat() – atrybuty formatowania paragrafu oraz typ bool – formatowanie znaczników Html.
Dodawanie tabel – dodanie tabeli do wybranej sekcji wykonujemy poprzez wywołanie funkcji addTable() na obiekcie typu PHPRtfLite_Container. Funkcja w miejscu swojego wywołania zwraca nowy obiekt typu PHPRtfLite_Table.
$table = $sect->addTable(); $table->addRows(3); $table->addColumn(1); $table->addColumn(2); $cell = $table->getCell(1, 2); $cell->writeText($text, $fontLink, $parPhp);
Dodaniem nowych wierszy do tabeli wykonuje się za pomocą funkcji addRows(), natomiast funkcją addColumns() dodajemy nowe kolumny. Aby pobrać daną komórkę tabeli w tym celu wykorzystujemy funkcję getCell(), jako parametry podając koordynaty żądanej komórki.
Przykład użycia
Po zapoznaniu się z głównymi obiektami biblioteki PHPRtfLite możemy wygenerować przykładowy dokument Rtf:
//rtf document
$rtf = new PHPRtfLite();
$rtf->setMargins(2, 1, 1 ,2);
//fonts
$titleFont = new PHPRtfLite_Font(16, 'Arial');
$textFont = new PHPRtfLite_Font(12, 'Times new Roman');
//paragraph
$parText = new PHPRtfLite_ParFormat();
$parText->setIndentFirstLine(2);
$parText->setTextAlignment('justify');
//setion
$sect = $rtf->addSection();
$sect->writeText($title, $titleFont);
$sect->emptyParagraph($titleFont, $parText);
$sectText = $rtf->addSection();
$sectText->writeText($text, $textFont, $parText);
//save document
$rtf->save('text.rtf')
Po utworzeniu instancji obiektu PHPRtfLite zostają ustawione marginesy dokumentu za pomocą funkcji setMargins(). Następnie definiowane są obiekty odpowiedzialne za czcionki i formatowania paragrafów, po czym zostają utworzone i dodane do treści dokumentu dwie sekcje. Po operacjach dodania nowej treści dane zostają zapisane jako dokument Rtf za pomocą funkcji save(), istnieje także możliwość wysłania utworzonego pliku do użytkownika za pomocą funkcji sendRtf(). Dodatkowe przykłady użycia biblioteki znajdują się na stronie głównej projektu w zakładce sample scripts:
http://www.phprtf.com/index.php/samples/.

Przykładowy plik Rtf wygenerowany przy pomocy biblioteki PHPRtfLite.
Nie do końca to związane z PHP, ale bardzo ciekawym programem do konwersji HTML => PDF jest wkhtmlpdf (http://code.google.com/p/wkhtmltopdf/). Wykorzystuje on WebKit widget z QT. Testowałem go przy kilku projektach i sprawdza się dobrze (stosunkowo łatwo też się podpina okładkę, nagłówki, stopki, etc).