Zend_Pdf. Таблицы (Zend_Pdf_Table). UTF-8
Рано или поздно, но всем приходится делать вывод данных в PDF. Всевозможная отчетность, бланки, да и просто сохранение каких-то отобранных пользователем данных - без PDF в таком случае не обойтись.
Zend_Pdf предоставляет возможности формирования таких документов, однако встроенных возможностей все же недостаточно.
Поэтому я стала рассматривать варианты сторонних библиотек. Основными кандидатами были:
Несмотря на то, что другие варианты тоже были, они отмелись практически сразу же.
Шаг 1. Скачиваем последнюю версию здесь и помещаем в папку library вашего проекта.
Шаг 2. Подключаем библиотеку.
Поскольку преимущество данной библиотеки - конвертация html в PDF, мне не хотелось писать обработчик для каждого экшна. Также запроса на создание PDF у меня отправляется ajax'ом, поэтому в init нужного контроллера добавила строки:
Здесь мы подключаем плагин Application_Plugin_Pdf, в котором и происходят все магические действия. В плагине у меня определено всего одно действие - dispatchLoopShutdown(). Согласно документации dispatchLoopShutdown() вызывается после выхода Zend_Controller_Front из его цикла диспетчеризации, т.е. мы получаем уже сформированный view.
На этом моя радость закончилась. При тестировании Dompdf не оправдал возложенных на него надежд.
Повторно рассматривать TCPDF я не стала и решила все-таки вновь вернуться к расширению самого Zend - Zend_Pdf_Table.
Итак, что делаем:
Шаг 1. Скачиваем библиотеку здесь и помещаем в папку library нашего проекта.
Шаг 2. Минус этой библиотеки, с которым я только начинаю бороться - невозможность брать уже готовый сформированный view для формирования из него PDF. Т.е. для каждого отчета, видимо, необходимо писать свой обработчик.
Подключаем в нужном экшне библиотеку и пользуемся!
Шаг 3. Чтобы PDF стал писать по-русски, я добавила четвертый (почему-то опущенный) параметр в вызовах функции drawText класса Cell - $page->drawText($line,$this->_getTextPosX($posX), $this->_getTextPosY($page,$y_inc), 'UTF-8');
Производительность Zend_Pdf_Table радует. Однако не хватает ее возможностей:
UPD1
При использовании UTF-8 для правильного расчета ширины столбцов необходимо изменить функцию _getTextWidth() класса Page:
Zend_Pdf предоставляет возможности формирования таких документов, однако встроенных возможностей все же недостаточно.
Поэтому я стала рассматривать варианты сторонних библиотек. Основными кандидатами были:
- TCPDF
- Dompdf
Несмотря на то, что другие варианты тоже были, они отмелись практически сразу же.
Dompdf
Дольше всего я возилась с Dompdf, и этот вариант был бы лучшим и на нем я бы остановилась, если бы он смог обрабатывать большой объем информации за приемлемое время. Однако приведу пример его использования:Шаг 1. Скачиваем последнюю версию здесь и помещаем в папку library вашего проекта.
Шаг 2. Подключаем библиотеку.
Поскольку преимущество данной библиотеки - конвертация html в PDF, мне не хотелось писать обработчик для каждого экшна. Также запроса на создание PDF у меня отправляется ajax'ом, поэтому в init нужного контроллера добавила строки:
if ($this->_getParam('pdf')) { $this->_helper->getHelper("layout")->disableLayout(); $front = Zend_Controller_Front::getInstance(); $front->registerPlugin(new Application_Plugin_Pdf()); $this->view->pdf = true; }
Здесь мы подключаем плагин Application_Plugin_Pdf, в котором и происходят все магические действия. В плагине у меня определено всего одно действие - dispatchLoopShutdown(). Согласно документации dispatchLoopShutdown() вызывается после выхода Zend_Controller_Front из его цикла диспетчеризации, т.е. мы получаем уже сформированный view.
$body = $this->getResponse()->getBody(); // получаем view $html = '<html><head> <meta http-equiv="Content-Type" content="charset=utf-8" /> // ДА! эта библиотека поддерживает русский язык! <title>Test</title> </head><body>'. '<script type="text/php"> if ( isset($pdf) ) { // здесь можно добавить header и footer для каждой страницы (например, вывод нумерации или логотипа) и все, что вашей душе угодно } </script> '. $body . '</body></html>'; $dompdf = new DOMPDF(); $dompdf->set_paper("a4", "portrait"); $dompdf->load_html($html); $dompdf->render(); $pdf = $dompdf->output(); $filename = 'tmp/test.pdf'; file_put_contents($filename, $pdf); $this->getResponse()->clearBody(); $this->getResponse()->appendBody($filename);
На этом моя радость закончилась. При тестировании Dompdf не оправдал возложенных на него надежд.
Повторно рассматривать TCPDF я не стала и решила все-таки вновь вернуться к расширению самого Zend - Zend_Pdf_Table.
Zend_Pdf_Table
С первого раза отношения с этой библиотекой у меня не сложились. Но я так просто не сдалась.Итак, что делаем:
Шаг 1. Скачиваем библиотеку здесь и помещаем в папку library нашего проекта.
Шаг 2. Минус этой библиотеки, с которым я только начинаю бороться - невозможность брать уже готовый сформированный view для формирования из него PDF. Т.е. для каждого отчета, видимо, необходимо писать свой обработчик.
Подключаем в нужном экшне библиотеку и пользуемся!
Шаг 3. Чтобы PDF стал писать по-русски, я добавила четвертый (почему-то опущенный) параметр в вызовах функции drawText класса Cell - $page->drawText($line,$this->_getTextPosX($posX), $this->_getTextPosY($page,$y_inc), 'UTF-8');
Производительность Zend_Pdf_Table радует. Однако не хватает ее возможностей:
- невозможно установить rowspan
- нет возможности вынести в header таблицы несколько строк.
UPD1
При использовании UTF-8 для правильного расчета ширины столбцов необходимо изменить функцию _getTextWidth() класса Page:
private function _getTextWidth($text) { $text = iconv('UTF-8', 'UTF-16BE//IGNORE', $text); $em = $this->_font->getUnitsPerEm (); $characters = array(); for ($i = 0; $i < strlen($text); $i++) { $characters[] = (ord($text[$i++]) << 8) | ord($text[$i]); } $glyphs = $this->_font->glyphNumbersForCharacters($characters); $widths = $this->_font->widthsForGlyphs($glyphs); $stringWidth = (array_sum($widths) / $em) * $this->_fontSize; return $stringWidth; }
Комментарии
Отправить комментарий