Как вставить картинку в документ MS Word в определенное место через 1С?

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

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

Подготовка окружения и инициализация COM-объекта

Для начала работы нам необходимо создать экземпляр приложения Word и открыть целевой файл. Рассмотрим базовый блок кода, который подготавливает документ к работе. Важно помнить о корректной обработке исключений, чтобы в случае ошибки сеанс Word не остался «висеть» в памяти сервера или клиентского компьютера.


// Инициализация приложения
Попытка
    WD = Новый COMОбъект("Word.Application");
Исключение
    Сообщить("Не удалось запустить MS Word. Проверьте установку приложения.");
    Возврат;
КонецПопытки;

// Открытие документа
Попытка
    WordDoc = WD.Documents.Open(ПолноеИмяФайла, , Ложь); // Открываем не только для чтения
Исключение
    WD.Quit();
    Сообщить("Ошибка при открытии файла: " + ПолноеИмяФайла);
    Возврат;
КонецПопытки;

WD.Visible = Ложь; // Скрываем окно для ускорения работы

Проблема использования Selection и переход к Range

Многие начинающие разработчики используют объект Selection, который представляет текущий курсор или выделенную область. Однако при программном открытии документа курсор по умолчанию стоит в самом начале. Если вызвать метод AddPicture у Selection, картинка предсказуемо окажется на первой странице.

Проанализируем более надежный подход: использование объекта Range (диапазон). Объект Range позволяет нам обращаться к любому участку документа, не перемещая видимый курсор. Чтобы вставить картинку в конкретное место, нам нужно сначала найти это место. Самый простой способ — использовать текстовую метку-заполнитель (например, «[МЕСТО_ПЕЧАТИ]»).

Решение 1: Поиск метки через перебор параграфов

Если структура документа простая, мы можем перебрать все абзацы (параграфы) и найти тот, который содержит нашу метку. Этот метод нагляден и прост в реализации.


ПутьККартинке = "C:\Temp\Signature.png";
Метка = "[ПОДПИСЬ]";

// Перебираем параграфы документа
Для Каждого ТекущийПараграф Из WordDoc.Paragraphs Цикл
    // Проверяем наличие текста метки в тексте параграфа
    Если СтрНайти(ТекущийПараграф.Range.Text, Метка) > 0 Тогда
        
        // Удаляем текст метки перед вставкой картинки
        ТекущийПараграф.Range.Text = СтрЗаменить(ТекущийПараграф.Range.Text, Метка, "");
        
        // Вставляем картинку в диапазон этого параграфа
        Картинка = ТекущийПараграф.Range.InlineShapes.AddPicture(ПутьККартинке, Ложь, Истина);
        
        // Настройка размеров (в пунктах)
        Картинка.Height = 60; 
        Картинка.Width  = 120;
        
        Прервать; // Выходим из цикла, если метка найдена и обработана
    КонецЕсли;
КонецЦикла;

Решение 2: Использование технологии Закладок (Bookmarks)

Рассмотрим более профессиональный метод. В шаблоне Word можно заранее расставить «Закладки» (в меню Word: Вставка -> Закладка). Это именованные области, к которым можно обратиться напрямую по имени. Это гораздо быстрее и надежнее, чем поиск по тексту, так как текст метки может случайно измениться пользователем.


ИмяЗакладки = "МестоПечати";

Если WordDoc.Bookmarks.Exists(ИмяЗакладки) Тогда
    // Получаем диапазон закладки
    ОбластьВставки = WordDoc.Bookmarks.Item(ИмяЗакладки).Range;
    
    // Вставляем изображение
    НоваяКартинка = ОбластьВставки.InlineShapes.AddPicture(ПутьККартинке, Ложь, Истина);
    
    // Можно задать масштаб в процентах от оригинала
    НоваяКартинка.ScaleHeight = 80;
    НоваяКартинка.ScaleWidth  = 80;
Иначе
    Сообщить("Закладка " + ИмяЗакладки + " не найдена в шаблоне!");
КонецЕсли;

Разница между InlineShapes и Shapes

Выясним важный технический нюанс. В объектной модели Word существует две коллекции для графики:

  1. InlineShapes: Картинка вставляется «в текст». Она ведет себя как большой символ. Если вы добавите текст выше, картинка сдвинется вниз вместе со строкой. Это идеально подходит для подписей в актах и счетах.
  2. Shapes: Это «плавающие» объекты. Они имеют абсолютные координаты на странице (X, Y) и могут располагаться поверх текста или под ним. Используйте Shapes.AddPicture, если вам нужно наложить «мокрую» печать поверх текста так, чтобы буквы просвечивали (для этого дополнительно настраивается прозрачность и обтекание).

Работа с изображениями из базы данных 1С

Чаще всего картинки хранятся в 1С в справочниках или регистрах сведений в виде типа ХранилищеЗначения. Поскольку COM-объект Word требует физический путь к файлу на диске, мы должны выполнить предварительную выгрузку.

Проанализируем шаги:

  1. Извлекаем двоичные данные из хранилища.
  2. Генерируем уникальное имя файла во временном каталоге.
  3. Записываем файл на диск.
  4. Передаем путь в Word.
  5. Удаляем временный файл после закрытия документа.

// Получаем картинку (например, из реквизита справочника)
ДвоичныеДанные = Справочники.Организации.НайтиПоНаименованию("НашаФирма").Печать.Получить();

Если ДвоичныеДанные <> Неопределено Тогда
    ИмяФайлаКартинки = КаталогВременныхФайлов() + "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С, вы сможете формировать профессиональные печатные формы любой сложности.

← На главную