是否有可能得到一个Excel文档的行数没有将整个文档加载到内存中?(Is it possible t

2019-07-03 20:06发布

我工作的那个巨大的处理Excel 2007中文件的应用程序,和我使用OpenPyXL做到这一点。 OpenPyXL具有读取Excel文件两种不同的方法 - 一个“正常”的方法,其中整个文档被加载到存储器一次,并且其中迭代器用于读取行到行的一个方法。

问题是,当我使用迭代方法,我没有得到任何文件的元数据,如列宽和行/列数,我真的需要这个数据。 我认为这个数据存储接近顶部的Excel文件中,所以它不应该是必要的整个10MB文件加载到内存中去访问它。

那么,有没有办法让阿霍德行/列数和列宽而不需要将整个文件加载到内存中第一次?

Answer 1:

添加到什么Hubro说,显然get_highest_row()已被弃用。 使用max_rowmax_column属性返回的行和列数。 例如:

    wb = load_workbook(path, use_iterators=True)
    sheet = wb.worksheets[0]

    row_count = sheet.max_row
    column_count = sheet.max_column


Answer 2:

该解决方案在这个答案建议已被弃用,并且可能不再起作用。


考虑看看OpenPyXL(源代码IterableWorksheet )我已经想通了如何从一个迭代工作表中的列和行数:

wb = load_workbook(path, use_iterators=True)
sheet = wb.worksheets[0]

row_count = sheet.get_highest_row() - 1
column_count = letter_to_index(sheet.get_highest_column()) + 1

IterableWorksheet.get_highest_column返回与列字母,你可以在Excel中看到,如“A”,“B”的字符串,“C”等,因此我也写一个函数来翻译列字母以从零开始的索引:

def letter_to_index(letter):
    """Converts a column letter, e.g. "A", "B", "AA", "BC" etc. to a zero based
    column index.

    A becomes 0, B becomes 1, Z becomes 25, AA becomes 26 etc.

    Args:
        letter (str): The column index letter.
    Returns:
        The column index as an integer.
    """
    letter = letter.upper()
    result = 0

    for index, char in enumerate(reversed(letter)):
        # Get the ASCII number of the letter and subtract 64 so that A
        # corresponds to 1.
        num = ord(char) - 64

        # Multiply the number with 26 to the power of `index` to get the correct
        # value of the letter based on it's index in the string.
        final_num = (26 ** index) * num

        result += final_num

    # Subtract 1 from the result to make it zero-based before returning.
    return result - 1

我还没有想出如何获取列的大小了,所以我决定用一个固定宽度的字体和自动缩放列我的应用程序。



Answer 3:

这可能是非常令人费解,我可能是缺少明显的,但没有OpenPyXL填充在可迭代工作表中的column_dimensions(见上面我的意见),我可以看到寻找列大小而不加载一切的唯一方法是直接解析XML :

from xml.etree.ElementTree import iterparse
from openpyxl import load_workbook
wb=load_workbook("/path/to/workbook.xlsx", use_iterators=True)
ws=wb.worksheets[0]
xml = ws._xml_source
xml.seek(0)

for _,x in iterparse(xml):

    name= x.tag.split("}")[-1]
    if name=="col":
        print "Column %(max)s: Width: %(width)s"%x.attrib # width = x.attrib["width"]

    if name=="cols":
        print "break before reading the rest of the file"
        break


Answer 4:

https://pythonhosted.org/pyexcel/iapi/pyexcel.sheets.Sheet.html看到:row_range()实用程序函数来获取行范围

如果你使用pyexcel,可拨打row_range获得最大的行。

蟒3.4试验合格。



文章来源: Is it possible to get an Excel document's row count without loading the entire document into memory?