При разработке серверных механизмов в 1С часто возникает задача автоматической обработки документов Microsoft Word. Традиционный путь через использование Word.Application (COM-объект) имеет существенные недостатки: он требует установки лицензионного пакета Microsoft Office на сервере, работает медленно и нестабильно в многопоточной среде, а также абсолютно недоступен при использовании серверов под управлением Linux. В этой статье мы разберем современные и эффективные способы чтения файлов Word, которые не требуют наличия установленного офиса на стороне сервера.
Прежде чем писать собственный парсер, проанализируем возможности, которые уже заложены в типовые решения от фирмы 1С. В библиотеке стандартных подсистем (БСП) и конфигурации «1С:Документооборот» (ДО) реализованы механизмы работы с файлами .docx, которые не используют COM-соединение. Это возможно благодаря тому, что формат .docx по своей сути является ZIP-архивом, содержащим набор XML-файлов. При необходимости повысить скорость формирования таких файлов можно применить способ оптимизации и ускорения печати в DOCX средствами БСП.
Рассмотрим, где именно в коде типовых решений можно найти примеры реализации:
УправлениеПечатью. Функции ИнициализироватьПечатнуюФорму и СформироватьДокумент позволяют работать с макетами офисных документов напрямую.ШаблоныПечатиОфисныхДокументов.СформироватьДокумент.АвтозаполнениеШаблоновФайловСервер и процедура ЗаполнитьФайлMSWordВXML.Принципиальное отличие здесь заключается в разделении форматов. Для старого бинарного формата .doc платформа все еще вынуждена обращаться к Word.Application, но для современного .docx используется «чистый» код 1С, который распаковывает архив и правит XML-структуру документа. Это позволяет выполнять операции на сервере без установки Word.
Если вам нужно просто извлечь текст из документа или произвести замену параметров, мы можем реализовать это самостоятельно, используя встроенные объекты платформы ЧтениеZipФайла и ЧтениеXML. Рассмотрим этот процесс по шагам.
Основной текст документа в формате .docx всегда располагается в файле word/document.xml внутри архива. Проанализируем пример кода для извлечения сырого текста из файла:
// Функция читает текст из файла docx на сервере
Функция ПрочитатьТекстИзDocx(ПутьКФайлу) Экспорт
ТекстДокумента = "";
ПутьКоВременномуФайлу = ПолучитьИмяВременногоФайла("zip");
КопироватьФайл(ПутьКФайлу, ПутьКоВременномуФайлу);
Архив = Новый ЧтениеZipФайла(ПутьКоВременномуФайлу);
ПутьРаспаковки = ПолучитьИмяВременногоФайла("");
СоздатьКаталог(ПутьРаспаковки);
// Извлекаем только основной контент
ЭлементАрхива = Архив.Элементы.Найти("word/document.xml");
Если ЭлементАрхива <> Неопределено Тогда
Архив.Извлечь(ЭлементАрхива, ПутьРаспаковки);
КонецЕсли;
Архив.Закрыть();
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.ОткрытьФайл(ПутьРаспаковки + "/word/document.xml");
Пока ЧтениеXML.Прочитать() Цикл
// Текст в OpenXML хранится внутри тегов <w:t>
Если ЧтениеXML.ТипУзла = ТипУзлаXML.НачалоЭлемента И ЧтениеXML.ЛокальноеИмя = "t" Тогда
ТекстДокумента = ТекстДокумента + ЧтениеXML.ПрочитатьСодержимое();
КонецЕсли;
КонецЦикла;
ЧтениеXML.Закрыть();
УдалитьФайлы(ПутьРаспаковки);
УдалитьФайлы(ПутьКоВременномуФайлу);
Возвращает ТекстДокумента;
КонецФункции
Важно: При таком подходе следует учитывать, что текст в XML может быть разбит на несколько узлов <w:t> даже внутри одного слова (например, из-за проверки орфографии или разного форматирования букв). Для сложной обработки (замена текста с сохранением стилей) рекомендуется использовать объект ЗаписьXML и аккуратно пересобирать структуру.
Если на сервере установлена ОС Windows или Linux, и вам требуется поддерживать не только .docx, но и старый формат .doc, можно использовать LibreOffice. Он отлично работает в так называемом "headless" режиме (без графического интерфейса).
Проанализируем ситуацию, когда нам нужно конвертировать документ в PDF или текст на сервере. Мы можем использовать объект ЗапуститьПриложение для вызова консольных команд LibreOffice. Это не требует COM-регистрации и работает значительно быстрее.
Пример команды для конвертации через серверный вызов:
Команда = "soffice --headless --convert-to pdf ""C:\Docs\Contract.doc"" --outdir ""C:\Temp""";
ЗапуститьПриложение(Команда,, Истина);
Этот способ хорош тем, что LibreOffice корректно обрабатывает сложные таблицы и вложенные объекты, которые трудно распарсить вручную через XML. Также для интеграции можно использовать объект com.sun.star.ServiceManager, если сервер позволяет использовать COM-соединения с OpenOffice.
Для высокопроизводительных задач, когда счет идет на тысячи документов в час, лучшим решением будет использование специализированных библиотек. Если ваш сервер работает на Windows, можно создать небольшую "обертку" на языке C# вокруг библиотеки DocumentFormat.OpenXml (разработка Microsoft). Эта библиотека специально создана для работы с офисными форматами без установки самого офиса.
Рассмотрим преимущества такого подхода:
Выясним еще одну интересную возможность платформы. Объект ФорматированныйДокумент в 1С умеет работать с HTML и RTF. Если ваша задача — отобразить содержимое Word-файла пользователю в управляемой форме или отредактировать его, вы можете предварительно сконвертировать .docx в HTML (например, через стороннюю утилиту pandoc) и загрузить результат в ФорматированныйДокумент.
// Пример загрузки HTML контента
МойДокумент = Новый ФорматированныйДокумент;
МойДокумент.УстановитьHTML(ТекстHTML, Новый Структура);
Хотя этот метод не является прямым чтением Word, он часто спасает при реализации визуальных редакторов шаблонов писем и договоров внутри 1С. Для оперативной обработки входящих заказов настраивается автоматическое создание договоров и счетов из электронных писем.
Подведем итог. Выбор метода зависит от ваших технических условий:
УправлениеПечатью или АвтозаполнениеШаблоновФайловСервер. Это самый безопасный и поддерживаемый путь.word/document.xml.Помните, что отказ от Word.Application на сервере — это залог стабильности вашей системы и существенная экономия на лицензиях ПО.