데이터를 덮어 쓰지 않고 기존 Excel 파일에 쓰는 방법 (Pandas 사용)?


120

팬더를 사용하여 다음과 같은 방식으로 파일을 엑셀에 씁니다.

import pandas

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

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

writer.save()

Masterfile.xlsx는 이미 여러 개의 다른 탭으로 구성되어 있습니다. 그러나 아직 "Main"이 포함되어 있지 않습니다.

Pandas는 "메인"시트에 올바르게 씁니다. 불행히도 다른 모든 탭도 삭제합니다.


1
예제 또는 ExcelReader를 줄 수 있습니까? 문서에서 이와 같은 것을 찾지 못했습니다.
BP_ 2013

1
판다에는 ExcelReader와 같은 것이 없다고 생각합니다. read_excel을 사용하여 Excel에서 데이터를 읽습니다. 데이터를 절약 할 수는 없다고 생각합니다.
BP_ 2013

1
@nrathaus 수없는 것ExcelReader
virtualxtc

질문이 정확히 무엇을 요구하는지에 대한 답변에 약간의 혼란이 있습니다. 일부 답변은 "Main"이 아직 존재하지 않는다고 가정하고 OP는 단순히 기존 Excel 통합 문서에 새 시트를 추가하는 것입니다. 다른 사람들은 "Main"이 이미 존재하고 OP가 "Main"의 맨 아래에 새 데이터를 추가하려고한다고 가정합니다.
TC Proctor 19

답변:


143

Pandas 문서에 따르면 xlsx 파일에 openpyxl을 사용합니다. 의 코드를 훑어 보면 ExcelWriter다음과 같은 것이 잘 될 수 있다는 단서가 제공됩니다.

import pandas
from openpyxl import load_workbook

book = load_workbook('Masterfile.xlsx')
writer = pandas.ExcelWriter('Masterfile.xlsx', engine='openpyxl') 
writer.book = book

## ExcelWriter for some reason uses writer.sheets to access the sheet.
## If you leave it empty it will not know that sheet Main is already there
## and will create a new sheet.

writer.sheets = dict((ws.title, ws) for ws in book.worksheets)

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

writer.save()

2
writer.sheets가 무엇인지 설명해 주시겠습니까?
BP_ 2013

5
어떤 이유로 ExcelWriter는이 변수를 사용하여 시트에 액세스합니다. 비워두면 Main 시트가 이미 있다는 것을 알지 못하고 새 시트를 만듭니다.
스키

2
이 솔루션은 잘 작동합니다. 하지만 한 가지 단점이 있습니다. 스프레드 시트 내의 수식과 연결을 끊습니다. 이 동작을 변경하는 방법에 대한 아이디어가 있습니까?
BP_

1
정확히 뭘 깨뜨려 ..? 이 질문을 별도의 질문으로하고 태그를 지정하고 openpyxl충분한 세부 정보를 제공 할 수 있습니다. 어떤 종류의 수식이 있는지, 데이터가 어떻게 업데이트되는지, 어떻게 수식을 제동합니까? 지금은 어쩔 수 없어요. 모르는 게 너무 많아요.
Ski

2
대신 .xlsm 파일과 함께 사용할 수 있습니까?
dapaz

39

다음은 도우미 기능입니다.

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

    # 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!

사용 예 :

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)

1
이 솔루션은 저에게 완벽하게 작동했지만 여기에 게시 된 다른 솔루션은 작동하지 않습니다. 감사합니다! 그냥 하나의 코멘트 : 파일이 존재하지 않을 때, 나는 오류 얻을 "나가서 설명하자면 NameError : 전역 이름 'FileNotFoundError가'정의되지 않습니다"
cholo14

1
@ cholo14, 이것을 지적 해 주셔서 감사합니다! Python 3.x에서 테스트 했으므로 해당 버그를 놓쳤습니다. 나는 ...이 질문에 대해 답을 수정 한
MaxU

1
이것은 나를 위해 일했지만 원래 xlsx 파일에서 xlsx 형식을 유지하는 방법이 있습니까?
2one

@ -2- 온, 나는 정확히 모른다 - 그것을 시도를 제공하거나 새 SO 질문 물어
MaxU

행 대신 열에 쓰는 방법이 있습니까? 시트를 자동으로 업데이트하고 싶지만 새 행을 추가하지는 않지만 열 감사합니다!
doomdaam

21

openpyxlversion 2.4.0pandasversion을 사용하면 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!

11
이것은 나를 위해 작동하지 않습니다. 이미 "Main"워크 시트가있는 경우 새 데이터 만 포함 된 "Main1"이라는 새 워크 시트를 만들고 "Main"워크 시트 내용은 변경하지 않습니다.
Qululu 2017-07-12

2
@Qululu 두 가지 목표 사이에이 질문에 혼란이있을 수 있다고 생각합니다. 이를 통해 기존 통합 문서에 추가 시트를 추가 할 수 있습니다. 기존 시트에 추가 데이터를 추가하기위한 것이 아닙니다 . 시트 이름 지정 충돌이있는 경우 시트 이름을 바꿉니다. 이것은 버그가 아니라 기능입니다.
TC Proctor 2019

