При переходе с толстого клиента на веб-клиент разработчики часто сталкиваются с тем, что привычные механизмы взаимодействия с внешними приложениями через COM-объекты перестают работать. Одной из наиболее востребованных задач является формирование сложных многостраничных отчетов в формате Excel. В рамках данной статьи мы подробно разберем, почему старые методы не подходят для браузера, как правильно перенести логику формирования на сервер и какими средствами платформы 1С стоит воспользоваться для достижения наилучшего результата.
Для начала выясним причину возникновения ошибок. Когда мы работаем в «Толстом клиенте», операционная система позволяет приложению 1С напрямую обращаться к установленным в системе компонентам Microsoft Office. Однако веб-клиент работает внутри браузера, который, в целях безопасности, изолирован от прямого взаимодействия с локальными ресурсами компьютера (так называемая «песочница»).
Рассмотрим стандартную ошибку «Отказано в доступе». Она возникает в двух случаях:
COMОбъект непосредственно в коде клиента (в браузере это технически невозможно для большинства современных движков, кроме устаревшего Internet Explorer).COMОбъект на стороне сервера, запущенного под технической учетной записью (например, USR1CV8), у которой нет прав на запуск интерактивных приложений Windows.Наиболее правильный архитектурный подход заключается в том, чтобы полностью исключить зависимость клиента от установленного ПО. Мы разделим задачу на три этапа: сбор данных на сервере, формирование файла в памяти сервера и передача готового двоичного контента пользователю.
Проанализируем ситуацию, когда нам всё же необходимо использовать Excel.Application на сервере. Чтобы избежать ошибки доступа, выполним следующие шаги:
Microsoft Excel Application и в свойствах на вкладке «Безопасность» разрешите запуск и активацию для пользователя, от имени которого работает сервер 1С.Desktop для корректной работы в фоновом режиме. Создайте их по путям:
После настройки прав мы можем использовать код, аналогичный тому, что применялся в толстом клиенте, но с обязательным выполнением в серверном контексте:
&НаСервере
Функция СформироватьExcelНаСервере()
Попытка
Excel = Новый COMОбъект("Excel.Application");
Excel.DisplayAlerts = Ложь;
Excel.Visible = Ложь;
РабочаяКнига = Excel.Workbooks.Add();
// Здесь логика добавления листов и заполнения данными
// ...
ИмяВременногоФайла = ПолучитьИмяВременногоФайла("xlsx");
РабочаяКнига.SaveAs(ИмяВременногоФайла);
РабочаяКнига.Close();
Excel.Quit();
ДвоичныеДанные = Новый ДвоичныеДанные(ИмяВременногоФайла);
АдресХранилища = ПоместитьВоВременноеХранилище(ДвоичныеДанные, ЭтаФорма.УникальныйИдентификатор);
Возврат АдресХранилища;
Исключение
ЗаписьЖурналаРегистрации("Ошибка формирования Excel", УровеньЖурналаРегистрации.Ошибка,,, ОписаниеОшибки());
ВызватьИсключение "Не удалось сформировать файл на сервере.";
КонецПопытки;
КонецФункции
Рассмотрим более современный и стабильный способ, который не требует установки Microsoft Office на сервер. Платформа 1С обладает мощным объектом ТабличныйДокумент, который умеет сохранять данные напрямую в формат .xlsx.
Выясним причину, по которой авторы часто отказываются от этого метода: по умолчанию метод Записать() сохраняет один табличный документ как один лист Excel. Однако, если нам нужно именно многостраничное решение, мы можем использовать механизм объединения нескольких табличных документов или специализированные внешние компоненты. Если же задача позволяет выгрузить данные в один документ с разделителями, ТабличныйДокумент — лучший выбор.
Пример записи файла:
ТабДок = Новый ТабличныйДокумент;
// Заполнение ТабДок данными...
ИмяФайла = ПолучитьИмяВременногоФайла("xlsx");
ТабДок.Записать(ИмяФайла, ТипФайлаТабличногоДокумента.XLSX);
Для опытных разработчиков существует путь генерации файла без использования COM и штатных средств вывода 1С. Файл .xlsx — это по сути ZIP-архив с набором XML-файлов. Мы можем программно собрать структуру папок и файлов, что позволит создавать книги с любым количеством листов и сложным форматированием чрезвычайно быстро.
Разберем алгоритм по шагам:
workbook.xml.ЗаписьZipФайла.Этот метод полностью исключает зависание процессов excel.exe на сервере и работает в десятки раз быстрее COM-соединения.
После того как файл сформирован на сервере и помещен во временное хранилище, нам необходимо инициировать его скачивание на компьютер пользователя. В веб-клиенте это делается через специализированные методы, которые учитывают особенности работы браузеров.
Посмотрим на пример кода для клиента:
&НаКлиенте
Процедура СформироватьИСкачать(Команда)
АдресФайла = СформироватьExcelНаСервере();
Если ЗначениеЗаполнено(АдресФайла) Тогда
ПараметрыПолучения = Новый ПараметрыПолученияФайла;
ПараметрыПолучения.Заголовок = "Сохранение отчета Excel";
// Используем метод получения файла, который предложит пользователю
// сохранить его или откроет стандартный диалог загрузки браузера
ПолучитьФайл(АдресФайла, "Отчет_Статистика.xlsx", Истина);
КонецЕсли;
КонецПроцедуры
Важно помнить, что при работе в веб-клиенте использование расширения для работы с файлами крайне желательно. Оно позволяет более гибко управлять путями сохранения и проверять наличие прав доступа к локальной файловой системе, если это необходимо.
Подводя итог, можно сказать, что работа с Excel в веб-клиенте требует смены парадигмы с «управления приложением на клиенте» на «генерацию контента на сервере». Мы проанализировали основные ошибки и выяснили, что:
ПолучитьФайл().Придерживаясь этих правил, вы обеспечите стабильную работу вашей информационной системы вне зависимости от того, какой браузер использует конечный пользователь.