2

我想知道如何在不使用 python 的 win32com 客户端从 excel 工作表中迭代的情况下读取整个列。

4

3 回答 3

13

您可以读取整个列,而无需使用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 快 2 个数量级 (146x)。请注意,Range 方法返回一个 2D 列表,其中每个内部列表都是一行。列表迭代转置vals为 2D 列表,其中内部列表是一列。

于 2013-09-03T14:46:32.527 回答
2

你看过openpyxl库吗?从文档中:

from openpyxl import load_workbook
wb = load_workbook(filename='file.xlsx')
ws = wb.get_sheet_by_name(name='Sheet1')
columns = ws.columns()

还支持迭代器和其他好东西。

于 2013-09-02T15:06:24.617 回答
1

最快的方法是通过API使用内置Range功能。win32com.client但是,我不是它的忠实粉丝。我认为 API 令人困惑且记录不充分,并且使用它不是很 Python (但这只是我)。

如果效率对您来说不是问题,您可以使用出色的 xlrd 库。像这样:

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(还有其他一些非常适合使用的方法)。

请记住,xlrd 代表“excel read”,所以如果你想写入一个 excel 文件,你需要一个名为“xlwt”的不同库(这也很好,虽然在我看来不如 xlrd)。

于 2013-09-02T14:49:04.803 回答