Добавление файла макроса в файл XLSX/XLSM с помощью Packaging

Я использую System.IO.Packaging создавать простые файлы Excel. Один из наших клиентов хотел бы иметь макрос автозапуска, который обновляет данные и пересчитывает лист.

Разбирая существующие листы, я вижу, что все, что вам нужно сделать, это добавить vbaProject.bin файл и измените несколько типов в _rels. Итак, я сделал макрос в одном файле, извлек vbaProject.binскопировал его в другой файл, и вот, вот макрос.

Я знаю, как добавлять части пакета, когда они в формате XML, такие как листы или сама книга, но я никогда не добавлял двоичный файл и не могу понять это. Кто-нибудь делал это раньше?

1 ответ

Решение

Ладно, я понял. Следуя предложению TnTinMn:

  1. Откройте новую книгу и введите свой макрос. Измените расширение на zip, откройте его, откройте xl папку и скопировать vbaProject.binгде-то легко найти.

  2. В своем коде.Net создайте новую деталь и добавьте ее в пакет как "xl/vbaProject.bin". Копировать побайтово изvbaProject.bin Вы извлечены выше. Он будет сжат при добавлении байтов.

  3. Затем вы должны добавить отношение к книге, которое указывает на ваш новый файл. Вы можете найти эти отношения вxl/_rels/workbook.xml.rels,

  4. Вы также должны добавить запись типа контента в корне документа, которая идет в [Content Types].xls, Это происходит автоматически при использовании параметра ContentType CreatePart

  5. И наконец, измените расширение на.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
Другие вопросы по тегам