2010-12-06 15 views
99

Leí el año pasado que xlrd se estaba actualizando para poder leer archivos xlsx (Excel 2007, 2010). ¿Hay alguna noticia sobre este desarrollo o el uso de otras utilidades de Python?Lectura de archivos xlsx con Python

+9

'xlrd' ahora es compatible con los archivos .xlsx directamente (consulte la respuesta de @ TankorSmash). Su función 'open_workbook' carga ya sea .xls o .xlsx (lo resolverá, no tienes que decir cuál es cuál). –

+1

Voté para cerrar esta pregunta como fuera de tema porque el tiempo lo ha reemplazado. Se discute [aquí] (http://meta.stackoverflow.com/questions/284974/is-this-on-topic-if-not-on-what-grounds) donde "de una época de estándares diferentes" (@ bmargulies) fue mencionado y ahora está obsoleto. – pnuts

+3

¿Alguien ha realizado un análisis sobre la correlación entre los votos al alza y los temas cerrados como "fuera del tema"? – duhaime

Respuesta

3

Apoyo para la lectura de los datos básicos (open_workbook (..., formatting_info = false)) de Excel 2007 .xlsx y .xlsm está en prueba alpha en el momento. Ver publicaciones previas en este grupo (buscar para "excel 2007 xlsx").

Desde el foro Regarding xlrd support for excel

3

archivos XLSX lectura es bastante simple, en realidad.

Son archivos ZIP con ciertos documentos XML con nombres fijos.

Puede - sin demasiados códigos - abrir el archivo ZIP, analizar los documentos XML relevantes y procesar los datos relevantes.

Éstos son algunos consejos: http://slott-softwarearchitect.blogspot.com/2010/10/xlsm-and-xlsx-files-finally-reaching.html

+5

los formatos antiguos ya no están sin documentar. Las nuevas fmts no están completamente documentadas, ej. la identificación de la celda ("Z99") y la identificación de la fila ("99") se consideran opcionales en el "estándar" --- la ingeniería inversa todavía requiere verificar qué Excel realmente acepta. Engañosamente simple; no debe haber tenido ninguna fecha o fecha en sus archivos xlsx :-) –

71

Eric Gazoni ha escrito openpyxl que se lee/escribe xlsx archivos Más detalles disponibles de his blog y la code repository para cualquier codificadores Python querer probarlo

+4

Y Heikki Junes hizo un puerto de Python 3, disponible en https://bitbucket.org/hjunes/openpyxl. –

+2

'openpyxl' es realmente lento. Ejecuté algunos puntos de referencia y descubrí que 'openpyxl' tarda más del doble que' xlrd' para leer un archivo de Excel. – Zenadix

+0

Estoy de acuerdo con @Zenadix, hice pruebas similares y xlrd es mucho más rápido. –

64

Un poco tarde para la fiesta, pero xlrd ahora admite de forma nativa xlsx. He actualizado 0.6.0-0.8.0 usando pip install xlrd --upgrade en el símbolo del sistema (WindowsKey + R continuación cmd) y ahora se lee xlsx sin ningún problema.

http://pypi.python.org/pypi/xlrd

+5

o easy_install -U xlrd – khan

+0

Por lo que el léame sugiere, es solo para lectura, no para escritura. – chhantyal

+0

Cita del responsable el 9/9/2016: _ "Los paquetes en cuestión son xlrd, xlwt y xlutils. Seré sincero y le diré que ya no debe usarlos a menos que tenga una necesidad particular de trabajar con archivos .xls . Si solo trabaja con archivos .xlsx, y ese es el único formato de Excel que debería buscar para crear hoy en día, entonces debería usar openpyxl en su lugar. "_ Https://groups.google.com/forum/#!msg/python -excel/P6TjJgFVjMI/g8d0eWxTBQAJ – phyatt

13
import openpyxl as px 
import numpy as np 

W = px.load_workbook('filename.xlsx', use_iterators = True) 
p = W.get_sheet_by_name(name = 'Sheet1') 

a=[] 

for row in p.iter_rows(): 
    for k in row: 
     a.append(k.internal_value) 

# convert list a to matrix (for example 5*6) 
aa= np.resize(a, [5, 6]) 

