При разработке решений в 1С часто возникает задача, когда необходимо сформировать какой-либо документ или набор данных на сервере, а затем предоставить пользователю возможность сохранить его на своем локальном компьютере. Это может быть отчет в формате Excel, PDF, текстовый файл CSV или любой другой документ. Передача данных с сервера на клиент и их последующая запись — это ключевой механизм, который мы с вами сегодня подробно разберем.
Мы рассмотрим несколько эффективных подходов, начиная от наиболее рекомендуемых и универсальных, до более специфических. Наша цель — не просто показать готовые решения, но и помочь вам понять логику работы каждого метода, чтобы вы могли применять их в своих проектах.
Механизм ВременноеХранилище является наиболее универсальным и рекомендуемым способом для передачи файлов и больших объемов данных с сервера на клиент, особенно при работе в тонком и веб-клиенте. Он позволяет избежать прямой сериализации объемных объектов через каналы связи, что значительно повышает производительность и надежность.
Рассмотрим подробнее, как это работает, и разберем по шагам весь процесс.
Помещение данных на сервере во ВременноеХранилище.
На первом шаге мы формируем необходимые данные на сервере (например, ТабличныйДокумент или ДвоичныеДанные файла) и помещаем их в специальное временное хранилище. Функция ПоместитьВоВременноеХранилище() возвращает уникальный адрес, по которому эти данные будут доступны.
Важно: во временное хранилище могут быть помещены только сериализуемые данные. Объем данных, передаваемых за один вызов, не должен превышать 4 ГБ в сериализованном виде.
Посмотрим на пример серверной функции, которая формирует табличный документ и помещает его в хранилище:
&НаСервере
Функция СформироватьИПоместитьТабличныйДокументВХранилище()
// Создаем и заполняем табличный документ
ТабДок = Новый ТабличныйДокумент;
ТабДок.Область(1, 1, 1, 1).Текст = "Пример данных";
ТабДок.Область(2, 1, 2, 1).Текст = "Из ВременногоХранилища";
// Помещаем табличный документ во временное хранилище
АдресХранилища = ПоместитьВоВременноеХранилище(ТабДок, УникальныйИдентификатор);
Возврат АдресХранилища;
КонецФункции
Передача адреса хранилища на клиент.
После того как данные помещены в хранилище, серверная функция возвращает клиенту только адрес, а не сам объект. Этот адрес представляет собой строку, которая значительно легче передается по сети.
Получение и сохранение файла на клиенте.
На клиентской стороне мы получаем адрес из временного хранилища. Для того чтобы пользователь мог выбрать место сохранения файла и его имя, мы используем объект ДиалогВыбораФайла в режиме РежимДиалогаВыбораФайла.Сохранение. После того как путь выбран, мы вызываем метод ПолучитьФайл(), который принимает адрес из временного хранилища и выбранный пользователем путь для сохранения.
Проанализируем пример клиентской процедуры:
&НаКлиенте
Процедура СохранитьФайлССервера()
// Вызываем серверную функцию для получения адреса
АдресХранилища = СформироватьИПоместитьТабличныйДокументВХранилище();
Если ПустаяСтрока(АдресХранилища) Тогда
Возврат;
КонецЕсли;
// Создаем диалог выбора файла для сохранения
Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Сохранение);
Диалог.Заголовок = "Сохраните файл";
Диалог.ПолноеИмяФайла = "МойДокумент.xlsx"; // Предлагаемое имя файла
Диалог.Фильтр = "Файлы Excel (*.xlsx)|*.xlsx|Все файлы (*.*)|*.*";
Если Диалог.Выбрать() Тогда
ПутьКФайлуНаКлиенте = Диалог.ПолноеИмяФайла;
Попытка
// Получаем файл из временного хранилища и сохраняем его на клиенте
ПолучитьФайл(ПутьКФайлуНаКлиенте, АдресХранилища);
Сообщить("Файл успешно сохранен: " + ПутьКФайлуНаКлиенте);
Исключение
Сообщить("Ошибка при сохранении файла: " + ОписаниеОшибки());
КонецПопытки;
Иначе
Сообщить("Сохранение файла отменено пользователем.");
КонецЕсли;
КонецПроцедуры
Удаление данных из хранилища.
Данные во временном хранилище привязываются к сеансу или форме и автоматически удаляются после закрытия формы, которая их поместила, или по истечении таймаута. Однако, при необходимости, вы можете явно удалить данные с помощью метода УдалитьИзВременногоХранилища(), передав ему адрес хранилища. Это может быть полезно для освобождения ресурсов, если файл больше не нужен, но форма еще активна.
&НаСервере
Процедура УдалитьФайлИзХранилища(АдресХранилища)
УдалитьИзВременногоХранилища(АдресХранилища);
КонецПроцедуры
Этот подход актуален, если вы работаете именно с объектом ТабличныйДокумент и хотите сохранить его в одном из поддерживаемых форматов (XLS, PDF, TXT, HTML и т.д.). В этом случае объект ТабличныйДокумент формируется на сервере, а затем полностью передается на клиент.
Разберем по шагам, как это реализовать.
Формирование табличного документа на сервере.
Начнем с серверной функции, которая создает и заполняет объект ТабличныйДокумент, а затем возвращает его клиенту.
&НаСервере
Функция СформироватьТабличныйДокументНаСервере()
// Создаем и заполняем табличный документ
ТабДок = Новый ТабличныйДокумент;
ТабДок.Область(1, 1, 1, 1).Текст = "Данные отчета";
ТабДок.Область(2, 1, 2, 2).Текст = "Строка 2, Колонка 1";
ТабДок.Область(2, 2, 2, 2).Текст = "Строка 2, Колонка 2";
ТабДок.ИмяПараметровПечати = "МойОтчетПараметрыПечати"; // Пример настройки
Возврат ТабДок;
КонецФункции
Передача объекта на клиент.
Серверная функция просто возвращает сформированный объект ТабличныйДокумент. Важно понимать, что в этом случае весь объект сериализуется и передается по сети. Для больших табличных документов это может быть менее эффективно, чем использование ВременноеХранилище.
Сохранение табличного документа на клиенте.
Получив объект ТабличныйДокумент на клиенте, мы можем использовать его метод Записать(). Этот метод позволяет сохранить документ в различных форматах, таких как Excel, PDF, HTML, TXT и другие. Как и в предыдущем случае, для интерактивного выбора пути сохранения мы используем ДиалогВыбораФайла.
Посмотрим на пример клиентской процедуры сохранения:
&НаКлиенте
Процедура СохранитьТабличныйДокументНаКлиенте()
// Вызываем серверную функцию для получения табличного документа
ТабличныйДокумент = СформироватьТабличныйДокументНаСервере();
Если ТабличныйДокумент = Неопределено Тогда
Возврат;
КонецЕсли;
// Создаем диалог выбора файла
Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Сохранение);
Диалог.Заголовок = "Сохраните табличный документ";
Диалог.ПолноеИмяФайла = "Отчет.xlsx"; // Предлагаемое имя файла
Диалог.Фильтр = "Файлы Excel (*.xlsx)|*.xlsx|Файлы PDF (*.pdf)|*.pdf|Все файлы (*.*)|*.*";
Если Диалог.Выбрать() Тогда
ПутьКФайлуНаКлиенте = Диалог.ПолноеИмяФайла;
ФорматСохранения = ФорматТабличногоДокумента.XLSX; // Формат по умолчанию
// Определяем формат сохранения по расширению файла
Расширение = НРег(Прав(ПутьКФайлуНаКлиенте, СтрДлина(ПутьКФайлуНаКлиенте) - СтрНайти(ПутьКФайлуНаКлиенте, ".")));
Если Расширение = "pdf" Тогда
ФорматСохранения = ФорматТабличногоДокумента.PDF;
ИначеЕсли Расширение = "htm" Или Расширение = "html" Тогда
ФорматСохранения = ФорматТабличногоДокумента.HTML;
ИначеЕсли Расширение = "txt" Тогда
ФорматСохранения = ФорматТабличногоДокумента.TXT;
КонецЕсли;
Попытка
// Записываем табличный документ в выбранный файл
ТабличныйДокумент.Записать(ПутьКФайлуНаКлиенте, ФорматСохранения);
Сообщить("Табличный документ успешно сохранен: " + ПутьКФайлуНаКлиенте);
Исключение
Сообщить("Ошибка при сохранении табличного документа: " + ОписаниеОшибки());
КонецПопытки;
Иначе
Сообщить("Сохранение табличного документа отменено пользователем.");
КонецЕсли;
КонецПроцедуры
Особенности свойств: При прямой передаче ТабличныйДокумент некоторые его свойства (например, ОриентацияСтраницы, АвтоМасштаб) сохраняются, но другие, такие как ТолькоПросмотр, могут быть потеряны или не иметь смысла при сохранении в файл.
Этот метод является очень гибким и отлично подходит для передачи текстовых данных, таких как CSV, XML, JSON или обычный текст. Суть подхода заключается в том, что на сервере мы формируем нужный текст в виде одной большой строки, передаем ее на клиент, а затем клиент записывает эту строку в файл.
Давайте выясним, как это реализовать.
Преобразование данных в строку на сервере.
На сервере мы преобразуем табличные или любые другие данные в текстовую строку. Например, если нам нужен файл CSV, мы можем построчно формировать его содержимое.
Рассмотрим пример серверной функции, которая возвращает CSV-строку:
&НаСервере
Функция СформироватьCSVСтрокуНаСервере()
Разделитель = ";";
РазделительСтрок = Символы.ПС; // Перевод строки
СтрокаCSV = "";
// Заголовок CSV
СтрокаCSV = СтрокаCSV + "Код" + Разделитель + "Наименование" + Разделитель + "Цена" + РазделительСтрок;
// Пример данных
СтрокаCSV = СтрокаCSV + "001" + Разделитель + "Товар 1" + Разделитель + "100.00" + РазделительСтрок;
СтрокаCSV = СтрокаCSV + "002" + Разделитель + "Товар 2" + Разделитель + "250.50" + РазделительСтрок;
СтрокаCSV = СтрокаCSV + "003" + Разделитель + "Услуга 1" + Разделитель + "500.00" + РазделительСтрок;
Возврат СтрокаCSV;
КонецФункции
Передача строки на клиент.
Серверная функция возвращает сформированную текстовую строку. Передача обычной строки по сети обычно не вызывает проблем, если строка не слишком велика.
Запись строки в файл на клиенте.
На клиенте мы получаем эту строку и используем объект ЗаписьТекста для записи ее в файл. Этот объект позволяет нам полностью контролировать процесс записи, включая выбор кодировки текста и разделителей строк.
Проанализируем пример клиентской процедуры:
&НаКлиенте
Процедура СохранитьСтрокуВФайлНаКлиенте()
// Вызываем серверную функцию для получения CSV-строки
СтрокаДляЗаписи = СформироватьCSVСтрокуНаСервере();
Если ПустаяСтрока(СтрокаДляЗаписи) Тогда
Сообщить("Получена пустая строка для записи.");
Возврат;
КонецЕсли;
// Создаем диалог выбора файла
Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Сохранение);
Диалог.Заголовок = "Сохраните текстовый файл";
Диалог.ПолноеИмяФайла = "Данные.csv"; // Предлагаемое имя файла
Диалог.Фильтр = "CSV-файлы (*.csv)|*.csv|Текстовые файлы (*.txt)|*.txt|Все файлы (*.*)|*.*";
Если Диалог.Выбрать() Тогда
ПутьКФайлуНаКлиенте = Диалог.ПолноеИмяФайла;
Попытка
// Создаем объект для записи текста
ЗаписьТекста = Новый ЗаписьТекста(ПутьКФайлуНаКлиенте, КодировкаТекста.UTF8); // Рекомендуется UTF8
// Записываем строку в файл
ЗаписьТекста.Записать(СтрокаДляЗаписи);
ЗаписьТекста.Закрыть();
Сообщить("Файл успешно сохранен: " + ПутьКФайлуНаКлиенте);
Исключение
Сообщить("Ошибка при сохранении файла: " + ОписаниеОшибки());
КонецПопытки;
Иначе
Сообщить("Сохранение файла отменено пользователем.");
КонецЕсли;
КонецПроцедуры
Мы с вами рассмотрели три основных подхода к передаче и записи файлов с сервера на клиент в 1С. Выбор конкретного метода зависит от типа передаваемых данных, их объема и требований к пользовательскому интерфейсу. Для большинства задач, особенно с большими файлами и в веб-клиенте, ВременноеХранилище будет наиболее предпочтительным решением. Если же вам нужен полный контроль над текстовым содержимым, передача строки — отличный вариант. А прямая передача ТабличныйДокумент подойдет для специфических случаев, когда необходим именно этот объект на клиенте.
Надеемся, что эта подробная инструкция поможет вам успешно реализовывать задачи по работе с файлами в 1С!
← К списку