Пользователь
0,0
рейтинг
16 января 2011 в 23:54

Разработка → HTML в PDF

PHP*
html to pdf

В далеком 2008 году уже была написана подобная статья и я попытался применить знания, но, к сожалению, не справился с русским языком (на denwer-е работал, на хостинге нет). Возможно сказалось отсутствие опыта. А недавно нашел хорошую библиотеку и решил поделиться. Топик, скорее всего, адресован начинающим программистом и ни на, что не претендует.

Для начала поставим задачу:


  1. Процесс конвертации должен быть простым — минимум кода;
  2. Отображать русский язык «из коробки»;
  3. Понимать html теги, изображения, CSS;
  4. Использовать бесплатную и хорошо документированную библиотеку.

Вводные данные


Сам процесс на столько прост, что принципиальной разницы в каком фреймворке его использовать нет. Конвертировать данные из HTML в PDF будем с помощью mPDF.

Реализация


Скачиваем и распаковываем в корневую директорию последнюю версию mPDF. Там же создадим файл index.php и добавим следующий код:
<?php
$html = '<table_ border="1"><tr_><td_>Пример 1</td_><td_>Пример 2</td_><td_>Пример 3</td_><td_>Пример 4</td_></tr_>
<tr_><td_>Пример 5</td_><td_>Пример 6</td_><td_>Пример 7</td_><td_><a_ href="http://mpdf.bpm1.com/" title="mPDF">mPDF</a_></td_></tr_></table_>';

include("mpdf50/mpdf.php");

$mpdf = new mPDF('utf-8', 'A4', '8', '', 10, 10, 7, 7, 10, 10); /*задаем формат, отступы и.т.д.*/
$mpdf->charset_in = 'cp1251'; /*не забываем про русский*/

$stylesheet = file_get_contents('style.css'); /*подключаем css*/
$mpdf->WriteHTML($stylesheet, 1);

$mpdf->list_indent_first_level = 0;
$mpdf->WriteHTML($html, 2); /*формируем pdf*/
$mpdf->Output('mpdf.pdf', 'I');
?>


Код css-файла:
table {text-align: center;font-size: 20pt;width: 100%;}

Работу библиотеки можно проверить на официальном сайте. Или, к примеру, сформировать вышеописанный пример.

Вот и все. Спасибо.

P.S.: Огромное спасибо хаброюзерам: rachiu, Zorkus, FeNUMe, Atrax, AusTiN за поддержку и человеческое отношение к новичкам.
Anton @antonick
карма
24,7
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

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

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

                С тем, что на сервере можно использовать gecko или webkit, я, разумеется, не спорю, речь именно об упомянутом скрипте.
    • +1
      по-моему там общераспространенные движки не при делах.
    • НЛО прилетело и опубликовало эту надпись здесь
      • +1
        Вот верный подход :) Даже по примерам PDFов на сайте видно что рендерер у них свой, на пхп. В код смотреть страшно :))
    • +3
      Как я понимаю себе этот механизм, 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

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

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

      A PHP class to generate PDF files from HTML with Unicode/UTF-8 and CJK support
    • 0
      Да, можно.
  • +2
    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+ страниц — только нужно памяти много (очень много).
  • +12
    На мой вкус, очень хорошее средство wkhtmltopdf. Рендерит как Webkit, вызывать можно из командной строки чем и как угодно.
    • 0
      Интересно как он картинки обрабатывает: для экрана достаточно 72/90dpi, а на печать от 300dpi. Собственно, можно ли там использовать картинки с высоким dpi или он все равно при отрисовки и сохранении в файл проставит 72dpi?
      • 0
        По моему опыту использования, он генерирует очень лёгкие pdf-ки и качество картинок неважное. Но, у него куча разных параметров, и один из них — "--disable-pdf-compression" — вроде бы, положительно влияет на качество.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.