Сохраняем изображения из базы 1С в файл: вручную, обработкой и через HTTP

· 10 мин

Содержание

Одну картинку из 1С проще всего выгрузить через список присоединённых файлов: откройте карточку объекта (например, номенклатуры), перейдите по ссылке Файлы, выделите изображение и выполните команду Сохранить как (если её нет на панели — она в меню Ещё). Файл сохранится на диск в исходном формате: JPG, PNG, BMP — в каком его загрузили.

Для сотен и тысяч изображений ручной путь не годится. Тут нужна внешняя обработка, которая берёт двоичные данные файлов запросом и пишет их в папку или ZIP-архив. Если картинки нужны сайту или другой программе — их отдают через HTTP-сервис с правильным заголовком Content-Type. Ниже все три сценария, плюс частые сбои и способы ускорить выгрузку.

Выгрузка изображения из 1С через обычный интерфейс

Большинство типовых конфигураций на 8.3 (Бухгалтерия 3.0, УТ 11, КА 2, ERP, УНФ) хранят картинки как присоединённые файлы. Механизм общий, поэтому порядок действий почти одинаковый.

Из карточки номенклатуры или другого объекта

  1. Откройте карточку товара, контрагента или документа.
  2. Перейдите по ссылке Файлы в шапке формы или по значку скрепки в командной панели.
  3. В списке файлов найдите нужное изображение. Колонка расширения подскажет формат.
  4. Выделите строку и выберите Сохранить как — в меню Ещё или в контекстном меню по правой кнопке.
  5. Укажите папку и имя. Расширение 1С подставит сама.

💡 Если нужно несколько файлов одного объекта, выделите их с зажатым Ctrl — команда сохранения работает и для группы строк, программа попросит выбрать каталог.

Через просмотр файла

Команда Открыть выгружает файл во временный каталог и запускает программу, которая в Windows связана с этим расширением. Из просмотрщика картинку можно сохранить уже его средствами. Способ рабочий, но временная копия остаётся в рабочем каталоге пользователя — для конфиденциальных изображений (сканы паспортов, договоров) лучше сразу Сохранить как.

Когда картинка лежит в поле формы

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

Картинка в печатной форме или отчёте

Логотип в счёте, факсимиле подписи, фото товара в прайс-листе — всё это табличный документ. Вытащить из него картинку можно двумя способами.

СпособКак сделатьЧто получите
Сохранить в ExcelВ форме печати кнопка сохранения → формат «Лист Microsoft Excel 2007 (XLSX)»Картинки внутри файла .xlsx
Найти исходникКарточка организации, настройки логотипа и подписейОригинальный файл в полном разрешении

Файл .xlsx — это обычный ZIP-архив. Переименуйте копию в .zip и откройте: изображения лежат в папке xl/media. Так удобно забрать сразу все картинки прайса.

⚠️ Картинка из печатной формы часто уже сжата и обрезана под размер ячейки. Если нужно качество — ищите оригинал. Логотип и подписи в Бухгалтерии 3.0 задают в карточке организации, в разделе с логотипом и факсимиле: оттуда и берите файл.

Где 1С хранит изображения и почему это важно для выгрузки

Способ выгрузки зависит от того, где физически лежат байты картинки. Вариантов три.

  • 📁 Присоединённые файлы в информационной базе. Справочники вида НоменклатураПрисоединенныеФайлы, сами данные — в служебном регистре сведений. Это вариант по умолчанию для типовых конфигураций.
  • 💾 Тома хранения файлов. Администратор может настроить хранение на диске сервера: в базе остаётся только запись о файле, а сам файл лежит в каталоге тома. Настройка — Администрирование → Общие настройки, блок про работу с файлами.
  • 🧩 Реквизит типа ХранилищеЗначения. Так хранят картинки в самописных решениях и в старых конфигурациях. Внутри — объект Картинка или ДвоичныеДанные.

Отдельный случай — картинки самой конфигурации: иконки команд, общие картинки. Они не данные, а часть метаданных. Из кода их получают так: БиблиотекаКартинок.ИмяКартинки.ПолучитьДвоичныеДанные().

Для программиста главное правило: в типовых конфигурациях не читайте регистр с данными файлов напрямую. Используйте функцию Библиотеки стандартных подсистем РаботаСФайлами.ДвоичныеДанныеФайла(). Она сама разберётся, в базе файл или на томе.

Чтение картинки из реквизита-хранилища выглядит так:

Значение = СсылкаНаОбъект.Картинка.Получить();
Если ТипЗнч(Значение) = Тип("Картинка") Тогда
	ДД = Значение.ПолучитьДвоичныеДанные();
	// Значение.Формат() вернёт ФорматКартинки: JPEG, PNG, BMP и т.д.
ИначеЕсли ТипЗнч(Значение) = Тип("ДвоичныеДанные") Тогда
	ДД = Значение;
Иначе
	ДД = Неопределено; // в хранилище пусто или лежит что-то другое
