En este apunte vamos a estar revisando cómo usar Excel (y LibreOffice Calc) con Python.
Vamos a utilizar algunas librerías y herramientas extras que pertenecen a Python para conseguir nuestro objetivo. En cada caso voy a mencionar en que forma encontrarlas. Algunas de estas herramientas: Openpyxl y Pandas.
Y así sin más…
Convertir archivos .xls en .xlsx con Python
Una planilla de Excel puede estar guardada en diferentes formatos. Y no todas las herramientas son capaces de abrir los mismos formatos.
Por lo pronto, al menos al momento de escribir esto, la librería Openpyxl puede leer las planillas guardadas como: xlsx / xlsm / xltx / xltm
En una oportunidad me encontré que necesitaba abrir un archivo de una planilla de cálculo guardada con el formato “.xls”. Para poder abrirla agregué este código a mi script de Python:
import pandas as pd # convierte un archivo en formato xls en otro formato xlsx def convertir(): df = pd.read_excel('lista.xls') df.to_excel('nueva_lista.xlsx', index=False) convertir()
Lo primero que hago es asegurarme de tener la librería Pandas en mi equipo.
Pandas, según su sitio web, se utiliza como herramienta de código abierto para el análisis y la manipulación de datos. Estos son algunos recursos para instalar Pandas:
– Instalación básica de Pandas
– Instalación de Pandas versión avanzada
Luego, en la primera linea del código propiamente dicho tengo:
import pandas as pd
Según entiendo, con esto traigo el módulo para poder usarlo dentro del código. Y al traerlo bajo el nombre “pd” puedo invocarlo rápidamente de manera directa con esas siglas.
Lo siguiente es crear un función, para usarla luego. Le puse de nombre a esa función “convertir” y en su interior tengo:
modificar = pd.read_excel('lista.xls')
La primera variable, llamada “modificar”, le pide al programa que lea el archivo Excel “lista.xls”. Este código trabaja en el mismo directorio en el que se encuentra instalado, por lo que esta planilla se encuentra en esa misma carpeta.
La segunda linea de la función dice:
modificar.to_excel('lista_nueva.xlsx', index=False, header=False)
Y lo que hace es que el programa revise la variable anterior, y la utilice para crear un nuevo archivo. Este nuevo archivo ya tiene la extensión “.xlsx” y se llama “lista_nueva”.
El nuevo archivo se va a generar también en el mismo directorio que el anterior documento “xls”. Los dos archivos van a existir a la vez, no voy a borrar nada.
Y eso es todo, ahora cuando llamo a la función:
convertir()
El programa crea un nuevo documento con el nombre y la extensión pedida, con eso conseguimos pasar nuestro archivo de “xls” a “xlsx”.
Buscar y copiar datos en Excel con Python
Para entender esto primero revisemos un programa que va a permitirnos:
– Buscar un dato en una planilla.
– Copiar toda la fila junto a la celda que contiene ese dato,
– Pegar la fila en un documento de Excel diferente.
Vamos a necesitar tener el módulo Openpyxl.
Y el código del programa es el siguiente:
import openpyxl #Directorios busqueda wb = openpyxl.load_workbook(r'/ruta_al_directorio/inventario.xlsx') # planillas activa ws = wb.active #Directorio y planilla de guardado wb2 = openpyxl.load_workbook(r'/ruta_al_directorio/guardados.xlsx') ws2 = wb2.active #listas a buscar inventariolista = [300980] def buscar_inventario(): for row in ws.iter_rows(): for cell in row: encontrado = [cell.value for cell in row] if cell.value in inventariolista: print(encontrado) ws2.append(encontrado) print("Articulo encontrado") buscar_inventario() wb2.save("guardados.xlsx") print("Archivo guardado.")
Esta primera parte, por decirlo de algún modo, sienta las bases de qué voy a buscar y donde voy a hacerlo.
Primero hago:
import openpyxl
Y con eso llamo a la librería openpyxl para poder utilizarla.
Luego describo el lugar donde se encuentra la planilla dentro de la que voy a buscar:
wb = openpyxl.load_workbook(r'/ruta_al_directorio/inventario.xlsx') ws = wb.active
Al parecer, un documento de Excel tiene dos componentes básicos. La guía de openpyxl utiliza la sigla “wb” para indicar un “workbook”.
Un workbook o libro de trabajo señala al documento de Excel en si mismo, en este caso llamado “inventario.xlsx”.
Por otra parte “ws” indica la “worksheet” o una hoja (planilla) dentro del documento principal. Un mismo documento puede estar compuesto por múltiples hojas, en principio llamadas por ejemplo “sheet1”, “sheet2”, “hoja1” o similar.
Podría especificar una hoja especifica dentro de mi archivo, pero al decir:
ws = wb.active
Quiero señalar que la hoja en la que estoy trabajando es la primera (o más bien, la única) dentro de mi workbook. Es la planilla activa del documento.
Lo siguiente en mi código es:
wb2 = openpyxl.load_workbook(r'/ruta_al_directorio/guardados.xlsx')
ws2 = wb2.active
Lo que estoy haciendo ahora es exactamente lo mismo que lo anterior. Agrego un nuevo documento ( guardados.xlsx) y señalo cual es la hoja de ese documento en la que voy a trabajar.
La principal diferencia es que mi intención no es la de buscar dentro de este archivo, quiero usarlo más tarde para poder guardar la nueva información encontrada.
Por último voy a crear una lista, en la cual incluyo lo que estoy buscando dentro de la planilla de Excel. Lo hago con:
inventariolista = [300980]
Mi intención es la de copiar toda la linea que contenga al producto señalado con el número: “300980”.
Lo que hago ahora es crear una función llamada “buscar inventario”:
def buscar_inventario(): for row in ws.iter_rows(): for cell in row: encontrado = [cell.value for cell in row] if cell.value in inventariolista: print(encontrado) ws2.append(encontrado) print("Articulo encontrado")
Al establecer:
for row in ws.iter_rows():
Quiero decir “por cada linea al revisar todas las lineas en la hoja ws”.
Y luego:
for cell in row:
Lo que quiere decir: “por cada celda en cada una de esas lineas”.
Esto es, mi programa va a revisar todas las lineas de la planilla, deteniéndose en cada una de las celdas.
encontrado = [cell.value for cell in row]
Este fragmento crea una nueva lista, llamada “encontrado”, que es parte de esta función. Esta lista se va a ir llenando con los elementos revisados en las celdas que coincidan con los propuestos en inventario lista”.
Lo que sigue explica mejor esto:
if cell.value in inventariolista: print(encontrado) ws2.append(encontrado) print("Articulo encontrado")
Si el valor de una celda coincide con alguno de los elementos de “inventario lista” (en este caso, el único valor buscado es: 300980) lo que va a ocurrir es que ese item va a ser agregado a la nueva lista “encontrado”.
Al escribir:
print(encontrado)
La terminal me devuelve que elementos se agregaron a esa lista hasta el momento.
Luego sucede que:
ws2.append(encontrado)
El programa actualiza la hoja del archivo de Excel correspondiente a “ws2”. En mi caso, esta es la hoja activa de la planilla donde estoy guardando la nueva información.
Y con:
print("Articulo encontrado")
La terminal me avisa si finalmente el programa encontró alguna coincidencia.
Ya casi llego al final de este breve programa. Lo que me queda es llamar a la función “buscar inventario” para ejecutarla:
buscar_inventario()
Y luego con:
wb2.save("guardados.xlsx")
Guardo los cambios, las celdas que se agregaron, en el archivo que hice para tal efecto. Sin este último paso cualquier modificación va a perderse al finalizar el programa.
Otra cosa importante es que cada nueva linea que se incluya va a escribirse al final el documento. Esto quiere decir que puedo correr el programa varias veces, y la información que se incluyó en el mismo cada vez no tendría porque borrarse.
Para terminar hago:
print("Archivo guardado.")
Esto como un simple recordatorio en la terminal, que me dice que el programa pudo completarse con éxito.
Lo que obtengo es una nueva planilla, que guarda el dato que encontré con el programa.
Agregar y usar una fórmula en Excel
Con este código buscamos multiplicar todos los valores de una columna por la cifra de una celda, con el objetivo de calcular el precio de unos productos.
import openpyxl #Directorio del archivo y planilla activa wb = openpyxl.load_workbook(r'/camino/al/direcorio/items.xlsx') ws = wb.active # Agregar una fila por debajo de la primera ws.insert_rows(2, amount=1) # Agergar nuevos valores a las celdas ws['C1'] = 'Impuesto:' ws['D1'] = '1.21' # Revisar todas las celdas de las columnas B hasta el final for row in range(3, ws.max_row + 1): # Agregar formula en columna C Para multiplicar columna B por el valor en D1 ws.cell(row=row, column=3).value = f'=B{row}*$D$1' # guardar todo esto en un nuevo archivo wb.save('nuevo_items.xlsx')
Bueno, en la primera parte no hay nada muy diferente a lo que venía haciendo:
import openpyxl #Directorio del archivo y planilla activa wb = openpyxl.load_workbook(r'/camino/al/direcorio/items.xlsx') ws = wb.active # Agregar una fila por debajo de la primera ws.insert_rows(2, amount=1) # Agergar nuevos valores a las celdas ws['C1'] = 'Impuesto:' ws['D1'] = '1.21'
Básicamente abro el archivo y la planilla. Luego creo una nueva fila debajo de la primera, para que la tabla pueda entenderse un poco mejor. Y por último agrego las nuevas celdas, especialmente importante la D1 donde agrego el valor de “1.21”.
Lo más importante para esta ocasión creo que es lo siguiente:
# Revisar todas las celdas de las columnas B hasta el final for row in range(3, ws.max_row + 1): # Agregar formula en columna C Para multiplicar columna B por el valor en D1 ws.cell(row=row, column=3).value = f'=B{row}*$D$1'
Esto va a revisar todas las filas desde la tercera hasta la última. Recordemos que el primer dato a evaluar empieza en la tercera fila, porque agregué una extra.
Y lo que sigue es agregar en la columna C la siguiente fórmula “B{row}*$D$1”.
Lo que resulta es multiplicar cada fila de B por el valor de D1. Lo bueno es que si luego reemplazamos el valor de D1 por otro en la planilla de Excel, el resultado de la fórmula se actualiza sola.
Para finalizar se guarda todo en un nuevo archivo diferente, con el objetivo de no alterar el original.
Conclusión
Con esto le doy cierre al texto sobre cómo usar Excel (y LibreOffice Calc) con Python.
Cada vez que escriba algo de este tema voy a actualizar esta entrada, para poder compilar la información en un solo lugar. Espero que te resulte de utilidad.
La seguimos en el próximo apunte.