Python xlrd接收来自Excel文本单元格的浮点数

5
我正在尝试使用xlrd从Excel文件中读取值。它在日期、数字和文本方面一直表现出色。我有一列(类别),其中包含文本单元格(单元格格式为文本)。当我打印单元格值时,显示的是浮点数而不是文本。我还打印了Cell对象的ctype来检查,它显示为数字。我已经阅读了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

第7列中的单元格的 cell.ctype 是什么? - Mike Pennington
我应该如何阅读您发布的代码以理解您的问题?您是如何知道它是浮点数的?从 print category 的输出中吗? - joaquin
@MikePennington,第7列单元格的ctype是xlrd.XL_CELL_NUMBER。我只是不确定为什么xlrd将文本单元格读取为数字。 - binaryFever
1
我知道我来晚了,但我遇到了完全相同的错误。你能修复它吗? - F.X.
2个回答

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)

0

我和OP有同样的问题,我认为我已经得出结论,在某些情况下,Python(xlrd)无法解决问题。你要看数据最初是如何输入到Excel表格中的。具体来说,如果数据输入到已经应用了正确“文本”格式的单元格中,或者数据输入到默认的“常规”格式单元格中,然后在输入数据后将单元格的格式更改为“文本”。

如果你将数据输入到预先格式化的单元格中,你的数字数据将被标记为Excel警告符号,表示你在格式化为文本的单元格中有数字数据。在这种情况下,xlrd将处理数据,返回与Excel工作表中显示的字符串相同的字符串。(例如,单元格内容在Excel中读取为“1”,而xlrd将返回“1”作为单元格值)

然而,如果在输入数字数据后更改单元格的格式,则会出现这样一种情况:Excel中的数据呈现为“1”,但是xlrd将返回一个单元格值为“1.0”的值。如果你检查这个单元格的xlrd cell.ctype,你会发现即使在Excel中将格式更改为文本,该单元格仍然被视为数字。

一个可能的解决办法是在excel字符串数据周围加上引号。这样可以防止excel从一开始就将数据视为数字值。

John Machin在他的回答中试图解释的是Excel的“文本格式”仅仅是一种格式。它不会改变数据的基本类型。如果Excel认为数据是数字,它将被存储为浮点数。就这样。结束了。即使你在一个数值公式中包含该单元格,比如SUM,你甚至可以看到它并没有被视为文本(尽管Excel提供了任何措辞)。如果你创建一个基本类型为文本的单元格,例如输入一个撇号后跟一个数字,那么该单元格将不会对SUM做出任何贡献。 - John Y
John Y -- 我理解你的意思。我的帖子是关于问题中的“如果Excel认为数据是数字”部分,因为我认为这就是混淆的根源。具体来说,设置单元格格式和输入单元格数据的顺序将影响Excel是否认为一段数据是数字还是文本。 - Doug
抱歉,直到现在我才完全理解了这个答案所表达的意思。对于“输入内容,然后设置格式”和“设置格式,然后输入内容”可能会产生不同结果这一点,我真的感到很困惑。但实际上确实如此。灵光乍现是在我回应 xlrd 存储库中的 issue 140 后的某个时候。 - John Y
唯一阻止我为这个答案点赞的是最后一段。你所说的“用引号括起来的Excel字符串数据”是什么意思?如果你使用前导撇号(或单引号)手动输入数据到Excel中,那么这个撇号不是数据的一部分,而是告诉Excel该数据应被视为文本。我能想到的唯一“括起来的引号”是作为公式的一部分来强制文本。如果你手动输入 ="1234",则生成的单元格值是一个长度为4的字符串。 - John Y

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接