Python写入Excel多Sheet时覆盖原文件问题排查请求
问题排查与解决方案
你遇到的核心问题是使用xlsxwriter引擎创建pd.ExcelWriter时,默认会直接覆盖已有文件,不支持追加工作表,而且两个脚本各自创建了独立的Writer实例,第二个实例打开文件时就把第一个脚本生成的文件彻底覆盖了。下面给你两种简单可行的解决办法:
方法一:改用openpyxl引擎实现工作表追加(推荐)
openpyxl是支持读写现有Excel文件的引擎,可以直接以追加模式打开文件并添加新工作表。
步骤1:修改第一个脚本(Eoc_Summary)
- 替换
ExcelWriter的引擎为openpyxl,并在main方法末尾添加关闭Writer的代码:
import pandas as pd import cx_Oracle import numpy as np import openpyxl from openpyxl import load_workbook from xlsxwriter.utility import xl_rowcol_to_cell class Summary(): def __init__(self, IO_Name, IO_ID): self.IO_Name=IO_Name self.IO_ID= IO_ID self.path = ("C://BiTeam-New-ProjectPython//Bi_Team_Project//Reports//{}({}).xlsx".format(self.IO_Name,self.IO_ID)) # 改用openpyxl引擎,mode='w'表示创建新文件 self.writer = pd.ExcelWriter(self.path, engine="openpyxl", mode='w', datetime_format="MM-DD-YYYY") # ...你的其他代码保持不变... def main(self): self.common_columns_summary() self.connect_TFR_summary() self.read_query_summary() self.access_data_summary() self.summary_creation() self.rename_cols_sumary() # 这里注意拼写,应该是summary? self.adding_column_Delivery_summary() self.adding_column_Spend() self.write_summary() self.common_summary() self.writer.close() # 新增:关闭Writer,确保文件保存
步骤2:修改第二个脚本(Eoc_Daily)
- 同样改用
openpyxl引擎,并且设置mode='a'(追加模式),同时处理同名工作表的情况:
import pandas as pd import cx_Oracle import numpy as np from xlsxwriter.utility import xl_rowcol_to_cell class Daily(): def __init__(self, IO_Name, IO_ID): self.IO_Name=IO_Name self.IO_ID= IO_ID self.path=("C://BiTeam-New-ProjectPython//Bi_Team_Project//Reports//{}({}).xlsx".format(self.IO_Name,self.IO_ID)) # 改用openpyxl引擎,mode='a'表示追加模式 # if_sheet_exists参数:如果同名Sheet存在,可选'replace'替换或'error'报错,根据你的需求选 self.writer = pd.ExcelWriter(self.path,engine="openpyxl", mode='a', datetime_format="MM-DD-YYYY", if_sheet_exists="replace") # ...你的其他代码保持不变... def main(self): self.common_Columns_daily() self.connect_TFR_daily() self.read_Query_daily() self.access_Data_KM_Sales_daily() self.KM_Sales_daily() self.rename_KM_Sales_daily() self.adding_vcr_ctr_IR_ATS_daily() self.write_KM_Sales_summary() self.formatting_daily() self.writer.close()
额外准备
确保已经安装openpyxl:
pip install openpyxl
方法二:共用同一个ExcelWriter实例(适合调整主脚本的场景)
如果可以修改主脚本的逻辑,我们可以在主程序中创建唯一的Writer实例,传递给两个类的对象,这样两个脚本都用同一个Writer写入,最后统一保存,避免覆盖问题。
步骤1:修改主脚本
import Eoc_Summary import Eoc_Daily import pandas as pd if __name__ == '__main__': IO_Name = input("Enter IO Name:") IO_ID = int(input("Enter the IO:")) path = f"C://BiTeam-New-ProjectPython//Bi_Team_Project//Reports//{IO_Name}({IO_ID}).xlsx" # 主程序中创建唯一的Writer实例 writer = pd.ExcelWriter(path, engine="xlsxwriter", datetime_format="MM-DD-YYYY") # 传递writer给两个类的实例 obj_summary = Eoc_Summary.Summary(IO_Name, IO_ID, writer) obj_summary.main() obj_daily = Eoc_Daily.Daily(IO_Name, IO_ID, writer) obj_daily.main() # 最后统一关闭Writer,保存所有工作表 writer.close()
步骤2:修改Eoc_Summary类
让类接收外部传入的Writer,不再自己创建:
class Summary(): # 新增writer参数 def __init__(self, IO_Name, IO_ID, writer): self.IO_Name=IO_Name self.IO_ID= IO_ID self.path = ("C://BiTeam-New-ProjectPython//Bi_Team_Project//Reports//{}({}).xlsx".format(self.IO_Name,self.IO_ID)) self.writer = writer # 使用传入的Writer # ...其他代码不变... def main(self): # ...你的原有代码... self.write_summary() self.common_summary() # 不要在这里关闭Writer,留到主程序统一处理
步骤3:修改Eoc_Daily类
同样接收外部传入的Writer:
class Daily(): # 新增writer参数 def __init__(self, IO_Name, IO_ID, writer): self.IO_Name=IO_Name self.IO_ID= IO_ID self.path=("C://BiTeam-New-ProjectPython//Bi_Team_Project//Reports//{}({}).xlsx".format(self.IO_Name,self.IO_ID)) self.writer = writer # 使用传入的Writer # ...其他代码不变... def main(self): # ...你的原有代码... self.write_KM_Sales_summary() self.formatting_daily() # 不要在这里关闭Writer,留到主程序统一处理
额外注意事项
- Windows路径可以用原始字符串避免转义问题,比如把
"C://..."改成r"C:\BiTeam-New-ProjectPython\Bi_Team_Project\Reports\..." - 检查代码中的拼写错误,比如第一个脚本里的
rename_cols_sumary()应该是rename_cols_summary()? - 运行前确保目标文件夹存在,否则会报错找不到路径
内容的提问来源于stack exchange,提问作者DKM
相关产品推荐
相关产品推荐

