Python xlrd命名范围值

时间:2014-06-26 17:47:02

标签: python excel xlrd named-ranges

在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??

我只想参考命名范围" Foo"在python代码中打印出值" 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可以读取文件。就我而言,指定的单元格是" sales"在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'

2 个答案:

答案 0 :(得分:4)

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

  

name_map [#]

     

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

您有两种选择。如果你真的只设置一个单元格的名称,那么你使用Name类的'cell'方法(参见文档):

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'

答案 1 :(得分:3)

最初的问题和示例完全由@jonnybazookatone answer below回答。扩展示例是一个不同的错误。这似乎是xlrd的不足之处,但我已经为你想要的东西破解了一个解决方案。第一节是解释,最后一节是黑客。

解释

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

实际报告的错误

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

是次要错误 - 表示此self.book个对象的None评估为Name

其次 - 我认为您错过了一个重要的细节,即您的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 = 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)