КонецЕсли;
Если ДД <> Неопределено Тогда
	ДД.Записать("C:\Выгрузка\picture.jpg");
КонецЕсли;

Здесь Картинка — имя реквизита в вашей конфигурации, подставьте своё.

Массовая выгрузка картинок номенклатуры внешней обработкой

Типовая задача: выгрузить фото всех товаров для маркетплейса или сайта, имя файла — код товара. В Бухгалтерии 3.0 и УТ 11 у номенклатуры есть реквизит ФайлКартинки — ссылка на основное изображение. Его и берём.

Схема обработки:

  1. Запрос выбирает товары с заполненной картинкой и сразу расширение файла.
  2. Для каждой строки получаем двоичные данные через БСП.
  3. Пишем файлы во временный каталог сервера и упаковываем в ZIP.
  4. Архив передаём на компьютер пользователя.

Серверная часть:

&НаСервере
Функция ВыгрузитьКартинкиНаСервере()

	Запрос = Новый Запрос;
	Запрос.Текст =
	"ВЫБРАТЬ
	|	Ном.Код КАК Код,
	|	Ном.ФайлКартинки КАК Файл,
	|	Ном.ФайлКартинки.Расширение КАК Расширение
	|ИЗ
	|	Справочник.Номенклатура КАК Ном
	|ГДЕ
	|	Ном.ФайлКартинки <> ЗНАЧЕНИЕ(Справочник.НоменклатураПрисоединенныеФайлы.ПустаяСсылка)
	|	И НЕ Ном.ПометкаУдаления";

	Каталог = ПолучитьИмяВременногоФайла("") + "\";
	СоздатьКаталог(Каталог);
	ИмяАрхива = ПолучитьИмяВременногоФайла("zip");
	Архив = Новый ЗаписьZipФайла(ИмяАрхива);

	Выборка = Запрос.Выполнить().Выбрать();
	Пока Выборка.Следующий() Цикл
		ДД = РаботаСФайлами.ДвоичныеДанныеФайла(Выборка.Файл, Ложь);
		Если ДД = Неопределено Тогда
			Продолжить; // файл недоступен, например, том не найден
		КонецЕсли;
		ИмяФайла = Каталог + СокрЛП(Выборка.Код) + "." + Выборка.Расширение;
		ДД.Записать(ИмяФайла);
		Архив.Добавить(ИмяФайла);
	КонецЦикла;

	Архив.Записать();
	Адрес = ПоместитьВоВременноеХранилище(Новый ДвоичныеДанные(ИмяАрхива), УникальныйИдентификатор);
	УдалитьФайлы(Каталог);
	УдалитьФайлы(ИмяАрхива);
	Возврат Адрес;

КонецФункции

Клиентская часть сохраняет архив через диалог:

&НаКлиенте
Процедура Выгрузить(Команда)
	Адрес = ВыгрузитьКартинкиНаСервере();
	ФайловаяСистемаКлиент.СохранитьФайл(Неопределено, Адрес, "kartinki.zip");
КонецПроцедуры

Разделитель \ в пути подходит для сервера на Windows. На Linux-сервере используйте ПолучитьРазделительПутиСервера().

Почему архив, а не запись прямо в C:\Выгрузка? В клиент-серверной базе серверный код пишет на диск сервера 1С, а не на компьютер пользователя. Файлы окажутся в чужой папке, и вы их не найдёте. Временное хранилище и сохранение на клиенте решают это и для файловой базы, и для веб-клиента.

Обработку подключают через Администрирование → Печатные формы, отчеты и обработки → Дополнительные отчеты и обработки или открывают через Файл → Открыть при наличии прав. Для запуска нужны права на чтение справочника номенклатуры и файлов.

Отдача картинки по HTTP: сайт, бот, мобильное приложение

Когда картинки нужны другой системе постоянно, выгружать их архивами неудобно. Лучше опубликовать в конфигурации HTTP-сервис: внешняя программа делает GET-запрос с кодом товара и получает изображение.

Главное в таком сервисе — заголовок Content-Type. Без него браузер или библиотека на стороне сайта не поймут, что пришла картинка, и покажут набор байтов или предложат скачать файл.

Функция КартинкаGET(Запрос)

	Код = Запрос.ПараметрыURL.Получить("code");
	Товар = Справочники.Номенклатура.НайтиПоКоду(Код);
	Если Товар.Пустая() ИЛИ Товар.ФайлКартинки.Пустая() Тогда
		Возврат Новый HTTPСервисОтвет(404);
	КонецЕсли;

	ДД = РаботаСФайлами.ДвоичныеДанныеФайла(Товар.ФайлКартинки, Ложь);
	Если ДД = Неопределено Тогда
		Возврат Новый HTTPСервисОтвет(500);
	КонецЕсли;

	Ответ = Новый HTTPСервисОтвет(200);
	Ответ.Заголовки.Вставить("Content-Type", MIMEТип(Товар.ФайлКартинки.Расширение));
	Ответ.Заголовки.Вставить("Cache-Control", "max-age=86400");
	Ответ.УстановитьТелоИзДвоичныхДанных(ДД);
	Возврат Ответ;

