При разработке фоновых заданий, регламентных процедур или логики на стороне сервера часто возникает задача автоматического формирования печатных форм и их сохранения в различных форматах. Метод Записать() объекта ТабличныйДокумент позволяет экспортировать данные в форматы MXL, XLS, XLSX, HTML и PDF. Однако на практике разработчики могут столкнуться с ситуацией, когда выгрузка в MXL или XLSX проходит успешно, а сохранение в PDF или HTML завершается системной ошибкой: «Неверный путь к файлу».
Разберем детально, почему возникает такое поведение, в чем заключается специфика серверного рендеринга PDF в платформе 1С:Предприятие и как гарантированно устранить эту проблему.
Сначала рассмотрим синтаксис метода выгрузки табличного документа в файл на сервере:
// Пример сохранения табличного документа в фоновом задании или на сервере
ИмяФайла = ПолучитьИмяВременногоФайла("pdf");
ТабДокумент.Записать(ИмяФайла, ТипФайлаТабличногоДокумента.PDF);
Платформа 1С поддерживает различные варианты форматов через системное перечисление ТипФайлаТабличногоДокумента:
PDF — стандартный формат документа PDF;PDF_A_1, PDF_A_2, PDF_A_3 — форматы стандарта долгосрочного архивного хранения PDF/A;MXL — собственный формат табличных документов 1С;XLSX, XLS95 — форматы электронных таблиц (при этом формат XLS95 на сервере не поддерживается).Проанализируем разницу в механизмах сохранения различных форматов. Когда 1С сохраняет документ в MXL или XLSX, платформа напрямую сериализует структуру данных и записывает ее в целевой файл на диске. Для этого процесса требуются только права на целевую директорию.
Формирование документов в форматах PDF и HTML работает принципиально иначе. Для генерации PDF платформе требуется полноценный рендеринг документа, включающий:
%TEMP%, %TMP% и %LOCALAPPDATA% учетной записи, от которой запущен рабочий процесс rphost (или служба сервера 1С ragent);HKEY_CURRENT_USER.Если служба сервера 1С запускается от имени выделенной сервисной или доменной учетной записи (например, usr1cv8), под которой ни разу не выполнялся интерактивный вход в Windows, профиль пользователя на сервере остается неинициализированным. Папка C:\Users\<ИмяПользователя> физически отсутствует или создана не полностью, а переменные среды временных файлов указывают на несуществующие пути. При попытке инициализации движка PDF платформа не может создать внутренние временные файлы и возвращает системную ошибку пути.
Также ошибку могут вызвать не вступившие в силу права доступа. Если сервисная учетная запись была добавлена в группу безопасности с доступом к каталогам без последующего обновления тикета безопасности сессии, процесс не сможет выполнить запись.
Разберем базовое и самое быстрое решение. Чтобы операционная система полностью создала дерево каталогов пользователя, реестр и временные папки, выполним интерактивный вход:
services.msc в свойствах службы «Агент сервера 1С:Предприятия» на вкладке «Вход в систему»).После инициализации профиля механизм рендеринга PDF получит доступ к необходимым системным ресурсам, и ошибка исчезнет.
Проанализируем правильный подход к генерации путей к файлам на стороне сервера. Никогда не следует жестко прописывать пути к дискам или папкам вручную (например, C:\temp\ или корень диска), так как у службы 1С может не быть прав на произвольные системные каталоги.
Всегда используем системную функцию ПолучитьИмяВременногоФайла(), которая возвращает гарантированно доступный путь в пределах рабочей временной директории процесса:
&НаСервере
Функция СформироватьПечатнуюФормуВPDF(СсылкаНаДокумент)
ТабДок = Новый ТабличныйДокумент;
// Формируем печатную форму штатным методом
Документы[СсылкаНаДокумент.Метаданные().Имя].Печать(ТабДок, СсылкаНаДокумент);
// Проверяем возможность вывода документа
Если НЕ ТабДок.Вывод Тогда
ТабДок.Вывод = Истина;
КонецЕсли;
// Получаем корректный временный путь для файла PDF
ПутьКФайлу = ПолучитьИмяВременногоФайла("pdf");
// Сохраняем табличный документ
ТабДок.Записать(ПутьКФайлу, ТипФайлаТабличногоДокумента.PDF);
// Читаем сформированный файл в двоичные данные
ДвоичныеДанныеФайла = Новый ДвоичныеДанные(ПутьКФайлу);
// Удаляем временный файл после обработки
УдалитьФайлы(ПутьКФайлу);
Возврат ДвоичныеДанныеФайла;
КонецФункции
Рассмотрим дополнительные нюансы, которые необходимо учитывать при формировании PDF на стороне сервера:
Вывод установлено в значение Ложь (или у пользователя в правах отключено право на вывод), вызов метода Записать() завершится исключением.msttcorefonts) и библиотеки fontconfig и freetype. При их отсутствии печатные формы в PDF могут выгружаться с искаженным текстом или пустыми строками.