You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 12:43:13