如何在不使用Interop的情况下将VBA代码注入Excel .xlsm?

Sno*_*rex 6 c# excel vba interop excel-vba

我的目标是将宏添加到Excel工作簿,而无需在Excel信任中心中启用"信任访问VBA项目对象模块".(启用访问似乎存在安全风险).

在我最初的事实查找搜索中发现了随机拼图: - 我看到VBA脚本作为vbaProject.bin存储在压缩的.xlsm文件中.- 有几个免费/商业资源可以使用excel文件: 创建excel没有interop和模板,有或没有行和列

如果只是在C#项目中有一个VBA脚本文件,C#代码从中提取并注入到Excel文档而没有VBA互操作,那将是很好的.任何快速/快速/简单/直接的方式,或者我应该使用上面链接的免费/商业资源吗?

Sno*_*rex 6

使用OpenXML SDK 2.0:

  1. 创建你的宏代码并以.xlsm格式保存,比如snorehorse.xlsm.
  2. 在OpenXML Productivity Toolkit中打开snorehorse.xlsm并在树根上执行Reflect Code.
  3. 找到宏的二进制代码.它是字符串格式,看起来像随机字符.
  4. 在IDE中,添加对OpenXML SDK的引用,并以编程方式创建或打开要将宏代码注入的excel文件.
  5. 将步骤3中找到的宏字符串复制到您的代码中.
  6. 将新的vba部件添加到目标.
  7. 将字符串数据提供给新的vba部分.
  8. 保存并运行并很高兴您绕过了信任中心.

示例代码:

using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;

private string partData = "...";

    public void vbaInjector{    
        [code to create / open spreadsheet using OpenXML omitted]
        VbaProjectPart vbaProjectPart1 = snoreSpreadsheetDoc.WorkbookPart.AddNewPart<VbaProjectPart>("rId8");
        System.IO.Stream data = GetBinaryDataStream(partData);
        vbaProjectPart1.FeedData(data);
        data.Close();
        [code to close spreadsheet and cleanup omitted]
    }


    private System.IO.Stream GetBinaryDataStream(string base64String)
    {
        return new System.IO.MemoryStream(System.Convert.FromBase64String(base64String));
    }
Run Code Online (Sandbox Code Playgroud)

我选择将OpenXML SDK dll添加到项目的本地构建中,以便最终用户不必自己安装SDK.

我认为这可以在较低的层次上完成,使用XML,而不使用OpenXML SDK,但我没有尝试学习如何做到这一点.如果有人可以发布代码,我会接受我的答案.

此外,如果有一种编程方式将VBA脚本(在嵌入式资源文件中)转换为excel期望格式的二进制字符串,则可以绕过每次要更改时必须复制并粘贴新的二进制数据字符串宏代码.这对我来说是一个很好的答案.

谢谢.