Lettura / analisi di file Excel (xls) con Python


Risposte:


92

Consiglio vivamente xlrd per leggere i .xlsfile.

voyager ha menzionato l'uso dell'automazione COM. Avendolo fatto io stesso alcuni anni fa, tieni presente che farlo è una vera PITA. Il numero di avvertimenti è enorme e la documentazione è carente e fastidiosa. Mi sono imbattuto in molti strani bug e trucchi, alcuni dei quali hanno richiesto molte ore per capirlo.

AGGIORNAMENTO: Per i .xlsxfile più recenti , la libreria consigliata per la lettura e la scrittura sembra essere openpyxl (grazie, Ikar Pohorský).


5
Per i file Excel 2007+ ( .xlsx) probabilmente useresti OpenPyXL .
Ikar Pohorský

48

Usare i panda:

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 sta usando xlrd per leggere; dovrai anche installare xlrd come dipendenza
congusbongus

25

Puoi sceglierne uno qualsiasi http://www.python-excel.org/
Suggerirei la libreria xlrd di python.

installalo usando

pip install xlrd

importare utilizzando

import xlrd

per aprire una cartella di lavoro

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

foglio aperto per nome

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

foglio aperto per indice

worksheet = workbook.sheet_by_index(0)

leggere il valore della cella

worksheet.cell(0, 0).value    

Il "valore della cella di lettura" non funziona ... solleva un'eccezione TypeError: l'oggetto 'Sheet' non è richiamabile. Tutto il resto ha funzionato alla grande.
Newbielp

13

Penso che Pandas sia il modo migliore per andare. C'è già una risposta qui con Panda che usa la ExcelFilefunzione, ma non ha funzionato correttamente per me. Da qui ho trovato la read_excelfunzione che funziona benissimo:

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

PS È necessario che la funzione sia xlrdinstallata affinché read_excelfunzioni

Aggiornamento 21-03-2020: come puoi vedere qui , ci sono problemi con il xlrdmotore e sarà deprecato. Il openpyxlè il miglior sostituto. Quindi, come descritto qui , la sintassi canonica dovrebbe essere:

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

AttributeError: l'oggetto 'dict' non ha l'attributo 'head'
lopezdp

4

Per xlsx mi piace la soluzione pubblicata in precedenza come https://web.archive.org/web/20180216070531//programming/4371163/reading-xlsx-files-using-python . Uso solo i moduli della libreria 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

I miglioramenti aggiunti sono il recupero del contenuto in base al nome del foglio, l'utilizzo di re per ottenere la colonna e il controllo se vengono utilizzate le sharedstrings.

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

Grazie per aver rinnovato la mia risposta!
Collin Anderson,

2

Puoi utilizzare una qualsiasi delle librerie elencate qui (come Pyxlreader basato su JExcelApi o xlwt ), oltre all'automazione COM per utilizzare Excel stesso per la lettura dei file, ma per questo stai introducendo Office come dipendenza del tuo software, che potrebbe non essere sempre un'opzione.


6
(1) pyxlreader è il vaiolo assoluto. Non devi averlo mai provato. Vedere i miei commenti qui: stackoverflow.com/questions/1243545/... (2) xlwtfile scrive; utilizzare xlrdper i file ReaD.
John Machin

2

Se hai bisogno del vecchio formato XLS. Di seguito il codice per 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

Potresti anche considerare di eseguire il programma (non python) xls2csv. Alimentalo con un file xls e dovresti recuperare un csv.


3
Ma il poster dice che deve leggere in Python ... Stai suggerendo di eseguire xls2csv, quindi analizzare il csvda Python?
hcarver

Python-excelerator contiene un wrapper py_xls2csv eseguibile attorno a un convertitore python.
fatal_error


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

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

Puoi trasformare CSV in Excel come sopra con pacchetti integrati. CSV può essere gestito con un pacchetto integrato di dictreader e dictwriter che funzionerà allo stesso modo del dizionario Python. il che lo rende molto facile, al momento non sono a conoscenza di alcun pacchetto integrato per Excel, ma mi sono imbattuto in openpyxl. Era anche abbastanza semplice e diretto Puoi vedere lo snippet di codice qui sotto sperando che questo aiuti

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

0

Per i .xlsfile più vecchi , puoi usarexlrd

o puoi usarlo xlrddirettamente importandolo. Come sotto

import xlrd
wb = xlrd.open_workbook(file_name)

Oppure puoi anche usare il pd.read_excel()metodo pandas , ma non dimenticare di specificare il motore, sebbene l'impostazione predefinita sia xlrd, deve essere specificato.

pd.read_excel(file_name, engine = xlrd)

Entrambi funzionano per .xlsformati di file precedenti . Infatti mi sono imbattuto in questo quando l'ho usato OpenPyXL, ho ricevuto l'errore di seguito

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.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.