Ошибка открытия файлов xlsx в python

Я пытаюсь открыть файл xlsx, созданный другой системой (это формат, в который всегда поступают данные, и который не находится под моим контролем). Я пробовал и openpyxl (v2.3.2) и xlrd (v1.0.0) (а также pandas (v0.20.1) read_excel и pd.ExcelFile(), которые используют xlrd, и поэтому могут быть спорными), и я сталкиваюсь с ошибками; плюс не найти ответы по моим запросам. Любая помощь приветствуется.

xlrd код:

import xlrd
workbook = xlrd.open_workbook(r'C:/Temp/Data.xlsx')

Ошибка:

Traceback (most recent call last):

  File "<ipython-input-3-9e5d87f720d0>", line 2, in <module>
    workbook = xlrd.open_workbook(r'C:/Temp/Data.xlsx')

  File "C:\Program Files\Anaconda3\lib\site-packages\xlrd\__init__.py", line 422, in open_workbook
    ragged_rows=ragged_rows,

  File "C:\Program Files\Anaconda3\lib\site-packages\xlrd\xlsx.py", line 833, in open_workbook_2007_xml
    x12sheet.process_stream(zflo, heading)

  File "C:\Program Files\Anaconda3\lib\site-packages\xlrd\xlsx.py", line 548, in own_process_stream
    self_do_row(elem)

  File "C:\Program Files\Anaconda3\lib\site-packages\xlrd\xlsx.py", line 685, in do_row
    self.sheet.put_cell(rowx, colx, None, float(tvalue), xf_index)

ValueError: could not convert string to float: 

код openpyxl:

import openpyxl
wb = openpyxl.load_workbook(r'C:/Temp/Data.xlsx')

Ошибка:

Traceback (most recent call last):

  File "<ipython-input-2-6083ad2bc875>", line 1, in <module>
    wb = openpyxl.load_workbook(r'C:/Temp/Data.xlsx')

  File "C:\Program Files\Anaconda3\lib\site-packages\openpyxl\reader\excel.py", line 234, in load_workbook
    parser.parse()

  File "C:\Program Files\Anaconda3\lib\site-packages\openpyxl\reader\worksheet.py", line 106, in parse
    dispatcher[tag_name](element)

  File "C:\Program Files\Anaconda3\lib\site-packages\openpyxl\reader\worksheet.py", line 243, in parse_row_dimensions
    self.parse_cell(cell)

  File "C:\Program Files\Anaconda3\lib\site-packages\openpyxl\reader\worksheet.py", line 188, in parse_cell
    value = _cast_number(value)

  File "C:\Program Files\Anaconda3\lib\site-packages\openpyxl\cell\read_only.py", line 23, in _cast_number
    return long(value)

ValueError: invalid literal for int() with base 10: ' '

код панды:

import pandas as pd
df = pd.read_excel(r'C:/Temp/Data.xlsx', sheetname='Sheet1')

Ошибка:

Traceback (most recent call last):

  File "<ipython-input-5-b86ec98a4e9e>", line 2, in <module>
    df = pd.read_excel(r'C:/Temp/Data.xlsx', sheetname='Sheet1')

  File "C:\Program Files\Anaconda3\lib\site-packages\pandas\io\excel.py", line 200, in read_excel
    io = ExcelFile(io, engine=engine)

  File "C:\Program Files\Anaconda3\lib\site-packages\pandas\io\excel.py", line 257, in __init__
    self.book = xlrd.open_workbook(io)

  File "C:\Program Files\Anaconda3\lib\site-packages\xlrd\__init__.py", line 422, in open_workbook
    ragged_rows=ragged_rows,

  File "C:\Program Files\Anaconda3\lib\site-packages\xlrd\xlsx.py", line 833, in open_workbook_2007_xml
    x12sheet.process_stream(zflo, heading)

  File "C:\Program Files\Anaconda3\lib\site-packages\xlrd\xlsx.py", line 548, in own_process_stream
    self_do_row(elem)

  File "C:\Program Files\Anaconda3\lib\site-packages\xlrd\xlsx.py", line 685, in do_row
    self.sheet.put_cell(rowx, colx, None, float(tvalue), xf_index)

ValueError: could not convert string to float: 

Для чего это стоит, вот пример фрагмента входного файла: Пример входного файла

Я предполагаю, что ошибки приходят из первой строки с пробелами после первого столбца - потому что ошибки исчезают, когда я удаляю первые две строки и. Я не могу пропустить первые две строки, потому что я хочу извлечь значение в ячейке A1. Я также хотел бы, чтобы считанные значения имели строковый тип, и позже будут преобразованы в число с плавающей точкой с проверкой ошибок. Спасибо!

===========

Обновление (9 августа, 10:00 по восточному времени): по предложению Чарли смог открыть файл Excel в режиме только для чтения; и был в состоянии прочитать большую часть содержимого - но все еще где-то сталкивался с ошибкой. новый код (извините, он не очень питонический - все еще новичок):

wb = openpyxl.load_workbook(r'C:/Temp/Data.xlsx', read_only=True)
ws = wb['Sheet1']
ws.max_row = ws.max_column = None

i=1
for row in ws.rows:
    for cell in row:
        if i<2000:
            i += 1
            try:
                print(i, cell.value)
            except:
                print("error")

Ошибка:

Traceback (most recent call last):

  File "<ipython-input-65-2e8f3cf2294a>", line 2, in <module>
    for row in ws.rows:

  File "C:\Program Files\Anaconda3\lib\site-packages\openpyxl\worksheet\read_only.py", line 125, in get_squared_range
    yield tuple(self._get_row(element, min_col, max_col))

  File "C:\Program Files\Anaconda3\lib\site-packages\openpyxl\worksheet\read_only.py", line 165, in _get_row
    value, data_type, style_id)

  File "C:\Program Files\Anaconda3\lib\site-packages\openpyxl\cell\read_only.py", line 36, in __init__
    self.value = value

  File "C:\Program Files\Anaconda3\lib\site-packages\openpyxl\cell\read_only.py", line 132, in value
    value = _cast_number(value)

  File "C:\Program Files\Anaconda3\lib\site-packages\openpyxl\cell\read_only.py", line 23, in _cast_number
    return long(value)

ValueError: invalid literal for int() with base 10: ' '

=========

Обновление 2 (10:35 утра): когда я читаю файл без ws.max_row и ws.max_column со значением None, код считывает только один столбец без ошибок. Значение в ячейке A66 "Создано из:". Но когда я читаю файл с ws.max_row и ws.max_column, установленными как None, эта конкретная ячейка вызывает проблемы. Но я могу прочитать все остальные ячейки до этого, и сейчас у меня все будет хорошо. спасибо, Чарли.

2 ответа

Решение

Похоже, исходный файл, вероятно, поврежден и содержит ячейки с пустыми строками, которые напечатаны как числа. Возможно, вы сможете использовать режим openpyxl только для чтения, чтобы пропустить первые строки буксировки.

Если ваша программа работает после удаления первых двух строк, давайте пропустим их. попробуйте использовать skiprows игнорировать первые 2 строки, которые являются пробелами или заголовками. Вы можете использовать parse метод из панды.

xls = pd.read_excel('C:/Temp/Data.xlsx')

df = xls.parse('Sheet1', skiprows=2) #assuming your data is on sheet1.
Другие вопросы по тегам