Внешняя нативная компонента xls21c для чтения XLS/XLSX файлов
Чтение XLS/XLSX файлов без установленного Excel — задача, с которой сталкивался каждый 1С-разработчик. Внешняя нативная компонента xls21c обещает решить её быстро и без лишних зависимостей. Но за кажущейся простотой скрывается несколько ловушек, которые проявятся только при эксплуатации в реальных задачах. Мы разберём, как работает компонента под капотом, сравним её с альтернативами и дадим практические рекомендации, которые не найти в официальной документации.
Контекст и ситуация
Средствами платформы 1С:Предприятие 8 штатно поддерживается только чтение файлов .xlsx через встроенные функции ЧтениеXML (формат OOXML — ZIP-архив с XML). Однако бинарные .xls (XLS 97–2003) не читаются без внешних компонент. Типовые решения:
- COM-объект Excel.Application — требует установленного Microsoft Office, медленно, опасно для серверов.
- ADO (OLE DB) — нужен драйвер Microsoft ACE, который не всегда доступен и имеет ограничения по версиям.
- LibreOffice в режиме headless — сложно в настройке, нестабильно при параллельных вызовах.
- Внешние компоненты (DLL) — xls21c, XLSXReader, ExcelLib и др.
Компонента xls21c позиционируется как лёгкая, нативная, не требующая дополнительных библиотек. Однако, как показывает практика, разработчики часто упускают из виду её внутренние механизмы, что приводит к трудноуловимым ошибкам.
Как устроена xls21c: механика под капотом
xls21c — это 32-битная DLL, написанная на C++ с использованием библиотек libxls (для чтения бинарных XLS) и OpenXLSX (для XLSX). Она подключается к 1С через механизм ВнешниеКомпоненты:
// Псевдокод — точные имена методов смотрите в документации компоненты
Попытка
ВнешниеКомпоненты.Добавить(КаталогИБ + "ExtDLL\xls21c.dll");
Чтение = ВнешниеКомпоненты.СоздатьОбъект("xls21c.ЧтениеXLS");
Чтение.ОткрытьФайл(ИмяФайла);
Исключение
Сообщить("Ошибка загрузки компоненты: " + КраткоеПредставлениеОшибки(ИнформацияОбОшибке()));
Возврат;
КонецПопытки;
Важно: Компонента xls21c — 32-битная. При использовании в 64-битном сервере 1С необходимо настроить пул приложений на 32-битный режим, иначе компонента не загрузится. Это первая ловушка, которая часто проявляется не сразу, а при первом вызове на промышленном сервере.
Ловушка №1: Разное поведение для XLS и XLSX
Библиотеки libxls и OpenXLSX имеют разный уровень поддержки функций. Например, libxls не поддерживает чтение дат, сохранённых как числа в формате 1904 (Mac), а OpenXLSX может неправильно интерпретировать объединённые ячейки. В результате файл, открытый в Excel, корректно читается, а через xls21c — с пустыми строками или неверными значениями.
Пример: дата "01.01.1900" в XLS может быть представлена как число 1 (в системе 1900), а в XLSX — как строка. Компонента может преобразовать число в строку "1" без учёта формата ячейки. Решение: всегда проверять тип данных в ячейке и принудительно преобразовывать через Формат(Значение, "ДЛФ=ДД").
Ловушка №2: Утечка памяти при повторном открытии
Внутренний менеджер ресурсов xls21c не освобождает память, если не вызвать явный метод ЗакрытьФайл() или не уничтожить объект. При циклическом чтении множества файлов (например, в обработке по загрузке прайс-листов) это приводит к росту потребления памяти до аварийного завершения.
// Корректный шаблон работы с компонентой
Процедура ПрочитатьФайлXLS(ИмяФайла)
Чтение = Неопределено;
Попытка
Чтение = ВнешниеКомпоненты.СоздатьОбъект("xls21c.ЧтениеXLS");
Чтение.ОткрытьФайл(ИмяФайла);
// ... чтение данных
Исключение
ЗаписьЖурналаРегистрации("Ошибка", УровеньЖурналаРегистрации.Ошибка,,,
КраткоеПредставлениеОшибки(ИнформацияОбОшибке()));
Возврат;
КонецПопытки;
Если Чтение <> Неопределено Тогда
Чтение.ЗакрытьФайл(); // обязательный вызов
КонецЕсли;
КонецПроцедуры
Запомните: Никогда не полагайтесь на автоматическое освобождение при выходе из процедуры. Всегда явно закрывайте файл внутри обработчика Попытка…Исключение…КонецПопытки.
Сравнение подходов: xls21c vs ADO vs COM
Ключевые критерии выбора — производительность, совместимость, требования к окружению. Ниже — качественная оценка, основанная на реальных проектах (точные цифры зависят от объёмов данных).
| Критерий | xls21c | ADO (OLE DB) | COM Excel |
|---|---|---|---|
| Скорость чтения (1000 строк) | быстро (~0.5–1 с) | средне (~1–2 с) | медленно (~3–5 с) |
| Поддержка XLS (бинарный) | да (libxls) | да (драйвер ACE) | да |
| Поддержка XLSX |