Может ли Pandas прочитать и изменить один рабочий лист Excel (вкладка) без изменения остальной части файла?

Во многих таблицах есть формулы и форматирование, которые инструменты Python для чтения и записи файлов Excel не могут точно воспроизводить. Это означает, что любой файл, который я хочу создать программно, должен быть тем, что я в основном создаю с нуля, а затем другие файлы Excel (с вышеупомянутой сложностью) должны ссылаться на этот файл (что создает множество других проблем с зависимостями).

Мое понимание вкладок файла Excel состоит в том, что они на самом деле представляют собой только набор файлов XML. Ну, можно ли использовать pandas (или один из основных движков чтения/записи, таких как xlsxwriter или openpyxl, чтобы изменить только одну из вкладок, оставив другие вкладки (с более злыми вещами там)?

EDIT: я попытаюсь еще раз сформулировать проблему на примере.

  • Excel Sheet test.xlsx имеет четыре вкладки (aka worksheets): Sheet1, Sheet2, Sheet3, Sheet4
  • Я читаю Sheet3 в DataFrame (позвоню ему df), используя pandas.read_excel()
  • Sheet1 и Sheet2 содержат формулы, графики и различное форматирование, которые ни openpyxl, ни xlrd не могут успешно проанализировать, а Sheet4 содержит другие данные. Я вообще не хочу касаться этих вкладок.
  • Лист2 фактически имеет некоторые ссылки на ячейки на Sheet3
  • Я делаю некоторые изменения в df и теперь хочу записать его обратно на sheet3, оставив другие листы нетронутыми (и ссылки на него из других рабочих листов в книге нетронутыми)

Могу ли я это сделать, и если да, то как?

Ответ 1

У меня был похожий вопрос о взаимодействии между Excel и Python (в частности, панды), и я был передан на этот вопрос.

Благодаря некоторым указаниям сообщества stackoverflow, я нашел пакет под названием xlwings, который, кажется, покрывает многие функции, необходимые HaPsantran.

Чтобы использовать пример OP:

Работая с существующим файлом Excel, вы можете оставить привязку в блоке данных (Sheet3), который вы хотите импортировать в pandas, назвав его в excel и сделав следующее:

# 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

проверил, что эта реализация не умерила существующую формулу в файле Excel

Дайте мне знать, если это решит вашу проблему и смогу ли я чем-нибудь помочь.

Большое спасибо разработчику xlwings, они сделали это возможным.


Ниже приведено обновление к моему предыдущему ответу после дальнейшего вопроса от @jamzsabb, и оно отражает измененный API после обновления xlwings до> = 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'

Ответ 2

Я на 90% уверен, что ответ "can pandas сделать это" - нет. Проводка негатива жесткая, потому что всегда может быть что-то умное, что я пропустил, но вот случай:

Возможные интерфейсные двигатели: xlrd/xlwt/xlutils, openpyxl и xlsxwriter. Никто не будет работать для ваших целей, так как xlrd/wt не поддерживает все формулы, xlsxwriter не может изменять существующие файлы xlsx, а openpyxl теряет изображения и диаграммы.

Так как мне часто нужно это делать, я только записывал простой вывод в отдельный файл, а затем вызывал win32api напрямую, чтобы копировать данные между книгами, сохраняя при этом всех моих сверстников. Это раздражает, потому что это означает, что я должен сделать это под Windows вместо * nix, но он работает.

Если вы работаете под Windows, вы можете сделать что-то подобное. (Интересно, имеет ли смысл добавить собственный вариант вставки, используя этот подход, чтобы помочь людям в этой ситуации, или если мы просто опубликуем рецепт.)


P.S.: Эта проблема раздражает меня достаточно время от времени, что я думал о достаточном изучении современного формата Excel, чтобы добавить поддержку для этой библиотеки в одну из библиотек.

PPS: Но поскольку игнорирование вещей, которые вы не обрабатываете, и их возвращение немодифицировано, кажется достаточно простым, тот факт, что никто, кажется, не поддерживает его, заставляет меня думать, что есть некоторые головные боли, и где Редмонд участвует, я готов поверить в это, @john-machin узнает подробности, если он о..

Ответ 3

Я добавляю ответ, который использует openpyxl. Начиная с версии 2.5, вы можете сохранять графики в существующих файлах (более подробную информацию о проблеме можно найти здесь).

В демонстрационных целях я создаю файл xlsx, используя pandas, следуя указаниям OP. Вкладка с именем "Лист2" содержит формулы, ссылающиеся на "Лист3", и содержит диаграмму.

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()

Ожидается test.xlsx после запуска приведенного выше кода:

test.xlsx after first block of code

Затем, если мы запустим приведенный ниже код, используя openpyxl, мы сможем изменить данные в "Sheet3", сохранив формулы и диаграммы в "Sheet2", и обновленные данные теперь находятся в этом файле.

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')

Ожидается test.xlsx после запуска второго блока кода:

test.xlsx after second block of code

Ответ 4

Насколько я знаю, Панды не делают этого сами по себе.

Я написал небольшую служебную библиотеку pandasxltable (на основе openpyxl), чтобы облегчить взаимодействие между шаблоном Excel и фреймами данных pandas. Библиотека позволяет извлекать данные в виде фрейма данных и обновлять таблицы данных Excel (на самом деле это не вкладка, а часть) из фрейма данных.

Ответ 5

если вы говорите о "листах" как "вкладках", тогда можно изменить только одну из вкладок, обратившись к конкретному, используя функцию parse(sheet_name).

приведен пример: Чтение файла Excel в python с помощью pandas

чтобы написать обратно в excel (при управлении листами) используйте функцию to_excel, здесь: http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.to_excel.html