I'm trying to extend this example using extarnal module to call generic methods. My goal is to create new xls file and write to it.
[Reflection.Assembly]::LoadWithPartialName("DocumentFormat.OpenXml") | Out-Null
[Reflection.Assembly]::LoadWithPartialName("DocumentFormat.OpenXml.Packaging")
[Reflection.Assembly]::LoadWithPartialName("DocumentFormat.OpenXml.Spreadsheet")
[Reflection.Assembly]::LoadWithPartialName("OpenXmlPowerTools")
Import-Module (join-path (Split-Path $MyInvocation.MyCommand.Path) "GenericMethods.psm1")
$document = [DocumentFormat.OpenXml.Packaging.SpreadsheetDocument]::Create("C:\Temp\text.xlsx", [DocumentFormat.OpenXml.SpreadsheetDocumentType]::Workbook)
$workbookPart = $document.AddWorkbookPart();
$workbookPart.Workbook = New-Object -TypeName DocumentFormat.OpenXml.Spreadsheet.Workbook
$worksheetPart = Invoke-GenericMethod -InputObject $workbookPart -MethodName AddNewPart -GenericType DocumentFormat.OpenXml.Packaging.WorksheetPart
$sheetData = New-Object -TypeName DocumentFormat.OpenXml.Spreadsheet.SheetData
$worksheetPart.Worksheet = New-Object -TypeName DocumentFormat.OpenXml.Spreadsheet.Worksheet -ArgumentList $sheetData
[DocumentFormat.OpenXml.Spreadsheet.Sheets]$foo = New-Object -TypeName DocumentFormat.OpenXml.Spreadsheet.Sheets
Invoke-GenericMethod -InputObject $document.WorkbookPart.Workbook -MethodName AppendChild -GenericType DocumentFormat.OpenXml.Spreadsheet.Sheets -ArgumentList $foo
$document.Close()
The problem is that this piece of code
[DocumentFormat.OpenXml.Spreadsheet.Sheets]$foo = New-Object -TypeName DocumentFormat.OpenXml.Spreadsheet.Sheets
Invoke-GenericMethod -InputObject $document.WorkbookPart.Workbook -MethodName AppendChild -GenericType DocumentFormat.OpenXml.Spreadsheet.Sheets -ArgumentList $foo
throws error Invoke-GenericMethod : No matching method was found
. Throws because New-Object
creates something that is treated as empty array by Invoke-GenericMethod
function. So the module is looking for generic methods with no parameters. Note thet first call to Invoke-GenericMethod
is working fine.
How should I call Invoke-GenericMethod
with -ArgumentList
parameter?
The problem with your code is that DocumentFormat.OpenXml.OpenXmlElement
class (base class for DocumentFormat.OpenXml.Spreadsheet.Sheets
) implement IEnumerable
interface. That makes PowerShell interpret any instance of DocumentFormat.OpenXml.Spreadsheet.Sheets
as collection, rather than singular object.
When you write just
$foo
PowerShell will enumerate collection and display child elements instead (to be precise, you will see child of the child, because formatting cmdlets normally do another enumeration of collections). And since you just created this object, it will be empty and nothing will be displayed.
To actually display $foo
object itself, you need to write it like this:
,$foo | Format-Table -Expand CoreOnly
or
,,$foo
The fact, that PowerShell interpret instance of DocumentFormat.OpenXml.Spreadsheet.Sheets
as collection, also affects how conversion to [Object[]]
(type of -ArgumentList
parameter) done. Instead of wrapping into single element array (as you want to call method with single argument), as it happens for singular objects, PowerShell create array from collection's elements.
To solve your issue you need to do wrapping into single element array by yourself. You can do that with unary comma oprator:
-ArgumentList (,$foo)