Как корректно выгрузить сформированный файл из 1С на компьютер пользователя

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

При разработке внешних обработок и отчетов в управляемом приложении 1С:Предприятие 8.3 часто возникает необходимость сформировать текстовый файл (например, для зарплатного проекта или обмена с банком) либо документ Excel и выгрузить его на рабочий стол пользователя. Однако при попытке поместить объект ТекстовыйДокумент во временное хранилище и скачать его с помощью функции НачатьПолучениеФайлов разработчики часто сталкиваются с ошибками: «Неправильный путь к файлу» или «Значение данного типа невозможно преобразовать для передачи как файл (Текстовый документ)».

Рассмотрим подробнее причины возникновения этой ошибки и разберем правильный алгоритм передачи файлов с сервера на клиент в 1С.

Анализ причины ошибки

Проанализируем ситуационную ошибку в исходном коде. Разработчик создает объект ТекстовыйДокумент, заполняет его строками и помещает объект напрямую во временное хранилище:


Текст = Новый ТекстовыйДокумент;
Текст.ДобавитьСтроку("BEGIN;@");
Текст.ДобавитьСтроку("END;");

Адрес = ПоместитьВоВременноеХранилище(Текст, УникальныйИдентификатор);

Выясним причину сбоя: платформа 1С при выгрузке файлов клиенту методами НачатьПолучениеФайлов или ПолучитьФайл ожидает, что во временном хранилище находятся двоичные данные (содержимое файла), а не объект прикладного программирования (такой как ТекстовыйДокумент, ТабличныйДокумент или ХранилищеЗначения).

Когда платформа пытается интерпретировать переданный объект как поток файла, возникает сбой файловой операции, так как платформа не может автоматически преобразовать структуру ТекстовыйДокумент в бинарный файл без предварительного сохранения на диск или перевода в двоичные данные.

Кроме того, при использовании метода НачатьПолучениеФайлов в третьем параметре часто ошибочно указывают полное имя файла вместо каталога. Третий параметр предназначен исключительно для указания каталога назначения, либо его следует оставлять пустым, если в массиве ОписаниеПередаваемогоФайла уже задан полный локальный путь.

Правильный алгоритм выгрузки файла

Сформируем правильную последовательность действий для сохранения файла из 1С на компьютер пользователя:

  1. На сервере создаем и заполняем нужный объект (ТекстовыйДокумент или ТабличныйДокумент).
  2. Получаем имя временного файла на сервере с помощью функции ПолучитьИмяВременногоФайла().
  3. Записываем объект во временный файл на диске сервера.
  4. Читаем созданный файл в объект ДвоичныеДанные.
  5. Помещаем объект ДвоичныеДанные во временное хранилище.
  6. Удаляем временный файл с сервера.
  7. На клиенте вызываем стандартные методы получения файлов платформы (НачатьПолучениеФайлов или НачатьПолучениеФайлаССервера).

Пример реализации выгрузки текстового файла

Посмотрим на практическую реализацию данного алгоритма. Создадим серверную функцию для формирования данных и клиентские процедура для интерактивного сохранения файла.

Код серверной части внешней обработки:


&НаСервере
Функция СформироватьТекстовыйФайлСервер()
    
    // 1. Создаем текстовый документ
    Текст = Новый ТекстовыйДокумент;
    Текст.ДобавитьСтроку("BEGIN;@");
    Текст.ДобавитьСтроку("END;");
    
    // 2. Получаем временный файл на сервере
    ИмяВременногоФайла = ПолучитьИмяВременногоФайла("txt");
    Текст.Записать(ИмяВременногоФайла, КодировкаТекста.UTF8);
    
    // 3. Преобразуем в двоичные данные
    Двоичные = Новый ДвоичныеДанные(ИмяВременногоФайла);
    
    // 4. Помещаем двоичные данные во временное хранилище
    АдресХранилища = ПоместитьВоВременноеХранилище(Двоичные, ЭтаФорма.УникальныйИдентификатор);
    
    // 5. Удаляем временный файл
    Попытка
        УдалитьФайлы(ИмяВременногоФайла);
    Исключение
        // Игнорируем ошибку удаления временного файла
    КонецПопытки;
    
    Возврат АдресХранилища;
    
КонецФункции

Код клиентской части для работы с диалогом сохранения:


&НаКлиенте
Процедура СохранитьФайл(Команда)
    
    // Получаем адрес хранилища с двоичными данными
    АдресХранилища = СформироватьТекстовыйФайлСервер();
    
    // Настраиваем диалог выбора файла
    ПараметрыВыгрузки = Новый Структура;
    ПараметрыВыгрузки.Вставить("Адрес", АдресХранилища);
    
    Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Сохранение);
    Диалог.Заголовок = "Укажите файл для сохранения";
    Диалог.Фильтр = "Текстовый файл (*.txt)|*.txt";
    Диалог.ПолноеИмяФайла = "ВТБ.txt";
    Диалог.МножественныйВыбор = Ложь;
    
    Обработчик = Новый ОписаниеОповещения("ВыгрузитьФайлВыборФайлаЗавершение", ЭтотОбъект, ПараметрыВыгрузки);
    Диалог.Показать(Обработчик);
    
КонецПроцедуры

&НаКлиенте
Процедура ВыгрузитьФайлВыборФайлаЗавершение(ВыбранныеФайлы, ДополнительныеПараметры) Экспорт
    
    Если ВыбранныеФайлы <> Неопределено И ВыбранныеФайлы.Количество() > 0 Тогда
        
        ПолноеИмяФайла = ВыбранныеФайлы[0];
        
        МассивФайлов = Новый Массив;
        МассивФайлов.Добавить(Новый ОписаниеПередаваемогоФайла(ПолноеИмяФайла, ДополнительныеПараметры.Адрес));
        
        ОбработчикЗавершения = Новый ОписаниеОповещения("СохранитьФайлЗавершение", ЭтотОбъект);
        
        // Третий параметр оставляем пустым, так как ПолноеИмяФайла уже содержит абсолютный путь
        НачатьПолучениеФайлов(ОбработчикЗавершения, МассивФайлов, , Ложь);
        
    КонецЕсли;
    
КонецПроцедуры

&НаКлиенте
Процедура СохранитьФайлЗавершение(ПолученныеФайлы, ДополнительныеПараметры) Экспорт
    Сообщить("Файл успешно выгружен на компьютер!");
КонецПроцедуры

Выгрузка табличных документов Excel (.xlsx)

Если требуется выгрузить файл Excel, алгоритм остается точно таким же, за исключением использования объекта ТабличныйДокумент и указания формата сохранения ТипФайлаТабличногоДокумента.XLSX.

Рассмотрим серверную функцию формирования Excel-файла:


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

Современный асинхронный способ получения файла

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


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

Важные замечания:

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

2. При работе в тонком клиенте и веб-клиенте гарантированным способом выгрузки произвольных данных является передача именно объекта ДвоичныеДанные.

← На главную