При программном формировании отчетов и выгрузке данных в Excel через COM-соединение разработчики часто сталкиваются с ситуацией: старый формат .xls сохраняется без ошибок, но при попытке записать файл с расширением .xlsx, .xlsm или .xlsb создается поврежденный или пустой документ без листов. Проанализируем причину этой проблемы и рассмотрим правильные способы сохранения файлов разных форматов.
При вызове метода SaveAs у объекта рабочей книги Excel вторым параметром передается числовой идентификатор формата файла — FileFormat. Если этот параметр не указан явно или передано устаревшее значение -4143 (константа xlWorkbookNormal), Excel пытается сохранить книгу в стандартном формате своей базовой версии (для Excel 97–2003 это бинарный .xls).
Если при этом в имени файла указано расширение .xlsx, возникает конфликт внутреннего формата и расширения. В результате файл либо не открывается, либо создается полностью пустым.
Разберем соответствие расширений файлов и числовых констант перечисления XlFileFormat, которые необходимо передавать в метод SaveAs:
xlOpenXMLWorkbook) — стандартная книга Excel без макросов (расширение .xlsx).xlOpenXMLWorkbookMacroEnabled) — книга Excel с поддержкой макросов (расширение .xlsm).xlExcel12) — двоичная книга Excel (расширение .xlsb), оптимальна для больших объемов данных.xlExcel8) — книга формата Excel 97–2003 (расширение .xls).xlCSV) — текстовый файл с разделителями (расширение .csv).xlWorkbookNormal) — формат книги по умолчанию для текущей установленной версии приложения.Посмотрим на практический пример кода на языке 1С, в котором создается новая книга, заполняются данные и выполняется корректное сохранение в современный формат .xlsx:
Попытка
Excel = Новый COMОбъект("Excel.Application");
Excel.DisplayAlerts = Ложь;
Excel.Visible = Ложь;
Книга = Excel.Workbooks.Add();
Лист = Книга.Worksheets(1);
// Заполняем тестовые ячейки
Лист.Cells(1, 1).Value = "Код";
Лист.Cells(1, 2).Value = "Наименование";
Лист.Cells(2, 1).Value = "00001";
Лист.Cells(2, 2).Value = "Товар 1";
ПутьКФайлу = "C:\Temp\Выгрузка.xlsx";
ФорматXLSX = 51;
// Передаем путь и код формата
Книга.SaveAs(ПутьКФайлу, ФорматXLSX);
Книга.Close(Ложь);
Excel.Quit();
Исключение
Если Excel <> Неопределено Тогда
Excel.Quit();
КонецЕсли;
ВызватьИсключение "Ошибка при работе с Excel: " + ОписаниеОшибки();
КонецПопытки;
Рассмотрим функцию, которая автоматически подбирает числовой код формата на основании расширения целевого файла:
Функция ПолучитьКодФорматаExcel(ИмяФайла)
Файл = Новый Файл(ИмяФайла);
Расширение = НРег(Файл.Расширение);
Если Расширение = ".xlsx" Тогда
Возврат 51;
ИначеЕсли Расширение = ".xlsm" Тогда
Возврат 52;
ИначеЕсли Расширение = ".xlsb" Тогда
Возврат 50;
ИначеЕсли Расширение = ".xls" Тогда
Возврат 56;
ИначеЕсли Расширение = ".csv" Тогда
Возврат 6;
Иначе
Возврат 51; // По умолчанию сохраняем в XLSX
КонецЕсли;
КонецФункции
Теперь применим эту функцию при пересохранении книги:
КодФормата = ПолучитьКодФорматаExcel(ПутьКФайлу);
Книга.SaveAs(ПутьКФайлу, КодФормата);
Выясним, когда можно обойтись без использования COMОбъект("Excel.Application"). Работа через COM имеет существенные ограничения: она зависит от установленного в операционной системе пакета Microsoft Office, работает только в ОС Windows и создает высокую нагрузку при выполнении на сервере.
Платформа 1С:Предприятие предоставляет штатный способ формирования файлов Excel с помощью объекта ТабличныйДокумент. Этот метод работает быстро, не требует установленного Excel и поддерживается на сервере 1С под управлением Linux:
ТабДок = Новый ТабличныйДокумент;
// Формируем содержимое документа через макет или программно
Область = ТабДок.ПолучитьОбласть("R1C1:R1C2");
ТабДок.Область("R1C1").Текст = "Код";
ТабДок.Область("R1C2").Текст = "Наименование";
// Сохраняем в файл формата XLSX
ТабДок.Записать("C:\Temp\Выгрузка.xlsx", ТипФайлаТабличногоДокумента.XLSX);
Использование свойства ТипФайлаТабличногоДокумента.XLSX позволяет сформировать полноценный файл Excel без вызова внешних COM-библиотек.