Как вставить параметры (ФИО, Дату) в документ Word из 1С?

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

При разработке на 1С часто возникает задача массовой генерации печатных форм в формате MS Word. Например, нам необходимо открыть большое количество шаблонов договоров или справок и вставить в них конкретные данные: ФИО, даты, суммы. Разберем по шагам несколько эффективных способов решения этой проблемы, от старых проверенных методов до современных нативных подходов и скриптов.

Способ 1: Использование COM-соединения (Word.Application)

Самый старый и известный способ — работа через ComApplication. В этом случае мы ищем в тексте документа заранее заданные ключевые слова (например, [ФИО] или [Дата]) и производим их замену.

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

  1. Требования к среде: На сервере 1С должен быть физически установлен лицензионный MS Word. Это невозможно на Linux-серверах.
  2. Нестабильность: Процессы WINWORD.EXE часто зависают в памяти, особенно при ошибках в коде 1С или при одновременной фоновой печати множества документов. Эти зависшие процессы начинают "утекать" по оперативной памяти и нагружать CPU сервера.
  3. Ограничения поиска: Стандартный метод поиска и замены в Word через COM имеет жесткое ограничение на длину заменяемой строки — не более 255 символов. Если нам нужно вставить длинный текст, этот метод выдаст ошибку, и придется использовать сложную работу с закладками.

Способ 2: Использование Python и библиотеки docxtpl

Если мы хотим сделать формирование быстрым "как пуля" и не зависеть от зависающих процессов Word, рассмотрим вариант с использованием небольшого скрипта на Python.

Для начала подготовим шаблон template.docx. В те места, куда нужно вставить данные, пропишем теги в двойных фигурных скобках:


{{fio}}
{{date}}

Далее установим Python и библиотеку docxtpl (команда pip install docxtpl). Посмотрим на пример кода простого фреймворка, который принимает данные из 1С через текстовый файл и массово генерирует документы:


from docxtpl import DocxTemplate

def do(file_name):
    data = ""
    with open(file_name, "r", encoding='utf-8') as f:
        data = f.read()
    
    # В data.txt данные передаются в виде списка списков:
    # [["Иванов Иван Иваныч", "01.03.1968"], ["Петров Иван...", "25.08.1978"]]
    all_data = eval(data)
    n = 0
    
    for d in all_data:
        fio, dt = d
        doc = DocxTemplate("template.docx")
        context = {'fio': fio, 'date': dt}
        doc.render(context)
        n += 1
        doc.save(f"{n}.docx")

do("data.txt")

В 1С нам останется только выгрузить нужные данные в файл data.txt и вызвать выполнение скрипта toword.py. Это работает очень быстро и не требует установленного офиса.

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

БСП умеет отлично работать с Word-шаблонами. Существует миф, что БСП делает это через COM-соединение. Выясним причину этого заблуждения: раньше это действительно было так. Но в современных версиях реализован нативный механизм разбора офисных документов (как .docx, так и .odt). 1С умеет на сервере (в том числе под управлением Linux) распаковывать документ, заменять параметры и собирать файл обратно без всякого COM.

Специфика разметки: В отличие от Python, где мы использовали {{fio}}, для БСП параметры в шаблоне нужно указывать по-другому:

  1. Простые параметры: {v8 ИмяПараметра} (например, {v8 ФИО}).
  2. Для вывода динамических таблиц: конструкции областей {v8 Область.СтрокаТаблицы}.

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

Способ 4: Полностью нативный метод 1С (без БСП, COM и Python)

Рассмотрим подробнее архитектуру формата .docx. По сути, это обычный ZIP-архив, внутри которого лежат папки с XML-файлами. Мы можем решить задачу массовой генерации средствами встроенного языка 1С без сторонних библиотек.

Разберем алгоритм по шагам:

  1. Загружаем шаблон .docx в базу как двоичные данные.
  2. При формировании распаковываем его во временный каталог, используя объект платформы ЧтениеZipФайла.
  3. Находим основной текст документа — он лежит по пути word/document.xml.
  4. Считываем этот файл и производим замену текста стандартной функцией СтрЗаменить() (ищем наши маркеры и меняем на переменные из 1С).
  5. Записываем измененный XML-файл обратно и упаковываем весь каталог с помощью ЗаписьZipФайла, указав расширение .docx.

Этот метод работает молниеносно, полностью кроссплатформенен и абсолютно безопасен для серверных процессов.

Лайфхак: Оптимизация массовой генерации документов

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

Для ускорения процесса мы можем один раз инициализировать макет, получить его готовую структуру в виде дерева XML и сохранить её в память (как строку или двоичные данные). При потоковой генерации 1С будет брать уже "предкомпилированную" структуру макета из кэша, что ускорит вывод файлов в несколько раз.

← На главную