Как вывести на печать ФорматированныйДокумент в 1С 8.3?

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

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

Разберем подробно, какие существуют варианты вывода форматированного документа на печать, проанализируем возможные ошибки при работе с изображениями и рассмотрим готовые примеры программного кода на встроенном языке 1С.

Особенности объекта ФорматированныйДокумент

Проанализируем сначала устройство самого объекта. ФорматированныйДокумент предназначен для работы с текстом, содержащим шрифтовое и абзацное форматирование, а также вложенные картинки. Чаще всего он хранится в базе данных внутри реквизитов с типом ХранилищеЗначения.

При извлечении данных из реквизита мы получаем объект, состоящий из элементов различных типов: текстовых блоков (ТекстФорматированногоДокумента) и графических объектов (КартинкаФорматированногоДокумента). Основная проблема вывода заключается в том, что печатный макет 1С строится на базе объекта ТабличныйДокумент, который требует явного заполнения ячеек или добавления графических рисунков.

Способ 1. Поэлементный обход и формирование ТабличногоДокумента

Рассмотрим первый метод вывода — прямой обход структуры документа с последовательным заполнением печатной формы. Этот вариант подходит, если требуется выводить текст и картинки в стандартный табличный документ 1С.

Выясним алгоритм действий:

  1. Извлекаем ФорматированныйДокумент из хранилища значений.
  2. Получаем массив внутренних элементов с помощью метода ПолучитьЭлементы().
  3. В цикле анализируем тип каждого элемента.
  4. Если элемент является текстом, передаем значение в параметр области табличного документа и выводим область.
  5. Если элемент является картинкой, программно создаем рисунок в области табличного документа, задаем его размеры и координаты, после чего выводим область.

Посмотрим на пример реализации данного алгоритма:


ФорматированныйДокумент = Выборка.Содержание.Получить();
ЭлементыФорматированногоДокумента = ФорматированныйДокумент.ПолучитьЭлементы();

Для Каждого Элемент ИЗ ЭлементыФорматированногоДокумента Цикл
    Если ТипЗнч(Элемент) = Тип("ТекстФорматированногоДокумента") Тогда
        ОбластьТекст.Параметры.Содержание = Элемент.Текст;
        ТабДок.Вывести(ОбластьТекст);
    Иначе
        // Создаем рисунок в области табличного документа
        КартинкаПечать = ОбластьКартинка.Рисунки.Добавить(ТипРисункаТабличногоДокумента.Картинка); 
        КартинкаПечать.Картинка = Элемент.Картинка; 
        
        // Настраиваем позиционирование и размеры
        КартинкаПечать.Верх = 0; 
        КартинкаПечать.Лево = 0; 
        КартинкаПечать.Высота = Элемент.Высота / 4; 
        КартинкаПечать.Ширина = Элемент.Ширина / 4; 
        
        // Отключаем отображение границ рисунка
        КартинкаПечать.ГраницаСверху = Ложь; 
        КартинкаПечать.ГраницаСлева = Ложь; 
        КартинкаПечать.ГраницаСправа = Ложь; 
        КартинкаПечать.ГраницаСнизу = Ложь; 
        
        КартинкаПечать.РазмерКартинки = РазмерКартинки.АвтоРазмер; 
        
        ТабДок.Вывести(ОбластьКартинка);
    КонецЕсли;
КонецЦикла;

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

Решение проблемы с картинками в формате Base64

В процессе работы с форматированными документами разработчики часто сталкиваются с ошибкой при попытке присвоения КартинкаПечать.Картинка = Элемент.Картинка. Ошибка возникаем в случаях, когда свойство Элемент.Картинка возвращает не объект Картинка, а текстовую строку Data URL, начинающуюся с префикса data:image/png;base64,....

Разберем, как правильно преобразовать данную строку в объект Картинка для корректной передачи в печатную форму. Нам потребуется отсечь служебный заголовок Data URL, декодировать чистый код Base64 в двоичные данные с помощью функции Base64Значение() и сформировать новый объект.

