Verilerin üzerine yazmadan (pandalar kullanarak) mevcut bir excel dosyasına nasıl yazılır?


120

Aşağıdaki şekilde excel dosyasına yazmak için pandaları kullanıyorum:

import pandas

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

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

writer.save()

Masterfile.xlsx zaten çok sayıda farklı sekmeden oluşur. Ancak, henüz "Ana" içermiyor.

Pandalar "Ana" sayfaya doğru bir şekilde yazar, ne yazık ki diğer tüm sekmeleri de siler.


1
bir örnek veya ExcelReader verebilir misiniz? Belgelerde buna benzer bir şey bulamadım.
BP_

1
Pandalarda ExcelReader gibi bir şey olmadığını düşünüyorum. Excel'den veri okumak için read_excel kullanıyorum. Verileri mükemmel hale getireceğini sanmıyorum.
BP_

1
@nrathaus orada görünmüyorExcelReader
virtualxtc

Cevaplarda sorunun tam olarak ne sorduğuna dair bazı karışıklıklar olduğuna dikkat edin. Bazı yanıtlar "Ana" nın henüz mevcut olmadığını ve OP'nin sadece mevcut bir excel çalışma kitabına yeni bir sayfa eklediğini varsayar. Diğerleri "Ana" nın zaten mevcut olduğunu ve OP'nin "Ana" nın altına yeni veriler eklemek istediğini varsayar.
TC Proctor

Yanıtlar:


143

Pandas belgeleri, xlsx dosyaları için openpyxl kullandığını söylüyor. Kodun hızlı ExcelWriterbir şekilde incelenmesi, bunun gibi bir şeyin işe yarayabileceğine dair bir ipucu verir:

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'in ne için olduğunu açıklar mısınız?
BP_

5
ExcelWriter bazı nedenlerle sayfaya erişmek için bu değişkeni kullanır. Boş bırakırsanız, Main sayfasının zaten orada olduğunu bilmez ve yeni bir sayfa oluşturur.
Kayak

2
Bu çözüm iyi çalışıyor. Yine de bir dezavantajı var. Elektronik tablodaki formülleri ve bağlantıları bozar. Bu davranışı nasıl değiştireceğiniz konusunda bir fikriniz var mı?
BP_

1
Tam olarak ne kırılırsın ..? Bunu ayrı bir soru olarak sorabilir, etiketleyebilir openpyxlve yeterli ayrıntı sağlayabilirsiniz: ne tür formüllere sahipsiniz, veriler nasıl güncellenir, formülleri nasıl bozar. Şimdi yardım edemiyorum, bilmediğim çok şey var.
Kayak

2
bunun yerine .xlsm dosyalarıyla kullanılabilir mi?
dapaz

40

İşte yardımcı bir işlev:

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

NOT: Pandalar <0.21.0 için, değiştirmek sheet_nameile sheetname!

Kullanım örnekleri:

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
Bu çözüm benim için mükemmel çalıştı, burada yayınlanan diğerleri çalışmıyor. Çok teşekkürler! Sadece bir yorum: dosya mevcut olmadığında, "NameError: genel adı 'FileNotFoundError' tanımlı değil" hatası alıyorum
cholo14

1
@ cholo14, bunu işaret ettiğiniz için teşekkür ederiz! Python 3.x üzerinde test ettim, bu yüzden bu hatayı kaçırdım.
Cevabımda düzelttim

1
Bu benim için çalıştı ancak xlsx biçimlendirmesini korumanın bir yolu var mı (orijinal xlsx dosyasından)?
2

@ 2one, tam olarak bilmiyorum - deneyin veya yeni bir SO sorusu sorun
MaxU

sadece satırlar yerine sütunlara yazmanın bir yolu var mı? Bir sayfayı otomatik olarak güncellemek istiyorum, ancak yeni satırlar eklemiyorum, ancak sütunlar teşekkürler!
doomdaam

21

