При разработке механизмов печати в системе 1С:Предприятие часто возникает задача вывода документов в формате PDF. Начиная с версии 8.3.16, в платформе появился специализированный объект ДокументPDF, который позволяет удобно отображать и распечатывать файлы этого формата. Однако многие разработчики сталкиваются с серьезным ограничением: объект не предоставляет прямого программного доступа к настройкам страницы, таким как Автомасштаб или Ландшафт. В этой статье мы подробно разберем, почему так происходит, и какие альтернативные способы решения задачи существуют.
Рассмотрим стандартную ситуацию, когда мы получаем PDF-файл, например, через HTTP-запрос, и хотим сразу отправить его на печать с определенными настройками. Типичный код загрузки документа выглядит следующим образом:
Если HTTPОтвет.КодСостояния = 200 Тогда
ДокPDF = Новый ДокументPDF();
ДокPDF.Прочитать(HTTPОтвет.ПолучитьТелоКакПоток());
// Здесь мы хотим задать параметры, но свойств ОриентацияСтраницы или Автомасштаб нет
ДокPDF.Показать("Печать документа");
КонецЕсли;
Проанализируем доступные методы объекта ДокументPDF. На текущий момент метод Напечатать() принимает всего два параметра: ПоказыватьДиалог и ИмяПринтера. Это означает, что платформа делегирует управление параметрами либо пользователю (через диалоговое окно), либо драйверу принтера по умолчанию. В отличие от привычного объекта ТабличныйДокумент, у ДокументPDF нет свойств, которые могли бы переопределить настройки самого контейнера PDF при выводе на печать.
Выясним причину такого поведения. PDF (Portable Document Format) — это фиксированный формат. Информация о размере страницы и её ориентации уже жестко «зашита» внутри самого файла. Когда 1С отправляет этот файл на принтер, она передает его как готовый набор инструкций. Если файл сформирован в портретной ориентации, а принтер ожидает ландшафтную, корректность вывода будет зависеть от того, умеет ли драйвер конкретного принтера автоматически поворачивать и масштабировать содержимое под размер носителя (функции типа «Fit to page»).
Если нам необходимо полностью автоматизировать процесс печати без участия пользователя, самым надежным способом будет использование сторонних консольных приложений. Проанализируем работу с популярной бесплатной утилитой SumatraPDF. Этот метод позволяет передать все необходимые параметры через командную строку.
Алгоритм действий будет следующим:
ЗапуститьПриложение().Посмотрим на пример реализации:
ПутьКФайлу = ПолучитьИмяВременногоФайла("pdf");
ДокPDF.Записать(ПутьКФайлу);
// Параметры: -print-to-default (печать на принтер по умолчанию)
// -print-settings "landscape,fit" (задание ландшафта и масштабирования)
КомандаЗапуска = """C:\Program Files\SumatraPDF\SumatraPDF.exe"" -print-to-default -print-settings ""landscape,fit"" " + ПутьКФайлу;
ЗапуститьПриложение(КомандаЗапуска, , Истина);
Этот способ позволяет гарантированно получить нужный результат, так как специализированные утилиты имеют гораздо более развитый интерфейс управления печатью PDF, чем встроенные средства платформы.
В современных конфигурациях, использующих БСП, предусмотрены механизмы для работы с печатными формами в формате PDF. Разберем, как это реализовано «под капотом». Зачастую БСП обходит ограничения платформы путем конвертации страниц PDF в растровые изображения (картинки), которые затем вставляются в обычный ТабличныйДокумент.
Преимущества этого подхода:
ТабличныйДокумент.ОриентацияСтраницы и ТабличныйДокумент.Автомасштаб.Однако стоит учитывать, что при таком подходе может незначительно снизиться качество текста и увеличиться время подготовки задания на печать, так как происходит процесс растеризации каждой страницы документа.
Рассмотрим еще один вариант, который часто обсуждается на форумах — использование объекта ПакетОтображаемыхДокументов. Посмотрим на его структуру. Этот объект предназначен для объединения нескольких документов в одно задание на печать. Хотя он позволяет задать имя принтера и количество копий, он также не содержит свойств для управления внутренней ориентацией страниц PDF-документов, входящих в пакет.
Переход от ДокументPDF к пакету выглядит так:
Пакет = Новый ПакетОтображаемыхДокументов;
ЭлементПакета = Пакет.Состав.Добавить();
ЭлементПакета.Данные = HTTPОтвет.ПолучитьТелоКакПоток(); // Передаем данные PDF
Пакет.Напечатать(РежимИспользованияДиалогаПечати.НеИспользовать);
К сожалению, этот метод не решает проблему масштабирования и ориентации, так как настройки пакета ограничены общими параметрами вывода.
Проанализируем ситуацию и выберем оптимальный путь:
ДокPDF.Напечатать(Истина). Пользователь сам выберет «Ландшафт» и «Вписать в страницу» в системном диалоге.ТабличныйДокумент.Таким образом, хотя встроенный объект ДокументPDF в 1С пока не обладает гибкостью ТабличногоДокумента в плане настроек печати, существующие обходные пути позволяют успешно решать бизнес-задачи любой сложности.