понедельник, 18 апреля 2011 г.

PHP. Создать multi-page PDF на основне набора SVG файлов

Появилась интересная задача: как на основе SVG файла создать PDF. SVG файл должен содержать картинки с подписями и  background  (создаваться может в сторонней программе).

Путем проб и ошибок выяснил: ImageMagic еще не умеет обрабатывать картинки при конвертации   SVG, если они задаются относительным путем или ссылкой. 

Выбор пал на Inscape - открытый редактор векторной графики. Кроме графической оболочки он предоставляет для работы консоль с набором команд (что собственно и требовалось). Кроме того, он полностью кросс-платформенный.

Устанавливаем его, если под Winndows то прописываем в Path путь к приложению.

Теперь из PHP можно юзать следующим образом:

$filename = "svg_dir/test.svg"; //path to SVG file
$pdf_filename="pdf_dir/test.pdf"; // output PDF

if(!file_exists($filename)){
  throw new Exception("{$filename} not exists!");
}

system("inkscape -T $filename -A $pdf_filename",$success);
if($success!=0){
  throw new Exception('Error inkscape convertation!');
}

На Хабре предлагают не создавать PDF c помощью Inkscape, так как они большого размера и предлагают сначала конвертировать в PostScript формат, а потом использовать утилиту  ps2pdf из пакета GhostScript для генерации непосредственно PDF. Размер такого файла действительно намного меньше чем прямая генерация PDF. Но у меня в задачи было условие создать много страничный PDF (inkscape и ps2pdf этого не умеют как оказалось).

Потому я поступил проще: с помощью Inkscape я генерю отдельные PDF файлы, например с именами page1.pdf, page2.pdf, ...., pageN.pdf.

Дальше я скачал утилиту pdftk,  которая умеет генрить мульти-страничные PDF и многое другое. Более детально по этому вопросу смотрим тут.

Пример использования:

pdftk pdf1.pdf pdf2.pdf ... pdfn.pdf cat output multipage.pdf

или по маске:

pdftk *.pdf cat output multipage.pdf

для вызова из PHP нужно вызывать в контексте system("pdftk....")


Если необходимо, то теперь можем с помощью pdf2ps и  ps2pdf  утилит (пакет GhostScript) оптимизировать получившийся PDF (оптимизация ухудшает качество, и как по мне, может только для предварительного просмотра использоваться или для особых задач- когда клиент получает высокое разрешение картинки только за отдельную плату).

Пример очень прост (незабываем, команды в ПХП прогоняем через оператор system или exec):

pdf2ps multipage.pdf multipage.ps
ps2pdf multipage.ps multipage.pdf

3 комментария:

  1. Хорошая статья но появились попросы:)

    Я заметил что когда сохраняешь PDF файл из консоли текст не возможно выделить в PDF-Reader'е. Но если открыть тот же SVG через гравический интерфейс и сохранить в PDF, текст выделяется нормально. Как быть?
    Спасибо.

    ОтветитьУдалить
  2. Все разобрался, ключ -Т для inkscape лишний.

    ОтветитьУдалить
  3. http://tavmjong.free.fr/INKSCAPE/MANUAL/html/CommandLine.html - дока по консоли

    http://tavmjong.free.fr/INKSCAPE/MANUAL/html/CommandLine-Export.html - здесь описание ключа -T


    Вырезка из доки:
    -T, --export-text-to-path
    The text objects should be converted to paths prior to export to a PS or EPS export. Then ensures that the text will be rendered properly regardless of which fonts are installed on a computer that displays or a printer that prints the resulting file.

    ОтветитьУдалить