使用打包将宏文件添加到 XLSX/XLSM 文件

Adding a macro file to an XLSX/XLSM file using Packaging

我正在使用 System.IO.Packaging 构建简单的 Excel 文件。我们的一位客户想要一个自动运行宏来更新数据并重新计算 sheet。

拆开现有的 sheets 我可以看到您需要做的就是添加 vbaProject.bin 文件并更改 _rels 中的一些类型。所以我在一个文件中制作了宏,提取了 vbaProject.bin,将其复制到另一个文件中,转眼之间,就有了宏。

我知道如何添加 XML 格式的包部分,例如 sheets 或工作簿本身,但我从未添加过二进制文件,我不能想办法。有人做过吗?

好的,我知道了。按照 TnTinMn 的建议:

  1. 打开一个新工作簿并输入您的宏。将扩展名更改为 zip,打开,打开xl文件夹,复制出vbaProject.bin 到容易找到的地方。

  2. 在您的 .Net 代码中,制作一个新的部件并将其添加到包中 'xl/vbaProject.bin'。从 vbaProject.bin 你在上面提取了。它会像你一样被压缩 添加字节。

  3. 然后您必须向指向的工作簿添加一个关系 你的新文件。您可以在中找到这些关系 xl/_rels/workbook.xml.rels.

  4. 您还必须在 文件,进入 [Content Types].xls。当您使用 CreatePart

  5. 的 ContentType 参数时会自动发生这种情况
  6. 最后,将扩展名更改为 .xlsm 或 .xltm

我从我的代码中的许多地方提取了以下内容,所以这是伪...

'the package...
Dim xlPackage As Package = Package.Open(WBStream, FileMode.Create)
'start with the workbook, we need the object before we physically insert it
Dim xlPartUri As URI = PackUriHelper.CreatePartUri(New Uri(GetAbsoluteTargetUri("/", "xl/workbook.xml"), UriKind.Relative)) 'the URI is relative to the outermost part of the package, /
Dim xlPart As PackagePart = xlPackage.CreatePart(xlPartUri, "application/vnd.ms-excel.sheet.macroEnabled.main+xml", CompressionOption.Normal)
'add an entry in the root _rels folder pointing to the workbook
xlPackage.CreateRelationship(xlPartUri, TargetMode.Internal, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument", "xlWorkbook") 'it turns out the ID can be anything unique
'now that we have the WB part, we can make our macro relative to it
Dim xlMacroUri As URI = PackUriHelper.CreatePartUri(New Uri(GetAbsoluteTargetUri("/xl/workbook.xml", "vbaProject.bin"), UriKind.Relative))
Dim xlMacroPart as PackagePart = xlPackage.CreatePart(xlPartUri, "application/vnd.ms-office.vbaProject", CompressionOption.Normal)
'time we link the vba to the workbook
xlParentPart.CreateRelationship(xlPartUri, TargetMode.Internal, "http://schemas.microsoft.com/office/2006/relationships/vbaProject", "rIdMacro") 'the ID on the macro can be anything as well
'copy over the data from the macro file
Using MacroStream As New FileStream("C:\yourdirectory\vbaProject.bin", FileMode.Open, FileAccess.Read)
    MacroStream.CopyTo(xlMacroPart.GetStream())
End Using
'
'now write data into the main workbook any way you like, likely using new Parts to add Sheets