Как реализовать открытие печатной формы в формате PDF без отображения интерфейса 1С

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

При разработке внешних печатных форм (ВПФ) часто возникает задача: при нажатии кнопки «Печать» документ должен не открываться в стандартном окне предварительного просмотра 1С, а сразу формироваться в формате PDF и открываться в системном приложении (браузере, Adobe Acrobat и т.д.). Основная сложность заключается в том, что стандартная подсистема печати Библиотеки Стандартных Подсистем (БСП) ожидает возврата заполненного объекта ТабличныйДокумент. Если его не передать или оставить пустым, система выдает ошибку: «В обработчике печати не сформирован табличный документ». Рассмотрим, как правильно обойти это ограничение и реализовать «бесшовное» открытие PDF.

Разберем причину возникновения проблемы

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

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

Шаг 1. Настройка регистрации внешней обработки

Первым делом нам нужно изменить сведения о внешней обработке. Вместо стандартного серверного метода мы будем использовать Вызов клиентского метода. Это позволит нам управлять процессом печати непосредственно из формы обработки, имея доступ к клиентскому контексту и методам запуска файлов.

В модуле объекта в функции СведенияОВнешнейОбработке необходимо указать параметр Использование. Рассмотрим пример:


Функция СведенияОВнешнейОбработке() Экспорт
    ПараметрыРегистрации = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке("2.3.1.73");
    
    НоваяКоманда = ПараметрыРегистрации.Команды.Добавить();
    НоваяКоманда.Представление = НСтр("ru = 'Договор купли-продажи (PDF)'");
    НоваяКоманда.Идентификатор = "ДоговорPDF";
    // Указываем тип вызова - клиентский метод
    НоваяКоманда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыВызовКлиентскогоМетода();
    НоваяКоманда.ПоказыватьОповещение = Истина;
    
    Возврат ПараметрыРегистрации;
КонецФункции

Важный нюанс: при использовании такого типа команды БСП будет искать экспортную процедуру Печать не в модуле объекта, а в модуле основной формы обработки.

Шаг 2. Создание формы и клиентской процедуры печати

Создадим в обработке форму (назовем ее ФормаОбработки) и назначим ее основной. В модуле этой формы пропишем логику управления процессом. Нам нужно получить данные с сервера, сохранить их во временный файл и запустить его.

Разберем пример клиентской процедуры:


&НаКлиенте
Процедура Печать(ИдентификаторКоманды, ОбъектыНазначения) Экспорт
    
    Если ИдентификаторКоманды = "ДоговорPDF" Тогда
        
        Для Каждого СсылкаНаОбъект Из ОбъектыНазначения Цикл
            
            // Получаем двоичные данные PDF с сервера
            ДанныеФайла = СформироватьPDFНаСервере(СсылкаНаОбъект);
            
            Если ДанныеФайла = Неопределено Тогда
                Продолжить;
            КонецЕсли;
            
            // Генерируем уникальное имя файла для избежания конфликтов
            ИмяФайла = "Договор_" + СсылкаНаОбъект.Номер + ".pdf";
            ПутьКФайлу = КаталогВременныхФайлов() + ИмяФайла;
            
            // Записываем и открываем
            ДанныеФайла.Записать(ПутьКФайлу);
            ЗапуститьПриложение(ПутьКФайлу);
            
        КонецЦикла;
        
    КонецЕсли;
    
КонецПроцедуры

Шаг 3. Формирование PDF на стороне сервера

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

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


&НаСервереБезКонтекста
Функция СформироватьPDFНаСервере(СсылкаНаОбъект)
    
    // Создаем табличный документ (логика заполнения макета)
    ТабДок = Новый ТабличныйДокумент;
    
    // Здесь должна быть ваша логика заполнения документа:
    // Макет = ПолучитьМакет("Макет");
    // Область = Макет.ПолучитьОбласть("Заголовок");
    // ТабДок.Вывести(Область);
    
    // Пример наполнения для теста
    ТабДок.Область(1,1).Текст = "Договор № " + СсылкаНаОбъект.Номер;
    
    // Сохраняем во временный файл на сервере и читаем в двоичные данные
    ВременныйПуть = ПолучитьИмяВременногоФайла("pdf");
    ТабДок.Записать(ВременныйПуть, ТипФайлаТабличногоДокумента.PDF);
    
    ДвоичныеДанные = Новый ДвоичныеДанные(ВременныйПуть);
    УдалитьФайлы(ВременныйПуть);
    
    Возврат ДвоичныеДанные;
    
КонецФункции

Дополнительные рекомендации по оптимизации

Рассмотрим несколько важных моментов, которые сделают ваше решение более надежным:

  1. Безопасность временных файлов: Использование фиксированного имени файла (например, Договор.pdf) в КаталогВременныхФайлов() может привести к ошибкам доступа, если пользователь попытается напечатать документ дважды, не закрыв предыдущий PDF-ридер. Всегда добавляйте к имени файла уникальный идентификатор или номер документа.
  2. Работа в веб-клиенте: Метод ЗапуститьПриложение имеет ограничения безопасности в браузерах. Для веб-клиента лучше использовать метод ПолучитьФайлFromServer (или НачатьПолучениеФайлаССервера в новых версиях платформы), который инициирует стандартную загрузку файла браузером.
  3. Очистка мусора: Файлы, созданные в КаталогВременныхФайлов() на стороне клиента, не всегда удаляются сразу. Рекомендуется периодически проводить очистку или использовать механизмы временного хранилища 1С.
  4. Тихая печать: Если ваша цель — отправить PDF сразу на принтер без открытия окна просмотра, вы можете передать в ЗапуститьПриложение параметры командной строки вашего PDF-ридера. Например, для Adobe Reader это ключ /p.

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

← На главную