Как записать в существующий файл excel без перезаписи данных (используя pandas)?
Я использую панд для записи в файл Excel следующим образом:
import pandas
writer = pandas.ExcelWriter('Masterfile.xlsx')
data_filtered.to_excel(writer, "Main", cols=['Diff1', 'Diff2'])
writer.save()
Masterfile.xlsx уже состоит из множества разных вкладок. Тем не менее, он еще не содержит "Main".
Pandas правильно пишет на "основной" лист, к сожалению, он также удаляет все остальные вкладки.
Ответы
Ответ 1
Pandas docs говорит, что использует openpyxl для xlsx файлов. Быстрый просмотр кода в ExcelWriter
дает представление о том, что что-то вроде этого может получиться:
import pandas
from openpyxl import load_workbook
book = load_workbook('Masterfile.xlsx')
writer = pandas.ExcelWriter('Masterfile.xlsx', engine='openpyxl')
writer.book = book
writer.sheets = dict((ws.title, ws) for ws in book.worksheets)
data_filtered.to_excel(writer, "Main", cols=['Diff1', 'Diff2'])
writer.save()
Ответ 2
Для меня skyjur ответ почти сработал. Я должен был явно настроить движок для автора:
writer = pd.ExcelWriter(excel_file, engine='openpyxl')
иначе он будет бросать
AttributeError: 'Workbook' object has no attribute 'add_worksheet'
Ответ 3
Вот вспомогательная функция:
def append_df_to_excel(filename, df, sheet_name='Sheet1', startrow=None,
truncate_sheet=False,
**to_excel_kwargs):
"""
Append a DataFrame [df] to existing Excel file [filename]
into [sheet_name] Sheet.
If [filename] doesn't exist, then this function will create it.
Parameters:
filename : File path or existing ExcelWriter
(Example: '/path/to/file.xlsx')
df : dataframe to save to workbook
sheet_name : Name of sheet which will contain DataFrame.
(default: 'Sheet1')
startrow : upper left cell row to dump data frame.
Per default (startrow=None) calculate the last row
in the existing DF and write to the next row...
truncate_sheet : truncate (remove and recreate) [sheet_name]
before writing DataFrame to Excel file
to_excel_kwargs : arguments which will be passed to 'DataFrame.to_excel()'
[can be dictionary]
Returns: None
"""
from openpyxl import load_workbook
import pandas as pd
# ignore [engine] parameter if it was passed
if 'engine' in to_excel_kwargs:
to_excel_kwargs.pop('engine')
writer = pd.ExcelWriter(filename, engine='openpyxl')
# Python 2.x: define [FileNotFoundError] exception if it doesn't exist
try:
FileNotFoundError
except NameError:
FileNotFoundError = IOError
try:
# try to open an existing workbook
writer.book = load_workbook(filename)
# get the last row in the existing Excel sheet
# if it was not specified explicitly
if startrow is None and sheet_name in writer.book.sheetnames:
startrow = writer.book[sheet_name].max_row
# truncate sheet
if truncate_sheet and sheet_name in writer.book.sheetnames:
# index of [sheet_name] sheet
idx = writer.book.sheetnames.index(sheet_name)
# remove [sheet_name]
writer.book.remove(writer.book.worksheets[idx])
# create an empty sheet [sheet_name] using old index
writer.book.create_sheet(sheet_name, idx)
# copy existing sheets
writer.sheets = {ws.title:ws for ws in writer.book.worksheets}
except FileNotFoundError:
# file does not exist yet, we will create it
pass
if startrow is None:
startrow = 0
# write out the new sheet
df.to_excel(writer, sheet_name, startrow=startrow, **to_excel_kwargs)
# save the workbook
writer.save()
ПРИМЕЧАНИЕ: для панд <0.21.0 замените sheet_name
sheetname
sheet_name
sheetname
!
Примеры использования:
append_df_to_excel('d:/temp/test.xlsx', df)
append_df_to_excel('d:/temp/test.xlsx', df, header=None, index=False)
append_df_to_excel('d:/temp/test.xlsx', df, sheet_name='Sheet2', index=False)
append_df_to_excel('d:/temp/test.xlsx', df, sheet_name='Sheet2', index=False, startrow=25)
Ответ 4
С openpyxl
версией 2.4.0
и pandas
версией 0.19.2
, процесс @ski приступил к получению немного проще:
import pandas
from openpyxl import load_workbook
with pandas.ExcelWriter('Masterfile.xlsx', engine='openpyxl') as writer:
writer.book = load_workbook('Masterfile.xlsx')
data_filtered.to_excel(writer, "Main", cols=['Diff1', 'Diff2'])
#That it!
Ответ 5
Старый вопрос, но я предполагаю, что некоторые люди все еще ищут это - так...
Я нахожу этот метод хорошим, потому что все рабочие листы загружаются в словарь имен листов и пар данных данных, созданных с помощью pandas с опцией sheetname = None. Простое добавление, удаление или изменение рабочих листов между чтением таблицы в формате dict и ее записью из dict. Для меня xlsxwriter работает лучше, чем openpyxl для этой конкретной задачи с точки зрения скорости и формата.
Примечание: будущие версии pandas (0.21.0+) изменят параметр "имя листа" на "имя листа".
# read a single or multi-sheet excel file
# (returns dict of sheetname(s), dataframe(s))
ws_dict = pd.read_excel(excel_file_path,
sheetname=None)
# all worksheets are accessible as dataframes.
# easy to change a worksheet as a dataframe:
mod_df = ws_dict['existing_worksheet']
# do work on mod_df...then reassign
ws_dict['existing_worksheet'] = mod_df
# add a dataframe to the workbook as a new worksheet with
# ws name, df as dict key, value:
ws_dict['new_worksheet'] = some_other_dataframe
# when done, write dictionary back to excel...
# xlsxwriter honors datetime and date formats
# (only included as example)...
with pd.ExcelWriter(excel_file_path,
engine='xlsxwriter',
datetime_format='yyyy-mm-dd',
date_format='yyyy-mm-dd') as writer:
for ws_name, df_sheet in ws_dict.items():
df_sheet.to_excel(writer, sheet_name=ws_name)
Для примера в вопросе 2013 года:
ws_dict = pd.read_excel('Masterfile.xlsx',
sheetname=None)
ws_dict['Main'] = data_filtered[['Diff1', 'Diff2']]
with pd.ExcelWriter('Masterfile.xlsx',
engine='xlsxwriter') as writer:
for ws_name, df_sheet in ws_dict.items():
df_sheet.to_excel(writer, sheet_name=ws_name)
Ответ 6
Я знаю, что это более старый поток, но это первый элемент, который вы находите при поиске, и вышеупомянутые решения не работают, если вам нужно сохранить диаграммы в книге, которую вы уже создали. В этом случае xlwings - лучший вариант - он позволяет писать в книгу Excel и хранить данные диаграмм/диаграмм.
простой пример:
import xlwings as xw
import pandas as pd
#create DF
months = ['2017-01','2017-02','2017-03','2017-04','2017-05','2017-06','2017-07','2017-08','2017-09','2017-10','2017-11','2017-12']
value1 = [x * 5+5 for x in range(len(months))]
df = pd.DataFrame(value1, index = months, columns = ['value1'])
df['value2'] = df['value1']+5
df['value3'] = df['value2']+5
#load workbook that has a chart in it
wb = xw.Book('C:\\data\\bookwithChart.xlsx')
ws = wb.sheets['chartData']
ws.range('A1').options(index=False).value = df
wb = xw.Book('C:\\data\\bookwithChart_updated.xlsx')
xw.apps[0].quit()
Ответ 7
Начиная с версии 0.24, вы можете упростить это с помощью ключевого аргумента mode
в ExcelWriter
:
import pandas as pd
with pd.ExcelWriter('the_file.xlsx', engine='openpyxl', mode='a') as writer:
data_filtered.to_excel(writer)
Ответ 8
def append_sheet_to_master(self, master_file_path, current_file_path, sheet_name):
try:
master_book = load_workbook(master_file_path)
master_writer = pandas.ExcelWriter(master_file_path, engine='openpyxl')
master_writer.book = master_book
master_writer.sheets = dict((ws.title, ws) for ws in master_book.worksheets)
current_frames = pandas.ExcelFile(current_file_path).parse(pandas.ExcelFile(current_file_path).sheet_names[0],
header=None,
index_col=None)
current_frames.to_excel(master_writer, sheet_name, index=None, header=False)
master_writer.save()
except Exception as e:
raise e
Это прекрасно работает, только то, что форматирование основного файла (файла, к которому мы добавляем новый лист) теряется.
Ответ 9
writer = pd.ExcelWriter('prueba1.xlsx'engine='openpyxl',keep_date_col=True)
Надежда "keep_date_col" поможет вам
Ответ 10
book = load_workbook(xlsFilename)
writer = pd.ExcelWriter(self.xlsFilename)
writer.book = book
writer.sheets = dict((ws.title, ws) for ws in book.worksheets)
df.to_excel(writer, sheet_name=sheetName, index=False)
writer.save()
Ответ 11
В пандах 0.24 есть лучшее решение:
with pd.ExcelWriter(path, mode='a') as writer:
s.to_excel(writer, sheet_name='another sheet', index=False)
до:
![enter image description here]()
после:
![enter image description here]()
так что обновите ваши панды сейчас:
pip install --upgrade pandas
Ответ 12
Мне удалось импортировать фрейм данных в существующий файл Excel с помощью этого кода:
from openpyxl import load_workbook
from openpyxl.utils.dataframe import dataframe_to_rows
Import pandas as pd
Rank = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20']
Team = ['Juventus', 'Napoli', 'Atalanta', 'Inter', 'AC Milan', 'Roma', 'Torino', 'Lazio', 'Sampdoria', 'Bologna', 'Sassuolo', 'Udinese', 'SPAL 2013', 'Parma Calcio 1913', 'Cagliari', 'Fiorentina', 'Genoa', 'Empoli', 'Frosinone', 'Chievo']
Points = ['90', '79', '69', '69', '68', '66', '63', '59', '53', '44', '43', '43', '42', '41', '41', '41', '38', '38', '25', '17']
tog = [Rank,
Team,
Points]
colo = ['rank', 'team', 'points']
complete = dict(list(zip(colo, tog)))
df2 = pd.DataFrame(complete)
wb = load_workbook('your/path/.xlsx')
wb.active = 2
ws = wb.active
for r in dataframe_to_rows(df2, index=False):
ws.append(r)
wb.save('your/path/.xlsx')
Теперь мой вопрос: как я могу добавить свой массив данных в другой ряд и в другой столбец? Например строка: 10, колонна: 15. Спасибо за вашу помощь.