Печать в docx методами БСП без COM объекта

29.07.24

Разработка - БСП (Библиотека стандартных подсистем)

Всё больше организаций выбирает для серверов под 1С операционные системы Linux. Одним из отличий систем Windows и Linux является отсутствие COM объектов, которые зачастую использовались для формирования печатных форм офисных документов (Word). Конечно, можно выполнять печать и на клиенте, но есть риск импортозамещения. В работе у меня случались проблемы с зависанием процесса Word, поэтому я не люблю его использовать.

Содержание

  1. Процедуры
  2. Макеты
  3. Принцип построения процедуры формирования документа

 

В БСП (библиотека стандартных подсистем) существуют механизмы работы с офисными документами без использования COM объектов. Попробовал поработать с этим механизмом, сформировал заметку, где описал возможности и то, как с ним нужно работать. Описание механизма на версии БСП 3.1.9, механизм этот существовал и в более ранних версиях.

Примечание: механизм работает с документами формата docx.

 

Процедуры

 

Начнем с описания процедур. Описание скопировано из инструкции БСП чтобы было под рукой. Библиотека стандартных подсистем 3.1.9/Работа с макетами офисных документов

В некоторых процедурах присутствуют параметры с меткой "Удалить", они не используются в процедурах, но и не везде им задано значение по умолчанию, поэтому при вызове процедуры нужно их указывать, чтобы не поймать ошибку.

 

ИнициализироватьМакетОфисногоДокумента

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

Пример вызова

Макет = УправлениеПечатью.ИнициализироватьМакетОфисногоДокумента(ДвоичныеДанныеМакета, УдалитьТипМакета, УдалитьИмяМакета)

Параметры

ДвоичныеДанныеМакета - ДвоичныеДанные - двоичные данные макета;
УдалитьТипМакета     - Строка - устаревший параметр, не используется;
УдалитьИмяМакета     - Строка - устаревший параметр, не используется.

Возвращаемое значение

Структура:
* ИмяКаталога - Строка - путь, куда распаковывается контейнер DOCX шаблона для дальнейшего анализа;
* СтруктураДокумента - Структура - информация по областям, разделам и колонтитулам, входящих в шаблон.

 

ВставитьРазрывНаНовуюСтроку

Вставляет разрыв между строками в виде символа перевода строки.

Пример вызова

УправлениеПечатью.ВставитьРазрывНаНовуюСтроку(ПечатнаяФорма).

Параметры

ПечатнаяФорма - см. УправлениеПечатью.ИнициализироватьПечатнуюФорму

 

ЗаполнитьПараметры

Заполняет параметры области печатной формы. Работает со всеми типами областей.

Пример вызова

УправлениеПечатью.ЗаполнитьПараметры(ПечатнаяФорма, Данные).

Параметры

ПечатнаяФорма - Структура - область печатной формы либо сама печатная форма.
Данные - Структура - данные заполнения.

 

ИнициализироватьПечатнуюФорму

Конструктор печатной формы в формате офисного документа.

Пример вызова

ПечатнаяФорма = УправлениеПечатью.ИнициализироватьПечатнуюФорму(УдалитьТипДокумента, УдалитьНастройкиСтраницыМакета, Макет)

Параметры

УдалитьТипДокумента            - Строка - устаревший параметр, не используется;
УдалитьНастройкиСтраницыМакета - Соответствие - устаревший параметр, не используется;
Макет                          - см. ИнициализироватьМакетОфисногоДокумента

Возвращаемое значение

Структура - описание создаваемой печатной формы:
* ИмяКаталога - Строка - путь, куда помещается структура каталогов конечного документа для последующей сборки контейнера DOCX.
* СтруктураДокумента - см. УправлениеПечатьюСлужебный.ИнициализироватьДокумент
* Тип - Строка
* ПоследняяВыделеннаяОбласть - Структура

 

ОбластьМакета

Получает область из макета печатной формы.

Пример вызова

Результат = УправлениеПечатью.ОбластьМакета(СсылкаНаМакет, ОписаниеОбласти).

Параметры

