Est-il possible d'obtenir le nombre de lignes D'un document Excel sans charger le document entier dans la mémoire?
je travaille sur une application qui traite d'énormes fichiers Excel 2007, et j'utilise OpenPyXL pour le faire. OpenPyXL a deux méthodes différentes pour lire un fichier Excel - une méthode "normale" où le document entier est chargé en mémoire à la fois, et une méthode où des itérateurs sont utilisés pour lire ligne par ligne.
le problème est que lorsque j'utilise la méthode iterator, Je ne reçois pas de méta-données de document comme les largeurs de colonne et le nombre de lignes/colonnes, et je vraiment besoin de ces données. Je suppose que ces données sont stockées dans le document Excel près du haut, donc il ne devrait pas être nécessaire de charger l'ensemble du fichier 10MB dans la mémoire pour y accéder.
alors, y a-t-il un moyen de mettre la main sur le nombre de lignes/colonnes et la largeur des colonnes sans charger d'abord tout le document dans la mémoire?
4 réponses
ajoutant à ce que disait Hubro, apparemment get_highest_row()
a été désapprouvée. À l'aide de la max_row
et max_column
propriétés renvoie le nombre de lignes et de colonnes. Par exemple:
wb = load_workbook(path, use_iterators=True)
sheet = wb.worksheets[0]
row_count = sheet.max_row
column_count = sheet.max_column
la solution suggérée dans cette réponse a été dépréciée et pourrait ne plus fonctionner.
jetez un coup d'oeil au code source D'OpenPyXL ( IterableWorksheet) j'ai trouvé comment obtenir le nombre de colonnes et de rangées à partir d'une feuille de travail itératrice:
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
renvoie une chaîne avec la lettre de la colonne que vous pouvez voir dans Excel, par exemple "A", "B", "C" etc. Donc j'ai aussi écrit une fonction pour traduire la colonne lettre à un indice basé sur zéro:
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
Je n'ai pas encore trouvé comment obtenir les tailles de colonne, donc j'ai décidé d'utiliser une police de caractères de largeur fixe et des colonnes graduées automatiquement dans mon application.
cela pourrait être extrêmement compliqué et je pourrais manquer l'évident, mais sans OpenPyXL remplir les dimensions column_ dans les feuilles de travail itérables (voir mon commentaire ci-dessus), la seule façon que je peux voir de trouver la taille de la colonne sans charger tout est de parser le xml directement:
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
https://pythonhosted.org/pyexcel/iapi/pyexcel.sheets.Sheet.html voir : row_range() la fonction d'Utilité pour obtenir la ligne
si vous utilisez pyexcel, vous pouvez appeler row_range get max rows.
python 3.4 test pass.