Как формировать документы DOCX в 1С на Linux без использования COM-объектов?

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

Переход с операционной системы Windows на Linux (например, Astra Linux) ставит перед разработчиком 1С серьезную проблему: привычный механизм COMОбъект, который годами использовался для взаимодействия с Microsoft Office, в среде Linux не существует. Если в вашей базе на Windows печатные формы формировались через Word.Application, то при переносе на Linux код перестанет работать, выдавая ошибку инициализации объекта. В рамках построения защищенной IT инфраструктуры на базе Astra Linux такие задачи требуют принципиально иного подхода.

В данной статье мы подробно разберем, как решить эту задачу с минимальными затратами, сохранив возможность формирования качественных документов в формате DOCX. Мы проанализируем несколько подходов: от низкоуровневой работы с XML до использования внешних микросервисов.

Метод 1: Прямая манипуляция XML внутри DOCX (Подход БСП)

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

Основная идея заключается в том, чтобы не "управлять" приложением Word, а напрямую изменять содержимое файла. Для реализации манипуляций с архивами можно использовать встроенные средства или изучить инструменты для распаковки и запаковки файлов, работающие на чистом языке 1С. Рассмотрим алгоритм реализации:

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

Посмотрим на пример кода, реализующего базовую логику замены текста:


// Пример упрощенной замены текста в XML
ПутьКДокументу = "word/document.xml";
ТекстДокумента = ЧтениеТекста.Прочитать(); 

// Важно помнить, что Word может разбивать одну метку на несколько тегов XML
// Например, "[ФИО]" может превратиться в "[", "ФИ", "О]" в разных тегах <w:t>
ТекстДокумента = СтрЗаменить(ТекстДокумента, "[ФИО]", ДанныеОбъекта.ФИО);

ЗаписьТекста = Новый ЗаписьТекста(ПутьКРаспакованномуФайлу, КодировкаТекста.UTF8);
ЗаписьТекста.Записать(ТекстДокумента);
ЗаписьТекста.Закрыть();

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

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

Если вам требуется сложное форматирование, работа с таблицами и списками, ручная правка XML может стать слишком трудоемкой. В этом случае рассмотрим вариант использования скрипта на языке Python. Подобный сценарий Python в среде Astra Linux позволяет значительно расширить возможности сервера 1С.

Библиотека docxtpl позволяет использовать синтаксис шаблонов (похожий на Jinja2) прямо внутри Word-файла. Вы подготавливаете шаблон, где переменные указаны в двойных фигурных скобках: {{ name }}. Скрипт на Python берет данные и "рендерит" готовый документ. Интересно, что несмотря на отказ от COM в Linux, знания о том, как устроен COM объект на Python для 1С, могут помочь в понимании принципов взаимодействия двух языков.

Пример скрипта:


from docxtpl import DocxTemplate

def generate_doc(template_path, output_path, data):
    doc = DocxTemplate(template_path)
    # data - это словарь с данными, например {'name': 'Иван Иванович'}
    doc.render(data)
    doc.save(output_path)

Из 1С этот скрипт можно вызвать через команду ЗапуститьПриложение. Это требует установленного интерпретатора Python на сервере или клиенте (в Astra Linux он предустановлен).

Метод 3: Создание легковесного HTTP-сервиса

Рассмотрим ситуацию, когда 1С работает на Linux-сервере, а обработку документов мы хотим вынести в отдельный сервис. Мы можем написать примитивный веб-сервер на Python или Go, который будет принимать данные в формате JSON, заполнять шаблон и возвращать готовый файл.

Проанализируем пример реализации серверной части на Python (используя стандартную библиотеку http.server и docxtpl):


# Упрощенный фрагмент серверной части
class DocxHandler(BaseHTTPRequestHandler):
    def do_POST(self):
        content_length = int(self.headers['Content-Length'])
        post_data = self.rfile.read(content_length)
        
        # Логика заполнения шаблона...
        # ...
        
        self.send_response(200)
        self.send_header('Content-type', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document')
        self.end_headers()
        self.wfile.write(generated_file_binary)

В 1С код вызова такого сервиса будет выглядеть современно и платформенно-независимо:


&НаКлиенте
Процедура СформироватьДокумент(Команда)
    Соединение = Новый HTTPСоединение("127.0.0.1", 8000);
    Запрос = Новый HTTPЗапрос("/");
    
    // Передаем имя шаблона и данные
    СтруктураДанных = Новый Структура("ИмяШаблона, ФИО", "Договор.docx", "Иванов Иван");
    ЗаписьJSON = Новый ЗаписьJSON;
    ЗаписьJSON.УстановитьСтроку();
    ЗаписатьJSON(ЗаписьJSON, СтруктураДанных);
    
    Запрос.УстановитьТелоИзСтроки(ЗаписьJSON.Закрыть());
    Ответ = Соединение.ОтправитьДляОбработки(Запрос);
    
    Если Ответ.КодСостояния = 200 Тогда
        ДвоичныеДанные = Ответ.ПолучитьТелоКакДвоичныеДанные();
        ДвоичныеДанные.Записать(ПутьКФайлуРезультату);
        ЗапуститьПриложение(ПутьКФайлуРезультату);
    КонецЕсли;
КонецПроцедуры

Метод 4: Использование LibreOffice в режиме Headless

Если вам нужно не только заполнить поля, но и конвертировать результат в PDF, лучшим инструментом в Linux будет LibreOffice. Он поддерживает работу через командную строку без запуска графического интерфейса.

Проанализируем команду для конвертации:

libreoffice --headless --convert-to pdf имя_файла.docx

Этот метод отлично сочетается с первым методом (правка XML): сначала вы создаете .docx путем замены текста в XML, а затем вызываете LibreOffice для финальной конвертации в PDF, если это необходимо пользователю.

Выводы и рекомендации

Мы рассмотрели несколько способов замены COM-технологии на Linux. Выбор конкретного пути зависит от ваших задач:

При переходе на Linux важно помнить, что идеология "управления приложением" (COM) уступает место идеологии "генерации контента". Рассмотрим этот переход не как проблему, а как возможность сделать систему более быстрой и стабильной.

← На главную