Как стать автором
Обновить

HTML в PDF

Время на прочтение2 мин
Количество просмотров120K
Всего голосов 144: ↑129 и ↓15+114
Комментарии81

Комментарии 81

А в каком, интересно, движке рендерится html?
Извините немного не понял вопрос, не могли бы уточнить.
Ну например разные браузеры рендерят по-разному, и то что выглядит хорошо например(!) в chrome, может не очень хорошо выглядеть в например(!) firefox, и те же css приставки вида -webkit, -moz и прочие.
А, весь же процесс происходит на сервере, так, что от браузера не зависит. Конечно, немного придется поднастроить, что бы все было красиво.
Ну на сервере тоже можно обработать браузерным движком, и, наверняка так и происходит, что-то же его рисует и ставит по местам.
Браузерные движки, видимо, не используются. См., что поддерживается (внизу демки с перечнем того, что поддерживается).
Странно.
Хорошо, уточню: распространённые браузерные движки — gecko/webkit/KHTML/Hv3 и др. — в данном случае не используются, по данной мною ссылке документы, демонстрирующие, что именно поддерживается упомянутым скриптом mPDF.

С тем, что на сервере можно использовать gecko или webkit, я, разумеется, не спорю, речь именно об упомянутом скрипте.
по-моему там общераспространенные движки не при делах.
НЛО прилетело и опубликовало эту надпись здесь
Вот верный подход :) Даже по примерам PDFов на сайте видно что рендерер у них свой, на пхп. В код смотреть страшно :))
Как я понимаю себе этот механизм, html-страница разбирается либо XML-парсером вроде SimpleXML, либо вообще регулярными выражениями. Строится некоторое дерево команд в памяти. После чего эти команды передаются на некоторый класс Builder, который и строит в соответствии с ними по кирпичикам этот PDF.

PDF состоит из списков команд, по которым ридер и рисует сам документ

пример
%PDF-1.4
%РФЕШ
5 0 obj
>
endobj
8 0 obj
(\376\377\004\043\004\101\004\102\004\060\004\075\004\076\004\062\004\072\004\060\000\040\000F\000r\000e\000e\000B\000S\000D\000\040)
endobj
9 0 obj
>
endobj
12 0 obj
(\376\377\004\022\004\113\004\061\004\076\004\100\000\040\004\117\004\067\004\113\004\072\004\060)
endobj
13 0 obj
>
endobj

От версии к версии формат этих команд менялся…
НЛО прилетело и опубликовало эту надпись здесь
А как у него с фоновыми изображениями в элементах и возможность задания фона для каждого листа? Например, фирстиль.
Вы знаете, я честно говоря не пробовал :) — использовал в основном для бухгалтерских отчетов. Надо тестировать, скачайте дистрибутив, там очень много примеров.
угу, я уже прочитал, поддерживает только bg-color. Я пользовался его прародителем HTML2FPDF и это его больное место — нет бекграундов и не может(не мог) генерировать input[type=text], плохо с абсолютным позиционированием и иногда с float нестабилен был. но 2 года назад это все равно лучшее, что вообще удалось найти php-based.
Подтверждаю. Сам довольно продолжительное время пользовался этой библиотекой.
Сейчас, судя по всему, проект окончательно заглох, а жаль.
@page background-image in the form url(image.png) or url('image.png') supported.
Может Вы не так прочитали?
$mpdf->charset_in = 'cp1251';

А можно в UTF-8?
вот ответ на Ваш вопрос =)

A PHP class to generate PDF files from HTML with Unicode/UTF-8 and CJK support
Да, можно.
office.webproduction.com.ua:3000/projects/packages/repository/show/trunk/PDF
svn://svn.webproduction.com.ua/packages/trunk/PDF/ (read-only free)

UTF-8, понимает таблицы, вложенные таблицы, div-ы, почти весь css, img, img на фоне и т.д.
Пробовали формировать PDFку на 100+ страниц — только нужно памяти много (очень много).
На мой вкус, очень хорошее средство wkhtmltopdf. Рендерит как Webkit, вызывать можно из командной строки чем и как угодно.
Интересно как он картинки обрабатывает: для экрана достаточно 72/90dpi, а на печать от 300dpi. Собственно, можно ли там использовать картинки с высоким dpi или он все равно при отрисовки и сохранении в файл проставит 72dpi?
По моему опыту использования, он генерирует очень лёгкие pdf-ки и качество картинок неважное. Но, у него куча разных параметров, и один из них — "--disable-pdf-compression" — вроде бы, положительно влияет на качество.

