В 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_*
) будет работать, но вам нужно использовать его везде, где вы получаете доступ к ячейке с листа.
Можете ли вы привести пример? – Alexander