Czytanie / analizowanie plików Excel (xls) w Pythonie


Odpowiedzi:


92

Bardzo polecam xlrd do czytania .xlsplików.

voyager wspomniał o zastosowaniu automatyzacji COM. Zrobiłem to kilka lat temu, ostrzegam, że robienie tego to prawdziwa PITA. Liczba zastrzeżeń jest ogromna, a dokumentacji brakuje i irytuje. Napotkałem wiele dziwnych błędów i pułapek, z których niektóre zajmowały wiele godzin.

AKTUALIZACJA: W przypadku nowszych .xlsxplików zalecaną biblioteką do czytania i pisania wydaje się być openpyxl (dzięki, Ikar Pohorský).


5
W przypadku plików Excel 2007+ ( .xlsx) prawdopodobnie używałbyś OpenPyXL .
Ikar Pohorský

48

Korzystanie z pand:

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
pandy używają xlrd do czytania; będziesz musiał również zainstalować xlrd jako zależność
congusbongus

25

Możesz wybrać jedną z nich http://www.python-excel.org/
Poleciłbym bibliotekę python xlrd.

zainstaluj go za pomocą

pip install xlrd

import za pomocą

import xlrd

aby otworzyć skoroszyt

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

otwórz arkusz według nazwy

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

otwórz arkusz według indeksu

worksheet = workbook.sheet_by_index(0)

odczytaj wartość komórki

worksheet.cell(0, 0).value    

„Odczyt wartości komórki” nie działa ... generuje błąd TypeError: obiekt „Arkusz” nie jest wywoływalny. Cała reszta działała świetnie.
Newbielp

13

Myślę, że Pandy to najlepsza droga. Jest już tutaj jedna odpowiedź z Pandami używającymi ExcelFilefunkcji, ale nie działała ona poprawnie dla mnie. Od tutaj znalazłem read_excelfunkcję, która działa dobrze:

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

PS Musisz mieć xlrdzainstalowany, aby read_excelfunkcja działała

Aktualizacja 21-03-2020: Jak widać tutaj , są problemy z xlrdsilnikiem i zostanie on wycofany. To openpyxlnajlepszy zamiennik. Tak więc, jak opisano tutaj , składnia kanoniczna powinna wyglądać następująco:

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

AttributeError: obiekt 'dict' nie ma atrybutu 'head'
lopezdp

4

W przypadku xlsx podoba mi się rozwiązanie opublikowane wcześniej jako https://web.archive.org/web/20180216070531//programming/4371163/reading-xlsx-files-using-python . Używam tylko modułów z biblioteki standardowej.

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

Dodane ulepszenia polegają na pobieraniu treści według nazwy arkusza, przy użyciu polecenia re do pobrania kolumny i sprawdzaniu, czy używane są wspólne ciągi znaków.

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

Dzięki za przywrócenie mojej odpowiedzi!
Collin Anderson

2

Możesz użyć dowolnej z wymienionych tutaj bibliotek (takich jak Pyxlreader, który jest oparty na JExcelApi lub xlwt ), a także automatyzacji COM, aby używać samego Excela do odczytu plików, ale w tym celu wprowadzasz Office jako zależność swojego oprogramowania, co nie zawsze jest opcją.


6
(1) pyxlreader to absolutna ospa. Nigdy tego nie próbowałeś. Zobacz moje komentarze tutaj: stackoverflow.com/questions/1243545/… (2) xlwtpliki WriTes; używać xlrddo plików ReaD.
John Machin

2

Jeśli potrzebujesz starego formatu XLS. Poniżej kod dla 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

Możesz również rozważyć uruchomienie (innego niż Python) programu xls2csv. Podaj plik xls i powinieneś odzyskać plik csv.


3
Ale plakat mówi, że musi czytać w Pythonie ... Sugerujesz uruchomienie xls2csv, a następnie przeanalizowanie csvz Pythona?
hcarver

Python-excelerator zawiera wykonywalne opakowanie py_xls2csv wokół konwertera języka Python.
fatal_error


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

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

Możesz zmienić CSV, aby wyróżniać się jak powyżej, dzięki wbudowanym pakietom. CSV można obsłużyć za pomocą wbudowanego pakietu dictreader i dictwriter, który będzie działał w taki sam sposób, jak działa słownik Pythona. co sprawia, że ​​jest to bardzo łatwe Obecnie nie znam żadnych wbudowanych pakietów dla programu Excel, ale natknąłem się na openpyxl. Było to również całkiem proste i proste. Możesz zobaczyć fragment kodu poniżej, mając nadzieję, że to pomoże

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

0

W przypadku starszych .xlsplików możesz użyćxlrd

możesz użyć xlrdbezpośrednio, importując go. Jak poniżej

import xlrd
wb = xlrd.open_workbook(file_name)

Możesz też użyć pd.read_excel()metody pandy , ale nie zapomnij określić silnika, chociaż domyślnie jest xlrdto ustawienie , należy go określić.

pd.read_excel(file_name, engine = xlrd)

Oba działają ze starszymi .xlsformatami plików. W rzeczywistości natknąłem się na to, kiedy korzystałem OpenPyXL, otrzymałem poniższy błąd

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.
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.