长话短说...我有一个脚本,它使用 RESTful API 从设备中提取配置信息。这个脚本比较长,但是长度无关紧要。
我遇到的问题是,当我设计脚本时,我是在 PS 5.1 中编写的,在 PS5.1 中一切正常。现在,尝试在 PS7 中使用脚本时遇到格式化输出的问题。
我目前使用 COM 对象导出到 Excel,而不是流行的 Import-Excel 模块。我希望它是独立的,并注意需要任何额外的东西。另外,我在编写脚本时并不知道该模块的存在,并且我不想重新设计整个脚本。
初始化 Excel 工作簿后,我会移动活动单元格并根据需要插入数据。所有这些都工作正常。当尝试添加单元格边框时,问题就出现了。
如果您在 PS5.1 中进行测试,您会发现它工作得很好,而在 7 中您会收到有关边框粗细的错误。
除了告诉我重新设计脚本并使用 Import-Excel 之外,任何帮助都将不胜感激。
在此输入
这是要演示的一批快速命令示例。显然,这需要在您的系统上安装 Excel。
$Excel = new-object -comobject excel.application
$Excel.Visible = $true
$ExcelWorkBook = $Excel.Workbooks.Add()
$WorkSheetIndex = 1
$ExcelWorkSheet = $ExcelWorkBook.Worksheets.Item($WorkSheetIndex)
$ExcelWorkSheet.Cells.Item(1, 1) = "Test Data"
#Formatting shortcuts
$lineStyle = "microsoft.office.interop.excel.xlLineStyle" -as [type]
$borderWeight = "microsoft.office.interop.excel.xlBorderWeight" -as [type]
$objRange = $ExcelWorkSheet.UsedRange
$objRange.Borders.LineStyle = $lineStyle::xlNone
$objRange.Borders.weight = $borderWeight::xlThin
$ExcelWorkSheet.Cells.Item(1, 1).Font.Size = 16
$ExcelWorkSheet.Cells.Item(1, 1).Font.Bold = $True
[void] $objRange.EntireColumn.Autofit()
PowerShell 7 错误:
OperationStopped: C:\Work\Internal\GIT\Appliance_Administration\Excel_Test.ps1:15
Line |
15 | $objRange.Borders.weight = $borderWeight::xlThin
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| Unable to set the Weight property of the Borders class
扩展评论,核心问题是表达式
"microsoft.office.interop.excel.xlBorderWeight" -as [type]
在 PowerShell Core 中计算为 $null
。
结果,
$borderWeight
是$null
,这行:
$objRange.Borders.weight = $borderWeight::xlThin
相当于
$objRange.Borders.weight = $null
相比之下,在 Windows PowerShell 中,表达式
"microsoft.office.interop.excel.xlBorderWeight" -as [type]
返回对 xlBorderWeight
类型的引用:
PS> $borderWeight = "microsoft.office.interop.excel.xlBorderWeight" -as [type]
PS> $borderweight
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True XlBorderWeight System.Enum
这是因为 Windows PowerShell 会在 GAC 中搜索程序集,但 PowerShell Core 不会 - 请参阅Windows PowerShell 5.1 和 PowerShell 7.x 之间的差异:
在尝试从 GAC 加载之前从模块基本路径加载程序集
以前,当二进制模块在 GAC 中具有模块程序集时,我们会先从 GAC 加载该程序集,然后再尝试从模块基本路径加载它。
一个快速而肮脏的解决方法是使用枚举的常量值 - 例如
$XlBorderWeight_xlThin = 2;
...
$objRange.Borders.weight = $XlBorderWeight_xlThin
但请注意,您也遇到了同样的问题
$lineStyle = "microsoft.office.interop.excel.xlLineStyle" -as [type]
。
看起来
$objRange.Borders.LineStyle = $null
不会导致错误,而 $objRange.Borders.weight = $null
会导致错误。
添加类型
Add-Type -Path "C:\WINDOWS\assembly\GAC_MSIL\Microsoft.Office.Interop.Excel\15.0.0.0__71e9bce111e9429c\Microsoft.Office.Interop.Excel.dll"
如果您想找到此路径的神奇值,您可以使用 Windows PowerShell 5.1:
PS> ("microsoft.office.interop.excel.xlLineStyle" -as [type]).Assembly.Location
C:\WINDOWS\assembly\GAC_MSIL\Microsoft.Office.Interop.Excel\15.0.0.0__71e9bce111e9429c\Microsoft.Office.Interop.Excel.dll
您需要使用 PowerShell Core 中的硬编码路径。选角
$objRange.Borders.weight
是一个
Variant
值 - 请参阅:
PS> $objRange.Borders | gm
TypeName: System.__ComObject#{00020854-0000-0000-c000-000000000046}
Name MemberType Definition
---- ---------- ----------
... snip ...
Weight Property Variant Weight () {get} {set}
Windows PowerShell 似乎很乐意将 xlBorderWeight
枚举值转换为
Variant
,但 PowerSHell Core不,因此您必须执行类似的操作,而不是通过将枚举强制转换为
int
:
$objRange.Borders.weight = [int]$borderWeight::xlThin
完成所有这些后,您的代码应该最终可以工作......