У вас включен AdBlock или иной блокировщик рекламы.

Пожалуйста, отключите его, доход от рекламы помогает развитию сайта и появлению новых статей.

Спасибо за понимание.

В другой раз
DevGang блог о програмировании
Авторизоваться

Создание PDF-файлов с помощью CakePHP

Для генерации PDF-файлов посредством CakePHP, рекомендуется использовать плагин CakePdf.

При его помощи довольно просто сгенерировать PDF из HTML, преобразовывать в файлы для загрузки, е-mail и т.д.

Установка

Во-первых, нужно решить какой движок вы будете использовать.

WkHtmlToPdf самая быстрая утилита, однако все будет зависеть от интерфейса командной строки (CLI) и правильной установки бинарных файлов. На разных операционных системах она будет работать по-разному, а может и вообще не работать.

При использовании исполняемых файлов в UNIX и Windows, проблем быть не должно.

Нужно просто скачать exe-файл для вашей системы тут

Далее подключите его в настройке конфигурации CakePdf:

Configure::write('CakePdf.binary', YOUR_PATH_TO . 'wkhtmltopdf\wkhtmltopdf.exe');

Если предварительно скомпилированные файлы для UNIX все же не работают, и команда apt-get install wkhtmltopdf не помогает, то вам необходимо скомпилировать их вручную.

Не забудьте также изменить путь к файлу, если он установлен не по умолчанию

Configure::write('CakePdf.binary', YOUR_PATH_TO . 'wkhtmltopdf/bin/wkhtmltopdf');

Обычно я выбираю библиотеку DomPdf, так как она достаточно надежная. И несмотря на то, что код PHP более медленный чем нативный подход, она работает со всеми операционными системами и настройками без необходимости установки дополнительных зависимостей. Если для вас действительно важна скорость, тогда вам следует пересмотреть вопрос использования внутренних библиотек сервера. Но для меня, генерация счет-фактур и прочего, не является критической по времени и обычно выполняется асинхронно в фоновом режиме через оболочки.

В DomPdf есть важный параметр "enable remote", если в PDF-файлах используются изображения.

define('DOMPDF_ENABLE_REMOTE', true);

Для CakePdf не забудьте данную часть настроек, она может выглядеть таким образом:

$config['CakePdf'] = array(
	'engine' => 'CakePdf.DomPdf',
	'options' => ...,
	'margin' => ...,
	'orientation' => 'portrait',
);

Посмотрите официальную документацию там есть все, что нужно знать по части установки.

Дополнительная настройка

Рекомендуемым способом является использование настройки CakePlugin::load('CakePdf', array('bootstrap' => true, 'routes' => true)); которая должна будет автоматически переключать классы просмотра.

Если вы не хотите, чтобы плагин загружал bootstrap/routes и предпочитаете делать это вручную, вам необходимо самостоятельно указать все ссылки с расширением .pdf до CakePdf плагина PdfView.

public $components = array(
	'RequestHandler' => array(
		'viewClassMap' => array('pdf' => 'CakePdf.Pdf')
	)
);

Также это полезно если вам нужно перезаписать/расширить PdfView класс, по какой-либо причине

Пропустить файлы маршрутизации плагина практично, если настройки расширений уже установлены в ваших маршрутах.

Router::parseExtensions();
Router::setExtensions(array('json', 'xml', 'rss', 'pdf')); // We just add pdf to the already defined ones

В таком случае вы можете просто обновить конфигурацию  APP/Config/routes.php:

Применение

В официальной документации уже все точно определено, поэтому я не буду рассматривать все детально. Краткий пример:

public function view($id) {
	$this->pdfConfig = array(
		'filename' => 'invoice',
		'download' => (bool)$this->request->query('download')
	);
	$invoice = $this->Invoice->find('first', array('conditions' => array('id' => $id)));
	$this->set(compact('invoice');
}

Если вы используете мой Tools плагин, можете просто применить $invoice = $this->Invoice->get($id).

Убедитесь в том, что у вас есть базовый PDF макет в /View/Layouts/pdf/default.ctp и шаблон представления для PDF в /View/Invoices/pdf/view.ctp.

Если вы предоставите доступ без расширения (/invoices/view/1), операция будет в состоянии отобразить обычную HTML-страницу со счетом-фактурой в табличной форме.

Если вы подключаете с расширением /invoices/view/1.pdf, то он автоматически переключит класс представления в PdfView и отобразит его в виде PDF-файла:

$this->Html->link('View PDF', array(
		'action' => 'view', $id, 'ext' => 'pdf'
));

Обратите внимание на хитрость с download , используя для этого строку запроса. Если подключаться с помощью ?download=1 произойдет загрузка файла, вместо простого отображения.

$this->Html->link('Download PDF', array(
		'action' => 'view', $id, 'ext' => 'pdf', '?' => array('download' => 1)
));

Рекомендации

URL-ссылки и пути

Для того чтобы все движки работали с вашими URL-ссылками и изображениями, выводимыми вспомогательными приложениями и, следовательно, с неструктурированными абсолютными URL-адресами (/controller/action/ и /img/foo.jpg), это небольшое изменение будет весьма полезным в вашем AppHelper:

/**
 * Overwrite to make URLs absolute for PDF content.
 *
 * @param mixed $url
 * @param bool $full
 * @return string
 */
public function url($url = null, $full = false) {
	if (!empty($this->request->params['ext']) && $this->request->params['ext'] === 'pdf') {
		$full = true;
	}
	return parent::url($url, $full);
}
/**
 * Overwrite to make paths for assets absolute so they can be found by the PDF engine.
 *
 * @param string $path
 * @param array $options
 * @return string
 */
public function assetUrl($path, $options = array()) {
	if (!empty($this->request->params['ext']) && $this->request->params['ext'] === 'pdf') {
			$options['fullBase'] = true;
	}
	return parent::assetUrl($path, $options);
}

Таким образом они станут абсолютными, полностью включая основу (схема+домен) в контексте PDF.

#PHP #CakePHP
Присоеденяйся в тусовку

Будь всегдя вкурсе новостей из мира IT