python 如何在 openpyxl 中制作列列表
How to make a list of columns in openpyxl in python
import openpyxl
infoFilePath='test.xlsx'
workbook = openpyxl.load_workbook(infoFilePath,read_only=True)
first_sheet = workbook.get_sheet_names()[0]
worksheet = workbook.get_sheet_by_name(first_sheet)
workbook.active
def iter_rows(ws):
for row in ws.iter_rows():
yield [cell.value for cell in row]
rows = list(iter_rows(worksheet))
print(rows)
如您所见,我成功地将打印 'rows' 作为列表。但是如何将 'columns' 打印为列表?当我使用 ws.iter_cols() 时,发生了错误。
openpyxl 是处理旧 excel 文件(xlsx/xlsm/xltx/xltm)的旧模块,文件访问中未启用 iter_cols()
您当前正在使用的模式。您还可以将访问模式更改为只读。你可以使用 print settings.
否则您可以使用许多其他模块,例如:
以下是一些可供选择的选项:
- xlwt(写入 xls 文件)
- xlrd(读取 xls/xlsx 个文件)
- xlsxwriter(写入 xlsx 文件)
您正在使用只读工作簿。
问题是 Worksheet.iter_rows()
和 Worksheet.iter_cols()
方法通过使用 Worksheet.cell()
.[=23 动态创建 "missing" 单元格来改变工作表的内部结构=]
事实上,Worksheet
实例将所有非空单元格存储在 dict
中,其中键是 (row_idx, col_idx)
元组,值是 Cell
实例。如果单元格为空(无值,无样式),则它不会存储在 dict
.
中
如果您使用 read_only = False
加载您的工作簿,您可以迭代工作表而不改变它。您可以访问 _cells
受保护的属性。
您可以使用此函数计算工作表中单元格的边界框:
def calculate_indexes(cells):
# Really efficient and low memory consuming (was profiled) algorithm
min_row_idx, min_col_idx = next(iter(cells), (1, 1))
max_row_idx, max_col_idx = min_row_idx, min_col_idx
for row_idx, col_idx in cells:
min_col_idx = min_col_idx if min_col_idx < col_idx else col_idx
min_row_idx = min_row_idx if min_row_idx < row_idx else row_idx
max_col_idx = max_col_idx if col_idx < max_col_idx else col_idx
max_row_idx = max_row_idx if row_idx < max_row_idx else row_idx
return min_col_idx, min_row_idx, max_col_idx, max_row_idx
其中cells是单元格坐标列表:
然后您可以像这样实现 iter_cols
:
def iter_cols(ws):
min_col_idx, min_row_idx, max_col_idx, max_row_idx = calculate_indexes(ws._cells.keys())
for col_idx in range(min_col_idx, max_col_idx + 1):
yield [(ws._cells[(row_idx, col_idx)] if (row_idx, col_idx) in ws._cells else None)
for row_idx in range(min_row_idx, max_row_idx + 1)]
for col in iter_cols(ws):
print(col)
import openpyxl
infoFilePath='test.xlsx'
workbook = openpyxl.load_workbook(infoFilePath,read_only=True)
first_sheet = workbook.get_sheet_names()[0]
worksheet = workbook.get_sheet_by_name(first_sheet)
workbook.active
def iter_rows(ws):
for row in ws.iter_rows():
yield [cell.value for cell in row]
rows = list(iter_rows(worksheet))
print(rows)
如您所见,我成功地将打印 'rows' 作为列表。但是如何将 'columns' 打印为列表?当我使用 ws.iter_cols() 时,发生了错误。
openpyxl 是处理旧 excel 文件(xlsx/xlsm/xltx/xltm)的旧模块,文件访问中未启用 iter_cols()
您当前正在使用的模式。您还可以将访问模式更改为只读。你可以使用 print settings.
否则您可以使用许多其他模块,例如: 以下是一些可供选择的选项:
- xlwt(写入 xls 文件)
- xlrd(读取 xls/xlsx 个文件)
- xlsxwriter(写入 xlsx 文件)
您正在使用只读工作簿。
问题是 Worksheet.iter_rows()
和 Worksheet.iter_cols()
方法通过使用 Worksheet.cell()
.[=23 动态创建 "missing" 单元格来改变工作表的内部结构=]
事实上,Worksheet
实例将所有非空单元格存储在 dict
中,其中键是 (row_idx, col_idx)
元组,值是 Cell
实例。如果单元格为空(无值,无样式),则它不会存储在 dict
.
如果您使用 read_only = False
加载您的工作簿,您可以迭代工作表而不改变它。您可以访问 _cells
受保护的属性。
您可以使用此函数计算工作表中单元格的边界框:
def calculate_indexes(cells):
# Really efficient and low memory consuming (was profiled) algorithm
min_row_idx, min_col_idx = next(iter(cells), (1, 1))
max_row_idx, max_col_idx = min_row_idx, min_col_idx
for row_idx, col_idx in cells:
min_col_idx = min_col_idx if min_col_idx < col_idx else col_idx
min_row_idx = min_row_idx if min_row_idx < row_idx else row_idx
max_col_idx = max_col_idx if col_idx < max_col_idx else col_idx
max_row_idx = max_row_idx if row_idx < max_row_idx else row_idx
return min_col_idx, min_row_idx, max_col_idx, max_row_idx
其中cells是单元格坐标列表:
然后您可以像这样实现 iter_cols
:
def iter_cols(ws):
min_col_idx, min_row_idx, max_col_idx, max_row_idx = calculate_indexes(ws._cells.keys())
for col_idx in range(min_col_idx, max_col_idx + 1):
yield [(ws._cells[(row_idx, col_idx)] if (row_idx, col_idx) in ws._cells else None)
for row_idx in range(min_row_idx, max_row_idx + 1)]
for col in iter_cols(ws):
print(col)