Powershell针对Excel的一些简单操作
稍微高级点的语言都会涉及到对COM对象的操作,作为微软自己进化的脚本语言,powershell有这个功能一点不稀奇,首先它使用 .NET Framework 提供的强大类库,很多特性和C#相似;其次,虽然作为脚本但它面向对象。使用powershell来管理WMI和COM更简单。
用微软官方的话概括powershell就是:
Windows PowerShell™ 是一种基于任务的命令行 shell 和脚本语言,专门用于管理系统。 Windows PowerShell™ 构建于 .NET Framework 之上,能够帮助 IT 专业人员和高级用户控制和自动管理 Windows 操作系统以及在 Windows 上运行的应用程序。
内置 Windows PowerShell 命令(称为 cmdlet)可用于通过命令行管理企业中的计算机。使用 Windows PowerShell™ Provider,您可以像访问文件系统那样轻松地访问数据存储,如注册表和证书存储。 此外,Windows PowerShell™ 还具有一个功能丰富的表达式分析程序和一种经过充分开发的脚本语言。
下面介绍powershell对excel的简单操作。
首先,我执行一条命令来获取系统当前正在运行的所有进程:
Get-Process cmdlet显示当前本地进程运行状态,包括处于打开状态的句柄数量、各种内存占用视图以及 CPU 使用率的快照。powershell和Linux shell一个很大的不同点就是大小写不敏感,无论是系统函数还是命令。这点可以减少犯错的概率。
您可能疑惑为什么讲这个?对于系统管理员来说,冗长的数据背后隐藏着大量细节,get-process是获取本地进程运行情况,当然加上-computername参数后可以访问远程计算机,但目前这个对于网络管理员来说犹如海市蜃楼,所以不得不使用windows WMI和 Win32_Process WMI 类来监视远程系统并以实用方式显示信息。如果认为 Get-Process 的输出内容非常丰富,请再仔细看看 Win32_Process 的输出:
很明显,这个输出很详细,但是可读性不强,管理员需要的是易于阅读的内存占用量报告。可以转用Excel实现自动操作。
自动化 Excel 有多难?实际上非常简单,因为 Microsoft 已创建了专门用于处理 Excel 的自动化模型。程序 ID 是 Excel.Application,它是一个 COM 对象。创建 Excel.Application 对象的实例时,Excel 会默认启动并运行,只是您看不见它。但是,可使用 visible 属性让 Excel 显示出来。
以下代码显示了如何创建 Excel.Application 对象、查询 visible 属性的状态,然后将 visible 属性设为 true:
然后,您会看到一个非常奇怪的 Excel 视图,它看起来就像 Excel 应用程序的一个外壳(如下图)。没有工作簿、没有电子表格,—个是光秃秃的 Excel。
当然,这个肯定是无法使用的,但是它是建立工作簿的前提,它是存放工作簿的容器。现在我们需要将一个工作簿添加到应用程序中。为此,需要借助工作簿对象的 add 方法。工作簿对象是从主 Excel.Application 对象进行访问的,正如您看到的,我们将工作簿对象存储在一个名为 $workbook 的变量中:
现在,需连接特定的电子表格。默认情况下,工作簿添加到 Excel 时,会向其中添加三个电子表格(sheet1,sheet2,sheeet3)。这些电子表格可通过数字进行标识。在以下代码行中,连接第一个电子表格并将返回的电子表格对象存储在名为 $sheet 的变量中:
现在我再运行一次$excel.Visible = $true来查看excel变成什么样了(建好了工作簿并且选择了sheet1):
现在,可将数据写入该电子表格。Excel 电子表格中的信息存储在单元格中。由于单元格位于电子表格之中,所以可使用 $sheet 变量中存储的电子表格对象访问特定的单元格。具体方法是使用指代电子表格中行和列的数字。在 Excel 电子表格中,行是数字而列是字母,这一点有些让人迷惑。但使用自动化模型时,行和列均为数字。第一个数字是行,第二个数字是列。只需对特定单元格进行赋值即可写入单元格:
这时,您再运行$excel.Visible = $true,查看excel变成啥样了:
嗯,意料之中,Excel 的一个不足是工作簿始终会创建三个电子表格,这有点浪费,因为我现在这个测试只需要第一个sheet。幸运的是,可利用自动化删除多余的电子表格:使用工作表集合连接第三个电子表格并调用 delete 方法。执行相同的操作删除第二个电子表格:
以上测试过程的代码如下:
下面我们开始将process中的内容移植到excel中。
电子表格的第一行将包含标头信息。将绘制边框并使属性名称显示为粗体。由于数据将从第二行开始,因此将值 2 赋给计数器变量 $x:
完成后,通过使用 item 方法选择单元格并指定行和列的坐标,向第一行赋值。接下来,使用直接赋值写入列标题:
以上结果是我电脑里正在运行的进程。我只选择了两个字段显示。
关于整个脚本的代码,如下:
$workbook.Worksheets.item(1).name="Processes"
$sheet = $workbook.WorkSheets.Item("Processes")
$x = 2
$lineStyle = "microsoft.office.interop.excel.xlLineStyle" -as [type]
$colorIndex = "microsoft.office.interop.excel.xlColorIndex" -as [type]
$borderWeight = "microsoft.office.interop.excel.xlBorderWeight" -as [type]
$chartType = "microsoft.office.interop.excel.xlChartType" -as [type]
for($b = 1 ; $b -le 2 ; $b++)
{
$sheet.cells.item(1,$b).font.bold = $true
$sheet.cells.item(1,$b).borders.LineStyle = $lineStyle::xlDashDot
$sheet.cells.item(1,$b).borders.ColorIndex = $colorIndex::xlColorIndexAutomatic
$sheet.cells.item(1,$b).borders.weight = $borderWeight::xlMedium
}
$sheet.cells.item(1,1) = "Name of Process"
$sheet.cells.item(1,2) = "Working Set Size"
foreach($process in $processes)
{
$sheet.cells.item($x, 1) = $process.name
$sheet.cells.item($x,2) = $process.workingSet
$x++
} #end foreach
$range = $sheet.usedRange
$range.EntireColumn.AutoFit() | out-null
关于powershell写入excel的简单知识先介绍到这,其实,在运行的过程的中您会发现,进程中的每个字段填入excel的过程是非常缓慢的,因为它是一个cell一个cell填入的,而不是一下子拷贝到excel中的,这些将在之后的随笔中介绍。
备注:这篇随笔是参考微软官方的一片博客并加入自己的理解写的,后续还将会简单介绍powershell操作excel&CSV的其它应用。
如有错误,欢迎指正,谢谢!
新闻热点
疑难解答
图片精选