【问题标题】:Python xlrd Named Range ValuePython xlrd 命名范围值
【发布时间】:2014-06-26 17:47:01
【问题描述】:

在 Python 中使用 XLRD 从 Excel 中读取数据。

简单的场景。我有一个带有值的单元格,它与一个命名范围相关联。

NamedRange "Foo" = Sheet1!$A$1 A1中的值为“Bar”

book =xlrd.open_workbook("")

rng =  book.name_map['foo'][0]  # lower case for some reason.

print rng.???   # how to print the cell value bar??

我只想在python代码中引用命名范围“Foo”并打印出单元格的值“Bar”。

编辑: 这是另一个更完整的例子:

import xlrd

workbook = xlrd.open_workbook('/path/to/metester.xls')
cell_obj = workbook.name_and_scope_map.get(('sales', -1))
# this does print Sheet1!$A$1
print cell_obj.formula_text
# this raises the NoneTypeError
print cell_obj.cell()

formula_text 用于确保 excel 可以读取文件。在我的例子中,命名单元格是 Sheet1 单元格 A1 中的“销售”。

返回:

Sheet1!$A$1
Traceback (most recent call last):
  File "tester.py", line 7, in <module>
    print cell_obj.cell()
  File "/usr/local/lib/python2.7/dist-packages/xlrd/book.py", line 253, in cell
    self.dump(self.book.logfile,
AttributeError: 'NoneType' object has no attribute 'logfile'

【问题讨论】:

  • 有什么解决办法吗?我试过 rng.cell() 并且给了我一个错误:AttributeError: 'NoneType' object has no attribute 'logfile'。我使用的是 0.9.3 版
  • @llamawithabowlcut 嗯 - 属性错误与 'the source code' 不相符 - Name.cell() 似乎只与 XLRDError 相符。你确定这是给你错误的那条线吗?因为它指的是logfile - 可能是您的日志设置或实际失败的东西?你能给我们一个更完整的用例吗?也许您的问题与@Dickster 的原始问题不同,您需要一个新问题?
  • @JRichardSnape:请看我的编辑。我没有其他导入,这是完整的代码。
  • @llamawithabowlcut 查看我的回答 - 您的问题与原始问题不同。感谢您确认您使用的是 .xlsx 而不是 .xls。让我知道它是否有效 - 花了一段时间才弄清楚。

标签: python excel xlrd named-ranges


【解决方案1】:

首先,如xlrd模块信息(https://secure.simplistix.co.uk/svn/xlrd/trunk/xlrd/doc/xlrd.html?p=4966)中所述,它是小写:

name_map [#]

从 lower_case_name 到 Name 对象列表的映射。该列表按范围顺序排序。列表中通常会有一项(全局范围的)。

你有两个选择。如果您真的只为单个单元格设置名称,则使用 Name 类的“单元格”方法(请参阅文档):

import xlrd
book = xlrd.open_workbook("")
Name = book.name_map['foo'][0]
print(Name.cell())

控制台:

text:'Bar'

但是,如果您已经命名了整个范围的值,那么您需要使用 Name 类的 area2d 方法:

import xlrd
book = xlrd.open_workbook("q1.xls")
Name = book.name_map['foo'][0]
Sheet, rowxlo, rowxhi, colxlo, colxhi = Name.area2d()
for i in range(rowxhi):
    print(Sheet.cell(i,0))

控制台:

text:'Bar'

【讨论】:

  • 正如我上面提到的 cell() 给了我一个错误:AttributeError: 'NoneType' object has no attribute 'logfile' (Sheet.cell(i,0)) 也给了我同样的错误)
  • 您需要提供更多详细信息,示例代码,如@J Richard Snape 所述
  • 感谢您的解释,乔尼。我正在尝试在 Excel 中使用表的名称范围,但我无法从 xlrd 中找到相应的函数。您是否知道如何读取分配了名称范围的表?
  • @Zong 我建议你在这里打开一个新问题并链接到它,它会比你等我快得多。
【解决方案2】:

@jonnybazookatone answer below 准确回答了最初的问题和示例。扩展示例是一个不同的错误。对我来说,这似乎是一个xlrd 缺陷,但我已经破解了你想要的解决方案。第一部分是解释,最后一部分是hack。

说明

查看更扩展的示例,错误消息是从处理Name 对象上的错误条件的lines of code 产生的,其中评估Name 范围内的公式的结果由于某种原因而失败。

实际报错

AttributeError: 'NoneType' object has no attribute 'logfile'

是一个次要错误 - 表明 self.book 对于此 Name 对象的计算结果为 None

其次,我认为您遗漏了一个重要细节,即您的 Excel 文件是 .xlsx 格式。注意尾随的 x。在普通的 xls 解析器中,Name 对象没有属性formula_text,因此您的代码失败并出现以下错误。

Traceback (most recent call last):
  File "D:\q1.py", line 16, in <module>
    print cell_obj.formula_text
AttributeError: 'Name' object has no attribute 'formula_text'

请注意您的代码示例 - 我花了一段时间来跟踪这种差异 - xlsx 文件由 xlrd 中的完全不同的代码解析。修复 xlsx 后,我可以重现您的错误。

在这种情况下,formula_text 属性只是将 R-C 符号引用提供给 您的命名范围的单元格。应该注意的是,function that sets formula_text 被警告 "#### UNDER CONSTRUCTION ####" 并且自 2012 年 xlsx 模块的初始提交以来一直存在。

问题是 - 据我所知 - 在打开 xlsx 时永远不会评估公式 - 所以你遇到了 Name.res 是 None 的错误,因此你会看到你的错误。这似乎是一个xlrd 错误/功能。

破解

我想出了一个讨厌的 hack,它可以通过扩展单元格引用在你的范围是单个单元格的情况下做你想做的事。请注意,对于像现在这样引用多个单元格的命名范围将失败,但可以轻松修改以应对这种情况:

hack = cell_obj.formula_text
(sheetName,ref) = hack.split('!')
(discard,colStr,rowStr) = ref.split('$')
col = 0
for i in range(len(colStr)):
    colAdd = string.ascii_uppercase.index(colStr)
    col += colAdd * 10**i
row = int(rowStr)-1
print("Trying to evaluate cell",row,col,"in sheet",sheetName)
print workbook.sheet_by_name(sheetName).cell(row,col)

【讨论】:

  • 对 .xls 与 .xlsx 错误感到抱歉...愚蠢,愚蠢的我。我喜欢 var "hack" 这个名字。
  • 没问题,容易犯错误。在我开始挖掘之前,我从来没有怀疑过 xls 与 xlsx 的处理方式是如此不同。很高兴我能解决它。无法抗拒 var 名称,很高兴你喜欢它 :)
  • 我已经提出github.com/python-excel/xlrd/pull/326 来修复次要错误
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多