Python导入SQL数据至.xlsm文件报错:无法读取工作簿
问题:将SQL Server数据写入已有.xlsm文件失败
正在进行Python数据分析项目,需将SQL Server中某表的所有数据复制到已有的.xlsm格式Excel文件。最初使用pandas+pyodbc,得知pandas默认不支持.xlsm后改用openpyxl,代码无法正常运行。
相关代码:
sql_table = 'table1' sql_query = f'SELECT * FROM {sql_table};' # 读取SQL Server中的处理后数据 processed_data = pd.read_sql_query(sql_query, conn_sql) data = pd.DataFrame(processed_data) wb = load_workbook('new.xlsm') ws = wb['Internal'] for r in dataframe_to_rows(data, index=False, header=True): ws.append(r) wb.save('new.xlsm')
已确认模块导入、SQL连接无问题,仅上述代码异常,操作对象为已有.xlsm文件而非新建文件。
预期结果:脚本无报错运行,目标Excel文件出现数据变更。
实际结果:抛出错误:
ValueError: Unable to read Workbook: could not read worksheets from new.xlsm.
This is most probably because the workbook source files contain some invalid XML.
解决方法
1. 排查文件本身的问题
- 手动打开
new.xlsm,确认文件未损坏、能正常打开;保存时选择「Excel启用宏的工作簿(.xlsm)」格式,确保XML结构合法。 - 复制原文件生成测试副本,避免原文件被其他程序锁定或本身存在损坏。
2. 修正openpyxl的加载参数
加载.xlsm文件时需明确指定保留宏和可写模式,修改加载代码:
from openpyxl import load_workbook from openpyxl.utils.dataframe import dataframe_to_rows # 新增read_only=False和keep_vba=True参数 wb = load_workbook('new.xlsm', read_only=False, keep_vba=True) ws = wb['Internal'] # 若需避免重复写入表头,可跳过表头行(假设工作表已有表头) for r in dataframe_to_rows(data, index=False, header=False): ws.append(r) wb.save('new.xlsm')
3. 备选方案:用pandas配合openpyxl引擎写入
实际上pandas支持写入.xlsm,只需指定engine='openpyxl',并通过参数保留宏、追加数据:
with pd.ExcelWriter('new.xlsm', engine='openpyxl', mode='a', if_sheet_exists='overlay', keep_vba=True) as writer: # 获取目标工作表当前最大行,从下一行开始写入 start_row = writer.sheets['Internal'].max_row # header=False避免重复写入表头,index=False不写入索引列 data.to_excel(writer, sheet_name='Internal', index=False, header=False, startrow=start_row)
内容的提问来源于stack exchange,提问作者PWDexter
相关产品推荐
相关产品推荐

