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

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

Это враппер к утилите wkhtmlto*. Сам инструмент — это консольные приложения.
изначально корректно работающей с кириллицей

Не думал, что в мире UTF-8 для кого-то это до сих пор проблема.
Вы удивитесь, но проблем с кодировками по прежнему много, тяжкое наследие так сказать.
При работе с FPDF и подобными библиотеками приходилось конвертировать русские ttf-шрифты в удобный ей формат, чтобы кириллица заработала в принципе. В MPDF это уже было сделано изначально.
Программа принимает html-код (в виде веб-адреса, пути к файлу либо строки кода) и генерирует на его основе php-файл на сервере.
может PDF?
1. Эмуляцией браузера по прайслисту… А пробовали не на пустой машине, а на VDS запустить? Вы же понимаете, что практически браузер запускаете?
2. Держать прайс на несколько тысяч позиций в переменной — это план победы. Когда он станет под миллион позиций — что делать будете?
3. Имея прайс текстом в одной переменной были проблемы с переводом его в UTF-8? Т.е. функция iconv на переменную не?
4. Вы вот так прямо «запрос-ответ» генерируете нечто большое? А если связь отвалится — будете перегенерировать? Кормите девопсов, которые потом будут предлагать вам облака для решения несуществующей проблемы? :) Не, я тоже генерю иногда на лету, но на 5-6 страничек, которые мне не жалко перегенерить.
5. Кстати, а как прайс становится HTML? Т.е. Вы ещё готовите специальный HTML, который можно превратить в читаемый прайс, коий HTML явно надо делать отдельно от того, что людям показывается. Ну т.е. в каких-то частных случаях этим действительно можно пренебречь, но… Изучаете конвертилку из HTML в PDF, включая шаблоны и вот всякие ключи… Чую бесовщину, обосновать не могу.
6. А LaTeX не? Пакет texmf сейчас вполне развит, даже TTF туда впихивается за милу душу. Генерация текста/таблиц может быть автоматизирована по самое небалуйся. Причем, если без изысков, то и изучать ничего изыскового не надо. Там сразу Вам и разбиение таблиц по страницам, и игра с текстом, и нумерация без явапрограмминга, и в общем чёрт в ступе. Два дня покурить над самим LaTeX, и потом всё делается быстрее, чем HTML-шаблоны.
Мы решали задачи конвертации прайса с тысячами позиций. Миллиона там не предполагалось. Будет миллион — будем генерировать в фоне, задействуем LaTeX. На VDS кстати еще быстрее, чем на пустой машине, работает.
Есть два варианта печатной формы прайс-листа: HTML и PDF. Обе показываем людям, кому в чем удобнее, в том и смотрят. PDF-версия фактически формируется из шаблона для HTML-версии. Соответственно, быстрее тиражируются изменения шаблона, если они требуются.
Я длительное время использовал MPDF, но он медленный, поэтому изучал альтернативы, тестировал разные варианты. Ещё один интересный сопособ: рендрить с помощью Node и PhantomJS: www.npmjs.com/package/phantomjs-pdf

Но я в итоге остановился на wkhtmltopdf. Расскажу свой опыт.

Во-первых, есть готовая обёртка на PHP: github.com/mikehaertl/phpwkhtmltopdf (сам ей не пользуюсь, у меня простая задача, все аргументы зафиксированы, нет смысла в этой обёртке)

Во-вторых, генерировать временный html файл на диске не обязательно, wkhtmltopdf умеет принимать исходный html через stdin, если указать параметр "-" (прочерк). На PHP получается как-то так:
$descriptorspec = [
    0 => ['pipe', 'r']; //stdin
    1 => ['pipe', 'w']; //stdout
    2 => ['pipe', 'w']; //stderr
];

//Обратите внимание на аргументы, которые я передаю при запуске wkthmltopdf 
//--disable-smart-shrinking без этого аргумента, всё становится каких-то не правильных пропорций
//--dpi 96 если принудительно не поставить dpi, то размеры указанные в css в милиметрах на печати будут совсем не такими!
//- последний аргумент это прочерк, чтобы передать html через stdin
//bypass_shell (только для Windows): при установке в TRUE процесс будет запущен в обход оболочки cmd.exe
//это нужно для обхода бага https://bugs.php.net/bug.php?id=60181 "proc_open fails to read quoted whitespaced directories in Windows"
$process = proc_open("/path/to/wkthmltopdf --disable-smart-shrinking --margin-left 20mm --dpi 96 -", $descriptorspec, $pipes, null, null, ['bypass_shell' => true]);