# save matrix aa as xlsx file 
WW=px.Workbook() 
pp=WW.get_active_sheet() 
pp.title='NEW_DATA' 

f={'A':0,'B':1,'C':2,'D':3,'E':4,'F':5} 

#insert values in six columns 
for (i,j) in f.items(): 
    for k in np.arange(1,len(aa)+1): 
     pp.cell('%s%d'%(i,k)).value=aa[k-1][j] 

WW.save('newfilname.xlsx') 
+1

Este ejemplo estuvo cerca, pero no funcionó para mí. Esto hizo - http://openpyxl.readthedocs.org/en/latest/optimized.html?highlight=load_workbook#optimized-reader –

18

Aquí es una implementación muy muy áspera usando sólo 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'): # <v>84</v> 
      value = el.text 
     if el.tag.endswith('}c'): # <c r="A3" t="s"><v>84</v></c> 
      if el.attrib.get('t') == 's': 
       value = strings[int(value)] 
      letter = el.attrib['r'] # AZ22 
      while letter[-1].isdigit(): 
       letter = letter[:-1] 
      row[letter] = value 
      value = '' 
     if el.tag.endswith('}row'): 
      rows.append(row) 
      row = {} 
    return rows 
+2

¡Esto funciona genial! Crea una fila que tiene {'A', 'value of column', 'B', 'value of column'} etc ... Me gustaría más adelante acceder al valor de la columna por el nombre de la columna en lugar de es carta Tiene alguna idea sobre esto? entonces en lugar de 'para la fila en filas: name = row ['A'] ...' sería 'para row in rows: name = row ['name']'. Espero que tenga sentido. – teewuane

+1

Lo hago agarrando los encabezados de columna de la primera fila y almacenándolos como un hash de nombre a índice. 'def read_header (fila): encabezamientos = {} para i en el rango (0, len (fila)): partidas [fila [i] .value] = i regrese partidas row_to_hash def (fila, cabecera) : NewRow = {} de clave en header.keys(): newRow [clave] = fila [encabezado [clave]] valor de retorno NewRow ' – MattK

+2

bien, he sido derrotado en mi lucha para poner un. bloque de código en los comentarios. – MattK

1

Sí gracias por el gran subrutina!

Lo he actualizado para permitir que el hash de filas use los nombres de las columnas como índice en lugar de letras, si se especifica una fila de encabezado.

readXlsx("mysheet.xlsx", sheet = 1, header = True) 

def readXlsx(fileName, **args): 

    import zipfile 
    from xml.etree.ElementTree import iterparse 

    if "sheet" in args: 
     sheet=args["sheet"] 
    else: 
     sheet=1 
    if "header" in args: 
     isHeader=args["header"] 
    else: 
     isHeader=False 

    rows = [] 
    row = {} 
    header = {} 
    z  = zipfile.ZipFile(fileName) 

    # Get shared strings 
    strings = [ el.text for e, el 
         in iterparse(z.open('xl/sharedStrings.xml')) 
         if el.tag.endswith('}t') 
         ] 
    value = '' 

    # Open specified worksheet 
    for e, el in iterparse(z.open('xl/worksheets/sheet%d.xml'%(sheet))): 
     # get value or index to shared strings 
     if el.tag.endswith('}v'):         # <v>84</v> 
      value = el.text 
     if el.tag.endswith('}c'):         # <c r="A3" t="s"><v>84</v></c> 

      # If value is a shared string, use value as an index 
      if el.attrib.get('t') == 's': 
       value = strings[int(value)] 

      # split the row/col information so that the row leter(s) can be separate 
      letter = el.attrib['r']         # AZ22 
      while letter[-1].isdigit(): 
       letter = letter[:-1] 

      # if it is the first row, then create a header hash for the names 
      # that COULD be used 
      if rows ==[]: 
       header[letter]=value 
      else: 
       if value != '': 

        # if there is a header row, use the first row's names as the row hash index 
        if isHeader == True and letter in header: 
         row[header[letter]] = value 
        else: 
         row[letter] = value 

      value = '' 
     if el.tag.endswith('}row'): 
      rows.append(row) 
      row = {} 
    z.close() 
    return rows