Как определить выбранный формат при сохранении файла через диалог выбора в веб-клиенте 1С

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

При разработке функционала выгрузки данных и сохранения табличных документов в тонком и веб-клиентах разработчики часто сталкиваются с различием в поведении системных диалогов. В тонком клиенте объект ДиалогВыбораФайла после закрытия окна диалога возвращает в свойство ИндексФильтра номер выбранной пользователем маски (фильтра). Однако в веб-клиенте это свойство сбрасывается или остается неизменным.

Рассмотрим подробно, почему это происходит, и проанализируем практические способы решения данной проблемы при выгрузке табличных документов в форматы с одинаковыми расширениями (например, HTML3, HTML4 и HTML5, имеющие общее расширение .htm или .html).

Причина поведения веб-клиента

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

Оригинальный объект ДиалогВыбораФайла при выполнении асинхронного метода Показать() копируется. Браузер не передает индекс выбранного пользователем фильтра обратно в структуру 1С. В результате в обработчике завершения свойство ИндексФильтра оказывается равным значению, которое было установлено до вызова диалога (или 0), даже если передавать сам объект диалога в ДополнительныеПараметры оповещения.

Способ 1. Уточнение формата с помощью интерактивного списка (ПоказатьВыборИзСписка)

Разберем первый практический вариант решения без отказа от системного диалога сохранения. Если выбранное пользователем расширение файла однозначно определяет формат (например, .xlsx или .pdf), система сохраняет документ сразу. Если же расширение может соответствовать нескольким типам (например, .htm), мы запрашиваем у пользователя уточнение с помощью метода ПоказатьВыборИзСписка().

Рассмотрим пример реализации данного подхода на клиенте:


&НаКлиенте
Процедура СохранитьТабличныйДокумент()
    
    Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Сохранение);
    Диалог.Фильтр = "Документ HTML (*.htm)|*.htm|Документ PDF (*.pdf)|*.pdf|Книга Excel (*.xlsx)|*.xlsx";
    
    ОповещениеЗавершения = Новый ОписаниеОповещения("СохранитьТабличныйДокументЗавершение", ЭтотОбъект);
    Диалог.Показать(ОповещениеЗавершения);
    
КонецПроцедуры

&НаКлиенте
Процедура СохранитьТабличныйДокументЗавершение(МассивФайлов, ДополнительныеПараметры) Экспорт
    
    Если МассивФайлов = Неопределено Или МассивФайлов.Количество() = 0 Тогда
        Возврат;
    КонецЕсли;
    
    ПолноеИмяФайла = МассивФайлов[0];
    
    // Определяем расширение файла
    ТочкаИндекс = СтрНайти(ПолноеИмяФайла, ".", НаправлениеПоиска.СКонца);
    Расширение = ?(ТочкаИндекс > 0, НРег(Сред(ПолноеИмяФайла, ТочкаИндекс + 1)), "");
    
    Если Расширение = "htm" Или Расширение = "html" Тогда
        // Расширение неоднозначно — запрашиваем уточнение формата HTML
        СписокФорматов = Новый СписокЗначений;
        СписокФорматов.Добавить(ТипФайлаТабличногоДокумента.HTML, "HTML (стандартный)");
        СписокФорматов.Добавить(ТипФайлаТабличногоДокумента.HTML3, "HTML 3");
        СписокФорматов.Добавить(ТипФайлаТабличногоДокумента.HTML4, "HTML 4");
        СписокФорматов.Добавить(ТипФайлаТабличногоДокумента.HTML5, "HTML 5");
        
        Контекст = Новый Структура("ИмяФайла", ПолноеИмяФайла);
        ОповещениеУточнения = Новый ОписаниеОповещения("УточнитьФорматЗавершение", ЭтотОбъект, Контекст);
        
        ПоказатьВыборИзСписка(ОповещениеУточнения, СписокФорматов);
    ИначеИли Расширение = "pdf" Тогда
        ВыполнитьСохранениеНаСервере(ПолноеИмяФайла, ТипФайлаТабличногоДокумента.PDF);
    ИначеИли Расширение = "xlsx" Тогда
        ВыполнитьСохранениеНаСервере(ПолноеИмяФайла, ТипФайлаТабличногоДокумента.XLSX);
    КонецЕсли;

КонецПроцедуры

&НаКлиенте
Процедура УточнитьФорматЗавершение(ВыбранныйЭлемент, Контекст) Экспорт
    
    Если ВыбранныйЭлемент <> Неопределено Тогда
        ВыполнитьСохранениеНаСервере(Контекст.ИмяФайла, ВыбранныйЭлемент.Значение);
    КонецЕсли;
    
КонецПроцедуры

Способ 2. Загрузка через временное хранилище (НачатьПолучениеФайлаИзВременногоХранилища)

Выясним, как реализовать сохранение файлов в веб-клиенте наиболее универсальным путем, рекомендованным для современных версий платформы. Данный способ не требует обязательной установки локального расширения работы с файлами и избавляет от проблем с системными диалогами операционной системы.

Посмотрим на порядок действий:

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

Проанализируем пример кода для этого варианта:


&НаКлиенте
Процедура ЭкспортироватьДокумент(ВыбранныйТипФайла, ИмяФайлаСРасширением)
    
    АдресХранилища = ПодготовитьФайлНаСервере(ВыбранныйТипФайла);
    
    Если ЗначениеЗаполнено(АдресХранилища) Тогда
        НачатьПолучениеФайлаИзВременногоХранилища(АдресХранилища, ИмяФайлаСРасширением);
    КонецЕсли;
    
КонецПроцедуры

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

Способ 3. Использование собственной формы экспорта

В типовых конфигурациях (например, в Библиотеке Стандартных Подсистем и 1С:Бухгалтерии 3.0) разработчики 1С применяют подход с вызовом специализированной управляемой формы экспорта печатных форм. В этой форме пользователю предоставляются:

Создание отдельной формы полностью снимает неопределенность с типами файлов, обеспечивает одинаковое поведение функции во всех веб-браузерах и тонком клиенте, а также позволяет сохранять сразу несколько документов в одном архиве или выбранной папке.

← На главную