楔子
估計有不少小伙伴在將DataFrame導入到Excel的時候,都遇到過這種尷尬的情況:
想將多個DataFrame導入到一個Excel文件的多個sheet中,但是卻發現生成的Excel文件里面只有最后一個sheet想給一個現有的Excel文件中追加一個sheet,結果發現其它的sheet都沒了,只剩下新追加的sheet
那么下面我們來看看如何解決這個問題。
同時導入多個sheet
如果是導入多個sheet的話,那么肯定不能直接使用原來to_excel("文件名")的方式,而是需要使用ExcelWriter。
import pandas as pd
df1 = pd.DataFrame({"a": [1, 2], "b": [3, 4]})
df2 = pd.DataFrame({"a": [2, 3], "b": [4, 5]})
df3 = pd.DataFrame({"a": [3, 4], "b": [5, 6]})
# 調用pd.ExcelWriter, 需要指定mode="a", engine="openpyxl"
# 但是注意: 將mode設置為"a"表示追加, 但是它要求文件必須存在, 否則報錯
"""
writer = pd.ExcelWriter(r"test.xlsx", mode="a", engine="openpyxl")
"""
# 因此首先我們需要生成這個文件
df1.to_excel("test.xlsx", index=False, sheet_name="a")
# 然后再實例化ExcelWriter
writer = pd.ExcelWriter(r"test.xlsx", mode="a", engine="openpyxl")
# 接下來還是調用to_excel, 但是第一個參數不再是文件名, 而是上面的writer
# 將剩下的兩個DataFrame寫進去
df2.to_excel(writer, index=False, sheet_name="b")
df3.to_excel(writer, index=False, sheet_name="c")
# 保存並關閉writer, 寫入磁盤
writer.save()
writer.close()

此時我們看到結果是沒有問題的,當然向已存在的Excel文件追加sheet也是同理。
覆蓋一個sheet
生成一個Excel文件、同時寫入多個sheet,以及追加sheet,我們已經知道該怎么做了,但是如何覆蓋一個sheet呢?首先我們覆蓋一個sheet的時候還要保證其它sheet不受影響,所以mode仍然要設置為追加模式。
下面問題來了,我們上面的Excel文件有"a"、"b"、"c"三個sheet,假設我們想將"b"這個sheet覆蓋掉,要怎么做呢?可能有伙伴認為,在追加的時候還指定sheet_name="b"不就行了,然鵝答案是不行的。

我們看到如果已有同名sheet,那么不會覆蓋,還是創建一個新的sheet,並自動在結尾處加一個1。如果我們在此基礎上再寫入"b"這個sheet的話,那么又會多出一個名為"b2"的sheet。所以最好的辦法是,在導入之前先將某個sheet刪除。
import pandas as pd
writer = pd.ExcelWriter(r"test.xlsx", mode="a", engine="openpyxl")
# pandas操作Excel底層也是依賴於其它的模塊, 比如xlrd、openpyxl
# 所以這里的 wb = writer.book 就相當於 from openpyxl import load_workbook; wb = load_workbook("xxx.xlsx")
wb = writer.book
# 查看已存在的所有的sheet, 總共是5個, "b1"和"b2"是自動創建的, 因為"b"已經存在了, 我們又導入了兩次
print(wb.sheetnames) # ['a', 'b', 'c', 'b1', 'b2']
# 下面我們來刪除sheet
wb.remove(wb["b1"])
wb.remove(wb["b2"])
wb.remove(wb["b"])
df = pd.DataFrame({"name": ["夏色祭", "白上吹雪"]})
# 我們將b這個sheet給刪除了, 所以此時再導入"b"這個sheet的時候就不會出現"b3"了
# 當然我們順便把"b1"和"b2"也給刪掉
df.to_excel(writer, index=True, sheet_name="b")
writer.save()
writer.close()

我們看到"b1"、"b2"兩個sheet就沒了,當然我們刪除的還有"b"這個sheet,只不過我們又重新創建了"b"這個sheet,當然數據也是我們創建的新數據。另外可能有人發現多個sheet的順序不再是原來的"a"、"b"、"c",這是因為在刪除"b"之后,"a"和"c"就靠在一起了,所以新寫入"b"的時候就排在"c"的后面了,當然個人覺得這沒有什么太大影響。
