openpyxl:一种更好的方法来读取一系列数字到数组

时间:2016-10-10 23:53:03

标签: python numpy openpyxl

我正在寻找使用openpyxl读取一系列单元格的更好(更可读/更少被黑客攻击)的方式。我现在所做的工作,但涉及组合excel单元格范围(例如A1:C3)通过组合字符串的位,感觉有点粗糙。

目前,这是我从特定单元格开始读取nCols列和nRows行的方式(最小工作示例,假设worksheet.xlsx在工作目录中,并且具有单元格在A1中的C3Sheet1中写入的引用:

from openpyxl import load_workbook
import numpy as np

firstCol = "B"
firstRow = 2

nCols = 2
nRows = 2

lastCol = chr(ord(firstCol) + nCols - 1) 

cellRange = firstCol + str(firstRow) + ":" + lastCol + str(firstRow + nRows - 1)

wsName = "Sheet1"
wb = load_workbook(filename="worksheet.xlsx", data_only=True)
data = np.array([[i.value for i in j] for j in wb[wsName][cellRange]])
print(data)

返回:

[[u'B2' u'C2']
 [u'B3' u'C3']]

除了有点难看之外,这种方法还存在功能限制。例如,在包含超过26列的工作表中,对于AA等列,它将失败。

使用openpyxl从给定的左上角读取nRowsnCols是否有更好/更正确的方法?

2 个答案:

答案 0 :(得分:1)

openpyxl提供了在数字列索引(基于1的索引)和Excel的'AA'样式之间进行转换的功能。有关详细信息,请参阅utils模块。

但是,一般来说,你几乎不需要它们。您可以使用工作表的get_squared_range()方法进行编程访问。而且,从openpyxl 2.4开始,您可以使用iter_rows()iter_cols()方法执行相同操作。 NB。 iter_cols()在只读模式下不可用。

使用iter_rows()的等效MWE将是:

from openpyxl import load_workbook
import numpy as np
wsName = "Sheet1"
wb = load_workbook(filename="worksheet.xlsx", data_only=True)
ws = wb[wsName]

firstRow = 2
firstCol = 2
nCols = 2
nRows = 2

allCells = np.array([[cell.value for cell in row] for row in ws.iter_rows()])

# allCells is zero-indexed
data = allCells[(firstRow-1):(firstRow-1+nRows),(firstCol-1):(firstCol-1+nCols)]
print(data)

使用get_squared_range()的等效MWE将是:

from openpyxl import load_workbook
import numpy as np

wsName = "Sheet1"
wb = load_workbook(filename="worksheet.xlsx", data_only=True)

firstCol = 2
firstRow = 2
nCols = 2
nRows = 2

data = np.array([[i.value for i in j] for j in wb[wsName].get_squared_range(
            firstCol, firstRow, firstCol+nCols-1, firstRow+nRows-1)])
print(data)

两者都返回:

[[u'B2' u'C2']
 [u'B3' u'C3']]

有关一起使用Pandas和openpyxl的更多信息,另请参阅https://openpyxl.readthedocs.io/en/default/pandas.html

答案 1 :(得分:0)

为了完整性(以后我可以在以后找到),使用@Rob在评论中建议的pandas函数read_excel的等效代码将是:

import pandas
import numpy as np
wsName = "Sheet1"
df = pandas.read_excel(open("worksheet.xlsx", "rb"), sheetname=wsName, header=None)

firstRow = 2
firstCol = 2
nCols = 2
nRows = 2

# Data-frame is zero-indexed

data = np.array(df.ix[(firstRow-1):(firstRow-2+nRows), (firstRow-1):(firstRow-2+nRows)])
print(data)

返回:

[[u'B2' u'C2']
 [u'B3' u'C3']]