При разработке интеграций и механизмов загрузки данных в 1С программисты часто сталкиваются с классическим подходом: использованием COM-объекта Excel.Application. Однако этот способ имеет огромный минус — на компьютере пользователя или на сервере 1С, где выполняется код, обязательно должен быть установлен лицензионный Microsoft Excel. В реалиях современных серверных систем (особенно под управлением Linux) или при работе в облачных сервисах установить полноценный офисный пакет невозможно или экономически нецелесообразно.
В этой статье мы подробно разберем, как решить задачу чтения файлов форматов XLS и XLSX штатными и альтернативными инструментами платформы 1С:Предприятие, полностью отказавшись от COM-объекта Excel.
Начиная с современных версий платформы 1С:Предприятие 8.3, разработчикам доступен мощный встроенный механизм чтения файлов Excel напрямую через объект ТабличныйДокумент. Это самый простой, быстрый и кроссплатформенный способ, который работает как на Windows, так и на Linux-серверах без каких-либо внешних библиотек и драйверов.
Рассмотрим по шагам, как прочитать файл Excel с помощью этого метода:
ТабличныйДокумент = Новый ТабличныйДокумент;
Попытка
// Чтение файла во внутренний формат табличного документа
ТабличныйДокумент.Прочитать(ИмяФайла, СпособЧтенияЗначенийТабличногоДокумента.Значение);
Исключение
Сообщить("Не удалось прочитать файл! Ошибка: " + ОписаниеОшибки(), СтатусСообщения.Важное);
Возврат;
КонецПопытки;
// Теперь мы можем обойти строки и колонки полученного документа
ВсегоСтрок = ТабличныйДокумент.ВысотаТаблицы;
ВсегоКолонок = ТабличныйДокумент.ШиринаТаблицы;
Для НомерСтроки = 1 По ВсегоСтрок Цикл
// Пример получения данных из первых трех колонок
Реквизит1 = ТабличныйДокумент.Область(НомерСтроки, 1).Текст;
Реквизит2 = ТабличныйДокумент.Область(НомерСтроки, 2).Значение; // Работает, если тип данных определен
Реквизит3 = ТабличныйДокумент.Область(НомерСтроки, 3).Текст;
// Обработка полученных данных...
КонецЦикла;
Параметр СпособЧтенияЗначенийТабличногоДокумента.Значение позволяет системе автоматически преобразовывать типы данных (числа, даты) при чтении, сохраняя их исходный вид, а не только текстовое представление.
Преимущества метода:
Ограничения метода:
rphost.Технология ADO (ActiveX Data Objects) позволяет представить файл Excel как реляционную базу данных, где листы книги выступают в роли таблиц, а строки — в роли записей. Это отличный выбор для операционной системы Windows, когда нужно прочитать конкретные листы или выполнить SQL-запрос к данным файла без его полной загрузки в память.
Выясним причину частой ошибки разработчиков при работе с ADO: «Источник данных не найден и не указан драйвер, используемый по умолчанию». Эта ошибка возникает, если строка подключения составлена некорректно или в операционной системе не установлены нужные драйверы доступа к данным (Access Database Engine).
Проанализируем правильные строки подключения для разных форматов файлов:
Для старого формата XLS (Excel 97-2003):
ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + СокрЛП(ИмяФайла) + ";Extended Properties=""Excel 8.0;HDR=YES;IMEX=1;""";
Для современного формата XLSX (Excel 2007 и старше):
ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + СокрЛП(ИмяФайла) + ";Extended Properties=""Excel 12.0 Xml;HDR=YES;IMEX=1;""";
Параметр HDR=YES указывает, что первая строка файла содержит заголовки колонок. Параметр IMEX=1 включает смешанный режим чтения данных (текст и числа в одной колонке будут считываться как текст, что предотвращает появление пустых значений в сложных таблицах).
Важное замечание по разрядности (32/64 бит): Если сервер 1С работает в 64-битной версии, стандартный 32-битный провайдер Microsoft.Jet.OLEDB.4.0 запустить не удастся. Вам потребуется установить 64-битный пакет Microsoft Access Database Engine Redistributable и использовать провайдер Microsoft.ACE.OLEDB.12.0.
Если в файле Excel несколько листов, и нам нужно динамически определить их имена, мы можем воспользоваться специальным расширением ADO — библиотекой ADOX. Разберем по шагам рабочий алгоритм получения списка листов книги:
// Создаем подключение ADO к файлу Excel
Connection = Новый COMОбъект("ADODB.Connection");
Connection.ConnectionString = ConnectionString; // Используем строку подключения из Решения 2
Попытка
Connection.Open();
Исключение
Сообщить("Ошибка открытия соединения: " + ОписаниеОшибки());
Возврат;
КонецПопытки;
// Используем ADOX для анализа структуры файла
Catalog = Новый COMОбъект("ADOX.Catalog");
Catalog.ActiveConnection = Connection;
КоличествоТаблиц = Catalog.Tables.Count;
СписокЛистов = Новый СписокЗначений;
Для Индекс = 0 По КоличествоТаблиц - 1 Цикл
ИмяТаблицы = Catalog.Tables(Индекс).Name;
// В структуре ADO листы Excel всегда заканчиваются символом "$"
// Именованные диапазоны или системные таблицы могут содержать "$_" или другие символы
ДлинаИмени = СтрДлина(ИмяТаблицы);
Если ДлинаИмени > 0 И Прав(ИмяТаблицы, 1) = "$" Тогда
// Очищаем имя от лишних символов и кавычек (если в имени были пробелы)
ЧистоеИмяЛиста = СтрЗаменить(ИмяТаблицы, "$", "");
ЧистоеИмяЛиста = СтрЗаменить(ЧистоеИмяЛиста, "'", "");
СписокЛистов.Добавить(ИмяТаблицы, ЧистоеИмяЛиста);
КонецЕсли;
КонецЦикла;
// Закрываем соединение
Connection.Close();
// Теперь у нас есть список реальных листов, и мы можем прочитать любой из них
Если СписокЛистов.Количество() > 0 Тогда
// Выберем, например, первый лист книги
ИмяПервогоЛиста = СписокЛистов[0].Значение; // Формат: "Лист1$"
// Загружаем данные листа через SQL-запрос
Recordset = Новый COMОбъект("ADODB.Recordset");
ТекстЗапроса = "SELECT * FROM [" + ИмяПервогоЛиста + "]";
Connection.Open();
Recordset.Open(ТекстЗапроса, Connection, 3, 1); // CursorType = 3 (Static), LockType = 1 (ReadOnly)
Пока НЕ Recordset.EOF Цикл
// Обработка полей строки таблицы
ЗначениеКолонки1 = Recordset.Fields(0).Value;
ЗначениеКолонки2 = Recordset.Fields(1).Value;
Recordset.MoveNext();
КонецЦикла;
Recordset.Close();
Connection.Close();
КонецЕсли;
Для самых продвинутых и высоконагруженных систем наиболее надежным и производительным решением является прямое чтение внутренней структуры XML-файлов. Напомним, что любой файл формата .xlsx — это обычный ZIP-архив, внутри которого находятся XML-файлы с разметкой и данными.
Рассмотрим концептуальную схему работы этого метода:
.xlsx во временный файл с расширением .zip.ЧтениеZipФайла для распаковки содержимого во временный каталог на диске.xl/workbook.xml содержит структуру книги и список всех листов с их именами и внутренними идентификаторами rId.xl/sharedStrings.xml содержит уникальный упорядоченный список всех текстовых строк, используемых в ячейках таблицы. Считываем его один раз через объект ЧтениеXML и помещаем в массив для быстрого доступа.xl/worksheets/sheet1.xml (и далее по номерам листов) содержат структуру строк и ячеек конкретного листа. При обходе XML-структуры листа мы находим координаты ячеек (например, "A1", "B2"), типы данных и ссылки на индексы строк из файла общих строк sharedStrings.xml.Этот метод работает со скоростью, недостижимой ни для одного COM-соединения, потребляет минимум оперативной памяти и полностью независим от операционной системы и установленных драйверов в Windows или Linux.
Если перед вами стоит задача разработки сложного и быстрого парсера, рекомендуется обратить внимание на готовые открытые библиотеки, написанные сообществом разработчиков 1С (например, NativeXLSX). Они реализуют этот подход «под капотом» и предоставляют разработчику удобные методы для чтения и записи файлов Excel на встроенном языке 1С.