@Qululu가 말했듯이 이것은 다른 이름으로 더 많은 시트를 만듭니다. MaxU의 첫 번째 솔루션은 작동하며 얻을 수있는 출력은 원하는만큼 여러 번 첫 번째 시트의 df입니다 (즉, 헤더도 여러 번 곱 해짐). 하나의 간단한 기술 : 각 반복 목록에 데이터 프레임을 추가합니다. 결국에는 연결하기 만하면됩니다. 같은 구조를 따르면 매력으로 작용합니다. list_my_dfs = [df1, df2, ...] # 데이터 프레임 목록 my_dfs_together = pd.concat (list_my_df) # 내 데이터 프레임을 단일 df로 연결
Susana Silva Santos

@SusanaSilvaSantos, TC Proctor가 바로 전에 댓글을 한 내용을 살펴보세요. OP는 기존 통합 문서에 존재하지 않는 워크 시트를 추가하려고했습니다. 이 코드는 그렇게합니다. 통합 문서 내의 기존 시트에 데이터를 추가하는 것은 범위의 일부가 아닙니다. 이것이 필요하지 않다면 이것으로 충분합니다.
mvbentes

16

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) 

3
나를 위해 덮어 씁니다.
keramat

10
@keramat 두 가지 다른 목표 사이 에이 질문에 혼란이있을 수 있다고 생각합니다. 이를 통해 기존 통합 문서에 추가 시트를 추가 할 수 있습니다. 기존 시트에 추가 데이터를 추가하기위한 것이 아닙니다 .
TC Proctor 2019

1
mode = 'a'더 많은 시트를 추가하지만 기존 시트의 데이터를 덮어 쓰려면 어떻게해야합니까?
혼동

11

오래된 질문이지만 일부 사람들은 여전히 ​​이것을 검색한다고 생각합니다.

모든 워크 시트가 sheetname = None 옵션으로 pandas가 만든 시트 이름 및 데이터 프레임 쌍의 사전에로드되기 때문에이 방법이 좋습니다. 스프레드 시트를 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)

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)

그러나 이러한 종류의 작업은 병합 된 셀, 셀 색상 및 셀 너비가 유지되지 않았습니다.
virtualxtc

1
예,이 방법을 사용하면 각 워크 시트가 pandas 데이터 프레임 (해당 Excel 서식 없음)으로 변환 된 다음 데이터 프레임에서 새 Excel 통합 문서 (원본과 동일한 이름을 가짐) 내의 워크 시트로 변환되기 때문에 서식 유형이 손실됩니다. 파일). openpyxl을 사용하는 새로운 "추가"방법이 곧 나올 것으로 보이며 원본 파일 워크 시트 형식을 유지할 수 있습니까? github.com/pandas-dev/pandas/pull/21251
b2002

11

이것이 오래된 스레드라는 것을 알고 있지만 이것은 검색 할 때 가장 먼저 찾은 항목이며 이미 만든 통합 문서에 차트를 유지해야하는 경우 위의 솔루션이 작동하지 않습니다. 이 경우 xlwings가 더 나은 옵션입니다. 엑셀 북에 쓸 수 있고 차트 / 차트 데이터를 유지할 수 있습니다.

간단한 예 :

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

파일이 먼저 존재하지 않는 경우 파일을 생성하는 방법이 있습니까?
Tinkinc

예, 문서를 살펴 보셨습니까? docs.xlwings.org/en/stable/api.html
flyingmeatball

wb = xw.Book (filename) 웹 사이트에서 책을 만든다고합니다. 하지만 나던
Tinkinc

wb = xw.Book ()은 기존 책을로드하려는 경로를 전달할 때 새로운 빈 책을 만듭니다.
flyingmeatball

1
참고 : xlwings는 실행중인 Excel 인스턴스와 상호 작용하므로 Linux에서 실행되지 않습니다.
virtualxtc

5

pandas 0.24에는 더 나은 솔루션이 있습니다.

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

전에:

여기에 이미지 설명 입력

후:

여기에 이미지 설명 입력

이제 판다를 업그레이드하십시오.

pip install --upgrade pandas

1
이것은 이전 답변
TC Proctor

1
미래에 대한주의 XslxWriter사항 일 뿐이며이 옵션 에서는 작동하지 않습니다 .
metinsenturk

그것은 기본적으로하지 작업으로도 않습니다 engine=openpyxl그냥라는 새로운 워크 시트를 추가 할 것 같은the only worksheet1
비욘 B

1
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

이것은 완벽하게 잘 작동하지만 마스터 파일 (새 시트를 추가 할 파일)의 서식이 손실된다는 것입니다.


0
writer = pd.ExcelWriter('prueba1.xlsx'engine='openpyxl',keep_date_col=True)

"keep_date_col"희망은 당신을 도와줍니다


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

3
이것은 저자의 질문에 답할 수 있지만 설명하는 단어 및 / 또는 문서 링크가 부족합니다. 원시 코드 조각은 주변에 문구가 없으면 그다지 도움이되지 않습니다. 좋은 답변을 작성하는 방법이 매우 도움 이 될 수도 있습니다. 답변을 수정하십시오.
Roy Scheffers 2018
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.