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;
}
Комментарии
Отправить комментарий