Просто, у меня такой задачи не стояло. Предлагаю Вам попробовать самим.
Хорошая штука, жалко только что оно за собой весь xorg тащит.
вроде как статическая сборка с патченным qt не тащит
Видимо, не тащит. Но этот lzma у меня не распаковывается, пишет «SetDecoderProperties() error»
Да, mPDF — одна из лучших бесплатных библиотек для создания pdf-файлов.
Тестировал 5 подобных библиотек, из всех них mPDF оказалась самой функциональной, которая умеет преобразовывать html в pdf и при этом дружит с русским языком.
Да, тоже перепробовал очень много, остановился на этой.
вот вы бы поделились бы нормальным обзором. с плюсами и иминусами
>>вот вы бы поделились бы нормальным обзором.
ну может быть, когда-нибудь, как выйду из минусов :))))
tcpdf — тоже одна из лучших и развивающихся. и функционал не меньше. правда для русского прийдется немного повозится со шрифтами.
>>правда для русского прийдется немного повозится со шрифтами.

Вот именно, придется повозиться со шрифтами :)
Насколько я помню, для tcpdf их нужно было генерировать, т.е. еще дополнительно нужно было ставить библиотечки…

Для генерации инвойсов и прочих счетов с поддержкой русского языка из HTML-формата, mPDF — достаточно с головой. Поставил и «поехал», на лишние заморочки времени нет.
Спасибо за топик. Добавлю эту возможность в свой текущий проект, очень в тему:)
О, думаю тут собрались все pdf-мастера, внимание вопрос:
Когда у меня была чистенькая винда, я с дуру поставил FoxitReader и все браузеры стали ассоциировать открываемые pdf файлы именно с фокситом. Потом я поставил себе Adobe и удалил FoxitReader. После чего у меня при чтении pdf файла через браузер возникает ошибка «FoxitReaderOCX.ocx failed to load». Теперь приходится сохранять все pdf файлы на компьютер и смотреть с компа. О Хабралюди, услышьте меня, помогите мне, что нужно сделать чтобы мой FireFox ассоциировал открываемые pdf файлы с Adobe?
В накстройках же есть вкладка Applications, в ней и задаюстся программы по умолчанию.
У меня была такая же проблема.
Но, заходя на очередной варезный сайт и видя надпись «FoxitReaderOCX.ocx failed to load», я только радовался, потому что знал — еще один вирус прошёл мимо меня :)
PDFки, которые мне действительно нужны, я сохранял и смотрел ч.н. offline.
НЛО прилетело и опубликовало эту надпись здесь
«mPDF is a PHP class...»

Может стоит перенести топик в блог PHP?
Прошлая статья была в Web-разработке, вот я и эту сюда добавил.
Т.е. вам таки не свойственно учиться на своих ошибках?)
:) не статью ту не я писал, к сожалению, если вы про это.
Oops :) Ну всё равно, подумайте лишний раз о том, чтобы топик в соответствующий блог перенести. Спасибо!
>А можно в UTF-8?

Можно, mPDF — как раз отлично работает с русским utf, в отличие от остальных
А как там русским?
В комбинации со встроенной в хром pdf-смотрелкой теперь можно начинать делать сайты целиком на pdf :)
На самом деле ведь в pdf даже собственный javascript вшит, и «кроссбраузерно», и для форм есть удобнейшие вещи.
BTW: На счет dompdf я когда-то хотел написать статью, о том как нам сервер хакеры взломали… Взломали через dompdf, там дыра!
А у него есть возможность управлять «постраничностью» в html-тэгах? Или вообще как-нибудь?

А то есть задача: Выводить заголовок + таблица (накладная, счет, например). Вот и нужно, чтобы на каждой новой странице выводился ее номер, шапка, кол-во строк на листе, суммы и т.д.

Может данная либа с этим справиться? Сейчас у меня с этим справляется TCPFD, но она очень неповоротливая и PDF файлы слишком большие для примитивных отчетов получаются. И то не без шаманства.

Может кто пробовал? Поделитесь опытом?
А Вы не пробовали использовать pdflatex для этих целей? По-моему самое то, когда речь идет о документах с жесткими требованиями к оформлению. Я с помощью php обычно только шаблон для LateX генерирую, а потом скармливаю его pdflatex. На выходе — красивая pdf-ка с соблюдением всех требований к документации. Единственный минус — нужно разобраться в LaTeX'e, чтобы сделать каркас шаблона.
Да. Это интересная идея для базы, работающей на выделенном сервере. Но может не подойдет для интеграции в интернет-магазин, который размещается на шареде…

