Как обработать и заполнить файл Excel по шаблону в 1С 8.3, если MS Excel не установлен на сервере?

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

При переводе обработок и печатных форм на управляемый интерфейс (например, при переходе на «1С:Зарплата и управление персоналом 3.1» или «1С:Бухгалтерия 3.0») разработчики часто сталкиваются с техническим ограничением: требуется сформировать сложный отчет по шаблону Microsoft Excel, однако сервер приложений 1С работает под управлением политики безопасности, запрещающей установку пакета MS Office на серверную машину.

Попытка вызвать Новый COMОбъект("Excel.Application") в серверном контексте в таком случае приводит к критической ошибке. Рассмотрим подробнее, как обойти это ограничение, правильно организовать передачу данных с сервера на клиент и сохранить исходную структуру шаблона Excel вместе с формулами и форматированием.

Анализ проблемы и архитектурные особенности

Проанализируем ключевые сложности, возникающие при адаптации старого кода к управляемым формам:

  1. Контекстное разделение: Все тяжелые расчеты и выборки из базы данных должны производиться на сервере, тогда как вызов COM-объекта Excel возможен только на клиенте, где установлен MS Office.
  2. Ограничения типов данных: Объект ТаблицаЗначений недоступен на клиенте в управляемом приложении. Данные, рассчитанные на сервере, необходимо конвертировать в клиентские типы (например, массив структур) или передавать через временное хранилище.
  3. Потеря формул при сохранении через Табличный документ: Стандартный механизм сохранени ТабличныйДокумент.Записать(..., ТипФайлаТабличногоДокумента.XLSX) вычисляет и превращает все формулы Excel в статичные значения, а также может терять настройки печати и закрепления областей.

Основное решение: Шаблон в двоичных данных и COM-автоматизация на клиенте

Разберем наиболее надежный и проверенный алгоритм работы. Шаблон `.xlsx` сохраняется непосредственно внутри внешнего отчета или обработки 1С в виде макета с типом Двоичные данные. На сервере выполняются все расчеты, а на клиенте происходит выгрузка шаблона во временный файл, открывается COM-объект Excel и заполняются необходимые ячейки.

Рассмотрим пошагово реализацию этого механизма в коде.

Шаг 1. Получение макета и подготовка данных на сервере

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


&НаСервере
Функция ПолучитьДанныеДляВыгрузки()
    
    // 1. Выполняем расчеты и формируем таблицу значений
    ТаблицаРезультат = Новый ТаблицаЗначений;
    ТаблицаРезультат.Колонки.Добавить("СотрудникИмя", Новый ОписаниеТипов("Строка"));
    ТаблицаРезультат.Колонки.Добавить("Оклад", Новый ОписаниеТипов("Число"));
    ТаблицаРезультат.Колонки.Добавить("Надбавка", Новый ОписаниеТипов("Число"));
    
    // (Заполнение таблицы данными расчетов...)
    СтрокаТЗ = ТаблицаРезультат.Добавить();
    СтрокаТЗ.СотрудникИмя = "Иванов И.И.";
    СтрокаТЗ.Оклад = 50000;
    СтрокаТЗ.Надбавка = 10000;
    
    // 2. Преобразуем ТаблицуЗначений в Массив Структур для передачи на клиент
    МассивРезультат = Новый Массив;
    Для Каждого Стр Из ТаблицаРезультат Цикл
        СтруктураСтроки = Новый Структура;
        Для Каждого Колонка Из ТаблицаРезультат.Колонки Цикл
            СтруктураСтроки.Вставить(Колонка.Имя, Стр[Колонка.Имя]);
        КонецЦикла;
        МассивРезультат.Добавить(СтруктураСтроки);
    КонецЦикла;
    
    Возврат МассивРезультат;

КонецФункции

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

КонецФункции

Шаг 2. Заполнение шаблона Excel на стороне клиента

На клиенте извлекаем двоичные данные, сохраняем их во временный файл `.xlsx`, запускаем Excel в фоновом режиме и заполняем строки:


