К статье
Практический материал

Разработка и Конфигурация · 11 мин

Как передать файл с сервера на клиент в 1С

Способы передачи файла с сервера на клиент в 1С: временное хранилище, ПолучитьФайл, НачатьПолучениеФайлаССервера. Примеры кода, типичные ошибки и проверка результата.

В клиент-серверном режиме работы 1С код выполняется в двух местах: на сервере, где находятся данные, и на клиенте, где работает пользователь. Файл, сформированный серверной процедурой (отчёт, выгрузка, архив), физически лежит на серверном компьютере, и пользователь не может его открыть напрямую. Чтобы передать файл с сервера на клиент, платформа 1С предоставляет несколько штатных механизмов, и выбор между ними зависит от размера файла, вида клиента (тонкий, толстый, веб) и требований к интерфейсу.

Ключевая идея всех способов одинакова: на сервере файл помещается во временное хранилище, а на клиенте извлекается по полученному адресу и сохраняется на диск пользователя. Различия касаются синхронных и асинхронных вызовов, работы с расширением для файлов в веб-клиенте и ограничений на объём передаваемых данных.

Ниже разобраны основные подходы с примерами кода на встроенном языке, условия их применения, типичные ошибки и способы проверить, что файл действительно дошёл до клиента без повреждений.

Как устроена передача файла между сервером и клиентом

В файловом режиме работы 1С серверной части нет, и вопрос передачи файла «с сервера на клиент» не возникает — весь код выполняется на одном компьютере. Проблема появляется именно в клиент-серверном варианте: серверный вызов не имеет доступа к диску пользователя, а клиентский код не видит файловую систему сервера.

Платформа решает это через временное хранилище — область памяти на сервере, доступную по специальному адресу вида e1cib/tempstorage/.... Серверная процедура кладёт туда данные (двоичные данные файла, табличный документ, картинку), возвращает клиенту адрес, и клиент забирает содержимое по этому адресу.

Важно понимать, что временное хранилище — не постоянное место. По умолчанию данные живут там до конца текущего серверного вызова или сеанса, поэтому адрес нужно использовать сразу, а для длительного хранения адреса применяют параметр УникальныйИдентификаторФормы, привязывающий данные к времени жизни формы.

Способ 1. Временное хранилище и ПолучитьИзВременногоХранилища

Это универсальный вариант, который работает в толстом клиенте и подходит для небольших файлов. На сервере файл читается в двоичные данные и помещается в хранилище, на клиенте извлекается и записывается на диск.

bsl
&НаСервере
Функция ПодготовитьФайлНаСервере()
    ДвоичныеДанные = Новый ДвоичныеДанные("C:\Reports\выгрузка.xml");
    Адрес = ПоместитьВоВременноеХранилище(ДвоичныеДанные, УникальныйИдентификатор);
    Возврат Адрес;
КонецФункции

&НаКлиенте
Процедура СохранитьФайл(Команда)
    Адрес = ПодготовитьФайлНаСервере();
    ДвоичныеДанные = ПолучитьИзВременногоХранилища(Адрес);
    ДвоичныеДанные.Записать("C:\Users\User\Documents\выгрузка.xml");
КонецПроцедуры

Метод ПолучитьИзВременногоХранилища — синхронный, поэтому в тонком и веб-клиенте он может быть недоступен при включённом режиме отказа от модальности и синхронных вызовов. В типовых конфигурациях, рассчитанных на тактичный режим, используют асинхронный аналог — НачатьПолучениеФайлаССервера.

После извлечения данных адрес хранилища желательно освободить вызовом УдалитьИзВременногоХранилища(Адрес), чтобы не накапливать мусор в памяти сервера при массовых операциях.

Способ 2. Асинхронная передача через НачатьПолучениеФайлаССервера

Для тонкого и веб-клиента правильный подход — асинхронные методы с описанием оповещения. Метод НачатьПолучениеФайлаССервера сам запрашивает у пользователя место сохранения (или использует указанный путь) и вызывает обработчик по завершении.

