Як зберегти новий аркуш у існуючому файлі Excel за допомогою Pandas?


86

Я хочу використовувати файли Excel для зберігання даних, розроблених за допомогою python. Моя проблема полягає в тому, що я не можу додавати аркуші до існуючого файлу Excel. Тут я пропоную зразок коду для роботи, щоб вирішити цю проблему

import pandas as pd
import numpy as np

path = r"C:\Users\fedel\Desktop\excelData\PhD_data.xlsx"

x1 = np.random.randn(100, 2)
df1 = pd.DataFrame(x1)

x2 = np.random.randn(100, 2)
df2 = pd.DataFrame(x2)

writer = pd.ExcelWriter(path, engine = 'xlsxwriter')
df1.to_excel(writer, sheet_name = 'x1')
df2.to_excel(writer, sheet_name = 'x2')
writer.save()
writer.close()

Цей код зберігає два кадри даних на двох аркушах із іменами "x1" та "x2" відповідно. Якщо я створюю два нових DataFrames і намагаюся використовувати один і той же код для додавання двох нових аркушів, 'x3' і 'x4', вихідні дані втрачаються.

import pandas as pd
import numpy as np

path = r"C:\Users\fedel\Desktop\excelData\PhD_data.xlsx"

x3 = np.random.randn(100, 2)
df3 = pd.DataFrame(x3)

x4 = np.random.randn(100, 2)
df4 = pd.DataFrame(x4)

writer = pd.ExcelWriter(path, engine = 'xlsxwriter')
df3.to_excel(writer, sheet_name = 'x3')
df4.to_excel(writer, sheet_name = 'x4')
writer.save()
writer.close()

Я хочу файл Excel із чотирма аркушами: 'x1', 'x2', 'x3', 'x4'. Я знаю, що 'xlsxwriter' - не єдиний "движок", існує "openpyxl". Я також бачив, що вже є інші люди, які писали про це питання, але все ще не можу зрозуміти, як це зробити.

Ось код, взятий за цим посиланням

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

Кажуть, що це працює, але важко зрозуміти, як. Я не розумію, що таке "ws.title", "ws" та "dict" у цьому контексті.

Який найкращий спосіб зберегти "x1" та "x2", а потім закрити файл, знову відкрити його та додати "x3" та "x4"?

Відповіді:


116

Дякую. Я вважаю, що повний приклад може бути корисним для всіх, хто має таку ж проблему:

import pandas as pd
import numpy as np

path = r"C:\Users\fedel\Desktop\excelData\PhD_data.xlsx"

x1 = np.random.randn(100, 2)
df1 = pd.DataFrame(x1)

x2 = np.random.randn(100, 2)
df2 = pd.DataFrame(x2)

writer = pd.ExcelWriter(path, engine = 'xlsxwriter')
df1.to_excel(writer, sheet_name = 'x1')
df2.to_excel(writer, sheet_name = 'x2')
writer.save()
writer.close()

Тут я генерую файл Excel, наскільки я розумію, насправді не має значення, чи генерується він за допомогою механізму "xslxwriter" чи "openpyxl".

Коли я хочу писати, не втрачаючи вихідних даних, тоді

import pandas as pd
import numpy as np
from openpyxl import load_workbook

path = r"C:\Users\fedel\Desktop\excelData\PhD_data.xlsx"

book = load_workbook(path)
writer = pd.ExcelWriter(path, engine = 'openpyxl')
writer.book = book

x3 = np.random.randn(100, 2)
df3 = pd.DataFrame(x3)

x4 = np.random.randn(100, 2)
df4 = pd.DataFrame(x4)

df3.to_excel(writer, sheet_name = 'x3')
df4.to_excel(writer, sheet_name = 'x4')
writer.save()
writer.close()

цей код робить роботу!


будь-яка ідея, чому, коли я спробую це, я отримую: ValueError: Немає редактора Excel "Sales Leads Calculations.xlsx"?
— bernando_vialli

1
так, це додавання аркуша до Excel без знищення вже існуючих аркушів. Дякую!
— Nikhil VJ

2
Зберігаючи файл Excel, як зберегти існуючі формати аркушів Excel?
— Vineesh TP

3
Якщо хтось читає це і задається питанням, як замінити існуючий аркуш з тим самим іменем замість того, щоб перейменовувати новий: Додайте рядок writer.sheets = dict((ws.title, ws) for ws in book.worksheets) після writer.book = book
— Harm te

1
@Stefano Fedele, чи можете ви зробити те саме оновлення існуючого Excel, використовуючи 'xlsxwriter' замість 'openpyxl'?
— М Нікеш,

15

