Как правильно программно сохранить табличный документ в MS Word и открыть его?

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

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

Разберем основные подходы к решению этой задачи: использование встроенных средств платформы 1С для прямого экспорта, запуск файла без явного сохранения пользователем, а также альтернативный вариант с прямым формированием документа в Microsoft Word через COM-соединение по готовому шаблону.

Способ 1. Штатное сохранение табличного документа в формат DOCX

Начиная с современных версий платформы 1С:Предприятие 8, табличный документ можно сохранить в формат Word напрямую с помощью встроенного метода Записать(). Для этого не требуется наличие установленного пакета Microsoft Office на компьютере или сервере.

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


ИмяФайла = "C:\Temp\ИндивидуальнаяУчетнаяКарточкаОС.docx";
ТабДокумент.Записать(ИмяФайла, ТипФайлаТабличногоДокумента.DOCX);

Проанализируем особенности этого метода:

  1. Кроссплатформенность: Экспорт выполняется платформенным механизмом. Код успешно отрабатывает как на клиенте под Windows или Linux, так и на стороне сервера 1С.
  2. Специфика макета: Табличный документ при конвертации преобразуется в единую сетку таблиц Word. Если печатная форма содержит секции с разным количеством и шириной колонок, объединенные ячейки, итоговый документ Word может получиться сложным для ручного редактирования пользователем.
  3. Параметры печати: Чтобы документ открылся корректно, рекомендуется заранее настроить свойства табличного документа (ориентацию страницы, поля, масштаб), так как они переносятся в параметры разделов DOCX.

Способ 2. Открытие сформированного документа без сохранения пользователем

Часто требуется открыть файл в Microsoft Word сразу по кнопке, не заставляя пользователя вручную выбирать путь на диске. Прямо из оперативной памяти открыть стороннее приложение невозможно, но мы можем использовать временный каталог операционной системы.

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

  1. Генерируем уникальное имя файла во временном каталоге с помощью функции ПолучитьИмяВременногоФайла().
  2. Сохраняем табличный документ в формате DOCX по полученному пути.
  3. Запускаем внешнее приложение через процедуру ЗапуститьПриложение(). Файл откроется в программе, которая ассоциирована в операционной системе с расширением .docx.

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


// Получаем путь во временном каталоге
ВременныйФайл = ПолучитьИмяВременногоФайла("docx");

// Сохраняем сформированный табличный документ
ТабДокумент.Записать(ВременныйФайл, ТипФайлаТабличногоДокумента.DOCX);

// Открываем документ в ассоциированном приложении (MS Word)
ЗапуститьПриложение(ВременныйФайл);

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

Способ 3. Формирование документа сразу в Word через COM-объект по шаблону

Если печатная форма представляет собой договор, соглашение или доверенность со сплошным текстом, попытка сверстать ее через ячейки табличного документа 1С часто приводит к визуальным дефектам при экспорте. В таких ситуациях правильнее формировать документ непосредственно в Word, используя заранее подготовленный шаблон с текстовыми метками-заполнителями.

Рассмотрим подробнее пример заполнения реквизитов и табличной части спецификации через COM-объект Word.Application:


// Создаем экземпляр приложения Word
мWord = СоздатьОбъект("Word.Application");
мWord.Visible = 0; 
мNewDoc = мWord.Documents;

// Открываем заранее подготовленный шаблон с метками вида [ПечНомерДоговора]
мШаблон = СокрЛП(КаталогШаблонов + "ШаблонДоговора.dotx"); 
мДок = мNewDoc.Add(мШаблон, 0, 0, 1);   

// Заполняем колонтитулы
мКолонтитул = мДок.Sections.Item(1).Headers.Item(1).Range;
мКолонтитул.Find.Execute("[ПечНомерДоговора]", 0, 0, , , , , , , мНомерДоговора, 2); 
мКолонтитул.Find.Execute("[ПечДатаДоговора]", 0, 0, , , , , , , Нрег(СокрЛП(мДатаДоговора)), 2); 

// Заменяем маркеры в основном тексте документа
мОбъект = мДок.Content;
мОбъект.Find.Execute("[ПечНомерДоговора]", 0, 0, , , , , , , мНомерДоговора, 2); 
мОбъект.Find.Execute("[ПечДатаДоговора]", 0, 0, , , , , , , Нрег(СокрЛП(мДатаДоговора)), 2); 
мОбъект.Find.Execute("[ПечПокупатель]", 0, 0, , , , , , , СокрЛП(мПокупатель), 2); 

// Если требуется заполнить таблицу номенклатуры (спецификацию)
Если ВидДоговора = Перечисление.ВидДоговора.ПоставкаТоваровПоСпецификации Тогда
    Счет.ВыбратьСтроки();
    СчетчикЦикла = 0;
    
    Пока Счет.ПолучитьСтроку() = 1 Цикл
        СчетчикЦикла = СчетчикЦикла + 1;
        // Добавляем новую строку в таблицу шаблона
        мОбъект.Tables(1).Rows.Add();
        
        // Заполняем ячейки созданной строки (с учетом смещения на строки заголовка)
        мОбъект.Tables(1).Cell(СчетчикЦикла + 1, 1).Range.Text = Счет.НомерСтроки;
        мОбъект.Tables(1).Cell(СчетчикЦикла + 1, 2).Range.Text = СокрЛП(Счет.Номенклатура.ПолнНаименование);
        мОбъект.Tables(1).Cell(СчетчикЦикла + 1, 3).Range.Text = СокрЛП(Формат(Счет.Количество, "Ч010.2"));
        мОбъект.Tables(1).Cell(СчетчикЦикла + 1, 4).Range.Text = Строка(Счет.Единица);
        мОбъект.Tables(1).Cell(СчетчикЦикла + 1, 5).Range.Text = глФрм(Счет.Цена);
        мОбъект.Tables(1).Cell(СчетчикЦикла + 1, 6).Range.Text = глФрм(Счет.Сумма);
    КонецЦикла;
КонецЕсли;

// Сохраняем результат и делаем окно Word видимым для пользователя
мДок.SaveAs(ИмяИтоговогоФайла);
мWord.Visible = 1; 
мWord.Application.WindowState = 1;

Выясним причину, почему данный метод требует осторожности:

  1. Зависимость от клиентской ОС: COM-объект Word.Application доступен только в среде Windows при установленном Microsoft Office.
  2. Недопустимость запуска на сервере: Нельзя вызывать интерактивный COM-объект Word в серверном коде или фоновых заданиях. Это может привести к зависанию процессов WINWORD.EXE в памяти и падению служб кластера.
  3. Обработка исключений: Работу с внешними COM-объектами всегда следует оборачивать в конструкцию Попытка ... Исключение, чтобы в случае ошибки гарантированно освобождать ресурсы и закрывать приложение методом Quit().

Таким образом, для простых отчетов и табличных выгрузок оптимально использовать встроенный метод ТабличныйДокумент.Записать() с типом DOCX, а для типовых договорных форм со сплошным текстом — непосредственное заполнение шаблонов.

← На главную