Телеграм: @camouf_ru Почта: mihail@bazarow.ru Заказать разработку проекта

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

Задача: при каждом посещении статьи, на сайте, нужно создавать 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 файла в свойство элемента (или хотите приложить, еще несколько файлов).


Просмотров: 667| Комментариев: 1

Комментарии

Внимание! все сообщения проходят премодерацию. Ваше сообщение появится после проверки
 
Текст сообщения*
Загрузить файл или картинкуПеретащить с помощью Drag'n'drop
Перетащите файлы
Ничего не найдено
Защита от автоматических сообщений
Загрузить файл
Нажимая кнопку "Отправить", Вы принимаете условия
Политики конфиденциальности и обработки персональных данных
Михаил Базаров
Сохранять и регистрировать файл можно методом
CFile::SaveFile
Имя Цитировать
Поделиться страницей Спасибо, это помогает развивать сайт.
Мой youtube канал. C 1-го сентября начнется выход видеокурса по разработке доски объявлений с мобильным приложением.
Перейти на канал Подписывайтесь и будьте в курсе:
Заметки разработчика

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

attention