СсылкаНаМакет   - Структура - макет печатной формы.
ОписаниеОбласти - Структура:
    * ИмяОбласти - Строка - имя области;
    * ТипТипОбласти - Строка - тип области: 
      "ВерхнийКолонтитул", "НижнийКолонтитул",
      "ВерхнийТитульныйКолонтитул", "НижнийТитульныйКолонтитул",
      "ВерхнийЧетныйКолонтитул", "НижнийЧетныйКолонтитул",
      "Общая",
      "СтрокаТаблицы", 
      "Список".

Возвращаемое значение

Структура - область макета.

 

ОчиститьСсылки

Удаляет временные файлы, образовавшиеся после раскрытия xml-структуры макета. Необходимо вызывать каждый раз после завершения формирования макета и печатной формы, а также в случае аварийного завершения формирования.
Пример вызова

УправлениеПечатью.ОчиститьСсылки(ПечатнаяФорма, УдалитьЗакрытьПриложение).

Параметры

ПечатнаяФорма            - см. УправлениеПечатью.ИнициализироватьПечатнуюФорму
УдалитьЗакрытьПриложение - Булево    - устаревший параметр, не используется.

 

ПрисоединитьИЗаполнитьКоллекцию

Добавляет область в печатную форму из макета, при этом заменяет параметры в области значениями из данных объекта. Применяется при множественном выводе области выводе области. (В этом месте на ИТС опечатка). Применяется этот метод только для областей с типом СтрокаТаблицы и Список
 

Пример вызова

УправлениеПечатью.ПрисоединитьИЗаполнитьКоллекцию(ПечатнаяФорма, ОбластьМакета, Данные, ПереходНаСледСтроку).

Параметры

ПечатнаяФорма - см. УправлениеПечатью.ИнициализироватьПечатнуюФорму
ОбластьМакета - см. УправлениеПечатью.ОбластьМакета
Данные - Массив - коллекция элементов типа Структура - данные объекта.
ПереходНаСледСтроку - Булево - Истина, если требуется вставить разрыв после вывода области.

 

ПрисоединитьОбласть

Присоединяет область в печатную форму из макета. Применяется при одиночном выводе области.

Пример вызова

УправлениеПечатью.ПрисоединитьОбласть(ПечатнаяФорма, ОбластьМакета, ПереходНаСледующуюСтроку).

Параметры

ПечатнаяФорма - см. УправлениеПечатью.ИнициализироватьПечатнуюФорму
ОбластьМакета - см. УправлениеПечатью.ОбластьМакета
ПереходНаСледующуюСтроку - Булево - Истина, если требуется вставить разрыв после вывода области.

 

ПрисоединитьОбластьИЗаполнитьПараметры

Добавляет область в печатную форму из макета, при этом заменяя параметры в области значениями из данных объекта. Применяется при одиночном выводе области.

Пример вызова

УправлениеПечатью.ПрисоединитьОбластьИЗаполнитьПараметры(ПечатнаяФорма, ОбластьМакета, Данные, ПереходНаСледующуюСтроку).

Параметры

ПечатнаяФорма - см. УправлениеПечатью.ИнициализироватьПечатнуюФорму
ОбластьМакета - см. УправлениеПечатью.ОбластьМакета
Данные - Структура - данные заполнения.
ПереходНаСледующуюСтроку - Булево - Истина, если требуется вставить разрыв после вывода области.

 

СформироватьДокумент

Формирует файл выходной печатной формы и помещает его в хранилище. Необходимо вызывать после помещения в структуру печатной формы всех необходимых областей.
Пример вызова

Результат = УправлениеПечатью.СформироватьДокумент(ПечатнаяФорма).

Параметры

ПечатнаяФорма - см. УправлениеПечатью.ИнициализироватьПечатнуюФорму

Возвращаемое значение

Строка - адрес хранилища, куда помещается сформированный файл.

 

Макет

 

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

Для указания параметра в макете мы пишем {v8 ИмяПараметра}.

