Как сформировать печатную форму документа на сервере и сохранить её в PDF на клиенте в 1С?

Программист 1С v8.3 (Управляемые формы) 1C:Бухгалтерия Бухгалтерский учет IT и автоматизация бизнеса
← На главную

При разработке в управляемом приложении часто возникает задача автоматического формирования печатной формы (например, счета на оплату покупателю) и последующей выгрузки результата в файл формата PDF на компьютере пользователя. Разберем по шагам, как устроен механизм подсистемы печати БСП, как правильно инициализировать структуру коллекций и какие типовые ошибки допускают разработчики при передаче табличного документа между клиентом и сервером.

Разбор исходной проблемы и механизма печати

В типовых конфигурациях на базе БСП (таких как «1С:Бухгалтерия предприятия 3.0», «1С:Управление торговлей 11», «1С:УНФ») печать документов выполняется через менеджер объекта. Процедура Печать в модуле менеджера ожидает на вход строго определенный набор параметров: массив ссылок на документы, коллекцию печатных форм, список объектов печати и структуру параметров вывода.

Если вызвать процедуру печати без корректно настроенной таблицы КоллекцияПечатныхФорм, процедура отработает вхолостую. Внутри стандартного алгоритма всегда проверяется условие УправлениеПечатью.НужноПечататьМакет, которое сверяет требуемое имя макета с колонкой ИмяВРЕГ. Если нужной строки в верхнем регистре нет в коллекции, макет сформирован не будет.

Решение 1: Формирование через менеджер документа с ручной инициализацией коллекции

Проанализируем рабочее решение, полученное автором. Здесь для вызова печати вручную формируется таблица значений со всеми колонками, необходимыми подсистеме БСП, после чего из нее извлекается заполненный ТабличныйДокумент.

Обратим внимание на частую ошибку начинающих программистов: перед присвоением результата функции переменной на клиенте не нужно писать ТабДок1 = Новый ТабличныйДокумент. Создание экземпляра объекта в этой строке бессмысленно, так как в следующей же строке переменной присваивается ссылка на новый объект, возвращенный с сервера.

Посмотрим на исправленный и оптимизированный пример кода:


&НаКлиенте
Процедура СохранитьСчетВPDF(Команда)
    // Получаем сформированный табличный документ с сервера
    ТабДок = СформироватьСчетНаСервере();
    
    // Сохраняем файл на клиенте в формате PDF
    Если ТабДок <> Неопределено Тогда
        ТабДок.Записать("C:\Temp\СчетНаОплату.pdf", ТипФайлаТабличногоДокумента.PDF);
    КонецЕсли;
КонецПроцедуры

&НаСервере
Функция СформироватьСчетНаСервере()
    // Создаем структуру коллекции печатных форм
    КоллекцияПечатныхФорм = Новый ТаблицаЗначений;
    КоллекцияПечатныхФорм.Колонки.Добавить("ИмяВРЕГ");
    КоллекцияПечатныхФорм.Колонки.Добавить("ИмяМакета");
    КоллекцияПечатныхФорм.Колонки.Добавить("Картинка");
    КоллекцияПечатныхФорм.Колонки.Добавить("ПолныйПутьКМакету");
    КоллекцияПечатныхФорм.Колонки.Добавить("СинонимМакета");
    КоллекцияПечатныхФорм.Колонки.Добавить("ТабличныйДокумент");
    КоллекцияПечатныхФорм.Колонки.Добавить("Экземпляров");

    // Обязательно указываем идентификатор печатной формы в ВЕРХНЕМ регистре
    НоваяСтрока = КоллекцияПечатныхФорм.Добавить();
    НоваяСтрока.ИмяВРЕГ = "СЧЕТЗАКАЗСПЕЧАТЬЮ";

    // Находим документ и формируем массив
    Документ = Документы.СчетНаОплатуПокупателю.НайтиПоНомеру("00000000200", Дата(2014, 1, 1)).Ссылка;
    МассивОбъектов = Новый Массив;
    МассивОбъектов.Добавить(Документ);

    ОбъектыПечати = Новый СписокЗначений;
    
    ПараметрыОтправки = Новый Структура;
    ПараметрыОтправки.Вставить("Получатель");
    ПараметрыОтправки.Вставить("Текст", "");
    ПараметрыОтправки.Вставить("Тема", "");

    ПараметрыВывода = Новый Структура;
    ПараметрыВывода.Вставить("ДоступнаПечатьПоКомплектно", Ложь);
    ПараметрыВывода.Вставить("ПараметрыОтправки", ПараметрыОтправки);

    // Вызываем стандартную печать менеджера документа
    Документы.СчетНаОплатуПокупателю.Печать(МассивОбъектов, , КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода);

    Если КоллекцияПечатныхФорм.Количество() > 0 Тогда
        Возврат КоллекцияПечатныхФорм[0].ТабличныйДокумент;
    КонецЕсли;

    Возврат Неопределено;
