tutorial read for espaƱol python excel xlsx openpyxl

python - read - openpyxl xls



iterando sobre un rango de filas usando ws.iter_rows en el lector optimizado de openpyxl (2)

De la documentación :

Nota: Cuando se crea una hoja de cálculo en la memoria, no contiene celdas. Se crean cuando se accede por primera vez. De esta forma, no creamos objetos a los que nunca se accedería, reduciendo así la huella de memoria.

Advertencia: Debido a esta característica, al desplazarse por las celdas en lugar de acceder directamente a ellas, las creará todas en la memoria, incluso si no les asigna un valor. Algo como

>>> for i in xrange(0,100): ... for j in xrange(0,100): ... ws.cell(row = i, column = j)

creará 100x100 celdas en la memoria, para nada.

Sin embargo, hay una forma de limpiar todas esas celdas no deseadas, lo veremos luego.

Creo que acceder a las propiedades de columnas o filas hará que muchas celdas tengan que cargarse en la memoria. Sugeriría solo tratar de acceder directamente a las celdas que necesita.

p.ej.

col_name = ''A'' start_row = 1 end_row = 99 range_expr = "{col}{start_row}:{col}{end_row}".format( col=col_name, start_row=start_row, end_row=end_row) for (time_cell,) in ws.iter_rows(range_string=range_expr): print time_cell.value.hour

Necesito leer un archivo xlsx de 10x5324 celdas

Esta es la esencia de lo que estaba tratando de hacer:

from openpyxl import load_workbook filename = ''file_path'' wb = load_workbook(filename) ws = wb.get_sheet_by_name(''LOG'') col = {''Time'':0 ...} for i in ws.columns[col[''Time'']][1:]: print i.value.hour

El código tardaba tanto en ejecutarse que debería (estaba realizando operaciones, no imprimiendo) y después de un tiempo me impacienté y lo cancelé.

¿Alguna idea de cómo puedo trabajar en el lector optimizado? Necesito iterar sobre un rango de filas, no sobre todas las filas. Esto es lo que intenté, pero está mal:

wb = load_workbook(filename, use_iterators = True) ws = wb.get_sheet_by_name(''LOG'') for i in ws.iter_rows[1:]: print i[col[''Time'']].value.hour

¿Hay alguna manera de que pueda hacerlo sin la función de rango?

Creo que una forma de hacerlo sería:

for i in ws.iter_rows[1:]: if i.row == startrow: continue print i[col[''Time'']].value.hour if i.row == endrow: break

pero hay una solución más elegante? (Eso tampoco funciona por cierto)


La solución más simple con un límite inferior sería algo como esto:

# Your code: from openpyxl import load_workbook filename = ''file_path'' wb = load_workbook(filename, use_iterators=True) ws = wb.get_sheet_by_name(''LOG'') # Solution 1: for row in ws.iter_rows(row_offset=1): # code to execute per row...

Aquí otra forma de ejecutar lo que describes, con la función de enumerate :

# Solution 2: start, stop = 1, 100 # This will allow you to set a lower and upper limit for index, row in enumerate(ws.iter_rows()): if start < index < stop: # code to execute per row...

La variable de índice mantiene el recuento de la fila en la que se encuentra, por lo que se puede usar en lugar de range o xrange. Este método es bastante sencillo y funciona con iteradores a diferencia del rango o el corte, y también se puede usar con el límite inferior, si se desea. ¡Aclamaciones!