遍历openpyxl中的只读工作簿中的列

我有一个很大的.xlsx文件 – 19列,5185行。 我想打开文件,读取一列中的所有值,对这些值做一些东西,然后在同一个工作簿中创build一个新列,并写出修改后的值。 因此,我需要能够在同一个文件中读写。

我原来的代码做到这一点:

def readExcel(doc): wb = load_workbook(generalpath + exppath + doc) ws = wb["Sheet1"] # iterate through the columns to find the correct one for col in ws.iter_cols(min_row=1, max_row=1): for mycell in col: if mycell.value == "PerceivedSound.RESP": origCol = mycell.column # get the column letter for the first empty column to output the new values newCol = utils.get_column_letter(ws.max_column+1) # iterate through the rows to get the value from the original column, # do something to that value, and output it in the new column for myrow in range(2, ws.max_row+1): myrow = str(myrow) # do some stuff to make the new value cleanedResp = doStuff(ws[origCol + myrow].value) ws[newCol + myrow] = cleanedResp wb.save(doc) 

但是,python在3853行之后抛出一个内存错误,因为工作簿太大了。 openpyxl文档表示使用只读模式( https://openpyxl.readthedocs.io/en/latest/optimized.html )来处理大型工作簿。 我正在尝试使用它; 但是,当我添加read_only = True参数时,似乎没有办法遍历列。

 def readExcel(doc): wb = load_workbook(generalpath + exppath + doc, read_only=True) ws = wb["Sheet1"] for col in ws.iter_cols(min_row=1, max_row=1): #etc. 

python抛出这个错误: AttributeError:'ReadOnlyWorksheet'对象没有属性'iter_cols'

如果我将上面的代码片段中的最后一行更改为:

 for col in ws.columns: 

python抛出相同的错误: AttributeError:'ReadOnlyWorksheet'对象没有属性'列'

遍历行很好(包括在我上面链接的文档中):

 for col in ws.rows: 

(没有错误)

此问题询问AttritubeError,但解决scheme是删除只读模式,这对我不起作用,因为openpyxl不会读取我的整个工作簿不是只读模式。

那么,如何迭代大型工作簿中的列呢?

而我还没有遇到这个问题,但是我会一次遍历列:如果工作簿很大,我怎样读写同一个工作簿?

谢谢!

根据文档 ,ReadOnly模式仅支持基于行的读取(列读取未实现)。 但是这不难解决:

 wb2 = Workbook(write_only=True) ws2 = wb2.create_sheet() # find what column I need colcounter = 0 for row in ws.rows: for cell in row: if cell.value == "PerceivedSound.RESP": break colcounter += 1 # cells are apparently linked to the parent workbook meta # this will retain only values; you'll need custom # row constructor if you want to retain more row2 = [cell.value for cell in row] ws2.append(row2) # preserve the first row in the new file break for row in ws.rows: row2 = [cell.value for cell in row] row2.append(doStuff(row2[colcounter])) ws2.append(row2) # write a new row to the new wb wb2.save('newfile.xlsx') wb.close() wb2.close() # copy `newfile.xlsx` to `generalpath + exppath + doc` # Either using os.system,subprocess.popen, or shutil.copy2() 

您将无法写入相同的工作簿,但是如上所示,您可以打开一个新的工作簿(以只写方式),写入并使用OS副本覆盖旧文件。

如果工作表只有大约10万个单元,那么你不应该有任何内存问题。 你应该进一步调查。

iter_cols()在只读模式下不可用,因为它需要对底层XML文件进行持续且非常低效的重新分析。 然而,使用zip将行转换为iter_rows()列相对容易。