При формировании печатной формы для заполнения областей мы передаем структуру, где ключ – это имя параметра. Всё, что мы передаем в качестве значения параметра будет преобразовано в строку методом Строка(). Если необходимо соблюдать определённое форматирование, то следует при заполнении структуры данных самостоятельно преобразовать значение в строку, отформатировать согласно требованиям.

Параметр можно указать в качестве адреса гиперссылки и заполнить его.

При формировании макета мне пришлось перепроверять форматирование параметров, потому что копировал из другого документа. Стало интересно как определяется форматирование текста, выводимого в параметр. Опытным путем было установлено, что форматирование определяется по первому символу имени параметра. Проверил я это с помощью ЛГБТ параметра

Я проверял на выделении текста цветом, полагаю с остальным форматированием текста работает также.

Для указания области мы заключаем часть макета в "кавычки" такого вида:
Начало области - {v8 Область.НаименованиеОбласти}
Конец области - {/v8 Область.НаименованиеОбласти}
 

Начало и конец области должны быть в основной части документа, нельзя размещать область или одну из "кавычек" в таблице. Заметил, что текст внутри области и "кавычки", окружающие область, должны находиться на разных строках, иначе при получении области программа не видит текст внутри области. И не нужно помещать область в область при разборе макета, программа определит только область верхнего уровня, а внутреннюю не увидит.

Для вывода таблиц шапку таблицы и строку таблицы мы заключаем в отдельные области, также для вывода списка.


 

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

 

 

Для вывода разрыва страниц в макете нужно подготовить область с заключенным в неё разрывом страниц, и выводить его при необходимости.


 

Но не все области нужно обозначать "кавычками". Колонтитулы сами по себе являются областями. Их не нужно обозначать, к ним нужно обратиться по их имени, которое нельзя изменить. Есть 6 областей колонтитула. Они будут присутствовать в макете в зависимости от настроек документа.

ВерхнийЧетныйКолонтитул, НижнийЧетныйКолонтитул – эти области появляются, если установлена настройка "Разные колонтитулы для четных и не четных страниц", это колонтитул четных страниц.

ВерхнийТитульныйКолонтитул, НижнийТитульныйКолонтитул – эти области появляются, если установлена настройка "Особый колонтитул для первой страницы", и как видно из названия это колонтитул первой страницы.

ВерхнийКолонтитул, НижнийКолонтитул – эти области появляются без специальных настроек, если включен отдельный колонтитул для первой страницы, то область будет обозначать колонтитул для всех остальных страниц. Если включена настройка различных четных и нечетных колонтитулов, то будет отвечать за нечетные колонтитулы.

При получении области из макета необходимо передать и имя области, и тип области: СтрокаТаблицы - для вывода таблицы; Список - для вывода списка; ВерхнийКолонтитул, ВерхнийЧетныйКолонтитул, ВерхнийТитульныйКолонтитул, НижнийКолонтитул, НижнийЧетныйКолонтитул, НижнийТитульныйКолонтитул - для вывода колонтитулов; Общая - для всего остального.

Заметил, что при разборе макета даже из пустого документа читается область "Абзац", её можно использовать как общую область (там просто символ переноса строки).

 

Принцип построения процедуры формирования документа

 
 Все процедуры формирования документа выполняются на сервере.

 

Теперь посмотрим, как мы можем заполнить документ. В основном вывод областей выглядит следующим образом. Сначала получаем область. Затем выводим её в документ и параллельно заполняем параметры.

ОбластьМакета = УправлениеПечатью.ОбластьМакета(Макет, Новый Структура("ИмяОбласти, ТипОбласти","ОбластьВМакете","Общая"));
УправлениеПечатью.ПрисоединитьОбластьИЗаполнитьПараметры(ПечатнаяФорма, ОбластьМакета, СтруктураСДаннымиДляЗаполнения, ПереходНаСледСтроку);
 

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

УправлениеПечатью.ЗаполнитьПараметры(ОбластьМакета, СтруктураСДаннымиДляЗаполнения);
УправлениеПечатью.ПрисоединитьОбласть(ПечатнаяФорма, ОбластьМакета, ПереходНаСледующуюСтроку);

 

