Подтвердить что ты не робот

Можно ли подсчитать количество строк в Excel без загрузки всего документа в память?

Я работаю над приложением, которое обрабатывает огромные файлы Excel 2007, и я использую OpenPyXL, чтобы сделать это. OpenPyXL имеет два разных метода чтения файла Excel - один "нормальный" метод, когда весь документ загружается в память сразу, и один метод, в котором итераторы используются для чтения строки за строкой.

Проблема заключается в том, что когда я использую метод итератора, я не получаю метаданных документа, таких как ширина столбцов и количество строк/столбцов, а я действительно нуждаются в этих данных. Я предполагаю, что эти данные хранятся в документе Excel близко к вершине, поэтому нет необходимости загружать весь 10 МБ файл в память, чтобы получить к нему доступ.

Итак, есть ли способ получить количество строк и столбцов и ширину столбцов, не загружая сначала весь документ в память?

4b9b3361

Ответ 1

Добавив к тому, что сказал Губро, очевидно, get_highest_row() устарел. Использование свойств max_row и max_column возвращает количество строк и столбцов. Например:

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

    row_count = sheet.max_row
    column_count = sheet.max_column

Ответ 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 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

Я все еще не понял, как получить размеры столбцов, поэтому я решил использовать шрифт с фиксированной шириной и автоматически масштабированные столбцы в моем приложении.

Ответ 3

Это может быть чрезвычайно запутанным, и я могу пропустить очевидное, но без OpenPyXL, заполняющего column_dimensions в Iterable Worksheets (см. мой комментарий выше), единственный способ увидеть размер столбца без загрузки всего - это проанализировать 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

Ответ 5

Python 3

import openpyxl as xl

wb = xl.load_workbook("Sample.xlsx", enumerate)

#the 2 lines under do the same. 
sheet = wb.get_sheet_by_name('sheet') 
sheet = wb.worksheets[0]

row_count = sheet.max_row
column_count = sheet.max_column

#this works fore me.