如何写入现有的excel文件而不覆盖数据(使用pandas)?

BP_*_*BP_ 105 python excel python-2.7 pandas

我使用pandas以下列方式写入excel文件:

import pandas

writer = pandas.ExcelWriter('Masterfile.xlsx') 

data_filtered.to_excel(writer, "Main", cols=['Diff1', 'Diff2'])

writer.save()
Run Code Online (Sandbox Code Playgroud)

Masterfile.xlsx已包含许多不同的选项卡.

Pandas正确写入"Main"表,不幸的是它还删除了所有其他选项卡.

Ski*_*Ski 128

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()
Run Code Online (Sandbox Code Playgroud)

  • ExcelWriter出于某种原因使用此变量来访问工作表.如果您将其留空,则不会知道主页已经存在并将创建新工作表. (4认同)
  • 你能解释一下什么是 writer.sheets 吗? (2认同)
  • 此解决方案工作正常.它有一个缺点.它打破了电子表格中的公式和连接.任何想法如何改变这种行为? (2认同)
  • 可以与.xlsm文件一起使用吗? (2认同)

Max*_*axU 26

这是一个辅助函数:

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()
Run Code Online (Sandbox Code Playgroud)

注意:对于Pandas <0.21.0,请替换sheet_namesheetname!

用法示例:

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)
Run Code Online (Sandbox Code Playgroud)

  • @cholo14,感谢您指出这一点!我已经在 Python 3.x 上测试过它,所以我错过了那个错误。我已经在答案中修复了它... (3认同)
  • 这个解决方案对我来说很完美,这里发布的其他解决方案不起作用。非常感谢!只有一条评论:当文件不存在时,我收到一个错误“NameError: global name 'FileNotFoundError' is not defined” (2认同)
  • 这对我有用,但是有没有办法保持 xlsx 格式(来自原始 xlsx 文件)? (2认同)
  • 有没有一种方法可以写入列而不是只写入行?就像我想自动更新工作表,但不附加新行,但列,谢谢! (2认同)
  • 从 pandas 1.2.0 开始,代码将产生一个问题(在 1.1.5 之前都可以正常工作),引发 `BadZipFile` 异常,因为在实例化 `pd.ExcelWriter` 时,它会创建大小为 0 字节的空文件并覆盖现有文件。必须指定 `mode='a'`。请参阅 /sf/answers/4660954581/ 和 /sf/ask/46530011/​​66/4046632 (2认同)

mvb*_*tes 18

随着openpyxl版本2.4.0pandas版本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's it!
Run Code Online (Sandbox Code Playgroud)

  • 这对我不起作用.如果已有"主"工作表,它将创建一个名为"Main1"的新工作表,仅包含新数据,并保持"主"工作表内容不变. (9认同)
  • @Qululu 我认为在两个不同目标之间的这个问题上可能存在混淆。这允许您向现有工作簿添加其他工作表。**不** 旨在将附加数据附加到现有工作表中。如果存在工作表命名冲突,则会重命名工作表。这是一个功能,而不是一个错误。 (4认同)

Wil*_*Ayd 11

从pandas 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) 
Run Code Online (Sandbox Code Playgroud)

  • @keramat我认为在两个不同目标之间可能对此问题感到困惑。这使您可以将其他工作表添加到现有工作簿。并非旨在将其他数据附加到现有工作表中。 (4认同)
  • 为我覆盖。 (3认同)
  • `mode = 'a'` 添加更多工作表,但是如果我想覆盖现有工作表上的数据怎么办? (3认同)

b20*_*002 10

老问题,但我猜有些人还在搜索这个 - 所以......

我发现这个方法很好,因为所有的工作表都被加载到工作表的名称和数据框对的字典中,由pandas使用sheetname = None选项创建.在将电子表格读取为dict格式并将其从dict中写回之间添加,删除或修改工作表非常简单.对我来说,xlsxwriter在速度和格式方面比openpyxl更适合这项特殊任务.

注意:未来版本的pandas(0.21.0+)会将"sheetname"参数更改为"sheet_name".

# 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)
Run Code Online (Sandbox Code Playgroud)

对于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)
Run Code Online (Sandbox Code Playgroud)


fly*_*all 10

我知道这是一个较旧的线程,但这是您在搜索时找到的第一个项目,如果您需要在已创建的工作簿中保留图表,则上述解决方案不起作用.在这种情况下,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()
Run Code Online (Sandbox Code Playgroud)


bla*_*eep 10

pandas 0.24 中有一个更好的解决方案:

with pd.ExcelWriter(path, mode='a') as writer:
    s.to_excel(writer, sheet_name='another sheet', index=False)
Run Code Online (Sandbox Code Playgroud)

前:

在此处输入图片说明

后:

在此处输入图片说明

所以现在升级你的熊猫:

pip install --upgrade pandas
Run Code Online (Sandbox Code Playgroud)

  • 只是为了将来注意,这不适用于“XslxWriter”选项。 (2认同)

归档时间:

查看次数:

117068 次

最近记录:

6 年,4 月 前