КонецФункции

Шаблон URL в метаданных HTTP-сервиса задайте вида /picture/{code}. Функцию MIMEТип() пишете сами — простое соответствие расширения и типа:

РасширениеContent-Type
jpg, jpegimage/jpeg
pngimage/png
gifimage/gif
bmpimage/bmp
webpimage/webp
svgimage/svg+xml
tif, tiffimage/tiff
остальноеapplication/octet-stream

Сравнивайте расширение в нижнем регистре: НРег(Расширение). Пользователи загружают и PHOTO.JPG, и photo.jpg.

⚠️ HTTP-сервис требует публикации базы на веб-сервере (IIS или Apache) и пользователя 1С, под которым будут ходить запросы. Дайте этому пользователю отдельную роль только с чтением номенклатуры и файлов — не администраторские права.

Обратная задача — забрать картинку из 1С по ссылке с внешнего сайта — решается через HTTPСоединение и HTTPЗапрос: ответ сервера получают методом ПолучитьТелоКакДвоичныеДанные() и сохраняют так же, через Записать().

Почему картинка не выгружается

Сбои при выгрузке почти всегда сводятся к нескольким ситуациям. Найдите свою:

Диагностика: выберите симптом

Ещё одна неочевидная причина — права. Пользователь видит товар, но не видит его файлы: доступ к присоединённым файлам в типовых конфигурациях часто наследует права на владельца, но ограничения на уровне записей могут скрыть часть картинок. Если обработка под одним пользователем выгружает 1 000 файлов, а под другим 700 — дело в правах, а не в коде.

Как ускорить выгрузку тысяч изображений

На базе с 20–50 тысячами товаров наивная обработка работает часами и падает по памяти. Вот что реально помогает.

  • ⚡ Одним запросом, без обращения через точку в цикле. Выборка.Файл.Расширение внутри цикла — это отдельное обращение к базе на каждую строку. Получайте расширение в самом запросе, как в примере.
  • 📦 Запись на диск сразу. Не копите двоичные данные в массиве или таблице значений: 10 000 фото по 500 КБ — это около 5 ГБ в памяти рабочего процесса. Получили — записали — забыли.
  • 🗜 Минимальное сжатие архива. JPEG и PNG уже сжаты, ZIP почти ничего не выиграет, а процессор потратит. Задайте при создании ЗаписьZipФайла минимальный уровень сжатия.
  • 🧮 Порциями. Выгружайте по 1 000–2 000 товаров: отбор по группе или по диапазону кодов. Один сбой не перечеркнёт всю работу.
  • 🕒 Фоновое задание. Долгую выгрузку запускайте фоновым заданием, а не из формы. Иначе клиент упрётся в таймаут, а пользователь не сможет работать.
  • 🔁 Только изменённое. Для регулярной синхронизации с сайтом запоминайте дату последней выгрузки и отбирайте файлы, изменённые позже. У присоединённых файлов в БСП есть реквизит с датой изменения — проверьте его имя в конфигураторе.

Для HTTP-сервиса главное ускорение — кеширование. Заголовок Cache-Control из примера позволяет сайту и браузеру не ходить в 1С за той же картинкой каждый раз. Если трафик большой, ставьте между 1С и сайтом кеширующий прокси или выгружайте картинки на файловое хранилище сайта раз в сутки.

⚠️ Выгрузка тяжёлая для сервера: тысячи чтений файлов и запись на диск. Запускайте её вне рабочего времени, если на сервере одновременно работают десятки пользователей, — иначе у них заметно замедлится проведение документов.

Частые вопросы

Можно ли выгрузить картинки товаров без программиста?
Если товаров десятки — да, вручную через список файлов в карточке. Для сотен и больше нужна внешняя обработка; готовые есть у разработчиков на маркетплейсах обработок, перед запуском проверьте их на копии базы.
В каком разрешении 1С отдаёт картинку?
В том, в каком её загрузили. Присоединённые файлы 1С не пережимает. Сжимается только отображение на форме и в печатной форме.
Как выгрузить картинки вместе с остальными данными товара?
Выгрузите товары в Excel или CSV с колонкой «имя файла картинки», а сами изображения — архивом с теми же именами. Маркетплейсы и сайты обычно принимают именно такую пару.
Почему у товара картинка есть на форме, а файл в списке не найден?
Значит, конфигурация хранит изображение в реквизите объекта, а не в присоединённых файлах. Такую картинку достаёт только код — через метод Получить() у хранилища значения.
Можно ли получить картинку через стандартный OData-интерфейс?
Можно, если опубликовать справочники файлов в составе стандартного интерфейса OData. Но для отдачи изображений сайту отдельный HTTP-сервис удобнее: он сразу возвращает файл с нужным Content-Type.