Можно сначала сформировать документ и вывести в него все области, а уже после заполнить параметры в печатной форме. Отмечу, что области можно получить заранее в начале блока заполнения. Если вы используете одну область несколько раз, заполняете параметры в области методом ЗаполнитьПараметры, то заполнить её другими значениями уже не получится. Такой проблемы не возникнет, если использовать методы ПрисоединитьОбластьИЗаполнитьПараметры и ПрисоединитьИЗаполнитьКоллекцию, так как они сначала выводят область в печатную форму, а затем заполняют параметры. Либо сначала вывести область в макет, а затем заполнить параметры. Это аналогично методу ПрисоединитьОбластьИЗаполнитьПараметры.

Вывод таблицы или списка можно реализовать разными способами. Вариант 1: выполнить заполнение и вывод области в цикле.

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

Вариант 2: выполнить заполнение, используя метод ПрисоединитьИЗаполнитьКоллекцию, он работает также, просто не придется реализовывать цикл. 

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

 

При необходимости можно вставить перенос строки, используя отдельную процедуру или, передав Истина в параметр процедуры заполнения "ПереходНаСледующуюСтроку".

УправлениеПечатью.ВставитьРазрывНаНовуюСтроку(ПечатнаяФорма);

 

Вывод картинок. Нашел два способа вывода картинок, точнее способы передачи параметра картинки. Первый рабочий второй нет. Второй метод не работает из-за ошибки в методе, разберем по порядку.

Можно выводить картинку также в параметр. Для этого создаем структуру со свойствами Ширина, Высота, АдресКартинки. АдресКартинки – это адрес двоичных данных во временном хранилище, что такое Высота и Ширина и так понятно. Задавать значения ширины и высоты не обязательно (он и без них её выведет), либо можно задать что-то одно, и программа рассчитает второй параметр пропорционально первому. Получившуюся структуру засовываем в другую структуру, в которой уже Ключ – это имя параметра в макете и выводим любым понравившимся методом.

СтруктураКартинки = Новый Структура;
СтруктураКартинки.Вставить("Ширина", 50);
СтруктураКартинки.Вставить("Высота", 50);
СтруктураКартинки.Вставить("АдресКартинки", АдресКартинки);

ОбластьМакета = УправлениеПечатью.ОбластьМакета(Макет, Новый Структура("ИмяОбласти, ТипОбласти","Область1","Общая"));
УправлениеПечатью.ПрисоединитьОбластьИЗаполнитьПараметры(ПечатнаяФорма, ОбластьМакета, Новый Структура("Параметр", СтруктураКартинки));
 

Второй способ (напоминаю, что он не работает из-за ошибки в коде) не требует формировать структуру, можно в качестве параметра передать адрес двоичных данных во временном хранилище.

ОбластьМакета = УправлениеПечатью.ОбластьМакета(Макет, Новый Структура("ИмяОбласти, ТипОбласти","Область1","Общая"));
УправлениеПечатью.ПрисоединитьОбластьИЗаполнитьПараметры(ПечатнаяФорма, ОбластьМакета, Новый Структура("Параметр", АдресКартинки));
 

Но в процедуре заполнения есть ошибка. Если мы передаем адрес, то программа понимает, что это картинка, но не определяет структуру с её размерами. Если мы передаем в качестве параметра структуру с адресом, даже, если там нет значений ширины и высоты, то структура для указания размеров будет определена дальше в коде. Для справки: ошибка находится в модуле УправлениеПечатьюСлужебный в процедуре ЗаполнитьПараметрыОбласти. 

 

 

Автор: Виктор Ф., разработчик 1С 

См. также

БСП (Библиотека стандартных подсистем) Программист Стажер Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

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

10.09.2024    986    MadRave    1    

11

БСП (Библиотека стандартных подсистем) Программист Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

А что, если долгожданная реализация Паузы в 1С смутно напоминает старую, проверенную? А?!

06.09.2024    879    n_mezentsev    10    

7

БСП (Библиотека стандартных подсистем) Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Добавим дополнительные свойства в новый документ средствами БСП