В любом случае спасибо за идею. Попробую.
CSS page-break-*?
Вы не искали альтернативы, чем они лучше-хуже?
Искал, все хорошие, все мощные, но вот с русским языком были проблемы, а тут все хорошо. Англоязычных программистов, видимо, не очень интересует наш великий и могучий.
Я помню, отчаявшись найти нормальные скрипты по сохранению документов в pdf и doc, мы нашли решение следующего плана:
— на сервере устанавливается OpenOffice & python
— из php-скрипта запускается команда на питоне, которая вызывает OpenOffice и сохраняет переданный html в выбранный нами формат.
Из минусов было только то, что конечный вид файла зависел от версии OO.
А как эта либа с большими данными работает? Требует много памяти?
Думаю, что прилично. Я просто на производительность их не тестировал. Использовал для проекта внутренней сети компании — там был отдельный сервер.
Два дня назад столкнулся с тем, что плагин на базе mPDF работает на сайте везде, кроме той страницы где он нужен, — руководство пользователя FreeNAS в 70+ страниц и больше сотни картинок. Не успевает отрендерить и отваливается по таймауту. Хостинг коллективный на «Инфобокс», таймаут для меня никто менять не будет, и остался я (вернее, читатели) без экспорта в PDF.
Можно попробовать, конечно, но думаю это и им в голову приходило. Например, по Ваше ссылке есть примечание о safe mode. А не это так другое придумают.

Все это похоже на изготовление самогона в коммунальной кухне с единственной плитой, — начать можно, но долго не протянешь.
Надо использовать правильный хостинг ;)

На спринтхосте мне удалось из под своего аккаунта даже redis установить (в домашнюю папку) и запустить )))

Такие мелочи, как set_time_limit тоже работают.

А вообще не думаю, что на хостинге PHP будет запущен в safe mode… Это слишком жестоко…
Посмотрите, что пишет php_info()…
Спасибо за совет, узнал новое (для меня PHP темный лес). Но вряд ли этим займусь сейчас: все-таки мой сайт это только хобби, да и экспорт в PDF не ключевая фича. У меня там есть экспорт в ODF, — как замена.

Насчет хостинга Вы, вероятно, правы. Единственное решение которое мне там предложили — переезд на VPS, с заметной для меня разницей в цене.
У меня была похожая проблема — отрендерить таблицу из 5к строк. Хостинг свой, поэтому таймаут я поменял, но по памяти не влезло, ему не хвататет даже 512 метров на процесс!
Что-то мне подсказывает, что PDF по-хорошему надо генерить с помощью сторонних утилит, а не средствами PHP.
У инфобокса на хостинге можно редактировать php.ini. Там можно задать свой таймаут и memory_limit. напишите в поддержку, они вам дадут доступ на редактирование.
Уже. И в тех.поддержку и сюда в их блог. Ответ одинаковый. Менять таймаут они не хотят.
Не-а. Черным по белому в заголовке написано: «Панграммы (из википедии)». Рекомендую заглянуть.
Да, будем знать.
Съешь ещё!
Зачем нужен этот закрытый формат? Как потом отредактировать этот pdf, добавит страницу, перевернуть?
Он рожден быть закрытым. ;) Идеей было — заменить бумажные документы. Оттуда и всякие фичи типа запрета на редактирование и «невозможности» копирования. За это его в бизнесе и любят.
А кто-нибудь мне может объяснить, зачем вообще нужна server-side генерация pdf из html?
Пусть юзеры сами ставят себе виртуальные принтеры и конвертируют что хотят в любых количествах.
Например, у нас в компании, это было сделано, для того, что бы пользователь смог ввести данные в форму и сформировать заявку, на предоставление/изменение доступа к какому либо ресурсу и. т. д.

А pdf потому, что филиалы находятся по всей стране, пользователей много (ИТ-специалистов мало), да и с принтерами, в удаленных уголках, иногда проблемы (работник может сохранить на флешку и распечатать на другом принтере). И выглядит pdf на всех компьютерах одинаково.
Invoices
Интересует возможность подписи созданных PDF'ok сертификатами. Никто не пробовал?
Было бы здорово. Но, наверно, это из области фантастики…
Спасибо. Когда-то искал нормальные библиотеки, не нашёл. Эта работает вполне прилично: news.sfu-kras.ru/pdf/7259
я, конечно, извиняюсь, но кто-нибудь догадался посмотреть исходник? 30 тысяч строк говнокода в одном файле. я такое даже тестировать не буду.
mPDF полностью убивает ссылки при слиянии нескольких pdf, что грустно.
Не поддерживает z-index.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации