¿Pueden Pandas leer y modificar una sola hoja de trabajo de Excel (pestaña) sin modificar el rest del archivo?

Muchas hojas de cálculo tienen fórmulas y formatos que las herramientas de Python para leer y escribir archivos de Excel no pueden reproducir fielmente. Eso significa que cualquier archivo que quiera crear programáticamente debe ser algo que básicamente creo desde cero, y luego otros archivos de Excel (con la sofisticación mencionada anteriormente) deben referirse a ese archivo (lo que crea una variedad de otros problemas de dependencia).

Mi comprensión de las “tabs” de los archivos de Excel es que en realidad son solo una colección de archivos XML. Bueno, ¿es posible usar pandas (o uno de los motores de lectura / escritura subyacentes, como xlsxwriter o openpyxl, para modificar solo una de las tabs, dejando intactas otras tabs (con más cosas perversas)?

EDITAR: Voy a tratar de articular más el problema con un ejemplo.

  • Hoja de Excel test.xlsx tiene cuatro tabs (también conocidas como hojas de trabajo): Hoja1, Hoja2, Hoja3, Hoja4
  • Leí Sheet3 en un DataFrame (llamémoslo df) usando pandas.read_excel ()
  • Sheet1 y Sheet2 contienen fórmulas, gráficos y varios formatos que ni openpyxl ni xlrd pueden analizar correctamente, y Sheet4 contiene otros datos. No quiero tocar esas tabs en absoluto.
  • Sheet2 en realidad tiene algunas referencias a celdas en Sheet3
  • Hago algunas ediciones a df y ahora quiero escribirlas de nuevo en la hoja 3, dejando intactas las otras hojas (y las referencias de otras hojas de trabajo en el libro intactas)

¿Puedo hacer eso y, si es así, cómo?

Tuve una pregunta similar con respecto a la interacción entre excel y python (en particular, pandas), y me remitieron a esta pregunta.

Gracias a algunos punteros de la comunidad stackoverflow, encontré un paquete llamado xlwings que parece cubrir muchas de las funcionalidades requeridas por HaPsantran.

Para usar el ejemplo de OP:

Trabajando con un archivo de Excel existente, puede soltar un ancla en el bloque de datos (Hoja3) que desea importar a pandas al nombrarlo en Excel y haga lo siguiente:

# opened an existing excel file 

wb = Workbook(Existing_file)

 # Find in the excel file a named cell and reach the boundary of the cell block (boundary defined by empty column / row) and read the cell 

df = Range(Anchor).table.value

 # import pandas and manipulate the data block df = pd.DataFrame(df) # into Pandas DataFrame df['sum'] = df.sum(axis= 1) # write back to Sheet3 Range(Anchor).value = df.values 

probado que esta implementación no atemperó la fórmula existente en el archivo excel

Déjame saber si esto resuelve tu problema y si hay algo en lo que pueda ayudarte.

Grandes felicitaciones al desarrollador de xlwings, lo hicieron posible.


A continuación, se incluye una actualización de mi respuesta anterior luego de otra pregunta de @jamzsabb, y para reflejar una API modificada después de que xlwings se actualice a> = 0.9.0.

 import xlwings as xw import pandas as pd target_df = xw.Range('A7').options(pd.DataFrame, expand='table').value # only do this if the 'A7' cell (the cell within area of interest) is in active worksheet #otherwise do: #sht = xw.Book(r'path to your xlxs file\name_of_file.xlsx`).sheets['name of sheet'] #target_df = sht.Range('A7').options(pd.DataFrame, expand='table').value # you can also change 'A7' to any name that you've given to a cell like 'interest_table` 

Tengo un 90% de confianza en que la respuesta a “los pandas pueden hacer esto” es no. Publicar un negativo es difícil, porque siempre podría haber algo inteligente que no haya visto, pero aquí hay un caso:

Los posibles motores de interfaz son xlrd/xlwt/xlutils , openpyxl y xlsxwriter . Ninguno funcionará para sus propósitos, ya que xlrd/wt no es compatible con todas las fórmulas, xlsxwriter no puede modificar los archivos xlsx existentes y openpyxl pierde imágenes y gráficos.

Como a menudo necesito hacer esto, solo escribo resultados simples en un archivo separado y luego llamo a win32api directamente para copiar los datos entre los libros de trabajo y conservar todas las figuras shinys de mi colega. Es molesto, porque significa que tengo que hacerlo en Windows en lugar de * nix, pero funciona.

Si estás trabajando bajo Windows, podrías hacer algo similar. (Me pregunto si tiene sentido agregar una opción de inserción nativa utilizando este enfoque para ayudar a las personas en esta situación, o si simplemente deberíamos publicar una receta).


PD: Este mismo problema me ha molestado lo suficiente de vez en cuando que pensé en aprender lo suficiente del moderno formato de Excel para agregar soporte a una de las bibliotecas.

PPS: Pero como ignorar las cosas que no está manejando y devolverlas sin modificar parece bastante fácil, el hecho de que nadie parezca admitirlo me hace pensar que hay algunos dolores de cabeza, y donde Redmond está involucrado, estoy dispuesto a creerlo. @ John-Machin sabría los detalles, si él trata de …

Estoy agregando una respuesta que utiliza openpyxl. A partir de la versión 2.5, puede conservar los gráficos en los archivos existentes (más detalles sobre el problema están disponibles aquí ).

Para propósitos de demostración, creo un archivo xlsx usando pandas siguiendo las pautas de OPs. La pestaña llamada ‘Hoja2’ tiene fórmulas que hacen referencia a ‘Hoja3’ y contiene un gráfico.

 import pandas as pd df = pd.DataFrame({'col_a': [1,2,3], 'col_b': [4,5,6]}) writer = pd.ExcelWriter('test.xlsx', engine='xlsxwriter') df.to_excel(writer, sheet_name='Sheet1', index=False) workbook=writer.book worksheet = writer.sheets['Sheet1'] df.head(0).to_excel(writer, sheet_name='Sheet2', index=False) workbook=writer.book worksheet = writer.sheets['Sheet2'] for i in range(2, len(df) + 2): worksheet.write_formula('A%d' % (i), "=Sheet3!A%d" % (i)) worksheet.write_formula('B%d' % (i), "=Sheet3!B%d" % (i)) chart = workbook.add_chart({'type': 'column'}) chart.add_series({'values': '=Sheet2!$A$2:$A$4'}) chart.add_series({'values': '=Sheet2!$B$2:$B$4'}) worksheet.insert_chart('A7', chart) df.to_excel(writer, sheet_name='Sheet3', index=False) df.to_excel(writer, sheet_name='Sheet4', index=False) writer.save() 

Se esperaba test.xlsx después de ejecutar el código anterior:

test.xlsx después del primer bloque de código

Luego, si ejecutamos el código a continuación, utilizando openpyxl, podemos modificar los datos en ‘Hoja3’ al tiempo que conservamos las fórmulas y el gráfico en ‘Hoja2’ y los datos actualizados se encuentran ahora en este archivo.

 from openpyxl import load_workbook wb = load_workbook('test.xlsx') ws = wb['Sheet3'] ws['B2'] = 7 ws['B3'] = 8 ws['B4'] = 9 wb.save('test.xlsx') 

Se esperaba test.xlsx después de ejecutar el segundo bloque de código:

test.xlsx despues del segundo bloque de codigo

Si está hablando de ‘hojas’ como ‘tabs’, entonces es posible modificar solo una de las tabs accediendo a la particular usando la función de parse(sheet_name) .

Un ejemplo está aquí: Leyendo un archivo de Excel en python usando pandas

para escribir de nuevo a Excel, (mientras controla las hojas) use la función to_excel , aquí: http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.to_excel.html