Выгрузка ТабличногоДокумента в XLSX кодом: сервер, клиент, поток

· 9 мин

Содержание

Чтобы программно сохранить табличный документ 1С в Excel, вызовите у него метод Записать с типом файла ТипФайлаТабличногоДокумента.XLSX: ТабДок.Записать("C:\Выгрузка\Остатки.xlsx", ТипФайлаТабличногоДокумента.XLSX). Excel на компьютере для этого не нужен: файл формирует сама платформа 1С:Предприятие 8.3, в том числе на сервере под Linux.

Вся сложность не в одной строке кода, а вокруг неё. Где физически появится файл — на сервере или у пользователя. Как отдать его в браузер. Почему суммы в Excel легли текстом и не суммируются.

Метод Записать: базовая запись файла Excel

Метод принимает два параметра: путь к файлу и тип файла. Расширение в имени ни на что не влияет — формат задаёт только второй параметр. Если тип не указать, платформа запишет внутренний формат MXL, и Excel такой файл не откроет.

Минимальный пример в серверной процедуре обработки:

&НаСервере
Процедура СохранитьВExcelНаСервере(ПутьКФайлу)

	ТабДок = Новый ТабличныйДокумент;
	Макет = РеквизитФормыВЗначение("Объект").ПолучитьМакет("Макет");

	ОбластьШапка = Макет.ПолучитьОбласть("Шапка");
	ОбластьШапка.Параметры.Дата = Формат(ТекущаяДатаСеанса(), "ДЛФ=D");
	ТабДок.Вывести(ОбластьШапка);

	ОбластьСтрока = Макет.ПолучитьОбласть("Строка");
	Для Каждого СтрокаТЧ Из Объект.Товары Цикл
		ОбластьСтрока.Параметры.Заполнить(СтрокаТЧ);
		ТабДок.Вывести(ОбластьСтрока);
	КонецЦикла;

	ТабДок.Записать(ПутьКФайлу, ТипФайлаТабличногоДокумента.XLSX);

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

Если документ уже лежит на форме — например, реквизит Результат в отчёте на СКД, — строить его заново не нужно. Достаточно вызвать Записать у этого реквизита.

Где работает метод

Где выполняется кодЗаписать в файлЧто учесть
Сервер (&НаСервере, общий модуль)✅Путь — на сервере 1С, права — у пользователя службы
Тонкий клиент✅Путь — на компьютере пользователя
Веб-клиент❌Только через временное хранилище и получение файла
Фоновое и регламентное задание✅Только серверные пути, диалогов нет

Если конфигурация открывается и в тонком клиенте, и в браузере, сразу пишите вариант «сервер → двоичные данные → клиент». Он работает везде, и второй код поддерживать не придётся.

XLS или XLSX: какой тип файла выбрать

У перечисления ТипФайлаТабличногоДокумента для Excel есть несколько значений. На практике выбор сводится к двум.

ТипФорматПредел строк на листПредел колонокКогда брать
XLSXOffice Open XML (Excel 2007 и новее)1 048 57616 384По умолчанию для любых новых выгрузок
XLSДвоичный формат Excel 97–200365 536256Только если файл читает старая программа, которая не понимает XLSX
XLS95Excel 9516 384256Практически не нужен
ODSOpenDocument (LibreOffice)——Когда получатель работает не в Excel

Главная причина выбрать XLSX — лимит строк. Реестр документов за год легко перевалит за 65 тысяч строк, и в XLS хвост просто не поместится в лист.

📌 Ещё два довода за XLSX:

  • 📦 файл в 3–5 раз меньше: внутри это сжатый ZIP-архив с XML;
  • 🔤 нет проблем с кодировкой кириллицы в старых просмотрщиках.

Расширение в пути должно совпадать с типом. Файл Отчет.xls, записанный с типом XLSX, Excel откроет с предупреждением «формат файла не соответствует расширению». Пользователь решит, что файл повреждён.

Подготовка табличного документа к сохранению в Excel

Сохранить файл — полдела. Чтобы получатель мог с ним работать, документ готовят ещё до вызова Записать.

Числа, а не текст

Самая частая жалоба: суммы в Excel выровнены по левому краю, СУММ по колонке даёт ноль. Причина — в ячейку попала строка. Так бывает, если параметр макета заполнили уже отформатированным значением, например Формат(Сумма, "ЧДЦ=2").

Чтобы в Excel ушло число, ячейка должна содержать значение, а не текст:

Область = ТабДок.Область(НомерСтроки, 5, НомерСтроки, 5);
Область.СодержитЗначение = Истина;
Область.ТипЗначения = Новый ОписаниеТипов("Число");
Область.Значение = 15340.50;
Область.Формат = "ЧДЦ=2";

В макете то же самое настраивается в свойствах ячейки: флажок «Содержит значение», тип значения «Число» и формат. Параметр при этом заполняют числом, без Формат().

Что ещё проверить перед записью

  • 📏 Ширина колонок. Задайте ШиринаКолонки у колонок с длинными наименованиями, иначе текст обрежется по границе ячейки.
  • 🔒 Защита. Свойство Защита и флаг ТолькоПросмотр относятся к работе в 1С; не рассчитывайте, что они превратятся в защиту листа Excel.
  • 🧹 Пустые строки шаблона. Если вывели область «Итого» до цикла, а потом удалили, проверьте, что лишние строки не остались внизу листа.
  • 🔢 Длинные коды. ИНН, штрихкоды и номера счетов выводите как текст. Иначе Excel покажет штрихкод 4601234567890 как 4,60123E+12.

Для отчёта на СКД ничего из этого делать вручную не нужно: компоновщик выводит числовые поля как значения, и после Записать они в Excel остаются числами.

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

Строка ТабДок.Записать("C:\Выгрузка\...") в серверной процедуре создаёт файл на сервере 1С, а не на компьютере пользователя. В файловой базе это часто один и тот же компьютер, поэтому ошибку замечают только после перехода на клиент-серверный вариант.

Временный файл на сервере

Если файл нужен только как промежуточный шаг — например, чтобы получить двоичные данные или приложить к письму, — пишите его во временный каталог:

ИмяВременногоФайла = ПолучитьИмяВременногоФайла("xlsx");
ТабДок.Записать(ИмяВременногоФайла, ТипФайлаТабличногоДокумента.XLSX);

ДвоичныеДанные = Новый ДвоичныеДанные(ИмяВременногоФайла);

Попытка
	УдалитьФайлы(ИмяВременногоФайла);
