Как программно конвертировать файл XLS в XLSX и прочитать его в 1С?

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

Возникает задача автоматической обработки данных из файлов Excel, которые поступают в устаревшем формате XLS (Excel 97-2003). При попытке прочитать такой файл с помощью COM-объекта в 1С могут возникать ошибки, или же код просто не видит данные, хотя с форматом XLSX все работает корректно. Рассмотрим, как решить эту проблему: программно преобразовать файл в современный формат XLSX или использовать альтернативные способы чтения данных.

Почему простое переименование файла не работает?

Первое, что может прийти в голову, — это просто сменить расширение файла с .xls на .xlsx с помощью функции ПереместитьФайл(). Это в корне неверный подход. Смена расширения не меняет внутреннюю структуру файла. Давайте разберемся в причинах.

Форматы XLS и XLSX принципиально разные:

Поэтому, просто переименовав файл, мы не превратим бинарную структуру в архив с XML. Excel, открывая такой файл, определит несоответствие содержимого расширению и либо выдаст ошибку, либо попытается восстановить данные, но для программной обработки через COM-объект такой файл будет "битым".

Решение 1: Программное пересохранение через COM-объект Excel

Самый надежный способ корректно преобразовать файл — это использовать для этого сам Excel через COM-соединение. Если файлов много, удобнее использовать конвертер из xls в xlsx. Мы программно откроем исходный XLS-файл и дадим Excel команду сохранить его в новом формате XLSX.

Для этого используется метод SaveAs объекта Workbook, которому нужно передать путь к новому файлу и числовой код формата. Для формата XLSX (Excel Workbook) используется код 51.

Посмотрим на пример кода:


Процедура КонвертироватьФайлВXLSX(ПутьКФайлуXLS, ПутьКНовомуФайлуXLSX)
    
    Попытка
        Эксель = Новый COMОбъект("Excel.Application"); // Если на этом этапе возникает ошибка, изучите статью, почему не работает COM
        // Скрываем окно Excel и отключаем системные сообщения
        Эксель.Visible = Ложь; 
        Эксель.DisplayAlerts = Ложь;
    Исключение
        Сообщить("Не удалось запустить Excel. Проверьте, что он установлен на сервере. " + ОписаниеОшибки());
        Возврат;
    КонецПопытки
    
    Попытка
        // Открываем исходный XLS файл
        Книга = Эксель.Workbooks.Open(ПутьКФайлуXLS);
        
        // Сохраняем книгу в новом формате XLSX
        // 51 - это константа VBA xlOpenXMLWorkbook, соответствующая формату XLSX
        Книга.SaveAs(ПутьКНовомуФайлуXLSX, 51);
        
        // Закрываем книгу без сохранения изменений (мы их уже сохранили в новый файл)
        Книга.Close(Ложь);
        
        Сообщить("Файл успешно сконвертирован: " + ПутьКНовомуФайлуXLSX);
        
    Исключение
        Сообщить("Ошибка при конвертации файла: " + ОписаниеОшибки());
    КонецПопытки;
    
    // Обязательно закрываем приложение Excel, чтобы не оставлять "висящих" процессов
    Эксель.Quit();
    
КонецПроцедуры

После выполнения этой процедуры вы получите корректный XLSX-файл, который уже можно будет обрабатывать вашим основным кодом, читающим данные.

Решение 2: Чтение данных с помощью встроенного объекта `ТабличныйДокумент`

Платформа 1С имеет собственный мощный инструмент для работы с таблицами, который умеет читать файлы Excel без участия самого Excel. Это объект ТабличныйДокумент. Этот способ является предпочтительным, так как:

Использовать его очень просто:


Процедура ПрочитатьДанныеЧерезТабличныйДокумент(ПутьКФайлу)

    ТабДок = Новый ТабличныйДокумент;
    
    Попытка
        ТабДок.Прочитать(ПутьКФайлу, СпособЧтенияЗначенийТабличногоДокумента.Значение);
    Исключение
        Сообщить("Не удалось прочитать файл. " + ОписаниеОшибки());
        Возврат;
    КонецПопытки;
    
    // Теперь можно обходить ячейки и получать из них данные
    // Например, получим значение из 17-й строки и 2-й колонки
    // Синтаксис "R17C2" означает Row 17 (строка), Column 2 (колонка)
    ФИО = ТабДок.Область("R17C2").Текст;
    Количество = ТабДок.Область("R17C4").Значение; // Можно получить и значение, если это число
    
    Сообщить("Прочитано ФИО: " + ФИО);
    
    // Дальнейший обход документа в цикле
    // ...
    
КонецПроцедуры

Важный момент: иногда встречаются XLS-файлы сложной структуры или с повреждениями, которые ТабличныйДокумент может прочитать некорректно или не прочитать вовсе. В таких случаях стоит вернуться к методу с COM или попробовать следующий вариант.

Решение 3: Чтение данных через ADO (ActiveX Data Objects)

Этот метод позволяет обращаться к листу Excel как к таблице базы данных, используя SQL-подобные запросы. Он часто работает быстрее, чем COM-автоматизация, и также не требует установленного Microsoft Office. Нужны только специальные драйверы OLEDB, которые обычно можно скачать с сайта Microsoft (Microsoft Access Database Engine Redistributable).

Ключевое отличие при работе с XLS и XLSX — это строка подключения.

Пример кода для чтения XLS-файла:


Процедура ПрочитатьДанныеЧерезADO(ПутьКФайлуXLS)

    Попытка
        Соединение = Новый COMОбъект("ADODB.Connection");
        
        // Строка подключения для старого формата XLS (Excel 97-2003)
        // HDR=YES означает, что первая строка на листе - это заголовок колонок
        СтрокаПодключения = "Provider=Microsoft.ACE.OLEDB.12.0;"
                         + "Data Source=" + ПутьКФайлуXLS + ";"
                         + "Extended Properties=""Excel 8.0;HDR=YES"";";
                         
        Соединение.Open(СтрокаПодключения);

    Исключение
        Сообщить("Ошибка подключения через ADO: " + ОписаниеОшибки());
        Возврат;
    КонецПопытки;
    
    // Имя листа должно быть в квадратных скобках со знаком $ в конце
    ТекстЗапроса = "SELECT * FROM [Лист1$]";
    
    НаборЗаписей = Соединение.Execute(ТекстЗапроса);
    
    Пока НЕ НаборЗаписей.EOF() Цикл
        
        // Обращаемся к данным по имени колонки (если HDR=YES) или по индексу
        ФИО = НаборЗаписей.Fields("ФИОРаботника").Value;
        Количество = НаборЗаписей.Fields("КоличествоОбедов").Value;
        
        // ... ваша логика обработки данных ...
        
        НаборЗаписей.MoveNext();
    КонецЦикла;
    
    НаборЗаписей.Close();
    Соединение.Close();

    Сообщить("Данные успешно прочитаны через ADO.");

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

Для чтения XLSX-файла строка подключения будет немного другой, изменится параметр Extended Properties:

"Extended Properties=""Excel 12.0 Xml;HDR=YES"";"

Этот способ очень эффективен для чтения больших объемов структурированных данных.

Решение 4: Конвертация через LibreOffice (для серверов на Linux)

Если код 1С исполняется на сервере под управлением ОС Linux, COM-объекты недоступны. В этом случае для конвертации можно использовать офисный пакет LibreOffice, который умеет работать из командной строки в "безголовом" режиме (без графического интерфейса).

Из 1С можно запустить внешнюю команду с помощью объекта ЗапуститьПриложение().

Команда для конвертации выглядит так:

libreoffice --convert-to xlsx /путь/к/файлу/my.xls --headless --outdir /путь/к/папке/результата

Этот метод требует, чтобы на сервере был установлен LibreOffice.

← На главную