İle openpyxlsürümü 2.4.0ve pandassürümü 0.19.2, ile geldi @ski süreç biraz daha basit olur:

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
Bu benim için çalışmıyor. Zaten bir "Ana" çalışma sayfası varsa, yalnızca yeni verilerle "Ana1" adlı yeni bir tane oluşturur ve "Ana" çalışma sayfası içeriğini değiştirmeden bırakır.
Qululu

3
@Qululu Bu soruda iki farklı hedef arasında karışıklık olabileceğini düşünüyorum. Bu, mevcut bir çalışma kitabına ek sayfalar eklemenize olanak tanır. Edilir değil mevcut bir tabakaya ek verileri eklemek için tasarlanmıştır. Bir sayfa adlandırma çakışması varsa, sayfayı yeniden adlandırır. Bu bir özelliktir, hata değildir.
TC Proctor

@Qululu'nun dediği gibi, bu yalnızca farklı adlarla daha fazla sayfa oluşturur. MaxU çalışmalarından elde edeceğiniz ilk çözüm ve elde edeceğiniz çıktı, istediğiniz kadar ilk sayfadaki df olacaktır (bu, başlıklar da birçok kez çarpılır.) Basit bir teknik: her yineleme veri çerçevesini bir listeye eklersiniz. Sonunda sadece concat yapman gerekiyor. Aynı yapıyı takip ederlerse bir cazibe işlevi görecektir. list_my_dfs = [df1, df2, ...] # Veri çerçevelerinizin listesi my_dfs_together = pd.concat (list_my_df) # concat my dataframe in a single df
Susana Silva Santos

@SusanaSilvaSantos, TC Proctor'un sizden hemen önce söylediklerine bir göz atın. OP, mevcut bir çalışma kitabına Varolmayan bir çalışma sayfası eklemek istedi. Bu kod bunu yapar. Çalışma kitabındaki mevcut bir sayfaya veri eklemek kapsamın parçası değildi. Buna gerek yoksa bu yeterli olacaktır.
mvbentes

16

Pandalar 0.24'ten başlayarak, bunu modeanahtar kelime bağımsız değişkeniyle basitleştirebilirsiniz ExcelWriter:

import pandas as pd

with pd.ExcelWriter('the_file.xlsx', engine='openpyxl', mode='a') as writer: 
     data_filtered.to_excel(writer) 

3
benim için üzerine yazıyor.
keramat

10
@keramat Bu soruda iki farklı hedef arasında karışıklık olabileceğini düşünüyorum. Bu, mevcut bir çalışma kitabına ek sayfalar eklemenize olanak tanır. Edilir değil mevcut bir tabakaya ek verileri eklemek için tasarlanmıştır.
TC Proctor

1
mode = 'a'daha fazla sayfa ekler, ancak ya mevcut sayfalardaki verilerin üzerine yazmak istersem?
Afallamış

11

Eski soru, ama tahmin ediyorum ki bazı insanlar hala bunu arıyor - yani ...

Bu yöntemi güzel buluyorum çünkü tüm çalışma sayfaları pandalar tarafından sheetname = None seçeneğiyle oluşturulan bir sayfa adı ve veri çerçevesi çiftleri sözlüğüne yükleniyor. Elektronik tabloyu dikte biçiminde okuma ve dikteden geri yazma arasında çalışma sayfalarını eklemek, silmek veya değiştirmek kolaydır. Benim için xlsxwriter, hız ve format açısından bu özel görev için openpyxl'den daha iyi çalışıyor.

Not: Pandaların (0.21.0+) gelecekteki sürümleri "sayfa adı" parametresini "sayfa_adı" olarak değiştirecektir.

# 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 sorusundaki örnek için:

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)

Bu tür bir işe yaradı, ancak birleştirilmiş hücrelerim, hücre renkleri ve hücre genişlikleri korunmadı.
virtualxtc

