При разработке сложных отчетов или печатных форм в 1С часто возникает ситуация, когда структура документа формируется полностью динамически. В таких случаях у нас нет заранее подготовленного макета с именованными областями, куда можно было бы просто вставить картинку. Мы сталкиваемся с необходимостью добавить графический объект в ТабличныйДокумент «на лету» через встроенный язык. Разберем по шагам, как это сделать правильно, чтобы избежать искажений и неполного отображения картинки.
Для начала проанализируем базовый механизм. В объекте ТабличныйДокумент существует коллекция Рисунки, которая позволяет хранить не только картинки, но и диаграммы, текстовые блоки или графические примитивы. Когда мы не используем макет, нам необходимо обратиться к этой коллекции напрямую.
Рассмотрим пример кода, который создает новый рисунок и помещает его в документ:
// Создаем новый табличный документ, если он еще не создан
ТабДок = Новый ТабличныйДокумент;
// Добавляем новый объект-рисунок в коллекцию
Рисунок = ТабДок.Рисунки.Добавить(ТипРисункаТабличногоДокумента.Картинка);
// Загружаем саму картинку
КартинкаОбъект = Новый Картинка(ПутьКФайлу);
Рисунок.Картинка = КартинкаОбъект;
На этом этапе мы создали контейнер, но он еще «не знает», где именно находиться на листе и какого он должен быть размера. Если оставить координаты по умолчанию, рисунок может просто не отобразиться или перекрыть важные данные.
Существует два основных способа размещения рисунка. Выясним, какой из них удобнее в разных ситуациях.
Способ 1: Использование координат в миллиметрах. Свойства Верх, Лево, Ширина и Высота объекта Рисунок принимают значения в миллиметрах. Это удобно, если вы точно знаете параметры печатной страницы. Однако здесь кроется главная ловушка: если вы установите Рисунок.РазмерКартинки = РазмерКартинки.РеальныйРазмер, а размер контейнера (в мм) окажется меньше физического размера картинки, вы увидите лишь фрагмент изображения. Для визуального замера областей документа в миллиметрах можно использовать экранную линейку для подгонки печатных форм.
Способ 2: Метод Расположить(). Это наиболее гибкий метод при программном выводе. Мы можем указать область ячеек, в границах которой должен находиться рисунок. Проанализируем пример:
// Определяем область ячеек, где будет картинка (например, с 2 по 10 строку и со 2 по 5 колонку)
ОбластьДляКартинки = ТабДок.Область(2, 2, 10, 5);
// Привязываем рисунок к этой области
Рисунок.Расположить(ОбластьДляКартинки);
Этот метод автоматически вычислит координаты в миллиметрах на основе высоты строк и ширины колонок. Это позволяет «вписать» логотип или фото товара прямо в сетку таблицы, которую мы формируем программно.
Посмотрим на ситуацию, когда выводится только маленький фрагмент изображения. Это происходит из-за несоответствия размеров контейнера-рисунка и физических параметров файла JPG. Чтобы картинка всегда отображалась целиком, крайне важно правильно настроить свойство РазмерКартинки.
Рассмотрим доступные варианты перечисления РазмерКартинки:
Расположить или координаты), сохранив свои пропорции. Она не растянется и не сожмется непропорционально.Рекомендуем использовать следующую комбинацию настроек:
Рисунок.РазмерКартинки = РазмерКартинки.Пропорционально;
// Отключаем отображение рамки, чтобы картинка смотрелась органично
Рисунок.Линия = Новый Линия(ТипЛинииРисункаТабличногоДокумента.НетЛинии);
Если ваша задача требует вывода картинки именно в её физическом размере (например, печать штрихкода или чертежа), нужно учитывать плотность пикселей. В 1С свойства Ширина и Высота рисунка — это миллиметры. Чтобы перевести пиксели в миллиметры, воспользуемся формулой: (Размер в пикселях / DPI) * 25.4.
Проанализируем программный способ получения этих данных:
КартинкаОбъект = Новый Картинка(ПутьКФайлу);
DPI_Горизонталь = КартинкаОбъект.ПлотностьПоГоризонтали();
DPI_Вертикаль = КартинкаОбъект.ПлотностьПоВертикали();
Если DPI_Горизонталь > 0 И DPI_Вертикаль > 0 Тогда
Рисунок.Ширина = (КартинкаОбъект.Ширина() / DPI_Горизонталь) * 25.4;
Рисунок.Высота = (КартинкаОбъект.Высота() / DPI_Вертикаль) * 25.4;
КонецЕсли;
Важно помнить, что если формирование табличного документа происходит на стороне сервера (например, в модуле менеджера или в фоновом задании), прямая инициализация Новый Картинка("C:\photo.jpg") может вызвать ошибку прав доступа. Сервер 1С может «не видеть» локальные диски вашего компьютера.
Правильный алгоритм совместной работы выглядит так:
ДвоичныеДанные.Картинка из этих данных.Пример безопасного кода:
// Считываем файл в двоичные данные
ДвоичныеДанныеФайла = Новый ДвоичныеДанные(ПутьКФайлу);
// Создаем картинку
НужнаяКартинка = Новый Картинка(ДвоичныеДанныеФайла);
// Назначаем рисунку
Рисунок.Картинка = НужнаяКартинка;
Подведем итог и соберем воедино все правила создания рисунка в динамическом табличном документе:
ТабДок.Рисунки.Добавить().ДвоичныеДанные для универсальности сервера и клиента).Рисунок.Расположить(ТабДок.Область(...)), предварительно объединив нужные ячейки через Объединить(), если картинка большая.РазмерКартинки.Пропорционально. Это гарантирует, что пользователь увидит изображение целиком, независимо от его исходного разрешения.НетЛинии.Следуя этим правилам, мы сможем формировать профессиональные отчеты с графикой, которые будут корректно выглядеть как на экране, так и при печати на принтере. При разработке стандартных документов с динамическими факсимиле и печатями можно использовать пример внешней печатной формы на БСП.