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

Vb.net 使用打包将宏文件添加到XLSX/XLSM文件,vb.net,excel,system.io.packaging,vba,Vb.net,Excel,System.io.packaging,Vba,我正在使用System.IO.Packaging构建简单的Excel文件。我们的一位客户希望有一个自动运行宏来更新数据并重新校准工作表 拆开现有的工作表,我可以看到您所需要做的就是添加vbaProject.bin文件,并在_rels中更改一些类型。因此,我在一个文件中创建了宏,提取了vbaProject.bin,将其复制到另一个文件中,然后就是宏 我知道如何添加XML格式的包部件,比如工作表或工作簿本身,但我从来没有添加过二进制文件,我也弄不清楚。以前有人做过吗?好的,我知道了。根据TNTINN

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

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


我知道如何添加XML格式的包部件,比如工作表或工作簿本身,但我从来没有添加过二进制文件,我也弄不清楚。以前有人做过吗?

好的,我知道了。根据TNTINN的建议:

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

  • 在.Net代码中,创建一个新部件并将其添加到包中,如下所示: “xl/vbaProject.bin”。从数据库中逐字节复制
    vbaProject.bin
    您在上面提取的。它将被压缩,因为你 添加字节

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

  • 您还必须在 文档,它进入
    [内容类型].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
    

    总的来说,这超出了我的范围,但是在标题中,您要求将宏文件添加到
    xslx
    文件中,但是
    xlsx
    文件不能保存宏文件。只有
    xlsm
    xlsb
    (和加载项/模板文件)如果传入了宏文件,我才更改扩展名。
    我在一个文件中创建了宏,提取了vbaProject.bin,将其复制到另一个文件中,然后就是宏
    ——让您随心所欲地工作。为什么您不能像对待zip文件一样对待包,并使用您选择的.Net zip库包含“vbaProject.bin”文件?实际上,这是一个很好的问题。。。让我们看看。注意:如果宏引用了新文件中不存在的工作表名称,它将使用这些名称创建不可见的工作表。这不是一个大问题,但您可以通过确保在宏中引用的任何名称也在新书中来避免它。我有非常类似的逻辑,但是对于我的更新程序,我也通过VBA证书签名进行复制。如果也要执行此操作,请确保复制“vbaProjectSignature.bin”、“VBAProjectSignatureFile.bin”和“\u rels\vbaProject.bin.rels”文件,并确保这些新文件在“[Content\u Types].xml”中有对签名的引用。