Ubuntu下Python写入.xlsm保留宏及提升写入效率求助
解决方案:Ubuntu下保留XLSM宏并优化大数据写入速度
一、保留XLSM文件宏的解决方法
1. 升级openpyxl到最新版本
旧版本openpyxl的keep_vba=True存在bug,会导致VBA代码丢失,先执行升级:
pip install --upgrade openpyxl
2. 优化工作表修改逻辑
不要直接删除所有行(可能破坏VBA关联的工作表结构),改为清空单元格内容:
# 替换原删除行的代码 for row in sheet.iter_rows(min_row=sheet.min_row, max_row=sheet.max_row): for cell in row: cell.value = None
3. LibreOffice UNO备选方案
如果openpyxl仍无法保留宏,可借助Linux原生支持的LibreOffice API操作文件:
- 先安装依赖:
sudo apt install libreoffice libreoffice-pyuno
- 核心操作示例:
import uno import os from com.sun.star.beans import PropertyValue import pandas as pd all_data = pd.read_csv('full.csv') file_path = 'data.xlsm' # 启动LibreOffice服务 local_context = uno.getComponentContext() resolver = local_context.ServiceManager.createInstanceWithContext( "com.sun.star.bridge.UnoUrlResolver", local_context ) ctx = resolver.resolve("uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext") smgr = ctx.ServiceManager desktop = smgr.createInstanceWithContext("com.sun.star.frame.Desktop", ctx) # 打开XLSM文件(隐藏窗口) file_url = uno.systemPathToFileUrl(os.path.abspath(file_path)) props = (PropertyValue("Hidden", 0, True, 0),) wb = desktop.loadComponentFromURL(file_url, "_blank", 0, props) sheet = wb.getSheets().getByName("Sheet1") # 清空数据 sheet.clearContents() # 写入表头 header = all_data.columns.tolist() for col_idx, val in enumerate(header): sheet.getCellByPosition(col_idx, 0).setValue(val) # 批量写入数据 for row_idx, row in all_data.iterrows(): for col_idx, val in enumerate(row.tolist()): sheet.getCellByPosition(col_idx, row_idx+1).setValue(val) # 保存并关闭 wb.store() wb.dispose()
二、优化15万行数据写入速度
逐单元格写入是效率最低的方式,以下两种方法可将写入时间压缩至几分钟内:
1. 使用openpyxl的append批量写入
# 清空内容后,批量追加行 rows = dataframe_to_rows(all_data, index=False, header=True) for row in rows: sheet.append(row)
2. 结合pandas to_excel批量写入
# 清空工作表内容 for row in sheet.iter_rows(min_row=sheet.min_row, max_row=sheet.max_row): for cell in row: cell.value = None # 用pandas直接写入,利用其批量优化 all_data.to_excel( file_path, sheet_name='Sheet1', engine='openpyxl', index=False, startrow=sheet.min_row-1 # 从第一行开始覆盖 )
完整优化脚本示例
import pandas as pd from openpyxl import load_workbook all_data = pd.read_csv('full.csv') file_path = 'data.xlsm' # 加载工作簿并保留VBA wb = load_workbook(filename=file_path, keep_vba=True) sheet = wb['Sheet1'] # 清空单元格内容(保留结构) for row in sheet.iter_rows(min_row=sheet.min_row, max_row=sheet.max_row): for cell in row: cell.value = None # 批量写入数据 rows = dataframe_to_rows(all_data, index=False, header=True) for row in rows: sheet.append(row) # 保存工作簿 wb.save(file_path)
内容的提问来源于stack exchange,提问作者Tendekai Muchenje
相关产品推荐
相关产品推荐

