Можно ли подсчитать количество строк в Excel без загрузки всего документа в память?
Я работаю над приложением, которое обрабатывает огромные файлы Excel 2007, и я использую OpenPyXL, чтобы сделать это. OpenPyXL имеет два разных метода чтения файла Excel - один "нормальный" метод, когда весь документ загружается в память сразу, и один метод, в котором итераторы используются для чтения строки за строкой.
Проблема заключается в том, что когда я использую метод итератора, я не получаю метаданных документа, таких как ширина столбцов и количество строк/столбцов, а я действительно нуждаются в этих данных. Я предполагаю, что эти данные хранятся в документе Excel близко к вершине, поэтому нет необходимости загружать весь 10 МБ файл в память, чтобы получить к нему доступ.
Итак, есть ли способ получить количество строк и столбцов и ширину столбцов, не загружая сначала весь документ в память?
Ответы
Ответ 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
Ответ 4
https://pythonhosted.org/pyexcel/iapi/pyexcel.sheets.Sheet.html
see: row_range() Утилита для получения диапазона строк
если вы используете pyexcel, можете вызвать row_range get max rows.
тестовый проход python 3.4.
Ответ 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.