bsl
&НаКлиенте
Процедура СохранитьФайл(Команда)
    Адрес = ПодготовитьФайлНаСервере();
    Оповещение = Новый ОписаниеОповещения("ПослеПолученияФайла", ЭтотОбъект);
    НачатьПолучениеФайлаССервера(Оповещение, Адрес, "выгрузка.xml");
КонецПроцедуры

&НаКлиенте
Процедура ПослеПолученияФайла(ПолученныйФайл, ДопПараметры) Экспорт
    Если ПолученныйФайл <> Неопределено Тогда
        ПоказатьОповещениеПользователя("Файл сохранён: " + ПолученныйФайл.ПолноеИмя);
    КонецЕсли;
КонецПроцедуры

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

Способ 3. Передача табличного документа и других объектов

Не всегда на клиент нужен именно файл с диска сервера. Часто серверная процедура формирует табличный документ (печатную форму, отчёт), который нужно показать или сохранить у пользователя. Табличный документ тоже помещается во временное хранилище и извлекается на клиенте.

bsl
&НаСервере
Функция СформироватьПечатнуюФорму()
    ТабДок = Новый ТабличныйДокумент;
    // ... заполнение табличного документа ...
    Возврат ПоместитьВоВременноеХранилище(ТабДок, УникальныйИдентификатор);
КонецФункции

&НаКлиенте
Процедура ПоказатьПечатнуюФорму(Команда)
    Адрес = СформироватьПечатнуюФорму();
    ТабДок = ПолучитьИзВременногоХранилища(Адрес);
    ТабДок.Показать("Печатная форма");
КонецПроцедуры

Тот же приём работает для картинок, макетов, структур с данными и других сериализуемых объектов. Если итоговая цель — именно файл Excel или PDF, табличный документ на клиенте сохраняется методом Записать с указанием типа файла.

Выбор способа под вашу ситуацию

Конкретный метод определяется видом клиента, размером файла и тем, должен ли пользователь видеть диалог сохранения.

Маршрут решения

Как выбрать действие

Толстый клиент, файл небольшой, код пишется быстроИспользуйте ПоместитьВоВременноеХранилище + ПолучитьИзВременногоХранилища
Тонкий или веб-клиент, тактичный режим без модальных вызововИспользуйте НачатьПолучениеФайлаССервера с описанием оповещения
Нужно передать печатную форму или отчёт, а не файл с дискаПомещайте в хранилище табличный документ и показывайте его на клиенте
Файл большой и передаётся регулярноРассмотрите альтернативу: общий сетевой каталог или обмен через базу вместо прямой передачи
Пользователь должен сам выбрать, куда сохранитьПередавайте в НачатьПолучениеФайлаССервера только имя файла без пути — платформа покажет диалог
МетодКлиентРежимОсобенности
ПолучитьИзВременногоХранилищаТолстыйСинхронныйПростой код, не подходит для тактичного режима
НачатьПолучениеФайлаССервераТонкий, вебАсинхронныйРекомендуемый способ, есть диалог сохранения
ПолучитьФайл (устаревший)ТолстыйСинхронныйСохранялся для совместимости, в новых разработках не применяется
Скачивание по ссылке в веб-клиентеВеб—Без расширения работы с файлами, средствами браузера

Проверка результата и типичные ошибки

После передачи файла убедитесь, что он не только появился на диске пользователя, но и открывается без ошибок. Повреждение чаще всего вызвано не сетью, а логическими ошибками: записью не тех данных или потерей адреса хранилища.

Контрольные точки

Как проверить результат

Файл создан на клиенте
Норма

Файл существует, размер больше нуля и близок к исходному

Тревожный признак

Файл нулевого размера или отсутствует — данные не были получены из хранилища

Содержимое файла
Норма

Файл открывается штатным приложением без ошибок

Тревожный признак

Ошибка формата — возможно, в хранилище помещён не тот объект или неверное расширение

Адрес хранилища
Норма

Адрес непустой, начинается со служебного префикса

Тревожный признак

Пустой адрес — серверная функция не вернула значение или упала с исключением

