66 votes

Est-il possible d'obtenir le nombre de lignes d'un document Excel sans charger tout le document en mémoire ?

Je travaille sur une application qui traite d'énormes fichiers Excel 2007, et j'utilise OpenPyXL pour le faire. OpenPyXL dispose de deux méthodes différentes pour lire un fichier Excel - une méthode "normale" où le document entier est chargé en mémoire en une seule 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 de l'itérateur, je n'obtiens aucune métadonnée du document, comme la largeur des colonnes et le nombre de lignes/colonnes, et je n'obtiens pas de métadonnées du document, comme la largeur des colonnes et le nombre de lignes/colonnes. vraiment ont besoin de ces données. Je suppose que ces données sont stockées dans le document Excel près du sommet, de sorte qu'il ne devrait pas être nécessaire de charger l'ensemble du fichier de 10 Mo dans la mémoire pour y accéder.

Existe-t-il un moyen de connaître le nombre de lignes/colonnes et la largeur des colonnes sans avoir à charger tout le document en mémoire ?

131voto

dransom90 Points 1458

En complément de ce qu'a dit Hubro, apparemment get_highest_row() a été supprimée. L'utilisation de la fonction max_row y max_column 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

18voto

Hubro Points 13319

La solution proposée dans cette réponse a été abandonnée et pourrait ne plus fonctionner.


En jetant un coup d'œil au code source d'OpenPyXL ( Feuille de travail itérable ) J'ai trouvé comment obtenir le nombre de colonnes et de lignes d'une feuille de calcul itérative :

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. C'est pourquoi j'ai également écrit une fonction pour traduire la lettre de la colonne en un index 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 toujours pas trouvé comment obtenir la taille des colonnes, c'est pourquoi j'ai décidé d'utiliser une police à largeur fixe et des colonnes à échelle automatique dans mon application.

3voto

Anders Stamnes Points 31

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.

2voto

Markus Points 1248

Cela peut être extrêmement compliqué et je peux passer à côté de l'évidence, mais sans OpenPyXL qui remplit les column_dimensions dans les Iterable Worksheets (voir mon commentaire ci-dessus), la seule façon que je vois de trouver la taille de la colonne sans tout charger est d'analyser 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

1voto

Cam Points 401

Options utilisant pandas.

  1. Récupère tous les noms de feuilles avec le nombre de lignes et de colonnes.

    import pandas as pd xl = pd.ExcelFile('file.xlsx') sheetnames = xl.sheet_names for sheet in sheetnames: df = xl.parse(sheet) dimensions = df.shape print('sheetname', ' --> ', dimensions)

  2. Comptage des lignes et des colonnes d'une seule feuille.

    import pandas as pd xl = pd.ExcelFile('file.xlsx') sheetnames = xl.sheet_names df = xl.parse(sheetnames[0]) # [0] get first tab/sheet. dimensions = df.shape print(f'sheetname: "{sheetnames[0]}" - -> {dimensions}')

sortie sheetname "Sheet1" --> (row count, column count)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X