КонецФункции

Решение 2: Использование стандартных методов БСП (рекомендуемый подход)

Рассмотрим более лаконичный и универсальный способ. В Библиотеке Стандартных Подсистем нет необходимости вручную добавлять колонки в таблицу значений. Для этого реализована штатная функция УправлениеПечатью.ПодготовитьКоллекциюПечатныхФорм, которая сама создает корректную структуру.

Разберем по шагам, как написать вызов:

  1. Подготавливаем коллекцию печатных форм, передав имя макета в функцию БСП.
  2. Передаем массив ссылок и сформированную коллекцию в процедуру печати менеджера объекта.
  3. Извлекаем результирующий ТабличныйДокумент с помощью функции УправлениеПечатью.СформироватьПечатныеФормы или напрямую из коллекции.

Посмотрим на реализацию серверной функции с использованием стандартных механизмов:


&НаСервере
Функция ПолучитьТабличныйДокументБСП(СсылкаНаДокумент)
    // Подготовка коллекции с помощью стандартной функции БСП
    ИменаМакетов = "СчетЗаказСПечатью";
    КоллекцияПечатныхФорм = УправлениеПечатью.ПодготовитьКоллекциюПечатныхФорм(ИменаМакетов);

    МассивОбъектов = Новый Массив;
    МассивОбъектов.Добавить(СсылкаНаДокумент);

    ОбъектыПечати = Новый СписокЗначений;
    ПараметрыВывода = УправлениеПечатью.ПодготовитьСтруктуруПараметровВывода();

    // Формирование печатной формы через менеджер документа
    Документы.СчетНаОплатуПокупателю.Печать(МассивОбъектов, Неопределено, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода);

    ПечатнаяФорма = КоллекцияПечатныхФорм.Найти("СЧЕТЗАКАЗСПЕЧАТЬЮ", "ИмяВРЕГ");
    Если ПечатнаяФорма <> Неопределено Тогда
        Возврат ПечатнаяФорма.ТабличныйДокумент;
    КонецЕсли;

    Возврат Неопределено;
КонецФункции

Важные технические нюансы и ограничения

При сохранении и передаче печатных форм между клиентом и сервером необходимо учитывать архитектурные особенности платформы «1С:Предприятие 8.3»:

  1. Ограничения веб-клиента: Метод ТабличныйДокумент.Записать() с прямым путем к файловой системе (например, C:\Temp\file.pdf) вызовет исключение в веб-клиенте из-за ограничений безопасности браузера. В веб-клиенте сохранение следует выполнять через помещение двоичных данных во временное хранилище на сервере и последующий вызов метода НачатьПолучениеФайлаССервера на клиенте.
  2. Сервер под управлением Linux: Если вы сохраняете табличный документ в формат PDF непосредственно на сервере под управлением ОС Linux, убедитесь, что в операционной системе установлены пакеты шрифтов Microsoft TrueType (например, msttcorefonts) и настроена библиотека fontconfig. При их отсутствии формирование PDF завершится критической ошибкой платформы или сформирует файл с поврежденными надписями.
  3. Сериализация и накладные расходы: Передача объекта ТабличныйДокумент с сервера на клиент влечет за собой передачу всех графических объектов, ячеек и факсимиле по сети. Если документ содержит сотни страниц или тяжелые изображения печатей, сериализация замедлит работу. В высоконагруженных сценариях рекомендуется конвертировать документ в PDF на сервере через временный файл, считывать в ДвоичныеДанные и передавать клиенту готовый сжатый поток.
← На главную