Из html в pdf – легко! Обзор конвертеров

    Ежедневно в процессе деятельности регистратора REG.RU, в котором я работаю программистом, совершаются сотни операций, требующих оформления каких-либо официальных документов. Среди них — различные договоры, счета, сертификаты и т.п., которые необходимо печатать как компании, так и клиентам. Для таких целей хорошо подходит формат PDF, который на сегодняшний день стал де-факто основным для обмена и распространения документации. Основными преимуществами этого формата можно назвать: кроссплатформенность, аппаратную независимость и безопасность. Все вышеперечисленное позволило PDF завоевать популярность среди пользователей и стать одним из самых распространенных.

    Как можно создавать документы в формате PDF на лету, из скрипта? Для таких целей существуют различные инструменты. Одним из них является язык разметки LaTeX, позволяющий автоматизировать многие задачи по подготовке статей, включая набор текста на нескольких языках, нумерацию разделов и формул, перекрёстные ссылки, размещение иллюстраций и многие другие. Но у LaTeX есть одна очень серьезная проблема: у него очень крутая кривая обучения. Чтобы выучить его, требуется затратить много времени. И в LaTeX'е очень неудобно работать с таблицами. Потратив много времени на поиск наилучшего решения, я пришел к выводу, что проще всего конвертировать готовую HTML страницу в PDF и передать клиенту. Я сделал обзор программ, которые можно использовать для такой конвертации.

    Требования к конвертерам

    Основное внимание уделялось таким особенностям конвертеров как:
    • Простота настройки шрифтов
    • Вставка разрыва страницы
    • Безразличие к X серверу
    • Поддержка CSS
    Желательно, чтобы шрифты и кодировку можно было легко настроить. В идеале, конвертер должен сам распознавать используемую кодировку и шрифт. Чтобы нужные данные помещались на одной странице, а не расползались на две, пользователи делают разрыв на странице. Хотелось бы иметь возможность создавать разрывы простым способом — через CSS свойство. Конвертер должен быть независим от X Windows, поскольку работает на Web-сервере, который и без X Windows'a сильно загружен. Конечно же, можно использовать Xvfb, но это не подходящее решение. Для теста были сделаны две простые HTML-странички, прошедшие валидацию. Первая страница содержит разрыв, сделанный CSS свойством, вторая — содержит сложную таблицу с объединениями ячеек.

    Так странички отображаются в браузере:
    image

    image

    Обзор

    wkhtmltopdf. Наверное, самый популярный на сегодняшний день конвертер и, как оказалось, неспроста. Его основа — движок webkit: шрифты берет из системы, умеет делать разрывы страниц, а для работы нужны библиотечные файлы от X-сервера.
    Пример работы:
    image image image
    Как видно из примера, wkhtmltopdf хорошо справился. Все блоки на месте, присутствуют картинки, есть разрыв страницы.

    webkit2pdf. Аналог wkhtmltopdf. Ему нужен запущенный X-сервер. С результатами его работы можно ознакомиться чуть выше.

    pisa(xhtml2pdf). Конвертер написан на python, а, значит, независим от Х-сервера. Умеет делать разрывы, шрифты настраиваются в отдельном CSS файле, путь к которому передается через параметр. Однако, очень привередливый: в случае малейших ошибок или недочетов в HTML коде падает.
    Пример работы:
    image image
    Очень плохо: шрифт определил правильно, с разметкой не справился.

    html2pdf. Прост в обращении, шрифты берет из системы, умеет делать разрывы страниц. Для конвертации использует какую-то старую версию браузера Firefox. Но ему нужен запущенный X-сервер. Помимо этого, может заглючить и отказаться работать. Платный.
    Пример работы:
    image image image
    Кроме подвала на второй странице, все блоки и картинки на месте.

    htmldoc. Простой конвертер без наворотов.
    Пример работы:
    image image
    Не понимает CSS.

    html2ps, ps2pdf. По характеристикам похож на htmldoc.
    Пример работы:
    image image

    prince. Платный конвертер, стоит недешево. Использует системные шрифты, умеет делать разрывы, безразличен к X-серверу.
    Пример работы:
    image image image
    Все съехало, проблемы с позиционированием.

    Результаты в виде таблицы
    Наименование Способ настройки шрифтов Поддержка разрывов страниц Независимость от X-сервера Поддержка CSS Бесплатный
    wkhtmltopdf Использует системные + + + +
    webkit2pdf Использует системные + - + +
    html2pdf Использует системные + - + -
    htmldoc Задаются через параметры - + - +
    pisa(xhtml2pdf) Нужно указывать пути к шрифтам в CSS файле + + + +
    Связка html2ps, ps2pdf ? - + - +
    prince Использует системные + + + -
    Выводы

    Как оказалось, с задачами конвертации лучше справились бесплатные конвертеры. Если нужно конвертировать страничку с большим объемом графики, фреймов и javascript, то лучше использовать конвертеры, основанные на webkit. Если же страничка с минимальным количеством HTML-элементов, то со своей задачей хорошо справится htmldoc.

    Примечание

    Обзор по PHP конвертерам можно почитать тут. А тут можно почитать обзор по online конвертерам.

    UPD: Отключите ваш блокиратор рекламы если картинки не видны.
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 24

      0
      Хороший обзор, благодарю!

      Часом, в процессе работы вам не приходилось конвертировать в PDF страницы с SVG-графикой? Интересно, как справляется с ней wkhtmltopdf.
        +1
        К сожалению не приходилось.
          +2
          к счастью…
          +1
          Справляется ок. единственный недочет — если в графике на странице есть прозачности (как я понял, этот баг не только к svg относится), на этой странице портятся шрифты в акробат ридере. В остальном же, график, нарисованный с помощью Raphaël никаких сюрпризов не подсунул.
            0
            Спасибо! Запишем еще один плюс Raphael!
          0
          а вот устроить конвертацию из pdf в html, если там есть таблицы ух как не просто
            +1
            Пользовался на нескольких проектах DomPDF, очень удобная штука, странно, что автор не включил ее в обзор
              +8
              Перезагрузите картинки на habrastorage.org/, будут отображаться у всех, заодно от удаления на внешнем сайте защитите.
                +1
                Спасибо, полезный обзор!
                  0
                  Хм… странно почему одни сайты wkhtmltopdf корректно генерит, а другие криво? с учетом того что верстка выглядит везде одинаково в браузерах… в некоторых случаях просто некоторые дивы не воспринимает
                    0
                    Некоторые сайты проверяют, кто запрашивает страницу и изменяют ее под клиента. То есть, смотрять User Agent, параметры броузера (размер экрана и тд).

                    Есть сайты, которые пытаются сохранить куку, и если она не принимается — выводят какой-нить рекламный блок (например, fishki.net)

                    Бывают проблемы, если на сайте используется java приложение, или еще какая сложная штука. Flash вообще больное место.

                    Но в целом, лично я wkhtmltopdf очень доволен, 95% страниц обрабатываются без проблем.
                      0
                      Если есть большой интерес, могу вывести где то около 500-600 скриншотов сайтов, со ссылками.

                      Посравниваете сами =)
                    0
                    а где картинки?
                      +1
                      Адблок их не признал)
                      +2
                      Использую php-класс mPDF как раз для подобной задачи. Не без напильника, но позволяет создать html-разметку для различного рода отчётов, бланков и т.д.

                      Поддерживает и html, и css. Ограниченно, но поддерживает.
                        0
                        Его единственный минус — это требовательность к ресурсам, как следствие — время генерации. Мне приходится генерировать документы по 100+ страниц с различными таблицами и время генерации составляет около 1 минуты на документ.
                        0
                        Я бы добавил ещё критериев:
                        — хедеры/футеры и номера страниц
                        — разделы с разными полями (не так, чтобы поля указаны в настройках на весь документ и всё тут)
                        — нестандартные шрифты с Unicode (часто бывает нужен фирменный шрифт)
                        — нормальная разбивка таблицы на несколько страниц, форматирование таблиц (рамки, цвета)
                        — нормальное позиционирование картинок (по скринам в статье видно, что тут не у всех гладко, а это может быть важно)

                        И может какой-то умеет экспортировать в RTF заодно?
                          +1
                          Всё вами перечисленное умеет делать MPDF
                          +2
                          Тоже мучался с такой же проблемой, каждый с разнообразными косяками, поэтому приходилось выбирать из наименьшего зла ;) для себя остановился на mPDF — он по-моему единственный умеет нормально делить таблицы на несколько страниц, чтобы заголовок таблицы дублировался на каждой и ячейку посередине не разрывало.
                          Ещё можно просмотреть TCPDF, dompdf — тоже довольно неплохие, но под мои задачи меньше подошли.

                          А вот поддержку widows и orphans (висящие строки в начале и в конце абзаца) вообще ни нашёл кто умеет, поэтому получается очень часто что в начале страницы остаётся одна строка с парой слов из предыдущего абзаца ;( Как это побороть не знаю, если у кого есть идеи — сообщайте, буду премного благодарен!
                            0
                            При отдаче генерируемого контента в PDF в рельсах использую prawn. Рекомендую, отличный инструмент!
                            0
                            Где в обзоре DocRaptor?

                            docraptor.com/
                              0
                              Пользуюсь xml2pdf www.alt-soft.com/Products_html2pdf.aspx, требует только .Net framework (ну или Mono, тоже работает)
                                0
                                Мы использовали pdf4b.ru, в массе получили оптимальный результат, но это сервис с API, а не либа

                                Only users with full accounts can post comments. Log in, please.