Повторные вызовы
Норма

Каждый вызов возвращает актуальные данные

Тревожный признак

Возвращаются устаревшие данные — адрес переиспользуется или не очищается

Типичные ошибки
01
Помещение в хранилище без УникальныйИдентификаторФормы — данные удаляются после серверного вызова, и клиент получает пустоту
02
Использование синхронных методов в тактичном режиме — код не компилируется или падает в тонком клиенте
03
Запись файла на сервере в каталог, недоступный учётной записи сервера 1С — исключение при чтении исходного файла
04
Передача очень больших файлов через хранилище — рост потребления памяти сервера и тайм-ауты вызовов
05
Отсутствие удаления из хранилища после использования — накопление данных в памяти при массовых операциях

Альтернативы прямой передаче файла

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

Другой вариант — сохранить файл в самой базе (в реквизите справочника или регистре сведений типа «ХранилищеЗначения»). Тогда клиент получает данные обычным запросом, без манипуляций с адресами, а файл остаётся доступен для повторного скачивания. Минус — рост размера базы.

Для обмена между отдельными системами (а не между сервером и клиентом одной базы) применяются HTTP-сервисы, веб-сервисы и файловый обмен — это уже задача интеграции, а не передачи внутри сеанса.

При отладке передачи файлов полезно временно выводить размер двоичных данных на сервере и на клиенте (ДвоичныеДанные.Размер()). Совпадение размеров — быстрый признак того, что данные не потерялись ни в хранилище, ни при записи на диск.
ПЗ
Практическое замечание

Часто задаваемые вопросы

Почему ПолучитьИзВременногоХранилища возвращает Неопределено?

Чаще всего адрес указывает на уже удалённые данные: хранилище было создано без привязки к форме, и содержимое очистилось после завершения серверного вызова. Передавайте в ПоместитьВоВременноеХранилище второй параметр — УникальныйИдентификатор формы. Также проверьте, что серверная функция действительно вернула адрес, а не завершилась исключением.

Работает ли передача файла в веб-клиенте?

Да, но с ограничениями. Без расширения работы с файлами доступна только передача через механизм скачивания браузера. Для полноценной записи по указанному пути и выбора каталога нужно подключить расширение методом НачатьПодключениеРасширенияРаботыСФайлами и использовать асинхронные методы.

Как передать файл, не показывая пользователю диалог сохранения?

Передайте в НачатьПолучениеФайлаССервера полный путь сохранения вместо одного имени файла. Учтите, что в веб-клиенте запись по произвольному пути возможна только с расширением работы с файлами и при наличии у пользователя прав на каталог.

Есть ли ограничение на размер передаваемого файла?

Жёсткого ограничения платформа не задаёт, но фактический предел определяется памятью сервера приложений и тайм-аутами вызовов. Файлы большого объёма надёжнее передавать через общий сетевой каталог или хранить в базе с выдачей по частям.

Чем отличается ПоместитьФайл от передачи с сервера на клиент?

ПоместитьФайл (и его асинхронный аналог НачатьПомещениеФайла) работает в обратную сторону — с клиента на сервер: пользователь выбирает файл на своём компьютере, и он загружается во временное хранилище. Для направления «сервер → клиент» используются ПолучитьИзВременногоХранилища и НачатьПолучениеФайлаССервера.

Можно ли передать сразу несколько файлов?

Да. Либо поместите каждый файл в хранилище отдельно и передайте клиенту массив адресов, либо упакуйте файлы в архив (например, объектом ЗаписьZipФайла) на сервере и передайте один архив — второй вариант обычно удобнее для пользователя.

Итог

Что важно запомнить

Передача файла с сервера на клиент в 1С строится на временном хранилище: сервер помещает данные и возвращает адрес, клиент извлекает их и сохраняет на диск. Для тонкого и веб-клиента используйте асинхронный НачатьПолучениеФайлаССервера, привязывайте хранилище к форме и очищайте его после использования. Большие файлы лучше передавать через общий каталог или хранение в базе.