Рассмотрим универсальный фрагмент кода для обработки изображений:


Если ТипЗнч(Элемент.Картинка) = Тип("Строка") Тогда
    СтрокаBase64 = Элемент.Картинка;
    
    // Находим позицию запятой, отделяющей заголовок "data:image/png;base64," от данных
    ПозицияЗапятой = СтрНайти(СтрокаBase64, ",");
    
    Если ПозицияЗапятой > 0 Тогда
        // Получаем кодированную строку без префикса
        ЧистыйBase64 = Сред(СтрокаBase64, ПозицияЗапятой + 1);
        
        // Преобразуем Base64 в ДвоичныеДанные
        ДвоичныеДанные = Base64Значение(ЧистыйBase64);
        
        // Инициализируем объект Картинка
        ОбъектКартинка = Новый Картинка(ДвоичныеДанные);
        
        КартинкаПечать.Картинка = ОбъектКартинка;
    КонецЕсли;
ИначеЕсли ТипЗнч(Элемент.Картинка) = Тип("Картинка") Тогда
    // Если объект уже имеет нужный тип
    КартинкаПечать.Картинка = Элемент.Картинка;
КонецЕсли;

Способ 2. Вывод через HTML и Поле HTML документа

Хотя поэлементный обход позволяет выводить текст и графику в ТабличныйДокумент, у этого способа есть существенный недостаток: при получении свойства .Текст теряется исходное оформление (полужирный шрифт, курсив, подчёркивания, цвета, выравнивание и списки).

Если необходимо сохранить 100% исходного форматирования и верстки, разберем альтернативный и наиболее эффективный подход — использование встроенного метода ПолучитьHTML().

Рассмотрим пошагово процесс подготовки форматированного документа к печати через HTML:

  1. Выгружаем содержимое документа в строку HTML и структуру картинок.
  2. Помещаем картинки во временное хранилище или сохраняем во временный каталог.
  3. Заменяем внутренние ссылки на картинки в HTML-коде.
  4. Загружаем итоговый HTML-код в элемент управляемой формы ПолеHTMLДокумента.
  5. Отправляем содержимое элемента на печать средствами браузерного движка.

Посмотрим на программную реализацию выгрузки HTML:


ТекстHTML = "";
СтруктураКартинок = Новый Структура;

// Экспортируем HTML-код и извлекаем картинки
ФорматированныйДокумент.ПолучитьHTML(ТекстHTML, СтруктураКартинок);

// Обрабатываем картинки из структуры и подготавливаем их для отображения
Для Каждого КлючИЗначение Из СтруктураКартинок Цикл
    ИмяФайла = КлючИЗначение.Ключ;
    ОбъектКартинка = КлючИЗначение.Значение;
    
    // Сохраняем картинки во временный каталог или кодируем в Base64 прямо в src
    Двоичные = ОбъектКартинка.ПолучитьДвоичныеДанные();
    СтрокаBase64 = Base64Строка(Двоичные);
    
    // Заменяем имя файла на Data URL в HTML коде
    ТекстHTML = СтрЗаменить(ТекстHTML, ИмяФайла, "data:image/png;base64," + СтрокаBase64);
КонецЦикла;

// Выводим полученный код в реквизит формы типа Строка (связанный с Полем HTML документа)
Элементы.ПолеHTML.Документ.open();
Элементы.ПолеHTML.Документ.write(ТекстHTML);
Элементы.ПолеHTML.Документ.close();

После того как страница сформирована в элементе формы, можно вызвать команду печати из контекста документа:


// Вызов диалога печати для поля HTML
Элементы.ПолеHTML.Документ.execCommand("Print");

Сравнение методов вывода на печать

Проанализируем сильные и слабые стороны каждого решения, чтобы выбрать оптимальный подход под конкретную задачу:

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

← На главную