При автоматизации документооборота часто возникает задача не просто заполнить текстовые поля в шаблоне Microsoft Word, но и вставить графические элементы: печати, подписи ответственных лиц или фотографии товаров. Стандартные методы записи в объект Selection часто приводят к тому, что изображение оказывается в самом начале документа, что не всегда удобно. В данной статье мы подробно разберем, как управлять позиционированием графики, используя объектную модель Word.Application через COM-соединение.
Для начала работы нам необходимо создать экземпляр приложения Word и открыть целевой файл. Рассмотрим базовый блок кода, который подготавливает документ к работе. Важно помнить о корректной обработке исключений, чтобы в случае ошибки сеанс Word не остался «висеть» в памяти сервера или клиентского компьютера.
// Инициализация приложения
Попытка
WD = Новый COMОбъект("Word.Application");
Исключение
Сообщить("Не удалось запустить MS Word. Проверьте установку приложения.");
Возврат;
КонецПопытки;
// Открытие документа
Попытка
WordDoc = WD.Documents.Open(ПолноеИмяФайла, , Ложь); // Открываем не только для чтения
Исключение
WD.Quit();
Сообщить("Ошибка при открытии файла: " + ПолноеИмяФайла);
Возврат;
КонецПопытки;
WD.Visible = Ложь; // Скрываем окно для ускорения работы
Многие начинающие разработчики используют объект Selection, который представляет текущий курсор или выделенную область. Однако при программном открытии документа курсор по умолчанию стоит в самом начале. Если вызвать метод AddPicture у Selection, картинка предсказуемо окажется на первой странице.
Проанализируем более надежный подход: использование объекта Range (диапазон). Объект Range позволяет нам обращаться к любому участку документа, не перемещая видимый курсор. Чтобы вставить картинку в конкретное место, нам нужно сначала найти это место. Самый простой способ — использовать текстовую метку-заполнитель (например, «[МЕСТО_ПЕЧАТИ]»).
Если структура документа простая, мы можем перебрать все абзацы (параграфы) и найти тот, который содержит нашу метку. Этот метод нагляден и прост в реализации.
ПутьККартинке = "C:\Temp\Signature.png";
Метка = "[ПОДПИСЬ]";
// Перебираем параграфы документа
Для Каждого ТекущийПараграф Из WordDoc.Paragraphs Цикл
// Проверяем наличие текста метки в тексте параграфа
Если СтрНайти(ТекущийПараграф.Range.Text, Метка) > 0 Тогда
// Удаляем текст метки перед вставкой картинки
ТекущийПараграф.Range.Text = СтрЗаменить(ТекущийПараграф.Range.Text, Метка, "");
// Вставляем картинку в диапазон этого параграфа
Картинка = ТекущийПараграф.Range.InlineShapes.AddPicture(ПутьККартинке, Ложь, Истина);
// Настройка размеров (в пунктах)
Картинка.Height = 60;
Картинка.Width = 120;
Прервать; // Выходим из цикла, если метка найдена и обработана
КонецЕсли;
КонецЦикла;
Рассмотрим более профессиональный метод. В шаблоне Word можно заранее расставить «Закладки» (в меню Word: Вставка -> Закладка). Это именованные области, к которым можно обратиться напрямую по имени. Это гораздо быстрее и надежнее, чем поиск по тексту, так как текст метки может случайно измениться пользователем.
ИмяЗакладки = "МестоПечати";
Если WordDoc.Bookmarks.Exists(ИмяЗакладки) Тогда
// Получаем диапазон закладки
ОбластьВставки = WordDoc.Bookmarks.Item(ИмяЗакладки).Range;
// Вставляем изображение
НоваяКартинка = ОбластьВставки.InlineShapes.AddPicture(ПутьККартинке, Ложь, Истина);
// Можно задать масштаб в процентах от оригинала
НоваяКартинка.ScaleHeight = 80;
НоваяКартинка.ScaleWidth = 80;
Иначе
Сообщить("Закладка " + ИмяЗакладки + " не найдена в шаблоне!");
КонецЕсли;
Выясним важный технический нюанс. В объектной модели Word существует две коллекции для графики:
Shapes.AddPicture, если вам нужно наложить «мокрую» печать поверх текста так, чтобы буквы просвечивали (для этого дополнительно настраивается прозрачность и обтекание).Чаще всего картинки хранятся в 1С в справочниках или регистрах сведений в виде типа ХранилищеЗначения. Поскольку COM-объект Word требует физический путь к файлу на диске, мы должны выполнить предварительную выгрузку.
Проанализируем шаги:
// Получаем картинку (например, из реквизита справочника)
ДвоичныеДанные = Справочники.Организации.НайтиПоНаименованию("НашаФирма").Печать.Получить();
Если ДвоичныеДанные <> Неопределено Тогда
ИмяФайлаКартинки = КаталогВременныхФайлов() + "print_temp.png";
ДвоичныеДанные.Записать(ИмяФайлаКартинки);
// Далее используем ИмяФайлаКартинки в методе AddPicture...
// ...
КонецЕсли;
Работа с COM-объектами требует дисциплины в управлении памятью. Если не закрыть приложение корректно, диспетчер задач будет переполнен процессами WINWORD.EXE. Выясним, как правильно завершать сессию.
Рекомендуется использовать следующую схему очистки:
// Сохранение и закрытие
WordDoc.Save();
WordDoc.Close();
WordDoc = Неопределено;
// Если больше нет открытых документов, закрываем Word
Если WD.Documents.Count = 0 Тогда
WD.Quit(0); // 0 соответствует wdDoNotSaveChanges
КонецЕсли;
WD = Неопределено;
Важный совет: При использовании метода AddPicture всегда устанавливайте второй параметр LinkToFile в Ложь (False), а третий SaveWithDocument в Истина (True). Это гарантирует, что изображение будет физически внедрено в файл .docx, а не останется ссылкой на ваш локальный диск C:\Temp, которую клиент не увидит при открытии файла на другом компьютере.
Мы рассмотрели различные способы вставки графических объектов в документы MS Word. Использование коллекции Paragraphs и текстовых меток — это отличный способ для динамических шаблонов, а работа с Bookmarks — самый быстрый и стабильный вариант для фиксированных форм. Комбинируя эти знания с правильной работой с временными файлами в 1С, вы сможете формировать профессиональные печатные формы любой сложности.