У наведеному вами прикладі ви завантажуєте існуючий файл bookі встановлюєте writer.bookзначення book. У рядку writer.sheets = dict((ws.title, ws) for ws in book.worksheets)ви отримуєте доступ до кожного аркуша книги як ws. Тоді заголовок аркуша wsтаким чином ви створюєте словник {sheet_titles: sheet}пар ключів, значень. Потім для цього словника встановлюється Writ.sheets. По суті, ці кроки просто завантажують наявні дані 'Masterfile.xlsx'та заповнюють ними ваш автор.

Тепер припустимо, у вас вже є файл із аркушами x1та x2як. Ви можете використовувати приклад коду для завантаження файлу, а потім можете зробити щось подібне, щоб додати x3та x4.

path = r"C:\Users\fedel\Desktop\excelData\PhD_data.xlsx"
writer = pd.ExcelWriter(path, engine='openpyxl')
df3.to_excel(writer, 'x3', index=False)
df4.to_excel(writer, 'x4', index=False)
writer.save()

Це повинно робити те, що ви шукаєте.


будь-яка ідея, чому, коли я спробую це, я отримую: ValueError: Немає редактора Excel "Sales Leads Calculations.xlsx"?
— bernando_vialli

18
це стирання вже існуючих аркушів.
— Nikhil VJ

13

Простий приклад написання кількох даних, щоб досягти успіху одночасно. А також, коли ви хочете додати дані на аркуш письмового файлу Excel (закритий файл Excel).

Коли ви вперше пишете в Excel. (Запис "df1" і "df2" в "1st_sheet" і "2nd_sheet")

import pandas as pd 
from openpyxl import load_workbook

df1 = pd.DataFrame([[1],[1]], columns=['a'])
df2 = pd.DataFrame([[2],[2]], columns=['b'])
df3 = pd.DataFrame([[3],[3]], columns=['c'])

excel_dir = "my/excel/dir"

with pd.ExcelWriter(excel_dir, engine='xlsxwriter') as writer:    
    df1.to_excel(writer, '1st_sheet')   
    df2.to_excel(writer, '2nd_sheet')   
    writer.save()    

Після закриття Excel, але ви хочете "додати" дані до того самого файлу Excel, але іншого аркуша, скажімо "df3" до імені аркуша "3rd_sheet".

book = load_workbook(excel_dir)
with pd.ExcelWriter(excel_dir, engine='openpyxl') as writer:
    writer.book = book
    writer.sheets = dict((ws.title, ws) for ws in book.worksheets)    

    ## Your dataframe to append. 
    df3.to_excel(writer, '3rd_sheet')  

    writer.save()     

Зауважте, що формат Excel не повинен бути xls, ви можете використовувати xlsx.


1
Не бачу, що додає ця відповідь. Насправді, неодноразове використання такого менеджера контекстів буде включати набагато більше вводу-виводу.
— Чарлі Кларк

8

Я настійно рекомендую вам працювати безпосередньо з openpyxl, оскільки зараз він підтримує Pandas DataFrames .

Це дозволяє зосередитись на відповідному коді Excel та Pandas.


3
Було б дуже корисно, якщо б ви могли додати трохи більше прикладів "панд", подібних до цього
— MaxU

Я сам багато не працюю з Pandas, тому я не можу навести стільки прикладів, але вітаю вдосконалення документації.
— Чарлі Кларк,

4

Для створення нового файлу

x1 = np.random.randn(100, 2)
df1 = pd.DataFrame(x1)
with pd.ExcelWriter('sample.xlsx') as writer:  
    df1.to_excel(writer, sheet_name='x1')

Для додавання до файлу використовуйте аргумент mode='a'у pd.ExcelWriter.

x2 = np.random.randn(100, 2)
df2 = pd.DataFrame(x2)
with pd.ExcelWriter('sample.xlsx', engine='openpyxl', mode='a') as writer:  
    df2.to_excel(writer, sheet_name='x2')

За замовчуванням mode ='w'. Див. Документацію .


3

Це можна зробити без використання ExcelWriter, за допомогою інструментів у openpyxl Це може значно полегшити додавання шрифтів до нового аркуша openpyxl.styles

import pandas as pd
from openpyxl import load_workbook
from openpyxl.utils.dataframe import dataframe_to_rows

#Location of original excel sheet
fileLocation =r'C:\workspace\data.xlsx'

#Location of new file which can be the same as original file
writeLocation=r'C:\workspace\dataNew.xlsx'

data = {'Name':['Tom','Paul','Jeremy'],'Age':[32,43,34],'Salary':[20000,34000,32000]}

#The dataframe you want to add
df = pd.DataFrame(data)

#Load existing sheet as it is
book = load_workbook(fileLocation)
#create a new sheet
sheet = book.create_sheet("Sheet Name")

#Load dataframe into new sheet
for row in dataframe_to_rows(df, index=False, header=True):
    sheet.append(row)

#Save the modified excel at desired location    
book.save(writeLocation)

Це гарне рішення, однак я не впевнений, що це також має значення. Ви маєте на увазі, що ви не можете цього робити ExcelWriterабо вам просто не потрібно?
— MattSom

