xlwings迭代处理Excel时仅保存最后一个工作表高亮问题求助
问题分析
你的代码仅保留最后一个工作表高亮效果的核心原因是:在循环的每次迭代中,你都重新打开原始的updated文件,修改单个工作表后保存覆盖,导致之前的高亮被新打开的原始文件覆盖。每次进入with xw.App块时,都是从原始文件开始操作,而非基于已修改的文件继续处理下一个工作表。
修正方案
将Excel应用和工作簿的打开操作移到循环外部,一次性加载工作簿后遍历所有共有工作表,完成所有高亮操作后再统一保存。同时简化工作表的查找逻辑,直接通过名称定位工作表。
修正后的代码
from pathlib import Path import pandas as pd import xlwings as xw initial_version = Path.cwd() / "ConfigurationReport_TEST.xlsx" updated_version = Path.cwd() / "ConfigurationReport_DEV2.xlsx" excel1 = pd.ExcelFile(initial_version) excel2 = pd.ExcelFile(updated_version) # 获取两个文件共有的工作表名称 shared_sheets = [sheet for sheet in excel1.sheet_names if sheet in excel2.sheet_names] # 仅打开一次Excel应用和工作簿 with xw.App(visible=False) as app: updated_wb = app.books.open(updated_version) for sheetname in shared_sheets: # 读取两个工作表的数据并填充空值 df1 = pd.read_excel(initial_version, sheet_name=sheetname).fillna('') df2 = pd.read_excel(updated_version, sheet_name=sheetname).fillna('') # 保留更新版的原始行索引,用于定位Excel中的行 df2_with_index = df2.reset_index() # 对比找出仅存在于更新版的行 merged_df = pd.merge(df1, df2_with_index, how='outer', indicator='Exist') right_only_rows = merged_df.query("Exist == 'right_only'") # 转换为Excel的行号(Excel行从1开始,表头占第1行,数据从第2行开始) highlight_row_indices = right_only_rows['index'].tolist() excel_highlight_rows = [row + 2 for row in highlight_row_indices] # 获取当前工作表并高亮指定行 ws = updated_wb.sheets[sheetname] used_range = ws.used_range for row in used_range.rows: if row.row in excel_highlight_rows: row.color = (255, 71, 76) # 浅红色高亮 # 所有工作表处理完成后统一保存 updated_wb.save(Path.cwd() / "Difference_Highlighted.xlsx")
关键修改点
- 统一加载工作簿:将
xw.App和updated_wb的初始化移到循环外,确保所有修改都基于同一个工作簿实例。 - 简化工作表定位:直接通过
sheetname获取工作表,替代原有的复杂索引查找逻辑。 - 统一保存操作:仅在所有工作表处理完成后执行一次保存,避免覆盖之前的修改。
- 优化共有工作表筛选:使用列表推导式直接获取两个文件共有的工作表名称,代码更简洁。
内容的提问来源于stack exchange,提问作者Abhinav
相关产品推荐
相关产品推荐

