我想使用xlrd来读取由其他人创建的一组.xlsx文件,这些文件遗憾地在Excel中错误地格式化了一列。该列是节标签(文本),如1.2.3.4。但它是作为约会形成的。它在Excel中显示OK,但是当我尝试使用xlrd读取它时,它将作为日期读入。我试过“converters = {'Section':str}”,但收到错误
OverflowError:标准化天数太大而无法放入C int
(有问题的细胞没有进入。)
我已经阅读了一下,但找不到修复.xlsx文件的好方法,以便列具有正确的数据类型。
如何修复或读取.xlsx文件,以便我可以正确读取正确的数据类型。
答案 0 :(得分: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(...))
一旦你弄清楚元组元素和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
您可以能够执行以下操作:
for r in sheet.nrows:
for cell in sheet.row(r):
try:
str(cell)
except ValueError:
cell.ctype = 1
一次,在您的脚本开始时,可以“修复”您的单元格以便稍后阅读它们,但由于我无法重现您的问题,我无法保证这一点
如果这不起作用,使用两种方法之一(使用safe_*
功能)将起作用,但您需要在从表格访问单元格的任何地方使用它。