python xlrd 从 Excel 文本单元格接收浮点数

5 投票
2 回答
11951 浏览
提问于 2025-04-17 08:32

我正在尝试使用xlrd从Excel文件中读取数据。到目前为止,它在处理日期、数字和文本方面都很顺利。我有一列(类别),里面的单元格包含文本(这些单元格的格式是文本)。但是,当我打印出单元格的值时,显示的却是一个浮点数,而不是文本。我还打印了单元格对象的类型,结果显示为数字。我查阅了xlrd的文档和教程,但找不到为什么会出现这种情况的原因。难道是我的Excel文件出了什么问题?有没有什么建议或者指引我该怎么做?

import xlrd
import datetime

workbook = xlrd.open_workbook('training.xls')
courseSheet = workbook.sheet_by_index(0)

for row in range(courseSheet.nrows):
    title = courseSheet.cell_value(row, 2)
    date = courseSheet.cell_value(row, 4)
    date = datetime.datetime(*xlrd.xldate_as_tuple(date, workbook.datemode))
    dateTuple = date.timetuple()
    category = courseSheet.cell_value(row, 7)
    print category

2 个回答

0

我和楼主遇到了一样的问题,经过一番思考,我觉得在某些情况下,Python(xlrd库)是没有办法解决这个问题的。你只能听天由命,看看数据最初是怎么输入到Excel表格里的。具体来说,如果数据是输入到一个已经设置为“文本”格式的单元格,或者是先输入到一个默认的“常规”格式的单元格,然后再把这个单元格的格式改成“文本”,就会出现问题。

如果你在一个已经设置好格式的单元格里输入数据,Excel会给你一个警告,提示你这个单元格是文本格式,但你输入的是数字数据。在这种情况下,xlrd会按照你的预期处理数据——也就是返回Excel表格里显示的内容。例如,如果单元格里显示的是“1”,那么xlrd也会返回“1”作为单元格的值。

但是,如果你在输入数字数据后才改变单元格的格式,那么在Excel里这个数据会显示为“1”,但xlrd却会返回“1.0”。如果你查看这个单元格的xlrd.cell.ctype,你会发现尽管Excel里格式已经改成了文本,但这个单元格仍然被当作数字来处理。

一个可能的解决办法是让你的Excel字符串数据用引号括起来。这样可以从一开始就避免Excel把数据当作数字来处理。

4

背景:对于每个单元格,xlrd会报告存储在XLS文件中的固有值(如果有的话)。这些值的类型最初是根据文件中的记录类型来确定的(例如,NUMBER和RK记录包含浮点数)。它会根据这里描述的格式进行分类,并利用这些信息在明显是日期、时间或日期时间而不是数字的情况下覆盖值类型。xlrd并不声称能够根据单元格的格式来呈现单元格值。

所讨论的单元格显然是以数字形式输入的。如果它们应用了文本格式,这并不意味着它们就是“文本单元格”。

你说“当我打印单元格值时,显示的是浮点数而不是文本”……请给出一些例子:(a) 文件创建时在单元格中输入了什么 (b) 有什么证据表明“这些单元格被格式化为文本” (c) repr(cell.value)是什么 (d) 你期望显示的“文本”是什么?

你可能会发现以下代码有用:

import xlrd, sys

def dump_cell(sheet, rowx, colx):
    c = sheet.cell(rowx, colx)
    xf = sheet.book.xf_list[c.xf_index]
    fmt_obj = sheet.book.format_map[xf.format_key]
    print rowx, colx, repr(c.value), c.ctype, \ 
        fmt_obj.type, fmt_obj.format_key, fmt_obj.format_str

book = xlrd.open_workbook(sys.argv[1], formatting_info=1)
sheet = book.sheet_by_index(0)
for rowx in xrange(sheet.nrows):
    for colx in xrange(sheet.ncols):
        dump_cell(sheet, rowx, colx)

撰写回答