xlrd Excel脚本将"#N/A"转换为42

7 投票
4 回答
5481 浏览
提问于 2025-04-16 11:25

我有一个脚本,它用xlrd模块从Excel表格中提取数据,特别是使用row_values()这个方法。这个方法工作得很好,除了在某些地方出现了“#N/A”,这是之前用VLookups生成的结果。在这种情况下,xlrd把“#N/A”当成了整数42。

我查看了一下字符串格式化的方法,但没发现这和问题有什么关系。

除了这个脚本发现了生命的意义(42),有没有人能建议一下可能是什么问题呢?

谢谢!

注意:这个表格里已经没有VLookups了,所有的值都是从其他表格复制过来的,都是普通的值,没有公式。

4 个回答

5

正如安德鲁所提到的,如果单元格里有错误,xlrd会写出这个错误的代码,你可以在这里看到相关信息:

0x00: '#NULL!',  # Intersection of two cell ranges is empty
0x07: '#DIV/0!', # Division by zero
0x0F: '#VALUE!', # Wrong type of operand
0x17: '#REF!',   # Illegal or deleted cell reference
0x1D: '#NAME?',  # Wrong function or range name
0x24: '#NUM!',   # Value range overflow
0x2A: '#N/A',    # Argument or function not available

把十六进制的代码0x2A转换成十进制,你会得到42这个值。为了避免这个问题,你可以在你的代码中使用类似下面的内容:

for rownum in xrange(sh.nrows):
    wr.writerow(['#N/A' if col.ctype == xlrd.XL_CELL_ERROR else col.value for col in sh.row(rownum)])
11

我觉得这个很有用。感谢约翰的最初帮助。

def xls_proc_text(cell, value_proc=None, text_proc=None):
    """Converts the given cell to appropriate text."""
    """The proc will come in only when the given is value or text."""
    ttype = cell.ctype
    if ttype == xlrd.XL_CELL_EMPTY or ttype == xlrd.XL_CELL_TEXT or ttype == xlrd.XL_CELL_BLANK:
        if text_proc is None:
            return cell.value
        else:
            return text_proc(cell.value)
    if ttype == xlrd.XL_CELL_NUMBER or ttype == xlrd.XL_CELL_DATE or ttype == xlrd.XL_CELL_BOOLEAN:
        if value_proc is None:
            return str(cell.value)
        else:
            return str(value_proc(cell.value))
    if cell.ctype == xlrd.XL_CELL_ERROR:
        # Apply no proc on this.
        return xlrd.error_text_from_code[cell.value]
5

在网上或者你电脑上的xlrd文档中(在浏览器里打开文档,然后按Ctrl-F #N/A),你可以找到一个从Excel内部代码到文本的转换表

你可能会发现sheet.row_types()方法Cell类文档很有用,这些内容可以帮助你理解sheet.row_types()返回的类型编号和其他编号之间的对应关系。需要注意的是,测试这些类型编号通常比用isinstance()来检查值更有效,而且使用类型编号不会产生歧义。

撰写回答