名为Range Valu的Python xlrd

2024-06-02 07:56:35 发布

您现在位置:Python中文网/ 问答频道 /正文

在Python中使用XLRD读取Excel。

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

NamedRange“Foo”=第1张!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()

公式文本存在,以确保excel能够读取文件。在我的例子中,命名的单元格是表1单元格A1中的“sales”。

返回:

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'

Tags: tonameobjmapfooa1barcell
2条回答

最初的问题和示例由@jonnybazookatone answer below准确地回答。扩展的示例是另一个错误。对我来说这似乎是一个不足,但我已经为你想要的东西破解了一个解决方案。第一节是解释,最后一节是黑客。

解释

再看看更为扩展的示例,错误消息是从lines of code生成的,该Name对象处理错误条件,其中在Name范围内计算公式的结果由于某种原因失败。

实际报告的错误

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

是第二个错误-表示此Name对象的self.book计算结果为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 ^{}是空的,"#### 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)

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

name_map [#]

A mapping from lower_case_name to a list of Name objects. The list is sorted in scope order. Typically there will be one item (of global scope) in the list.

你有两个选择。如果只为单个单元格设置名称,则使用名称类的“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'

相关问题 更多 >