1
Evet, bu yöntemle bu tür biçimlendirme kaybolacak çünkü her çalışma sayfası bir pandas veri çerçevesine dönüştürülüyor (bu excel biçimlendirmelerinin hiçbiri olmadan), daha sonra veri çerçevelerinden çalışma sayfalarına dönüştürülüyor ve yeni bir excel çalışma kitabıyla (orijinaliyle aynı ada sahip) dosya). Openpyxl kullanan yeni bir "ekleme" yöntemi, orijinal dosya çalışma sayfası biçimlendirmesini koruyabilecek gibi görünüyor olabilir. github.com/pandas-dev/pandas/pull/21251
b2002

11

Bunun daha eski bir iş parçacığı olduğunu biliyorum, ancak bu, arama yaparken bulduğunuz ilk öğedir ve önceden oluşturduğunuz bir çalışma kitabındaki grafikleri saklamanız gerekiyorsa yukarıdaki çözümler çalışmaz. Bu durumda, xlwings daha iyi bir seçenektir - excel kitabına yazmanıza izin verir ve çizelgeleri / grafik verilerini tutar.

basit örnek:

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

Önce yoksa dosya oluşturmanın bir yolu var mı?
Tinkinc

Evet, belgeleri incelediniz mi? docs.xlwings.org/en/stable/api.html
flyingmeatball

wb = xw.Book (dosya adı) web sitelerinde bir kitap oluşturduğunu söylüyor. ama olmuyor
Tinkinc

wb = xw.Book (), mevcut bir kitabı yüklemeye çalıştığınız yolu geçtiğinizde yeni bir boş kitap oluşturur.
flyingmeatball

1
Not: xlwings, çalışan bir Excel örneğiyle etkileşime girer ve bu nedenle Linux'ta çalışmaz.
virtualxtc

5

Pandalar 0.24'te daha iyi bir çözüm var:

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

önce:

görüntü açıklamasını buraya girin

sonra:

görüntü açıklamasını buraya girin

pandalarınızı şimdi yükseltin:

pip install --upgrade pandas


1
Gelecek için sadece bir uyarı, bu seçenekle çalışmıyor XslxWriter.
metinsenturk

aynı zamanda varsayılan engine=openpyxlolarak çalışmaz çünkü sadece yeni bir çalışma sayfası ekleyecektir.the only worksheet1
Björn 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

Bu gayet iyi çalışıyor tek şey, ana dosyanın (yeni sayfa eklediğimiz dosya) biçimlendirmesinin kaybolmasıdır.


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

"Keep_date_col" umudu size yardımcı olur


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
Bu, yazarların sorusunu yanıtlasa da, bazı açıklayıcı sözcüklerden ve / veya belgelere bağlantılardan yoksundur. Ham kod parçacıkları, etraflarında bazı ifadeler olmadan pek yardımcı olmaz. Ayrıca bulabilirsiniz iyi bir cevap yazmayı çok yararlı. Lütfen cevabınızı düzenleyin.
Roy Scheffers

0

Yöntem:

  • Mevcut değilse dosya oluşturabilir
  • Sayfa adına göre mevcut excel'e ekle
import pandas as pd
from openpyxl import load_workbook

def write_to_excel(df, file):
    try:
        book = load_workbook(file)
        writer = pd.ExcelWriter(file, engine='openpyxl') 
        writer.book = book
        writer.sheets = dict((ws.title, ws) for ws in book.worksheets)
        df.to_excel(writer, **kwds)
        writer.save()
    except FileNotFoundError as e:
        df.to_excel(file, **kwds)

Kullanımı:

df_a = pd.DataFrame(range(10), columns=["a"])
df_b = pd.DataFrame(range(10, 20), columns=["b"])
write_to_excel(df_a, "test.xlsx", sheet_name="Sheet a", columns=['a'], index=False)
write_to_excel(df_b, "test.xlsx", sheet_name="Sheet b", columns=['b'])
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.