2015-03-30 3 views
0

Я хочу использовать xlrd для чтения набора файлов .xlsx, созданного кем-то другим, который, к сожалению, неправильно форматировал столбец в Excel. Столбец - это метка раздела (текст), такая как 1.2.3.4. но он формируется как дата. Он отображает ОК в Excel, но когда я пытаюсь прочитать его при использовании xlrd, он считывается как дата. Я попытался «конвертеры = {„Раздел“: ул}», но получил ошибкуможет python xlrd изменить тип столбца в файле .xlsx

OverflowError: (. Ячейка в вопросе не было никаких записей) нормированные дни слишком большой, чтобы поместиться в C междунар

Я немного почитал, но не могу найти хороший способ зафиксировать файл .xlsx, чтобы столбцы имели нужный тип данных.

Как исправить или прочитать файл .xlsx, чтобы я мог читать нужный тип данных без ошибок.

+0

Можете ли вы привести пример? – Alexander

ответ

0

В Excel, если ячейка отформатирована как дата, она сохраняется как номер с плавающей запятой. (См. Dates in Excel Spreadsheets).

Таким образом, исходные данные ввода теряются. Единственное, что хранится, это число с плавающей запятой, которое перестраивается Excel при загрузке.

Вы можете проверить это, распечатав содержимое ячейки. Если вы не можете, по какой-либо причине (вы говорите, что это вызывает ошибку), вы можете захватить ячейку и изменить ее атрибут ctype на 1 для текста. Например:

cell = sheet.cell(r,c) 
print(cell) # xldate:37623.0 (if this causes an error, comment it out) 
cell.ctype = 1 
print(cell) # text:37623.0 

Что вы может быть в состоянии сделать это чесать исходное значение путем преобразования числа с плавающей запятой в кортеже с помощью xlrd.xldate_as_tuple

cell = sheet.cell(r,c) 
print(cell) 
print(xlrd.xldate_as_tuple(cell.value, workbook.datemode)) 

Пример вывода:

1/2/3     # Entered in cell 
xldate:37623.0   # print(cell) 
(2003, 1, 2, 0, 0, 0) # print(xlrd.xldate_as_tuple(...)) 

1/2/3     # Entered in cell 
xldate:38415.0   # print(cell) 
(2003, 1, 2, 0, 0, 0) # print(xlrd.xldate_as_tuple(...)) 

Затем вы должны напрямую использовать данные кортежа, как только вы выясните взаимосвязь между элементами кортежа и th e отображает данные Excel.

Если это не сработает, минимальный пример файла с расширением .xls будет полезен для дальнейшей диагностики.

Примечание: Это было написано с использованием xlrd версии 0.9.3. В приведенных выше примерах workbook представляет собой переменную, удерживающую рабочую книгу (например, через xlrd.open_workbook), а sheet - переменная, удерживающая рабочий лист (например, через workbook.sheet_by_index).


Обновление: За обсуждение в комментариях, вы можете сделать что-то вроде:

import xlrd 

workbook = xlrd.open_workbook('file.xlsx', ragged_rows=True) 
sheet = workbook.sheet_by_index(0) 

def safe_cell(cell): 
    try: 
     str(cell) 
    except ValueError: 
     cell.ctype = 1 
    return cell 

def safe_get(sheet, r, c): 
    cell = sheet.cell(r,c) 
    return safe_cell(cell) 

И тогда доступ к ячейкам с одним из следующих подходов:

# Approach (a) 
for r in sheet.nrows: 
    for c in sheet.ncols: 
     cell = safe_get(sheet, r, c) 
     # You can now operate on cell without worrying about it raising a ValueError 

# Approach (b) 
for r in sheet.nrows: 
    for cell in sheet.row(r): 
     cell = safe_cell(cell) 
     # You can now operate on cell without worrying about it raising a ValueError 

You май сможет сделать что-то вроде:

for r in sheet.nrows: 
    for cell in sheet.row(r): 
     try: 
      str(cell) 
     except ValueError: 
      cell.ctype = 1 

Однажды, в начале вашего скрипта, и он может «исправить» свои клетки для того, когда вы читаете их позже, но так как я не могу воспроизвести проблему, я не могу гарантировать это.

Если это не сработает, использование одного из двух подходов (с использованием функций safe_*) будет работать, но вам нужно использовать его везде, где вы получаете доступ к ячейке с листа.

+0

Спасибо. Я получил «ValueError: недействительный литерал для int() с базой 10:« »на шаге« печать (ячейка) ». Это может сработать. Я могу« исправить »отдельную ячейку для печати в« правильном »формате. есть быстрый способ скорректировать все ячейки во всех столбцах на всех листах во всех книгах, которые я должен обрабатывать? Я могу шагнуть через все ячейки один за другим, но может быть более элегантный способ. – pheon

+0

@ pheon Просто, чтобы быть ясным, когда вы запускаете шаги в первом блоке кода, вы получаете 'ValueError' для первой' print (cell) ', но когда вы меняете' ctype', вы можете получить доступ к данным? Если это правда, то у меня есть представление о том, как убедиться, что все ячейки, которые в противном случае ошибочно устанавливались в 'ctype = 1', прежде чем вы их прочитали, и только те, которые были бы ошибкой, - это будет работать вы? – jedwards

+0

Да. Правильно. В наборе файлов .xlsx, которые я пытаюсь прочитать, есть много ячеек, которые помечены как «дата» Excel, которые вызывают ошибку, когда Я пытаюсь прочитать их в пандах, используя xlrd. Ваше исправление работает по принципу «по отдельности», но то, что мне действительно нужно, - это общее решение, которое не вызовет ошибки при чтении всех файлов. – pheon