При разработке печатных форм и отчетов перед разработчиком нередко встает задача выгрузить данные в формат Microsoft Word (DOCX). Часто требуется не просто сформировать файл на диске, но и автоматически открыть его пользователю либо изначально создать сложный текстовый документ, например договор или доверенность со строгим форматированием.
Разберем основные подходы к решению этой задачи: использование встроенных средств платформы 1С для прямого экспорта, запуск файла без явного сохранения пользователем, а также альтернативный вариант с прямым формированием документа в Microsoft Word через COM-соединение по готовому шаблону.
Начиная с современных версий платформы 1С:Предприятие 8, табличный документ можно сохранить в формат Word напрямую с помощью встроенного метода Записать(). Для этого не требуется наличие установленного пакета Microsoft Office на компьютере или сервере.
Посмотрим на пример кода, где сформированный табличный документ сохраняется на диск:
ИмяФайла = "C:\Temp\ИндивидуальнаяУчетнаяКарточкаОС.docx";
ТабДокумент.Записать(ИмяФайла, ТипФайлаТабличногоДокумента.DOCX);
Проанализируем особенности этого метода:
Часто требуется открыть файл в Microsoft Word сразу по кнопке, не заставляя пользователя вручную выбирать путь на диске. Прямо из оперативной памяти открыть стороннее приложение невозможно, но мы можем использовать временный каталог операционной системы.
Разберем по шагам алгоритм решения:
ПолучитьИмяВременногоФайла().ЗапуститьПриложение(). Файл откроется в программе, которая ассоциирована в операционной системе с расширением .docx.Посмотрим на пример программной реализации:
// Получаем путь во временном каталоге
ВременныйФайл = ПолучитьИмяВременногоФайла("docx");
// Сохраняем сформированный табличный документ
ТабДокумент.Записать(ВременныйФайл, ТипФайлаТабличногоДокумента.DOCX);
// Открываем документ в ассоциированном приложении (MS Word)
ЗапуститьПриложение(ВременныйФайл);
При таком подходе файл физически сохраняется на диске во временной папке, но для пользователя процесс выглядит как мгновенное открытие печатной формы в Word без лишних диалоговых окон.
Если печатная форма представляет собой договор, соглашение или доверенность со сплошным текстом, попытка сверстать ее через ячейки табличного документа 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;
Выясним причину, почему данный метод требует осторожности:
Word.Application доступен только в среде Windows при установленном Microsoft Office.WINWORD.EXE в памяти и падению служб кластера.Попытка ... Исключение, чтобы в случае ошибки гарантированно освобождать ресурсы и закрывать приложение методом Quit().Таким образом, для простых отчетов и табличных выгрузок оптимально использовать встроенный метод ТабличныйДокумент.Записать() с типом DOCX, а для типовых договорных форм со сплошным текстом — непосредственное заполнение шаблонов.