Не совсем ответ, но на вопрос выше, но я постараюсь рассказать о своем опыте, может быть, он поможет кому-нибудь где-нибудь в будущем.
wkthmltopdf - это действительно ЕДИНСТВЕННОЕ решение , которое сработало для меня и может дать то, что я называю приемлемыми результатами.Тем не менее, некоторые незначительные изменения в CSS должны были быть сделаны, однако, он работал очень хорошо, когда дело доходит до рендеринга контента.Все остальные пакеты действительно подходят только в том случае, если у вас достаточно простой документ с одной базовой таблицей и т. Д. Нет возможности получить их для получения достоверных результатов по сложным документам с элементами дизайна, CSS, несколькими перекрывающимися изображениями и т. Д. Если в игре используются сложные документы- не тратьте время (как я) - иди прямо к wkhtmltopdf .
Осторожно - установка wkhtmltopdf сложна .Мне было не так легко, как ребята сказали в своих комментариях (одна из причин может заключаться в том, что я не слишком знаком с Linux).Статический двоичный файл не работал для меня по какой-то причине, которую я не могу объяснить.Я подозреваю, что были проблемы с версией - очевидно, есть разница между версиями для разных ОС и процессоров, возможно, у меня версия vrong.Для установки нестатической версии, прежде всего, вам нужен root-доступ к серверу, это очевидно. Я установил его с apt-get
, используя PuTTy , прошло довольно хорошо.Мне повезло, что мой сервер уже имел все предрасположенности для установки wkhtmltopdf.Так что это было легко для меня :) (кстати, вам не нужно заботиться о символических ссылках или обёртках, как говорят многие уроки - я потратил часы, пытаясь понять, как выполнить эту часть, в конце концов, я дал ееи все работает хорошо, хотя)
После установки я получил довольно известную ошибку Cannot connect to X server
.Это связано с тем, что нам нужно запустить wkhtmltopdf без заголовка на «виртуальном» x сервере .Обойти это было также довольно просто (если не заботиться о символических ссылках). Я установил его с apt-get install xvfb
.Это также прошло довольно хорошо для меня, никаких проблем.
После завершения я смог запустить wkhtmltopdf
.Осторожно - мне потребовалось некоторое время, чтобы понять, что попытка запустить xvfb
была неправильным путем - вместо вы должны запустить xvfb-run
.Мой PHP-код теперь выглядит следующим образом exec("xvfb-run wkhtmltopdf --margin-left 16 /data/web/domain.com/source.html /data/web/domain.com/target.pdf");
(обратите внимание на параметр командной строки --margin-left 16
для wkhtmltopdf
- он делает мой контент более центрированным; я оставил его на месте, чтобы продемонстрировать, как можно использовать параметры командной строки).
Я также хотел защитить сгенерированные файлы PDF от редактирования (в моем случае, защита печати также возможна).После некоторого исследования я обнаружил этот класс из ID Security Suite .Прежде всего я должен сказать - ЭТО СТАРЫЙ (я использую PHP 5+).Тем не менее, я сделал некоторые улучшения в нем.Прежде всего - это оболочка для FPDF библиотеки , поэтому в пакете есть файл fpdf.php.Я заменил этот файл из последней версии FPDF, которую я получил отсюда .Это сделало мои предупреждения PHP более устойчивыми.Я также изменил $pdf =& new FPDI_Protection();
и удалил знак &
, поскольку получал устаревшее предупреждение для него.Тем не менее, это еще не все.Вместо того, чтобы искать и изменять код, я просто включил сообщение об ошибке lvl в 0 с помощью error_reporting(0);
(хотя отключения только предупреждений должно быть достаточно).Теперь кто-то скажет, что это не «хорошая практика».Я использую весь этот материал во внутренней системе, поэтому мне не нужно беспокоиться.Конечно, сценарии могут быть изменены в соответствии с последними требованиями.Для меня я не хотел тратить другие часы, работая над этим. Будьте осторожны, когда в сценарии написано $pdf->SetProtection(array('print'), '', $password);
(я разрешил печатать свои документы, как вы можете видеть).Мне потребовалось некоторое время, чтобы понять, что первый аргумент - это права доступа . секунда - ПАРОЛЬ ПОЛЬЗОВАТЕЛЯ - если вы укажете это, то для открытия документов потребуется пароль (я оставил это поле пустым). Третий - ПАРОЛЬ ВЛАДЕЛЬЦА - это то, что вам нужно, чтобы документы были "защищены" от редактирования, копирования и т. Д.
Весь мой код теперь выглядит так:
// get the HTML content of the file we want to convert
$invoice = file_get_contents("http://www.domain.com/index.php?s=invoices-print&invoice_no=".$_GET['invoice_no'];
// replace the CSS style from a print version to a specially modified PDF version
$invoice = str_replace('href="design/css/base.print.css"','href="design/css/base.pdf.css"',$invoice);
// write the modified file to disk
file_put_contents("docs/invoices/tmp/".$_GET['invoice_no'].".html", $invoice);
// do the PDF magic
exec("xvfb-run wkhtmltopdf --margin-left 16 /data/web/domain.com/web/docs/invoices/tmp/".$_GET['invoice_no'].".html /data/web/domain.com/web/docs/invoices/".$_GET['invoice_no'].".pdf");
// delete the temporary HTML data - we don't need that anymore since our PDF is created
unlink("docs/invoices/tmp/".$_GET['invoice_no'].".html");
// workaround the warnings
error_reporting(0);
// script from ID Security Suite
function pdfEncrypt ($origFile, $password, $destFile){
require_once('libraries/fpdf/FPDI_Protection.php');
$pdf = new FPDI_Protection();
$pdf->FPDF('P', 'in');
//Calculate the number of pages from the original document.
$pagecount = $pdf->setSourceFile($origFile);
//Copy all pages from the old unprotected pdf in the new one.
for ($loop = 1; $loop <= $pagecount; $loop++) {
$tplidx = $pdf->importPage($loop);
$pdf->addPage();
$pdf->useTemplate($tplidx);
}
//Protect the new pdf file, and allow no printing, copy, etc. and
//leave only reading allowed.
$pdf->SetProtection(array('print'), '', $password);
$pdf->Output($destFile, 'F');
return $destFile;
}
//Password for the PDF file (I suggest using the email adress of the purchaser).
$password = md5(date("Ymd")).md5(date("Ymd"));
//Name of the original file (unprotected).
$origFile = "docs/invoices/".$_GET['invoice_no'].".pdf";
//Name of the destination file (password protected and printing rights removed).
$destFile = "docs/invoices/".$_GET['invoice_no'].".pdf";
//Encrypt the book and create the protected file.
pdfEncrypt($origFile, $password, $destFile );
Надеюсь, это поможет кому-то сэкономить время в будущем.Все это решение заняло у меня около 12 часов для внедрения в нашу систему выставления счетов.Если бы информация о wkhtmltopdf
была лучше для таких пользователей, как я, которые не слишком знакомы с Linux / UNIX, я мог бы сэкономить некоторые часы, потраченные на это.
Однако - то, что не убивает, делает тебя сильнее :) Так что теперь я немного лучше, когда я сделал этот забег:)