Исключение
	ЗаписьЖурналаРегистрации("Выгрузка в Excel",
		УровеньЖурналаРегистрации.Предупреждение, , ,
		ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;

ПолучитьИмяВременногоФайла только придумывает уникальное имя во временном каталоге, файл не создаёт. Удаление — ваша обязанность. Без УдалитьФайлы каталог Temp сервера за полгода регулярных выгрузок разрастается на гигабайты.

Постоянный каталог на сервере

Для регламентной выгрузки в общую папку используйте сетевой путь вида \\fileserver\Обмен\Остатки.xlsx, а не букву диска. Буква подключённого диска видна только в сеансе пользователя Windows, а служба сервера 1С работает под своей учётной записью и такого диска не видит.

Правила для каталога:

  1. Дайте учётной записи службы сервера 1С (часто это USR1CV8) права на запись в папку.
  2. Проверьте существование каталога через Новый Файл(Путь).Существует() и создайте его функцией СоздатьКаталог, если нужно.
  3. Добавляйте в имя файла дату и время: "Остатки_" + Формат(ТекущаяДатаСеанса(), "ДФ=yyyyMMdd_HHmmss") + ".xlsx". Так новая выгрузка не упрётся в файл, который кто-то держит открытым.

Двоичные данные: выгрузка без файла и передача пользователю

Чтобы отдать Excel пользователю, правильная схема выглядит так: на сервере получить двоичные данные, положить их во временное хранилище, на клиенте сохранить файл.

Шаг 1. Двоичные данные на сервере

В актуальных версиях платформы 8.3 метод Записать принимает не только имя файла, но и поток. Тогда временный файл на диске вообще не нужен:

&НаСервере
Функция ПодготовитьФайлExcel()

	ТабДок = СформироватьТабличныйДокумент();

	Поток = Новый ПотокВПамяти;
	ТабДок.Записать(Поток, ТипФайлаТабличногоДокумента.XLSX);
	ДвоичныеДанные = Поток.ЗакрытьИПолучитьДвоичныеДанные();

	Возврат ПоместитьВоВременноеХранилище(ДвоичныеДанные, УникальныйИдентификатор);

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

Если платформа старая и запись в поток не поддерживается, используйте вариант с временным файлом из предыдущего раздела. Результат тот же — объект ДвоичныеДанные.

УникальныйИдентификатор формы в ПоместитьВоВременноеХранилище привязывает данные к форме: хранилище очистится, когда форму закроют.

Шаг 2. Сохранение на клиенте

В конфигурациях на БСП (Бухгалтерия 3.0, ЗУП 3.1, УТ 11 и большинство отраслевых) есть готовая процедура, которая сама покажет диалог и работает в веб-клиенте:

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

	Адрес = ПодготовитьФайлExcel();
	ФайловаяСистемаКлиент.СохранитьФайл(Неопределено, Адрес, "Остатки.xlsx");

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

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

Excel во вложении письма или в архиве

Те же двоичные данные пригодятся без клиента вообще:

  • 📧 добавить во вложения ИнтернетПочтовоеСообщение и отправить отчёт по расписанию;
  • 🗂 положить во вложения справочника файлов;
  • 🗜 упаковать несколько отчётов в один архив через ЗаписьZipФайла: записать каждый табличный документ во временный файл, добавить его методом Добавить, затем вызвать Записать у архива.

Сравнение способов: Записать или COM-объект Excel

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

СпособНужен ExcelLinux-серверСкорость на 10 000 строкКогда оправдан
ТабличныйДокумент.ЗаписатьНетДаСекундыОбычная выгрузка отчёта или печатной формы
COM Excel.ApplicationДа, на машине, где выполняется кодНетМинутыНужны формулы, сводные таблицы, макросы в готовом файле
Запись в поток + почта/хранилищеНетДаСекундыРегламентные рассылки, веб-клиент

COM-объект на сервере 1С вдобавок требует лицензии Office на сервере и регулярно оставляет в памяти зависшие процессы EXCEL.EXE. Если формулы всё же нужны, сначала сохраните файл через Записать, а затем откройте его через COM только для доработки.

Ошибки при записи файла и как их перехватить

Вызов Записать оборачивайте в Попытка … Исключение. Иначе одна занятая папка обрушит всё регламентное задание, и пользователь увидит системное окно без подсказки, что делать.

Попытка
	ТабДок.Записать(ПутьКФайлу, ТипФайлаТабличногоДокумента.XLSX);
Исключение
	ТекстОшибки = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
	ЗаписьЖурналаРегистрации("Выгрузка в Excel",
		УровеньЖурналаРегистрации.Ошибка, , , ТекстОшибки);
	ВызватьИсключение СтрШаблон(
		"Не удалось сохранить файл %1. Проверьте, что он не открыт в Excel и папка доступна.",
		ПутьКФайлу);
КонецПопытки;

Пользователю — короткое понятное сообщение, в журнал регистрации — полный текст с номером строки модуля. Так администратор найдёт причину, не воспроизводя ошибку.

Диагностика: выберите симптом

Большие документы

На табличном документе в несколько сотен тысяч строк запись идёт долго и съедает память рабочего процесса. Для таких выгрузок:

  1. Запускайте формирование в фоновом задании, чтобы не блокировать интерфейс.
  2. Разбивайте выгрузку на несколько файлов — например, по месяцам или организациям.
  3. Не держите на форме одновременно табличный документ и его двоичные данные: после записи присвойте переменной с документом Неопределено.

Частые вопросы

Как открыть файл сразу после сохранения?
На клиенте вызовите ЗапуститьПриложение с путём к файлу или, в конфигурациях на БСП, ФайловаяСистемаКлиент.ОткрытьФайл. Файл откроется в программе, которая назначена в Windows для расширения .xlsx.
Сохранятся ли в Excel цвета, шрифты и объединённые ячейки?
Да, шрифты, заливка, рамки, объединения и ширина колонок переносятся. Расшифровки 1С не переносятся: в Excel это обычный текст ячейки без перехода к документу.
Как сохранить в Excel из внешней обработки без доработки конфигурации?
Внешняя обработка выполняется так же, как встроенная: формируете табличный документ в её модуле и вызываете Записать. Права пользователя на открытие внешних обработок должны быть включены.
Как прочитать Excel обратно в табличный документ?
У табличного документа есть метод Прочитать, который в современных версиях 8.3 открывает файлы XLSX. Для загрузки данных в справочники значения потом обходят по ячейкам через метод Область.
Нужна ли лицензия Microsoft Office на сервере?
Для метода Записать — нет: файл формирует платформа. Office на сервере нужен только при работе через COM-объект Excel.Application.