Leer / analizar archivos de Excel (xls) con Python

Respuestas:

92

Recomiendo encarecidamente xlrd para leer .xlsarchivos.

voyager mencionó el uso de la automatización COM. Habiendo hecho esto yo mismo hace unos años, tenga en cuenta que hacer esto es un verdadero PITA. La cantidad de advertencias es enorme y la documentación es deficiente y molesta. Me encontré con muchos errores extraños y errores, algunos de los cuales me llevó muchas horas resolver.

ACTUALIZACIÓN: Para .xlsxarchivos más nuevos , la biblioteca recomendada para lectura y escritura parece ser openpyxl (gracias, Ikar Pohorský).

taleinat
fuente
5
Para archivos de Excel 2007+ ( .xlsx) probablemente usaría OpenPyXL .
Ikar Pohorský
48

Usando 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...
borgomeister
fuente
1
pandas está usando xlrd para hacer la lectura; también deberá instalar xlrd como una dependencia
congusbongus
25

Puede elegir cualquiera de ellos http://www.python-excel.org/
Recomendaría la biblioteca python xlrd.

instalarlo usando

pip install xlrd

importar usando

import xlrd

abrir un libro de trabajo

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

hoja abierta por nombre

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

hoja abierta por índice

worksheet = workbook.sheet_by_index(0)

leer valor de celda

worksheet.cell(0, 0).value    
Somil
fuente
El "valor de celda de lectura" no funciona ... genera un TypeError: el objeto 'Hoja' no es invocable. Todo el resto funcionó muy bien.
Newbielp
13

Creo que Pandas es la mejor manera de hacerlo. Ya hay una respuesta aquí con Pandas usando la ExcelFilefunción, pero no funcionó correctamente para mí. Desde aquí encontré la read_excelfunción que funciona bien:

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

PD : Necesitas tener la función xlrdinstalada para que read_excelfuncione

Actualización 21-03-2020: como puede ver aquí , hay problemas con el xlrdmotor y va a quedar obsoleto. El openpyxles el mejor reemplazo. Entonces, como se describe aquí , la sintaxis canónica debe ser:

dfs = pd.read_excel("your_file_name.xlsx", sheet_name="your_sheet_name", engine="openpyxl")
Foad
fuente
AttributeError: el objeto 'dict' no tiene el atributo 'head'
lopezdp
4

Para xlsx, me gusta la solución publicada anteriormente como https://web.archive.org/web/20180216070531//programming/4371163/reading-xlsx-files-using-python . Solo uso módulos de la biblioteca estándar.

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

Las mejoras agregadas son obtener contenido por nombre de hoja, usar re para obtener la columna y verificar si se usan cadenas compartidas.

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
Hans de Ridder
fuente
¡Gracias por revivir mi respuesta!
Collin Anderson
2

Puede usar cualquiera de las bibliotecas enumeradas aquí (como Pyxlreader que se basa en JExcelApi o xlwt ), además de la automatización COM para usar Excel en sí para la lectura de los archivos, pero para eso está presentando Office como una dependencia de su software, que puede no ser siempre una opción.

Esteban Küber
fuente
6
(1) pyxlreader es la viruela absoluta. No debes haberlo probado nunca. Vea mis comentarios aquí: stackoverflow.com/questions/1243545/… (2) xlwtarchivos WriTes; utilizar xlrdpara archivos ReaD.
John Machin
2

Si necesita el formato XLS antiguo. Debajo del código para 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))
Kairat Koibagarov
fuente
0

También puede considerar ejecutar el programa (que no sea de Python) xls2csv. Aliméntelo con un archivo xls, y debería recuperar un csv.

moi
fuente
3
Pero el cartel dice que necesita leer en Python ... ¿Está sugiriendo ejecutar xls2csvy luego analizar csvdesde Python?
hcarver
Python-excelerator contiene un contenedor py_xls2csv ejecutable alrededor de un convertidor de Python.
fatal_error
0

Para archivos de Excel más antiguos, existe el módulo OleFileIO_PL que puede leer el formato de almacenamiento estructurado OLE utilizado.

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

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

Puede convertir CSV para sobresalir como arriba con paquetes incorporados. CSV se puede manejar con un paquete incorporado de dictreader y dictwriter que funcionará de la misma manera que el diccionario de Python. lo que lo hace muy fácil. Actualmente no tengo conocimiento de ningún paquete incorporado para Excel, pero me encontré con openpyxl. También fue bastante directo y simple. Puede ver el fragmento de código a continuación, espero que esto ayude

    import openpyxl
    book = openpyxl.load_workbook(filename)
    sheet = book.active 
    result =sheet['AP2']
    print(result.value)
Akash g krishnan
fuente
0

Para .xlsarchivos más antiguos , puede usarxlrd

o puede utilizarlo xlrddirectamente importándolo. Como abajo

import xlrd
wb = xlrd.open_workbook(file_name)

O también puede usar el pd.read_excel()método pandas , pero no olvide especificar el motor, aunque el valor predeterminado es xlrd, debe especificarse.

pd.read_excel(file_name, engine = xlrd)

Ambos funcionan para .xlsformatos de archivo más antiguos . De hecho, me encontré con esto cuando lo usé OpenPyXL, obtuve el siguiente error

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.
Deepak Harish
fuente