if (is_resource($process)) {
    
    //Пишем в stdin html контейнт
    fwrite($pipes[0], $html);
    fclose($pipes[0]);

    //Читаем результаты и ошибки, если они вам нужны в приложении
    $stdOut = stream_get_contents($pipes[1]);
    $stdErr = stream_get_contents($pipes[2]);
    fclose($pipes[1]);
    fclose($pipes[2]);

    $exitCode= proc_close($process);

}


Более подробно про разные параметры принимаемые wkthmltopdf рекомендую почитать здесь: wkhtmltopdf.org/usage/wkhtmltopdf.txt

Да, если нужен header-html и footer-html, то пара временных html файлов на диске всё-таки понадобится.

В третьих, на Linux машинах есть неприятный баг, что шрифты выглядят меньше, чем при печати в PDF этого же html файла с помощью браузера: github.com/wkhtmltopdf/wkhtmltopdf/issues/2171
По этому багу, в том числе, есть много обсуждений на StackOverflow, но фикса в ближайшее время не предвидится, предлагается workaround: github.com/wkhtmltopdf/wkhtmltopdf/issues/2171#issuecomment-139164039

Но я использую другой подход: есть отдельный windows сервер, на котором запускается wkthmltopdf, а обращение идёт к нему через простенький самописный веб-сервис: принимает html контент в POST и возвращает готовый PDF — так и живём.

Вообще по wkhtmltopdf активность на github почти нулевая, баги не фиксятся, но ничего лучше пока не нашел. Кто знает C++ — присоединяйтесь к проекту, внесите свой вклад в opensource!

Есть ещё www.princexml.com — но он платный и жутко дорогой!
Главная проблема wkhtmltopdf — старый webkit, большая часть багов связана именно с этим. ветка 0.12 основана на 4-ом QT и соответственно довольно древней версии webkit. Ветка 0.13 же основана на Qt 5.4 и, если удалось собрать и оно не крэшнулось, то там все получше.

Веселье в ном что альтернативы нет, можно пробовать запустить хром скажем и распечатать страницу через селениум какой, но это извращение то еще. Штуки же типа phantomjs (сейчас вышла вторая версия, использующая Qt 5.4) используют для генерации скриншетов и рендринга PDF код wkhtmltopdf, так что всеравно придется ждать.

принимает html контент в POST и возвращает готовый PDF — так и живём.

