Определить кодировку в XLS

Как определить кодировку в xls?

Windows программа, делает отчет в xls, записи кириллицы в кодировке cp1251, иногда отчет редактируют в LibreOffice, LibreOffice открывает без проблем и сохраняет записи в utf-8, Pandas с кодировкой cp1251 выводит нечитаемый текст и падает с ошибкой. Как мне определить кодировку символов в xls, если я не знаю редактировали отчет или нет, если кодировка Utf-8 ничего не трбуется, если кодировка cp1251 нужно перекодировать в utf-8 (перекодировать я могу).

Файл до редактирования https://disk.yandex.ru/d/m6p2XH-LgobpJg Файл после редактирования в libreOffice https://disk.yandex.ru/i/jZud5jiqLQQdRw

Если открывать otchet.xls

excel_data = pd.read_excel('otchet.xls')

Появляется надпись

*** No CODEPAGE record, no encoding_override: will use 'iso-8859-1'
и в другой функции 
ValueError: cannot convert float NaN to integer

Если открывать так, тоже все нормально открывается, но как определить в какой кодировке открывать?

import xlrd
workbook = xlrd.open_workbook(source_file, encoding_override='cp1251')

Ответы (2 шт):

Автор решения: CrazyElf

Вы можете просто перебрать возможные кодировки пока не перестанет выбрасываться исключение:

import xlrd
import pandas as pd

def read_excel(filename):
    for encoding in ('UTF-8', 'cp1251'):
        try:
            wb = xlrd.open_workbook(filename, encoding_override=encoding)
            df = pd.read_excel(wb)
            return df
        except:
            print(f'Не удалось прочитать файл {filename} в кодировке {encoding}')
    print(f'Не удалось найти подходящую кодировку для файла {filename}')

df = read_excel('otchet.xls')
→ Ссылка
Автор решения: Алексей Р

Можно попытаться по-простому отличить исходный файл от пересохраненного. Так, в исходном первый байт 0x09, а в пересохраненном 0xD0. Если маркер устойчивый (надо проверить и на других файлах), то это сработает.

import pandas as pd
import xlrd

original, modified = '09', 'd0'
for file in r'c:\Users\Alex20\Downloads\otchet.xls', r'c:\Users\Alex20\Downloads\otchet_after_edit.xls':
    with open(file, 'rb') as f:
        first_byte = f.read(1).hex()
        if first_byte == original:
            wb = xlrd.open_workbook(file, encoding_override='cp1251')
            df = pd.read_excel(wb)
        elif first_byte == modified:
            df = pd.read_excel(file)
        else:
            print(f'Файл `{file}` имеет неизвестный формат, чтение невозможно')
    print(file, '\n', df)
c:\Users\Alex20\Downloads\otchet.xls 
           Имя  № сотрудника           Дата Время Состояние   Описание исключения  Рабочий код
0  Корнилов К          9997  2024-07-15 07:09:51    Пришел  Неправильное состоян          0.0
1  Корнилов К          9997  2024-07-15 16:53:47      Ушел  Неправильное состоян          0.0
2  Корнилов К          9997  2024-07-16 07:14:21    Пришел  Неправильное состоян          0.0
3  Корнилов К          9997  2024-07-16 17:01:08      Ушел  Неправильное состоян          0.0
c:\Users\Alex20\Downloads\otchet_after_edit.xls 
           Имя  № сотрудника           Дата Время Состояние   Описание исключения  Рабочий код
0  Корнилов К          9997  2024-07-15 07:09:51    Пришел  Неправильное состоян            0
1  Корнилов К          9997  2024-07-15 16:53:47      Ушел  Неправильное состоян            0
2  Корнилов К          9997  2024-07-16 07:14:21    Пришел  Неправильное состоян            0
3  Корнилов К          9997  2024-07-16 17:01:08      Ушел  Неправильное состоян            0
→ Ссылка