可以使用python xlrd更改.xlsx文件中的列类型

时间:2015-03-30 02:25:49

标签: python excel xlrd

我想使用xlrd来读取由其他人创建的一组.xlsx文件,这些文件遗憾地在Excel中错误地格式化了一列。该列是节标签(文本),如1.2.3.4。但它是作为约会形成的。它在Excel中显示OK,但是当我尝试使用xlrd读取它时,它将作为日期读入。我试过“converters = {'Section':str}”,但收到错误

OverflowError:标准化天数太大而无法放入C int

(有问题的细胞没有进入。)

我已经阅读了一下,但找不到修复.xlsx文件的好方法,以便列具有正确的数据类型。

如何修复或读取.xlsx文件,以便我可以正确读取正确的数据类型。

1 个答案:

答案 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_*功能)将起作用,但您需要在从表格访问单元格的任何地方使用它。