Вариант с windows сервер худо-бедно живой, если у вас он есть. Вот только кастыли с RPC можно было бы заменить на какой-нибудь MQ, например RabbitMQ
А смысл в этих телодвижениях, если есть вполне живой LaTeX? Там тоже есть какие-то баги и всё такое, но вот туда бы как раз влить усилия.
смысл в html с css3 с поддержкой svg — так генерируем бейджи для печати со штрихкодами.
А зачем? Он не предназначен для этого ) Сколько я не пытался шаблонизировать для PDF, какими только библиотеками — один фиг изучаешь особенности конкретного рендера. А смысл? Для того же LaTeX есть просто шаблон для штрихкодов. И делается это проще. И хорошо когда одна страница и не надо программировать в HTML многостраничность таблицы например. И опять же — HTML это немного не типографская штука…
Что то не понял) Вы про вынесение временных файлов на диск перед сборкой? В нашем случае мы выносим. Проблем с бейджами, делениями на листы для двухсторонней печати (бейдж на другой скан паспорта) на принтере нет. php ->html->wkhtmltopdf->pdf все гладко и относительно удобно. Штрихи генерятся на php в svg. Уж зачем Latex нужен вот не пойму :-) Помоему это шаг назад.
Удобнее wkhtmltopdf ничего и нет, увы.
Зачем как шаблон использовать HTML? В чём смысл? Опять же. Если это одноразовая задача — не вопрос, смысл ясен. Но если нет, то зачем? LaTeX шаг назад? :) Тогда UTF-8 тоже. Его придумали два стрика для своего недоюникса в самом начале 90-ых, который так и не выстрелил. И /procfs кстати тоже. Про HTML, который ножницами вырезали из IBM SGML 70-ых я и вообще молчу :) И про PDF, который есть расширенная версия PS, который где-то в районе 80-ых застрял, ктсати тоже :) LaTeX вполне жив в различных видах, развивается и до сих пор вполне используется для различной верстки. Имеет кучу всяких шаблонов и расширений, вполне вменяемых. Изначально служил и служит для автоматизации создания книг, брошюр, листовок и всё такое. Прямо вот для него работа. Там сложно начать, но при этом он прост. Для половины задач есть готовые решения. Усложнения задач проходят мягко и хорошо. Рендеринг однозначный, в отличии от. Не требует подпорок для большинства задач. Иногда надо поднапрячься, чтобы придумать как верно на нем что-то сделать, но это делается, как я уже говорил — без подпорок.
потому html везде в вебраработке и бейджики на нем сделать не проблема. Latex шаг назад в вебразработке в скорости изменения макета. Конечно, на LaTeX много кто верстает без проблем, но для бейджиков прикручивать его ну уж совсем лищнее коли на wkhtmltopdf все устраивает. Тут все просто — если все устраивает то оно отлично: -)
Если задачи будут куда сложнее, то LaTeX можно рассматривать.
Ну я ранее вроде сказал, что если только бэджик, или там бэджик, счет и акт — то фиг с ним. Но попробуйте просто для себя (из любопытства) заморочиться — я Вас уверяю, там изменение макета будет намного быстрее, чем типогравская подгонка XML-подобного языка :) Не обязательно кстати даже ставить ПО — есть какое-то количество онлайн-сервисов редактирования. Там принцип в два окна — в левом пишешь, в правом показывается итоговый pdf. Понравится — поставите ПО уже себе для автоматизации.
Однако, у топикастера немного другая проблема и он там бегает вокруг листа с подпорками и свистелками. И вот ему бы как раз и заморочиться.
Пример интересный.
Из всего, что пробовали, wkhtmltopdf самая быстрая и корректная утилита. А header-html и footer-html нужны, там элементы фирменного бланка с графикой.
Пару лет уже не генерировал длинные таблицы через wkhtmltopdf, но раньше был баг с разрезанием ячеек и текста в них, если таблица занимала несколько страниц. Насколько я помню, css для переноса на другой лист wkhtmltopdf не понимал.
Наверно это. как уже выше сказали, из-за того, что движок внутри старый используется.
Может кто-то знает исправлено это сейчас или нет? Столкнулся с такой же проблемой в dompdf (таблицы с colspan rospan), все воркараунды некрасивые
Пока не исправлено, ячейки режутся неровно. Где это критично и размер ячейки предсказуем, вынуждены предварительно разбивать таблицу на несколько таблиц, по числу страниц. Где некритично — оставляем как есть.
exec($cd); — это пять. Можете смело удалять данную строку, она ничего не делает.
Согласен, в этом примере эта команда лишняя.
Отличная программа.
Сделал граф. обёртку на коленке:
https://yadi.sk/d/QfcP4VGvuY3Z2
Если шо не так, пишите
Меня попрекнули за эту прогу, но сейчас дам ссылку.
Все работает, только момент --encoding непонятно, как работает, у пары сайтов не нашел или кодировку или шрифт.
Вот, последний релиз:
https://yadi.sk/d/lJPGEPvtuYCvY
По дефолту используется флаг -n — отключить жабу
Запуск проверен на xpюше 32бита и 7 64 бита
Попрекнули за то, что делаете бесполезную вещь, выкладывая код через файлообменник.
Все эти ссылки дохнут и вот пример того что даже за сутки вы файл зарубили. Получается комментарий только засоряет.
Используйте это https://gist.github.com/
все же уже готово)) а главное удобно для поддержки и шаринга и комментинга. Идеально ж. Какой к черту яндекс диск)
Сорри, я не профессиональный разработчик и не знаю всех совр. средств.
Про гитхаб, конечно, слышал… но, согласитесь, я имею полное право выложить туда, куда сочту нужным.
конечно имеете, тока оно померло в течение дня) а другие в свою очередь имеют то что тоже считают нужным) А на гисте не помрет)
Может быть, когда-нибудь освою.
Прога слишком уж простая.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации