Телеграм: @bazarow_ru Почта: mihail@bazarow.ru

Создать pdf файл из элемента инфоблока, дать скачать пользователю, поддерживать в актуальном состоянии или отправить на e-mail.

Просмотров: 5362

Задача: при каждом посещении статьи, на сайте, нужно создавать pdf файл с ее содержимым и записывать в свойство инфоблока.

Сконвертировать HTML в PDF файл и сохранить:

Для начала, нам нужно просто сгенерировать pdf файл и сохранить. Сделать это можно несколькими способами, но при всех нужно использовать дополнительные библиотеки. Я буду использовать DOMPDF так как, с помощью него можно как угодно сверстать pdf файл, используя обычный html.

Так же, можете обратить внимание на библиотеку FPDF- класс PHP, который позволяет создавать файлы PDF на чистом PHP, то есть без использования библиотеки PDFlib.

Pdf файл будем создавать из текста статьи. В детальном шаблоне статьи создаем файл result_modifier.php (если его еще нет) и создаем переменную с html кодом будущего pdf файла. Сверстать можете как угодно:

$articleTitle = $arResult['NAME']; // название статьи
$articleImg = base64_encode(
	file_get_contents($arResult['DETAIL_PICTURE']['SRC'])
); // картинка
$articleText = $arResult['DETAIL_TEXT']; // текст статьи
$articleID = $arResult['ID']; // ID статьи-элемента

$articleToPdf = 
'<html lang=ru><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><body>
<style type="text/css">
    * {box-sizing: border-box; margin: 0; padding: 0;}
    body {font-family: DejaVu Sans;}
    h1 {font-size: 25px; text-align: center;}
    img {margin:0px 20px; max-width: 100%;}
    p {font-size: 15px; line-height: 23px;}
</style>
<body>'.
   '<h1>' . $articleTitle  . '</h1>'.
   '<img src="data:image/jpg;base64,' . $articleImg . '" width="100%">'.
   '<p>'. $articleText . '</p>'.
'</body></html>';

Обратите внимание: картинку статьи мы преобразовали в base64 иначе она не отобразится в pdf файле.

Теперь качаем библиотеку DOMPDF и загружаем на сайт и подключаем в этом же файле (result_modifier.php). Если планируете использовать библиотеку повсеместно на сайте, можете подключить ее глобально ко всему проекту. Мне нужно только в статьях.

require_once 'ПУТЬ_КУДА_ЗАГРУЗИЛИ_DOMPDF/dompdf/autoload.inc.php';
use Dompdf\Dompdf;
$dompdf = new Dompdf();
$dompdf->loadHtml($articleToPdf);
$dompdf->setPaper('a4', 'portrait');
$dompdf->render();
$output = $dompdf->output(0);

Пояснения:

  • use Dompdf\Dompdf: подключили класс Dompdf
  • dompdf->loadHtml: загрузили наш HTML код со статьей
  • $dompdf->setPaper: установли формат бумаги в A4 с портретной ориентацией. В Dompdf много настроек, по поводу вывода. Смотрите в документации.
  • dompdf->render: запустили генерацию pdf файла.
  • $output = $dompdf->output: в переменной $output получили pdf файл возвращенный как строка.

Теперь, сохраним pdf файл в свойство инфоблока. Сделаем это методом CIBlockElement::Update.

$el = new CIBlockElement;
$PROP = array();
$PROP['ATT_PDF_FILE'] = CFile::MakeFileArray($output);
$arUpdateArticle = Array(
  "PROPERTY_VALUES"=> $PROP,
);
$res = $el->Update($articleID, $arUpdateArticle);
Если, хотите сразу сохранить файл в произвольное место, используйте:
file_put_contents('/ПУТЬ_КУДА_СОХРАНЯЕТЕ/'.$articleTitle.".pdf", $output);

Если хотите отдать файл на скачивание сразу, используйте
$dompdf->stream($articleTitle . ".pdf");
вместо $output = $dompdf->output(0);

Если не хотите, что бы файл создавался каждый раз и пересохранялся: обверните его в проверку на наличие файла.

if (empty($arResult['PROPERTY']['ATT_PDF_FILE']['VALUE'])) {
		....
		Весь наш код
		....
	}

Соотвественно, не используйте условие- если файл нужно создавать каждый раз. Например: статья постоянно меняется и нужно держать pdf файл в актуальном состоянии.

Pdf файл будет создаваться каждый раз при открытии статьи и для каждого пользователя будет максимально актуальным.

Отправить файл на электронную почту, через почтовое событие.

Если хотите реализовать отправку файла на электронную почту, можете использовать метод CEvent::Send

Создаем почтовое событие, например: SEND_ARTICLE_PDF_FILE примерно, с таким содержанием:


Ваш файл #PDF_NAME#.pdf  во вложении к этому письму

И обработчик, в который получаем email пользователя

Event::send(array(
	"EVENT_NAME" => "SEND_ARTICLE_PDF_FILE",
	"LID" => "s1",
	"C_FIELDS" => array(
		"PDF_NAME" => $articleTitle,
		"USER_MAIL" => $userEmail // Это используем в поле "Кому"
    ),
   "FILE" => array($arResult['PROPERTY']['ATT_PDF_FILE']['VALUE']),
));

Данный метод поставит почтовое событие в очередь. Если хотите отправить вне очереди используйте Event::sendImmediate вместо Event::send

В параметр "FILE" можете передать массив ID зарегистрированных в системе файлов или полные пути до файлов - если не используете запись pdf файла в свойство элемента (или хотите приложить, еще несколько файлов).

Михаил Базаров 16.04.2021
Сохранять и регистрировать файл можно методом
CFile::SaveFile
Артем 20.05.2022
Добрый день! Данным метод подойдет для формирования pdf файла в разделе корзина? чтобы пользователь при переходе в корзину - мог сразу выгрузить свой заказ при клике на кнопку? ну и, соответственно, на почту отправлять ему файл pdf при заказе
Михаил Базаров 20.05.2022
Цитата
Артем написал:
Добрый день! Данным метод подойдет для формирования pdf файла в разделе корзина? чтобы пользователь при переходе в корзину - мог сразу выгрузить свой заказ при клике на кнопку? ну и, соответственно, на почту отправлять ему файл pdf при заказе

В целом да. Так же собрать все данные в html массив и сгенерировать pdf ку

Записная книжка разработчика

Примерно с 2013-го года пишу заметки по разработке сайтов на Битрикс.
Вы можете задавать уточняющие вопросы в комментариях- отвечаю или дополняю заметки по возможности.

Глобальные фильтры на всякие случаи жизни Просмотров: 47208 Глобальный фильтр, нужен чаще всего, для вывода определенных элементов, из общего массива... Наличие на складах в умном фильтре 1С-Битрикс, с автоматическим обнов... Просмотров: 1160 Задача: добавить возможность фильтрации товаров по складам в умном фильтре. Данные должны ... Создание блога с комментариями, оценками и просмотрами на сайте с 1С-... Просмотров: 24582 Если на вашем сайте требуется создание раздела с блогом или новостями, статьями. Записям в... Установка вебсервера на Apple M1 (нативный ARM стек), оптимизированны... Просмотров: 7441 Появилась задачка, установить стек MAMP (macOS, Apache, MYSQL, PHP) на рабочий ноутбук с п... Дополнительные параметры в меню Битрикс Просмотров: 20802 Иногда нужно присвоить какой-то функционал к конкретному пункту меню в битрикс. Например о... Вывести минимальную и максимальную цену в разделе каталога Битрикс. Просмотров: 3689 Что бы вывести минимальную и максимальную стоимость товаров, из каталога 1С-Битрикс, доста... Бонус за выполненный заказ на внутренний счет пользователя Просмотров: 5096 Задача: после того как заказ, в интернет-магазине, перешел в статус "Выполнен" начислить п... Проверка на наличие элементов, текущего пользователя, в заданном инфо... Просмотров: 6184 Если стоит задача, определить наличие элементов созданных пользователем на сайте. Можно во... Многосайтовость битрикс на разных доменах и поддоменах Просмотров: 63231 Часто спрашивают "как настроить многосайтовость Битрикс на разных доменах", решил записать... Кастомизация компонента восстановления пароля bitrix:system.auth.forg... Просмотров: 26834 Достаточно часто спрашивают как кастомизировать компонент восстановления пароля пользовате... Вывести разделы инфоблока в которых находится элемент Битрикс Просмотров: 17038 Если нужно в карточке товара или новости, вывести структуру разделов в котором находится э... Показ страницы сайта в боковом слайдере, на примере всплывающей формы... Просмотров: 3250 Если вы хотите сделать подгрузку любой страницы сайта в боковой слайдер, для этого в битри... Постраничная навигация в списке разделов Битрикс- catalog.section.lis... Просмотров: 9955 Если в магазине очень много разделов и хочется вывести их с постраничной навигацией: можно... Использование WebP изображений в 1С-Битрикс (на Битрикс: Веб окружени... Просмотров: 28200 WebP это современный формат сжатия изображений, который позволяет, при правильных настройк... Минимальная сумма заказа в корзине и оформлении заказа в 1С-Битрикс Просмотров: 9832 В этой заметке добавим возможность установки минимальной суммы заказа, в новом шаблоне кор... Показать только один тип цены в каталоге Битрикс Просмотров: 14977 Достаточно часто, при создании сайта на битрикс, можно столкнуться с такой проблемой: на с... Связанные элементы в карточке товара, с помощью catalog.section Просмотров: 15800 Достаточно часто, при разработке магазинов на битрикс, требуется выводить связанные элемен... Очистка корзины в 1С-Битрикс одним нажатием Просмотров: 29636 В стандартной корзине Битрикс не хватает кнопки для полной очистки корзины одним нажатием... Автоматически отгрузить заказ и сменить статус отгрузки, при выполнен... Просмотров: 975 Проблема: Заказы, на сайте, обрабатываются только в 1С. При этом 1С не работает с отгрузка... Цвета торговых предложений из Highload инфоблоков в списке товаров Просмотров: 14935 Подвернулся на доработку очень старый сайт, работал еще на 11-ой версии Битрикс. Выполнили...