我想知道如何使用Python的win32com客户端在不迭代Excel表格的情况下读取整个列。
使用 Range
集合可以在不迭代工作表的情况下阅读整个列。如果性能是任何问题,您应该永远不要使用Cells
。Python 使用 win32com 模块与 Excel COM 库交互。每当您使用 Python 和 COM(Excel、PowerPoint、Acess、ADODB 等)时,最大的性能限制因素之一将是 COM 和 Python 之间的 IO。使用 Range
方法只需要进行一次 COM 方法调用,而使用 Cells
则每行都需要进行一次。如果您在 VBA 或 .NET 中执行相同操作,这也会更快。
在接下来的测试中,我创建了一个工作表,在单元格 A1 到 A2000 中随机生成了 10 个字符,然后使用 Range 和 Cells 将这些值提取到列表中。
import win32com.client
app = win32com.client.Dispatch("Excel.Application")
s = app.ActiveWorkbook.Sheets(1)
def GetValuesByCells():
startTime = time.time()
vals = [s.Cells(r,1).Value for r in range(1,2001)]
return time.time() - startTime
def GetValuesByRange():
startTime = time.time()
vals = [v[0] for v in s.Range('A1:A2000').Value]
return time.time() - startTime
>>> GetValuesByRange()
0.03600001335144043
>>> GetValuesByCells()
5.27400016784668
在这种情况下,Range方法比Cells方法快两个数量级(146倍)。请注意,Range方法返回一个二维列表,其中每个内部列表都是一行。列表迭代将vals
转置为一个二维列表,其中内部列表是一列。
你是否看过openpyxl库?根据文档:
from openpyxl import load_workbook
wb = load_workbook(filename='file.xlsx')
ws = wb.get_sheet_by_name(name='Sheet1')
columns = ws.columns()
此外,还支持迭代器和其他好用的工具。
Range
功能,通过win32com.client
API实现。然而,我不是它的粉丝。我认为API很混乱且文档不好,使用它并不是很Pythonic(但这只是我的看法)。import xlrd
book = xlrd.open_workbooks('Book1')
sheet = book.sheet_by_name('Sheet1')
sheel.col(1)
sheet.col(2)
# and so on...
sheet.col_values
(还有一些其他非常好用的方法)。SELECT
从数据库中检索结果集一样。也就是说,在检索之前必须处理任何必须进行的“迭代”。在数据库的情况下,SQL 引擎可能在内部进行迭代,但您看到的只是一个“返回值”,其中包含多个值。因此,对于 Excel,OP 希望指定一个范围,然后将所有值“一次性”抓取到元组中。这可能是可能的,也可能不可能;我不太了解 COM。 - John Yxlrd
,但它并没有什么特别优化的地方。 - John Y
win32com
读取整列而不进行迭代”。 - John Yxlrd
相比表现如何。如果差异微不足道,那么xlrd
将是明显的赢家。 - yuvi