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

使用Spire.XLS处理XLSM文件后宏代码丢失的技术求助

解决XLSM文件修改后宏代码丢失的C#方案

方案1:Spire.XLS内置VBA项目保留API

Spire.XLS提供VbaProject属性可直接读取、写入宏项目,提取原文件的VBA字节流后注入修改后的文件,能完整保留类模块、窗体后台代码等所有宏内容。

示例代码:

using Spire.Xls;

// 读取原文件并提取VBA项目字节流
var originalWb = new Workbook();
originalWb.LoadFromFile("your_file.xlsm");
byte[] vbaBytes = originalWb.VbaProject.ToBytes();

// 加载文件并执行修改操作
var modifiedWb = new Workbook();
modifiedWb.LoadFromFile("your_file.xlsm");
// 示例修改:更新单元格内容、合并单元格
modifiedWb.Worksheets[0].Range["A1"].Text = "Updated Content";
modifiedWb.Worksheets[0].Range["A1:C1"].Merge();

// 注入原VBA项目
modifiedWb.VbaProject.LoadFromBytes(vbaBytes);

// 保存为启用宏的XLSM格式
modifiedWb.SaveToFile("modified_file.xlsm", ExcelVersion.Version2016);

注意:若当前Spire.XLS版本对类模块支持有限,可尝试升级至最新版本。

方案2:Spire.XLS + OpenXML 完整保留VBA部件

如果Spire内置API无法处理复杂宏结构,可结合OpenXML复制原文件的所有VBA相关部件到修改后的文件,确保宏代码100%保留。

示例代码:

using Spire.Xls;
using DocumentFormat.OpenXml.Packaging;

// 步骤1:用Spire修改内容并保存临时文件
string tempPath = "temp_modified.xlsm";
var workbook = new Workbook();
workbook.LoadFromFile("your_file.xlsm");
// 执行自定义修改操作
workbook.Worksheets[0].Range["D5"].Value = "New Value";
workbook.Worksheets[0].Range["D5:E5"].Merge();
workbook.SaveToFile(tempPath, ExcelVersion.Version2016);

// 步骤2:用OpenXML复制原文件的VBA部件到临时文件
using (var originalDoc = SpreadsheetDocument.Open("your_file.xlsm", false))
using (var modifiedDoc = SpreadsheetDocument.Open(tempPath, true))
{
    var originalVbaPart = originalDoc.WorkbookPart.VbaProjectPart;
    if (originalVbaPart == null) return;

    // 删除修改后文件的空VBA部件(若存在)
    var existingVbaPart = modifiedDoc.WorkbookPart.VbaProjectPart;
    if (existingVbaPart != null)
    {
        modifiedDoc.WorkbookPart.DeletePart(existingVbaPart);
    }

    // 复制原VBA项目及所有模块
    var newVbaPart = modifiedDoc.WorkbookPart.AddPart<VbaProjectPart>(originalVbaPart);
    foreach (var module in originalVbaPart.VbaModules)
    {
        newVbaPart.AddPart(module.OpenXmlPart, module.RelationshipId);
    }

    // 同步宏签名属性
    modifiedDoc.WorkbookPart.Workbook.WorkbookProperties.VbaProjectSigned = 
        originalDoc.WorkbookPart.Workbook.WorkbookProperties.VbaProjectSigned;
}

// tempPath即为保留完整宏的最终文件

方案3:修正Interop.Excel复制合并单元格的用法

你提到的Interop.Excel无法复制合并单元格是用法问题,以下代码可正确复制含合并单元格的区域并保留宏:

using Microsoft.Office.Interop.Excel;
using System;

var excelApp = new Application { Visible = false };
try
{
    var originalBook = excelApp.Workbooks.Open("your_file.xlsm");
    var newBook = excelApp.Workbooks.Add();

    // 复制整个工作表(含合并单元格和格式)
    originalBook.Worksheets[1].Copy(newBook.Worksheets[1]);

    // 执行内容修改
    newBook.Worksheets[1].Range["A1"].Value = "Modified Text";

    // 保存为启用宏的格式
    newBook.SaveAs("modified_file.xlsm", XlFileFormat.xlOpenXMLWorkbookMacroEnabled);
}
catch (Exception ex)
{
    Console.WriteLine(ex.Message);
}
finally
{
    excelApp.Quit();
    System.Runtime.InteropServices.Marshal.ReleaseComObject(excelApp);
}

若只需复制特定区域:

Range sourceRange = originalBook.Worksheets[1].Range["A1:B2"];
Range targetRange = newBook.Worksheets[1].Range["A1"];
sourceRange.Copy();
targetRange.PasteSpecial(XlPasteType.xlPasteAll); // 保留所有格式(含合并单元格)

内容的提问来源于stack exchange,提问作者BWhite

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 14:52:18