02.09.2024    3535    John_d    10    

51

БСП (Библиотека стандартных подсистем) Программист Платформа 1С v8.3 1С:Розница 3.0 Россия Бесплатно (free)

Описание возможности печати произвольного QR-кода в текстовом (не фискальном) документе ККМ с помощью типовых функций БПО.

22.07.2024    682    KirillZ44    6    

9

Инструментарий разработчика БСП (Библиотека стандартных подсистем) Программист Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

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

2 стартмани

03.05.2024    1653    25    Hitcher    3    

13
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. Neuroproton 32 30.07.24 06:11 Сейчас в теме
Классная штука, конечно, писал такие ПФ. Есть один огромный для меня минус, никак не проверить, вмещается ли область на страницу. Это сильно мешало, пришлось даже уговорить клиента на "ручную" доработку (самому удалить или добавить перенос строки) после формирования ПФ
PROSTO-1C; +1 Ответить
8. Aleskey_K 35 01.08.24 10:38 Сейчас в теме
(1) в шаблоне есть возможность настроить "не отрывать от следующего", "не разрывать абзац". Возможно, поможет.
9. Neuroproton 32 01.08.24 12:29 Сейчас в теме
(8) что я только не пробовал, глючит страшно, то не выведет что-то, то разнесет весь текст за поля, жуткая вещь... Возможно, дело в кривых шаблонах от клиента, но намучался я знатно
2. cheshirshik 70 30.07.24 11:20 Сейчас в теме
Странно, что тут нет адептов секты СОМ. Я за новые технологии. В современных реалиях, когда сервера на Винде говорят "До свидания" данные технологии будут востребованы. Статью плюсую. Пригодится.
PROSTO-1C; Maindevice; brr; +3 Ответить
3. Maindevice 30.07.24 21:05 Сейчас в теме
Вопрос. А макет офисного документа каким образом задаётся? Это Word документ инициализированный, как двоичные данные?
Тема сама по себе крайне практичная. Неоднократные проблемы с COM объектами и не особо понятный код (смесь русского и английского в синтаксисе) вызывают у меня стойкое отвращение при работе с данными объектами. Хочется с этим сталкиваться по минимуму.
PROSTO-1C; +1 Ответить
4. Wilka 105 30.07.24 23:19 Сейчас в теме
(3)
Вопрос. А макет офисного документа каким образом задаётся? Это Word документ инициализированный, как двоичные данные?

Макет ворд идет в формате docx, это означает что используется разметка Office Open XML. Вы можете любой файл в формате docx распаковать и увидите из чего он состоит.
user1201514; PROSTO-1C; +2 Ответить
5. YA_112988337 31.07.24 06:46 Сейчас в теме
(3) Да всё правильно. Это документ docx в двоичных данных. Если например мы делаем это во внешней печатной форме то загружаем документ docx в макеты как двоичные данные и уже там где нужно получаем его через ПолучитьМакеет("ИмяМакетаСДвоичнымиДаннымиDocx")
PROSTO-1C; +1 Ответить
6. d.zhukov 1455 31.07.24 10:22 Сейчас в теме
Можно ли с помощью данного механизма установить автора документа?
PROSTO-1C; +1 Ответить
7. YA_112988337 31.07.24 11:13 Сейчас в теме
(6) Насколько я знаю функции БСП данного программного интерфейса не позволяют это сделать
PROSTO-1C; +1 Ответить
10. glek 120 02.08.24 10:08 Сейчас в теме
Классная, удобная штука. Только так и смог победить вывод типа первый лист - портрет, второй - альбом, остальные портрет. Пришлось делать на COM.
PROSTO-1C; +1 Ответить
11. user1755379 15.08.24 09:24 Сейчас в теме
(6) Можно в колонтитулах настроить указание автора и вывести область колонтитулов в документ.
12. akR00b 24 06.09.24 15:04 Сейчас в теме
с картинкой +, изучив метод вывода БСП пришили к понимаю что нужна структура. Информации по этой теме не было.
Оставьте свое сообщение