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

时间:2018-02-05 20:17:21

标签: vb.net excel-vba system.io.packaging vba excel

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

拉开现有工作表我可以看到你需要做的就是添加vbaProject.bin文件并在_rels中更改几种类型。所以我在一个文件中创建了宏,提取了vbaProject.bin,将其复制到另一个文件中,然后就是宏。

我知道如何在XML格式中添加包部件,如工作表或工作簿本身,但我从未添加过二进制文件,我无法弄明白。有人曾经这样做过吗?

1 个答案:

答案 0 :(得分:0)

好的我明白了。遵循TnTinMn的建议:

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

  2. 在.Net代码中,创建一个新的Part并将其添加到Package as ' XL / vbaProject.bin&#39 ;.从中逐字节复制 您在上面提取的vbaProject.bin。它会像你一样被压缩 添加字节。

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

  4. 您还必须在根目录中添加内容类型条目 文档,进入[Content Types].xls。当您使用CreatePart的参数

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

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

    '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