Здравствуйте! В данной статье мы рассмотрим автоматическую генерацию PDF документа средствами PHP. Реализуем возможность сохранять любую статью на сайте в PDF формате. Данный функционал будем разворачивать на CMS 1c-Bitrix. Чем больше изучаю эту платформу, тем больше убеждаюсь в качестве её разработки.
Итак, общий алгоритм будет следующим: при сохранении, ипдейте элемента в инф. блоке, создается/обновляется PDF документ. Что бы ни изобретать велосипед, для создания PDF файла, будем использовать библиотеку mPDF (http://mpdf1.com/) . На момент написания статьи, последний актуальный релиз mPDF v5.7. Качаем архив, разархивируем и заливаем на сервер (в корень сайта).
Теперь задача стоит в выборе метода генерации, можно создать отдельный скрипт, передать ему ID элемента и на выходе выплюнуть сгенерированный файл, можно повесить обработчик на события: создание и апдейт элемента инф. блока. Для теста я выбрал второй вариант, т.к. поток статей не очень большой и не будет существенной нагрузки при перезаписи или создании PDF документов.
Теперь при создании или апдейте элемента будет создаваться или обновляться PDF файл с текстом статьи. В данном примере текст документа генерируется из названия и детального описания элемента. Названием файла выступает его уникальный ID.
Так же прописываем обработчик, который будет удалять сгенерированный файл, при удалении элемента:
Как обучающая - гуд, но на практике я бы обращался к файлу посреднику (/bitrix/pdf.php?ID=13), который на лету бы генерил PDF. Это даст бОльшую гибкость. Ну и проверку прав можно будет вкорячить. Сейчас есть риск утечки запрещенной инфы.
И
$res = CIBlockElement::GetByID($arFields['ID']);
а это зачем? Ведь в arFields все нужное прилетает.
С производительностью у mPDF беда, подходит только для простых вещей. Для генерации pdf самый оптимальный вариант - это wkhtml2pdf, но не всегда есть возможность установить эту команду на сервер.
Антон Долганин , ага косячок, подправлю. Эту функцию использую еще в одной компоненте, где на вход прилетает только ID, поэтому доп. запрос сохранился.
mPDF не поддерживает mbstring.func_overload 2. Когда-то много времени потерял, почему не работало. Реально работает TCPDF, но результат бывает некрасивый. TCPDF далеко не все атрибуты и стили поддерживает.
Зайцев Артемий, тоже использую TCPDF. Уже и не помню, почему в своё время не подружился с mPDF, но не подружился =) Ну и баркоды нативно, в виденных примерах mPDF для генерации ШК используют код из TCPDF.
А как решили проблемы с mbstring.func_overload ? Для mPDF требуется 0, а для bitrix выше. Просто возникла такая проблема, на локал хосте удалось через htaccess в отдельной папке где формируется файл, указать этот параметр равный "0". Но при переносе на новый сервер с версии (php 5.3+) это уже сделать невозможно. В общем на новом сервере, файлы формируются в 2-а раза меньшим объемом и не открываются ("файл поврежден и не может быть восстановлен") На старом все ок.
Немного не понял в какой файл вставлять код функций function IBlockAfterSave($arFields) И подскажите как применить все это дело только к определенному инфоблоку? например по ID инфоблока
Опять возникла эта проблема, на тот момент сменил библиотеку на dompdf, но сейчас именно mpdf нужно, т.к. с картинками она лучше работает.
Хостинг timeweb, через htaccess в нужной папке установили mbstring.func_overload 0, проверяем через phpinfo все ок. Но файл все равно генерируется с иероглифами.
Все нормально работает, если в корне сайта в htaccess укажем mbstring.func_overload 0, но для bitrix так нельзя.
Где кроется собака ? bitrix где то все равно свой mbstring.func_overload 2 подсовывает что ли ?
Скорее всего дело в том, что func_overload 0 нужно определять в той папке, откуда у вас вызывается библиотека, а не внутри модуля. Ведь эта настройка именно для каталога в котором фактически работает скрипт, вызываться-то он откуда угодно может при этом.
Скажем, у нас сейчас на одном из проектов используется mpdf, сама библиотека в /bitrix/php_interface/vendor/mpdf , а вызывается она в /order/pdf/, настройки mbstring установлены именно для /order/pdf/ и всё корректно работает, при том, что для всего остального сайта func_overload 2.
Попробуйте переложить в ту папку, откуда идёт вызов библиотеки.
на основе get параметров подсоединяется другой шаблон сайта
Я изменил параметр func_overload в :
- Папке где компонента модуля сохранение в pdf - в папке модуля сохранение в pdf - в новом шаблоне сайта - в папке catalog, где присутствуем на момент вызова "сохранение в pdf"
Безрезультатно.
Вроде бы везде где только можно сделал, уже ума не приложу где копать, буду рад любым размышлениям вслух))
вначале закинул в эту папку левый файл и там выполнил команду оба значения были равны нулю, но решил сделать как вы надоумели, в исполняемом файле запустить))) и опа, local value равно 2, хотя master 0.
1) надо создать .htaccess внутри /catalog , в нём переопределить, посмотреть на local ещё раз.
2) Master 0 , т.к., видимо, в конфиге веб-сервера для вашего виртуал хоста так указано (или так по умолчанию), далее вы его переопределяете через корневой .htaccess для всего проекта, а локальным .htaccess уже ставите для конкретной папки.
По идее, локальная установка как раз должна дать local 0 в этой папке.
Вячеслав Трембач, тут все хитрее оказалось, и меня удивляет почему сразу не понял это )))
Bitrix же использует роутинг, и получается если мы напрямую к папке не обращаемся, изначальный вход у нас происходит если не ошибаюсь то на /bitrix/urlrewrite.php
Поэтому решил задачу тем что
передаю url не
/catalog2/model-okb-9102-csx/?wd_export=Y&pdf=Y (поэтому и были расхождения в master и local значения параметры func_overload)
а /catalog2/detail.php?wd_export=Y&pdf=Y&ELEMENT_CODE=okb-9102-csx
И все заработало! )))))
Спасибо большое, Вячеслав за участие в этом небольшом расследовании ))) Надеюсь эти комментарии кому то помогут ))
Щербак Михаил написал: require($_SERVER["DOCUMENT_ROOT"]."/MPDF57/mpdf.php");
Здравствуйте. Подскажите что не так. У меня с этой строчной "require($_SERVER["DOCUMENT_ROOT"]."/Папка/mpdf.php");" в файле init.php функция IBlockAfterSave зависает. помогает только Restart httpd В логах ничего нет. версию MPDF пробовал и 5.7 и 6.0. Заранее спасибо.
Ага. Меня тоже засмущала строчка из описания библиотеки. mPDF is not compatible with PHP function overloading (mbstring.func_overload) Сейчас у меня ка просит битрикс mbstring.func_overload=2 PHP Version 7.0.33Ну все же попробую...
Груздев Александр, Мы решили эту проблему просто. Для директории со скриптом который генерит pdf установили значение mbstring.func_overload=0 А остальной сайт работает с mbstring.func_overload=2 ))
Группы на сайте создаются не только сотрудниками «1С-Битрикс», но и партнерами компании. Поэтому мнения участников групп могут не совпадать с позицией компании «1С-Битрикс».