Lecture / analyse de fichiers Excel (xls) avec Python


117

Quelle est la meilleure façon de lire les fichiers Excel (XLS) avec Python (pas les fichiers CSV ).

Existe-t-il un package intégré qui est pris en charge par défaut dans Python pour effectuer cette tâche?



18
@voyager: il veut LIRE les fichiers pas les écrire
John Machin

Réponses:


92

Je recommande vivement xlrd pour la lecture de .xlsfichiers.

voyager a mentionné l'utilisation de l'automatisation COM. Ayant fait cela moi-même il y a quelques années, sachez que faire cela est un vrai PITA. Le nombre de mises en garde est énorme et la documentation fait défaut et ennuyeuse. J'ai rencontré de nombreux bugs et pièges étranges, dont certains ont pris plusieurs heures à résoudre.

MISE À JOUR: Pour les .xlsxfichiers plus récents , la bibliothèque recommandée pour la lecture et l'écriture semble être openpyxl (merci, Ikar Pohorský).


5
Pour les fichiers Excel 2007+ ( .xlsx), vous utiliserez probablement OpenPyXL .
Ikar Pohorský

48

Utilisation de pandas:

import pandas as pd

xls = pd.ExcelFile("yourfilename.xls")

sheetX = xls.parse(2) #2 is the sheet number

var1 = sheetX['ColumnName']

print(var1[1]) #1 is the row number...

1
pandas utilise xlrd pour faire la lecture; vous devrez également installer xlrd en tant que dépendance
congusbongus

25

Vous pouvez choisir l'un d'entre eux http://www.python-excel.org/
Je recommanderais la bibliothèque python xlrd.

installez-le en utilisant

pip install xlrd

importer en utilisant

import xlrd

pour ouvrir un classeur

workbook = xlrd.open_workbook('your_file_name.xlsx')

ouvrir la feuille par nom

worksheet = workbook.sheet_by_name('Name of the Sheet')

ouvrir la feuille par index

worksheet = workbook.sheet_by_index(0)

lire la valeur de la cellule

worksheet.cell(0, 0).value    

La "lecture de la valeur de la cellule" ne fonctionne pas ... elle déclenche une TypeError: l'objet 'Sheet' n'est pas appelable. Tout le reste a très bien fonctionné.
Newbielp le

13

Je pense que Pandas est la meilleure voie à suivre. Il y a déjà une réponse ici avec Pandas utilisant la ExcelFilefonction, mais cela n'a pas fonctionné correctement pour moi. De là, j'ai trouvé la read_excelfonction qui fonctionne très bien:

import pandas as pd
dfs = pd.read_excel("your_file_name.xlsx", sheet_name="your_sheet_name")
print(dfs.head(10))

PS Vous devez avoir xlrdinstallé pour que la read_excelfonction fonctionne

Mise à jour 21-03-2020: Comme vous pouvez le voir ici , il y a des problèmes avec le xlrdmoteur et il va être obsolète. C'est openpyxlle meilleur remplacement. Ainsi, comme décrit ici , la syntaxe canonique devrait être:

dfs = pd.read_excel("your_file_name.xlsx", sheet_name="your_sheet_name", engine="openpyxl")

AttributeError: l'objet 'dict' n'a pas d'attribut 'head'
lopezdp

4

Pour xlsx, j'aime la solution publiée plus tôt sous https://web.archive.org/web/20180216070531//programming/4371163/reading-xlsx-files-using-python . J'utilise uniquement des modules de la bibliothèque standard.

def xlsx(fname):
    import zipfile
    from xml.etree.ElementTree import iterparse
    z = zipfile.ZipFile(fname)
    strings = [el.text for e, el in iterparse(z.open('xl/sharedStrings.xml')) if el.tag.endswith('}t')]
    rows = []
    row = {}
    value = ''
    for e, el in iterparse(z.open('xl/worksheets/sheet1.xml')):
        if el.tag.endswith('}v'):  # Example: <v>84</v>                            
            value = el.text
        if el.tag.endswith('}c'):  # Example: <c r="A3" t="s"><v>84</v></c>                                 
            if el.attrib.get('t') == 's':
                value = strings[int(value)]
            letter = el.attrib['r']  # Example: AZ22                         
            while letter[-1].isdigit():
                letter = letter[:-1]
            row[letter] = value
            value = ''
        if el.tag.endswith('}row'):
            rows.append(row)
            row = {}
    return rows

Les améliorations ajoutées consistent à récupérer le contenu par nom de feuille, à utiliser re pour obtenir la colonne et à vérifier si les chaînes partagées sont utilisées.