Ви можете зробити це за допомогою Excelwriter, але мені стає простіше, просто використовуючи openpyxl.
— Jis Mathew

2

Ви можете прочитати наявні аркуші, які вас цікавлять, наприклад, "x1", "x2", в пам'ять і "записати" їх назад перед додаванням нових аркушів (майте на увазі, що аркуші у файлі та аркуші в пам'яті є двома різними речі, якщо ви їх не прочитаєте, вони будуть загублені). Цей підхід використовує лише 'xlsxwriter', без участі у openpyxl.

import pandas as pd
import numpy as np

path = r"C:\Users\fedel\Desktop\excelData\PhD_data.xlsx"

# begin <== read selected sheets and write them back
df1 = pd.read_excel(path, sheet_name='x1', index_col=0) # or sheet_name=0
df2 = pd.read_excel(path, sheet_name='x2', index_col=0) # or sheet_name=1
writer = pd.ExcelWriter(path, engine='xlsxwriter')
df1.to_excel(writer, sheet_name='x1')
df2.to_excel(writer, sheet_name='x2')
# end ==>

# now create more new sheets
x3 = np.random.randn(100, 2)
df3 = pd.DataFrame(x3)

x4 = np.random.randn(100, 2)
df4 = pd.DataFrame(x4)

df3.to_excel(writer, sheet_name='x3')
df4.to_excel(writer, sheet_name='x4')
writer.save()
writer.close()

Якщо ви хочете зберегти всі існуючі аркуші, ви можете замінити наведений вище код між початком і кінцем на:

# read all existing sheets and write them back
writer = pd.ExcelWriter(path, engine='xlsxwriter')
xlsx = pd.ExcelFile(path)
for sheet in xlsx.sheet_names:
    df = xlsx.parse(sheet_name=sheet, index_col=0)
    df.to_excel(writer, sheet_name=sheet)

1
#This program is to read from excel workbook to fetch only the URL domain names and write to the existing excel workbook in a different sheet..
#Developer - Nilesh K
import pandas as pd
from openpyxl import load_workbook #for writting to the existing workbook

df = pd.read_excel("urlsearch_test.xlsx")

#You can use the below for the relative path.
# r"C:\Users\xyz\Desktop\Python\

l = [] #To make a list in for loop

#begin
#loop starts here for fetching http from a string and iterate thru the entire sheet. You can have your own logic here.
for index, row in df.iterrows():
    try: 
        str = (row['TEXT']) #string to read and iterate
        y = (index)
        str_pos = str.index('http') #fetched the index position for http
        str_pos1 = str.index('/', str.index('/')+2) #fetched the second 3rd position of / starting from http
        str_op = str[str_pos:str_pos1] #Substring the domain name
        l.append(str_op) #append the list with domain names

    #Error handling to skip the error rows and continue.
    except ValueError:
            print('Error!')
print(l)
l = list(dict.fromkeys(l)) #Keep distinct values, you can comment this line to get all the values
df1 = pd.DataFrame(l,columns=['URL']) #Create dataframe using the list
#end

#Write using openpyxl so it can be written to same workbook
book = load_workbook('urlsearch_test.xlsx')
writer = pd.ExcelWriter('urlsearch_test.xlsx',engine = 'openpyxl')
writer.book = book
df1.to_excel(writer,sheet_name = 'Sheet3')
writer.save()
writer.close()

#The below can be used to write to a different workbook without using openpyxl
#df1.to_excel(r"C:\Users\xyz\Desktop\Python\urlsearch1_test.xlsx",index='false',sheet_name='sheet1')

1
Я не стежу, як це пов'язано з питанням, за винятком того, що це про excel.
— Artog

Я працював над пошуком повного рішення для читання та запису до існуючої книги, але не зміг знайти те саме. Тут я знайшов підказку про те, як писати до існуючої книги, тому я подумав дати повне рішення для своєї проблеми. Сподіваюся, це ясно.
— nileshk611

0

Інший досить простий спосіб зробити це - зробити такий метод:

def _write_frame_to_new_sheet(path_to_file=None, sheet_name='sheet', data_frame=None):
    book = None
    try:
        book = load_workbook(path_to_file)
    except Exception:
        logging.debug('Creating new workbook at %s', path_to_file)
    with pd.ExcelWriter(path_to_file, engine='openpyxl') as writer:
        if book is not None:
            writer.book = book
        data_frame.to_excel(writer, sheet_name, index=False)

Ідея тут полягає в тому, щоб завантажити книгу в path_to_file, якщо вона існує, а потім додати data_frame як новий аркуш з іменем аркуша . Якщо робочої книги не існує, вона створюється. Здається , що ні openpyxl або xlsxwriter Append, так як в прикладі з @Stefano вище, ви дійсно повинні навантаження , а потім переписати додавання.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.