&НаКлиенте
Процедура ВыгрузитьВExcelКлиент()

    // 1. Извлекаем файл шаблона из временного хранилища
    АдресХранилища = ПолучитьМакетШаблона("ШаблонExcel");
    ДвоичныеДанные = ПолучитьИзВременногоХранилища(АдресХранилища);
    
    ИмяФайлаШаблона = ПолучитьИмяВременногоФайла("xlsx");
    ДвоичныеДанные.Записать(ИмяФайлаШаблона);
    
    // 2. Получаем данные расчетов с сервера
    ДанныеДляПечати = ПолучитьДанныеДляВыгрузки();
    
    // 3. Подключаемся к MS Excel
    Попытка
        Excel = Новый COMОбъект("Excel.Application");
    Исключение
        ПоказатьПредупреждение(, "Не удалось создать объект MS Excel. Проверьте правильность установки приложения.");
        Возврат;
    КонецПопытки;
    
    Попытка
        // Отключаем обновление экрана для ускорения работы
        Excel.ScreenUpdating = Ложь;
        Excel.DisplayAlerts = Ложь;
        
        Книга = Excel.WorkBooks.Open(ИмяФайлаШаблона);
        Лист = Книга.WorkSheets(1);
        
        НачальнаяСтрока = 5; // Номер строки в шаблоне, откуда начинается таблица
        ТекущаяСтрока = НачальнаяСтрока;
        
        Для Каждого СтрДанных Из ДанныеДляПечати Цикл
            
            Лист.Cells(ТекущаяСтрока, 1).Value = СтрДанных.СотрудникИмя;
            Лист.Cells(ТекущаяСтрока, 2).Value = СтрДанных.Оклад;
            Лист.Cells(ТекущаяСтрока, 3).Value = СтрДанных.Надбавка;
            
            // Задаем формулу Excel для итоговой суммы в строке
            // Используем свойство FormulaLocal для формул на языке локализации (русский)
            Лист.Cells(ТекущаяСтрока, 4).FormulaLocal = СТРЗаменить("=B%1+C%1", "%1", Строка(ТекущаяСтрока));
            
            ТекущаяСтрока = ТекущаяСтрока + 1;
            
        КонецЦикла;
        
        // Включаем интерфейс обратно
        Excel.ScreenUpdating = Истина;
        Excel.DisplayAlerts = Истина;
        Excel.Visible = Истина;
        
    Исключение
        Excel.Quit();
        Excel = Неопределено;
        ВызватьИсключение ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
    КонецПопытки;

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

Тонкости записи формул и оптимизация работы с COM-объектами

При работе с COM-объектом Microsoft Excel следует учитывать несколько важных технических особенностей:

  1. Разница между Formula и FormulaLocal: Свойство Cells().Formula принимает названия функций исключительно на английском языке (например, =SUM(A1:A10)) с запятой в качестве разделителя аргументов. Если вы пишете формулы на русском языке (например, =СУММ(A1;A10)), используйте свойство Cells().FormulaLocal.
  2. Ускорение обработки: Обязательно отключайте перерисовку экрана и вывод предупреждений через свойства Excel.ScreenUpdating = Ложь и Excel.DisplayAlerts = Ложь перед началом цикла заполнения. Это повышает скорость заполнения в 3–5 раз.
  3. Корректное завершение процессов: Всегда закрывайте соединение с объектом в блоке Попытка ... Исключение. В противном случае процессы EXCEL.EXE будут зависать в диспетчере задач пользователя.
  4. Форматы файлов: При использовании формата `.xls` (Excel 97-2003) действуют жесткие ограничения (65 536 строк и 256 столбцов). Рекомендуется всегда использовать формат `.xlsx` (Excel 2007 и выше).

Альтернативный вариант: Прямое редактирование XLSX на сервере без MS Excel (ZIP / XML)

Если требуется выполнять всю работу строго на сервере без применения клиентского COM-объекта, проанализируем архитектуру файла `.xlsx`. Файл формата OpenXML представляет собой обычный ZIP-архив, внутри которого находятся XML-файлы с содержимым и структурой книги.

Выясним порядок действий для редактирования файла средствами 1С на сервере:

  1. Распаковать файл-шаблон `.xlsx` во временный каталог с помощью встроенного объекта ЧтениеZipФайла.
  2. Прочитать и модифицировать файлы `xl/worksheets/sheet1.xml` (данные ячеек и формулы) и `xl/sharedStrings.xml` (общие текстовые строки) с использованием объектов ЧтениеXML, ЗаписьXML или DOMДокумент.
  3. Запаковать отредактированный каталог обратно в файл с помощью объекта ЗаписьZipФайла.

Этот способ работает с высокой скоростью прямо на сервере, не требует наличия установленного пакета MS Office и полностью сохраняет исходное форматирование, макросы (`.xlsm`), графики и существующие формулы шаблона.

← На главную