def xlsx(fname,sheet):
    import zipfile
    from xml.etree.ElementTree import iterparse
    import re
    z = zipfile.ZipFile(fname)
    if 'xl/sharedStrings.xml' in z.namelist():
        # Get shared strings
        strings = [element.text for event, element
                   in iterparse(z.open('xl/sharedStrings.xml')) 
                   if element.tag.endswith('}t')]
    sheetdict = { element.attrib['name']:element.attrib['sheetId'] for event,element in iterparse(z.open('xl/workbook.xml'))
                                      if element.tag.endswith('}sheet') }
    rows = []
    row = {}
    value = ''

    if sheet in sheets:
    sheetfile = 'xl/worksheets/sheet'+sheets[sheet]+'.xml'
    #print(sheet,sheetfile)
    for event, element in iterparse(z.open(sheetfile)):
        # get value or index to shared strings
        if element.tag.endswith('}v') or element.tag.endswith('}t'):
            value = element.text
        # If value is a shared string, use value as an index
        if element.tag.endswith('}c'):
            if element.attrib.get('t') == 's':
                value = strings[int(value)]
            # split the row/col information so that the row leter(s) can be separate
            letter = re.sub('\d','',element.attrib['r'])
            row[letter] = value
            value = ''
        if element.tag.endswith('}row'):
            rows.append(row)
            row = {}

    return rows

Merci d'avoir ravivé ma réponse!
Collin Anderson le

2

Vous pouvez utiliser l'une des bibliothèques répertoriées ici (comme Pyxlreader basé sur JExcelApi ou xlwt ), ainsi que l' automatisation COM pour utiliser Excel lui-même pour la lecture des fichiers, mais pour cela, vous introduisez Office en tant que dépendance de votre logiciel, ce qui n'est peut-être pas toujours une option.


6
(1) pyxlreader est la vérole absolue. Vous ne devez jamais l'avoir essayé. Voir mes commentaires ici: stackoverflow.com/questions/1243545/… (2) xlwtfichiers WriTes; utiliser xlrdpour les fichiers ReaD.
John Machin

2

Si vous avez besoin d'un ancien format XLS. Ci-dessous le code pour ansii 'cp1251'.

import xlrd

file=u'C:/Landau/task/6200.xlsx'

try:
    book = xlrd.open_workbook(file,encoding_override="cp1251")  
except:
    book = xlrd.open_workbook(file)
print("The number of worksheets is {0}".format(book.nsheets))
print("Worksheet name(s): {0}".format(book.sheet_names()))
sh = book.sheet_by_index(0)
print("{0} {1} {2}".format(sh.name, sh.nrows, sh.ncols))
print("Cell D30 is {0}".format(sh.cell_value(rowx=29, colx=3)))
for rx in range(sh.nrows):
   print(sh.row(rx))


0

Vous pouvez également envisager d'exécuter le programme (non-python) xls2csv. Donnez-lui un fichier xls et vous devriez récupérer un csv.


3
Mais l'affiche dit qu'il a besoin de lire en Python ... Proposez-vous d'exécuter xls2csv, puis d'analyser le csvdepuis Python?
hcarver

Python-excelerator contient un wrapper py_xls2csv exécutable autour d'un convertisseur python.
fatal_error


0
    with open(csv_filename) as file:
        data = file.read()

    with open(xl_file_name, 'w') as file:
        file.write(data)

Vous pouvez activer CSV pour exceller comme ci-dessus avec des packages intégrés. CSV peut être géré avec un package intégré de dictreader et dictwriter qui fonctionnera de la même manière que le dictionnaire python. ce qui le rend beaucoup plus facile. Je ne connais actuellement aucun package intégré pour Excel, mais j'avais rencontré openpyxl. C'était aussi assez simple et direct.Vous pouvez voir l'extrait de code ci-dessous en espérant que cela aide

    import openpyxl
    book = openpyxl.load_workbook(filename)
    sheet = book.active 
    result =sheet['AP2']
    print(result.value)

0

Pour les .xlsfichiers plus anciens , vous pouvez utiliserxlrd

soit vous pouvez l'utiliser xlrddirectement en l'important. Comme ci-dessous

import xlrd
wb = xlrd.open_workbook(file_name)

Ou vous pouvez également utiliser la pd.read_excel()méthode pandas , mais n'oubliez pas de spécifier le moteur, bien que la valeur par défaut soit xlrd, il doit être spécifié.

pd.read_excel(file_name, engine = xlrd)

Les deux fonctionnent pour les anciens .xlsformats de fichiers. En fait, je suis tombé sur cela lorsque j'ai utilisé OpenPyXL, j'ai l'erreur ci-dessous

InvalidFileException: openpyxl does not support the old .xls file format, please use xlrd to read this file, or convert it to the more recent .xlsx file format.
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.