使用打包将宏文件添加到 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 的建议:
打开一个新工作簿并输入您的宏。将扩展名更改为
zip,打开,打开xl
文件夹,复制出vbaProject.bin
到容易找到的地方。
在您的 .Net 代码中,制作一个新的部件并将其添加到包中
'xl/vbaProject.bin'。从
vbaProject.bin
你在上面提取了。它会像你一样被压缩
添加字节。
然后您必须向指向的工作簿添加一个关系
你的新文件。您可以在中找到这些关系
xl/_rels/workbook.xml.rels
.
您还必须在
文件,进入 [Content Types].xls
。当您使用 CreatePart
的 ContentType 参数时会自动发生这种情况
最后,将扩展名更改为 .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
我正在使用 System.IO.Packaging
构建简单的 Excel 文件。我们的一位客户想要一个自动运行宏来更新数据并重新计算 sheet。
拆开现有的 sheets 我可以看到您需要做的就是添加 vbaProject.bin
文件并更改 _rels 中的一些类型。所以我在一个文件中制作了宏,提取了 vbaProject.bin
,将其复制到另一个文件中,转眼之间,就有了宏。
我知道如何添加 XML 格式的包部分,例如 sheets 或工作簿本身,但我从未添加过二进制文件,我不能想办法。有人做过吗?
好的,我知道了。按照 TnTinMn 的建议:
打开一个新工作簿并输入您的宏。将扩展名更改为 zip,打开,打开
xl
文件夹,复制出vbaProject.bin
到容易找到的地方。在您的 .Net 代码中,制作一个新的部件并将其添加到包中 'xl/vbaProject.bin'。从
vbaProject.bin
你在上面提取了。它会像你一样被压缩 添加字节。然后您必须向指向的工作簿添加一个关系 你的新文件。您可以在中找到这些关系
xl/_rels/workbook.xml.rels
.您还必须在 文件,进入
[Content Types].xls
。当您使用 CreatePart 的 ContentType 参数时会自动发生这种情况
最后,将扩展名更改为 .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