PHP. Создание PDF-файлов «на лету» в кодировке UTF-8
Как-то решал я задачу по созданию скрипта на PHP для генерации PDF-файлов. Важное условие – входящие данные в кодировке UTF-8.
Казалось бы, какие могут быть сложности, ведь PHP-шных классов для генерации PDF написано достаточно, но оказалось что решение этой задачи целая проблема.
На лабораторный стол ко мне попали следующие классы: FPDF, TCPDF, mPDF, UFPDF.
Исследование показало, что:- класс FPDF не дружит с юникодом;
- TCPDF и mPDF не работали из-за лимитов памяти для выполнения на хостинге (бывает и такое);
- класс UFPDF (на самом деле это модифицированная версия FPDF, которая работает с UTF-8) на первый взгляд показался мне подходящим кандидатом. Его я и стал использовать.
Походу использования класса, обнаружилось несколько проблем. Сначала были проблемы с украинскими символами, которые решились парочкой правок в коде UFPDF. Но потом, когда я начал рисовать таблицы, выяснилось что класс не умеет нормально переносить текст в ячейках таблицы. После вызова метода MultiCell текст в следущей ячейке сползал вниз.
Пришлось маленько «поломать» голову. В результате получился класс UFPDF2, который является расширением UFPDF и в котором корректно работает метод MultiCell.
UFPDF2 работает аналогично UFPDF, который, с свою очередь, работает также как и FPDF. Поэтому пользуемся документацией FPDF.
Пример использования класса:
define('FPDF_FONTPATH', 'font/');
include_once('ufpdf2.php');
$pdf = new UFPDF2();
$pdf->Open();
$pdf->SetTitle("Тестовый документ");
$pdf->SetAuthor('Steven Wittens');
$pdf->AddFont('LucidaSansUnicode', '', 'lsansuni.php');
$pdf->AddPage();
$pdf->SetFont('LucidaSansUnicode', '', 32);
$pdf->Write(12, "Test.\n");
$pdf->Write(12, "Тестовая строка.\n");
$pdf->Close();
$pdf->Output('unicode.pdf', 'F');
Примеры PDF-файлов сгенерированных классом: pdf1, pdf2, pdf3.
Скачать UFPDF2.
Для работы класса необходим класс UFPDF. Скачать UFPDF.
Документация по FPDF
(#) Yuriy:
увы, появляется ошибка; "FPDF error: Could not include font definition file". Не смортя на то что файлы лежат на месте и права выставленны максимальные.(#) szpargalki:
А вы генерировали файлы шрифтов? В архиве с UFPDF есть файлик README.txt - в нем инструкция по генерации.Для примера, использующего шрифт LucidaSansUnicode, нужно выполнить следующие действия:
1. берем файл lsansuni.ttf
2. копируем его в каталог ufpdf/tools
3. выполняем команду $ ttf2ufm -a -F lsansuni.ttf
4. затем команду $ php -q makefontuni.php lsansuni.ttf lsansuni.ufm
5. копируем сгенерированные lsansuni.php, lsansuni.z and lsansuni.ctg.z в каталог ufpdf/font
Все, пример должен работать.
(#) Артем:
Помогите пожалуйста, делаю все по мануалу, уже второй шрифт генерирую, но пишет:Unsupported font type: TrueTypeUnicode
Не знаю, что делать, не могли бы выложить исходники своих шрифтов?
(#) szpargalki:
Скачайте этот архив http://goo.gl/HO5pjqТам рабочий пример для трех шрифтов DroidSans, DroidSansMono и LaudatioC. Попробуйте у себя и сообщите о результатах.
(#) Андрей:
Помогите, пожалуйста, разобраться. Почему-то не получаются внешние ссылки.Кстати в Ваших примерах (pdf1, pdf2, pdf3) ссылки тоже не рабочие...
(#) dimka:
Не понял. Какие внешние ссылки?Вы имели ввиду URL внизу страницы?
(#) greynemo:
А как подключать шрифты на Linux? Эти команды в терминале не пойдут ...(#) dimka:
Проблема только с ttf2ufm. Есть бинарник под виндовс, а под вашу систему его нет.В архиве с UFPDF есть каталог с исходниками ttf2ufm. Там лежит файл winbuild.bat. Создаем по аналогии файл linuxbuild.sh:
#!/bin/sh
gcc -c bdf.c
gcc -c ttf2pt1.c
gcc -c pt1.c
gcc -c ttf.c
gcc -c t1asm.c
gcc -c bitmap.c
gcc -o ttf2ufm ttf2pt1.o pt1.o t1asm.o ttf.o bdf.o bitmap.o -lm
gcc -o t1asm -DSTANDALONE t1asm.c
Даем ему права на запуск chmod +x linuxbuild.sh
Запускаем и получаем скомпилированный по вашу систему ttf2ufm.
Дальше все по инструкции, приведенной выше.
(#) Евгений:
День добрый!!!метод Output() вторым параметром принимает куда выводить I,F,D,S
у меня из 4-х параметров работает только F
I - выводит иероглифы
При параметре D файл скачивается, но при открытии выдает ошибку
S - вообще ничего не происходит
В чем может быть проблема?
(#) Евгений:
У меня стоит задача сгенерировать с помощью PHP PDF файл из изображения SVG. Сначала попробовал класс FPDF, но он не поддерживает генерацию PDF файла из изображения SVG, тогда обратился к другому классу TCPDF, он отлично генерирует PDF из изображений SVG, но о возникла следующая проблема – все русские буквы в изображение SVG, при генерации PDF отображаются вопросительными знаками. Как побороть данную проблему? Помогите, пожалуйста.
(#) dimka:
Может проблема в шрифтах?
Можно ли ему подсунуть другой какой-либо файл шрифтов и попробовать сгенерировать pdf?
(#) Evil:
Поставил FPDF – нет поддержки UTF,
Поставил UFPDF – начались ошибки со шрифтами,
Поставил UFPDF2 – понеслась дальше Warning: filesize() [function.filesize]: stat failed for font/font/times.php in F:\путь\fpdf\fpdf.php on line 1170
FPDF error: Font file not found
Походу чем дальше тем хуже.
(#) Владимир:
Поставил ufpdf2 вывел кириллицу и картинки – полет нормальный.
По ходу были несколько ворнингов которые легко исправил.
Спасибо большое!
(#) vasena:
Пришлось маленько «поломать» голову. В результате получился класс UFPDF2, который является расширением UFPDF и в котором корректно работает метод MultiCell.
Хрен там, он корректно работает только для двухстрочного текста, для трех строк он начинает выдавать пустые строки в середине (т.е. есть первая и последняя строка видны, а между – пусто) лечится это заменой функции usubstr на корректную:
function usubstr($arr, $from, $to=false){
if (!$to) $to = count($arr) – $from;
$res = “”;
for($i=0; $i<$to; $i++) {$res .= $this->code2utf($arr[$from + $i]);}
return $res;
}
Далее – видим что теперь текст появился, однако если у вас более чем 3 строки, то начинает проявлятся другой баг, а именно начинают пропадать буквы в конце строки и слова ломаться не по пробелам. Как я выяснил, автор заплатки решил поставить лишнюю заплатку, а именно везде где использовался while для перебора символов в тексте заменил на foreach, чтобы убрать по его мнению лишнюю строку $c=$s[$i]; а это черевато, т.к. теперь мы не контролируем индекс, а значит перенос у нас проиходит там где хочется( foreach’у). Лечится это заменой всех фраз foreach($s as $c) на while($i<count($s)) и возвратом из комментариев $c=$s[$i];
Пока все. Найду еще что-то напишу.
PS кстати, с поддержкой UTF-8 вы теряете поддержку копирования текста (по крайней мере для родного Adobe Reader, хотя Foxit нормально копирует)
(#) Tvolod:
А не могли бы обновить ссылку на UFPDF или залить его на файл-шару? Ссылка из текста не работает, поиск по сайту acko.net ничего не дал.
Спасибо за статью!
(#) Tvolod:
Новая ссылка на UFPDF такая: http://acko.net/blog/ufpdf-unicode-utf-8-extension-for-fpdf/