PowerShell操作Excel、CSV详细介绍

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:

代码如下:

PS > $excel = New-Object -ComObject Excel.Application   ==>创建一个excel应用的COM对象
PS > $excel.Visible    ==>默认新建的excel视图不显示,即没有打开
False
PS > $excel.Visible = $true    ==>看到下面的界面

  然后,您会看到一个非常奇怪的 Excel 视图,它看起来就像 Excel 应用程序的一个外壳(如下图)。没有工作簿、没有电子表格,—个是光秃秃的 Excel。

当然,这个肯定是无法使用的,但是它是建立工作簿的前提,它是存放工作簿的容器。现在我们需要将一个工作簿添加到应用程序中。为此,需要借助工作簿对象的 add 方法。工作簿对象是从主 Excel.Application 对象进行访问的,正如您看到的,我们将工作簿对象存储在一个名为 $workbook 的变量中:

代码如下:

$workbook = $excel.Workbooks.add()   ==>现在添加了一个空的工作簿

现在,需连接特定的电子表格。默认情况下,工作簿添加到 Excel 时,会向其中添加三个电子表格(sheet1,sheet2,sheeet3)。这些电子表格可通过数字进行标识。在以下代码行中,连接第一个电子表格并将返回的电子表格对象存储在名为 $sheet 的变量中:

代码如下:

$sheet = $workbook.worksheets.Item(1)   ==>表示我使用的是第一个sheet

现在我再运行一次$excel.Visible = $true来查看excel变成什么样了(建好了工作簿并且选择了sheet1):

现在,可将数据写入该电子表格。Excel 电子表格中的信息存储在单元格中。由于单元格位于电子表格之中,所以可使用 $sheet 变量中存储的电子表格对象访问特定的单元格。具体方法是使用指代电子表格中行和列的数字。在 Excel 电子表格中,行是数字而列是字母,这一点有些让人迷惑。但使用自动化模型时,行和列均为数字。第一个数字是行,第二个数字是列。只需对特定单元格进行赋值即可写入单元格:

代码如下:

$sheet.cells.item(1,1) = "Test"   ==>我在第一个单元格填入“Test”

这时,您再运行$excel.Visible = $true,查看excel变成啥样了:

嗯,意料之中,Excel 的一个不足是工作簿始终会创建三个电子表格,这有点浪费,因为我现在这个测试只需要第一个sheet。幸运的是,可利用自动化删除多余的电子表格:使用工作表集合连接第三个电子表格并调用 delete 方法。执行相同的操作删除第二个电子表格: 

代码如下:

$workbook.workSheets.item(3).delete()
$workbook.WorkSheets.item(2).delete()

   这样只剩下sheet1了,接下来,重命名剩余的电子表格。这一点非常重要,因为如果决定使用 ActiveX 数据对象 (ADO) 来查询 Excel 电子表格,将在连接字符串中使用此电子表格名称。因此,要使代码易读且直观,电子表格应具有逻辑名称。要重命名电子表格,只需向特定电子表格的 name 属性赋一个值即可。以下代码将第一个电子表格重命名为 "Processes": 

代码如下:

$workbook.WorkSheets.item(1).Name = "Processes"

  现在,需连接重命名后的电子表格。使用工作表对象的 Item 方法并将电子表格的名称指定给它: 

代码如下:

$sheet = $workbook.WorkSheets.Item("Processes")

   这时我们再查看excel的样子:

以上测试过程的代码如下:

代码如下:

$excel = New-Object -ComObject Excel.Application
#$excel.Visible = $true
$workbook = $excel.Workbooks.add()
$sheet = $workbook.worksheets.Item(1)
$sheet.cells.item(1,1) = "Test"
$workbook.workSheets.item(3).delete()
$workbook.WorkSheets.item(2).delete()
$workbook.WorkSheets.item(1).Name = "Processes"
$excel.Visible = $true

下面我们开始将process中的内容移植到excel中。
 
  电子表格的第一行将包含标头信息。将绘制边框并使属性名称显示为粗体。由于数据将从第二行开始,因此将值 2 赋给计数器变量 $x:

代码如下:

$x=2

   接下来的四行代码创建四个枚举类型。枚举类型用于告诉 Excel 允许将哪些值填入特定的选项类型。例如,xlLineStyle 枚举用于确定所绘制线条的类型:双线条、虚线等。MSDN 上详细介绍了这些枚举值。
为使代码更易于阅读,针对将使用的每个枚举类型创建一个快捷别名。实际上,我们将把代表枚举名称的字符串转换成 [type]。 

代码如下:

$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]

  现在需格式化第一行。使字体为粗体,将线条定义为 xlDashDot,允许自动指定颜色,并将边框宽度设为中等粗细:

代码如下:

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
}

完成后,通过使用 item 方法选择单元格并指定行和列的坐标,向第一行赋值。接下来,使用直接赋值写入列标题:

代码如下:

$sheet.cells.item(1,1) = "Name of Process"
$sheet.cells.item(1,2) = "Working Set Size"

  现在,需将 WMI 查询产生的 $processes 变量中存储的进程信息放入适当的单元格中。使用 foreach 语句遍历进程信息集合。将变量 $process 定义为集合枚举器(占位符),并选择将名称和 workingSetSize 属性分别写入第一列和第二列。$x 变量将在此发挥作用。从第二行开始,在遍历进程集合的同时,递增 $x 变量的值以便它始终指向集合中的当前行。通过以下代码,即可对 $processes 进程信息集合中存储的所有数据进行整理分类: 

代码如下:

foreach($process in $processes)
{
 $sheet.cells.item($x, 1) = $process.name
 $sheet.cells.item($x,2) = $process.workingSetSize
 $x++
}

  填写完 Excel 电子表格后,可以调整列的大小以使单元格与其中所存储数据的尺寸相同。为此,可通过指定要使用的列坐标来创建一个范围;但是,也可以只使用电子表格的 usedRange 属性。创建完范围对象后,选择 EntireColumn 属性并使用 AutoFit 方法调整列的大小。由于该方法始终会返回数据,我将结果传送给 Out-Null cmdlet。从而避免控制台上布满了杂乱无用的信息。下面是所用的代码:

代码如下:

$range = $sheet.usedRange
$range.EntireColumn.AutoFit() | out-null

  至此,已完成所有任务此时的电子表格具有所有进程的名称和内存工作集,相当不错。来看看完成后的成果:

以上结果是我电脑里正在运行的进程。我只选择了两个字段显示。

关于整个脚本的代码,如下:

代码如下:

$processes=Get-Process
$excel = New-Object -ComObject Excel.Application
#$excel.Visible = $true
$workbook = $excel.Workbooks.add()
$sheet = $workbook.worksheets.Item(1)
$workbook.Worksheets.item(3).delete()
$workbook.Worksheets.item(2).delete()

$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的其它应用。

  如有错误,欢迎指正,谢谢!

(0)

相关推荐

  • PowerShell操作Excel、CSV详细介绍

    Powershell针对Excel的一些简单操作 稍微高级点的语言都会涉及到对COM对象的操作,作为微软自己进化的脚本语言,powershell有这个功能一点不稀奇,首先它使用 .NET Framework 提供的强大类库,很多特性和C#相似:其次,虽然作为脚本但它面向对象.使用powershell来管理WMI和COM更简单. 用微软官方的话概括powershell就是: Windows PowerShell™ 是一种基于任务的命令行 shell 和脚本语言,专门用于管理系统. Windows

  • Java I/O 操作及优化详细介绍

    概要: 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象.即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作. Java I/O I/O,即 Input/Output(输入/输出) 的简称.就 I/O 而言,概念上有 5 种模型:blocking I/O,nonblocking I/O,I/O multiplexing (select and poll),signal driven I/O (SIGIO),asynchr

  • python操作xml文件详细介绍

    关于python读取xml文章很多,但大多文章都是贴一个xml文件,然后再贴个处理文件的代码.这样并不利于初学者的学习,希望这篇文章可以更通俗易懂的教如何使用python 来读取xml 文件. 一.什么是xml? xml即可扩展标记语言,它可以用来标记数据.定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言. abc.xml 复制代码 代码如下: <?xml version="1.0" encoding="utf-8"?> <catalo

  • Swift中的指针操作和使用详细介绍

    Apple期望在Swift中指针能够尽量减少登场几率,因此在Swift中指针被映射为了一个泛型类型,并且还比较抽象.这在一定程度上造成了在Swift中指针使用的困难,特别是对那些并不熟悉指针,也没有多少指针操作经验的开发者(包括我自己也是)来说,在Swift中使用指针确实是一个挑战.在这篇文章里,我希望能从最基本的使用开始,总结一下在Swift中使用指针的一些常见方式和场景.这篇文章假定你至少知道指针是什么,如果对指针本身的概念不太清楚的话,可以先看看这篇五分钟C指针教程(或者它的中文版本),应

  • python利用xlsxwriter模块 操作 Excel

    xlsxwriter 简介 用于以 Excel 2007+ XLSX 文件格式编写文件,相较之下 PhpSpreadsheet 支持更多的格式读写. 优点 文本,数字和公式写入,速度很快,占用内存小 支持诸如格式设置,图像,图表,页面设置,自动过滤器,条件格式设置等功能 缺点 无法读取或修改现有的 Excel XLSX 文件 演示 其使用流程,与你使用 excel 流程一致,只不过将你主步骤分解成了一个个对象实例来操作,通过引用实现操作关联 import xlsxwriter # 1.创建工作簿

  • C# 基于NPOI操作Excel

    目录 1 单元格下拉框 2 添加批注 3 读取数据 结语 常见问题解决 NPOI 导出添加批注功能 POI导出Excel时下拉列表值超过255的问题 日期格式导入混乱 注意 1 单元格下拉框 在开发中我们会遇到为单元格设置下拉框.一般可以编写如下: var cellRanges = new CellRangeAddressList(firstRow, lastRow, firstCol, latsCol); DVConstraint constraint = DVConstraint.Creat

  • powershell玩转sqlite数据库详细介绍

    脚本经常需要处理文本,有时候是行列整齐文本.那么powershell脚本处理行列文本有几种方法呢?一种是excel,另外的一些是?access?sqlite? sqlite是一个很小巧的,很方便嵌入到脚本语言中的,关系型数据库.它给powershell提供了一个免费的,处理行列整齐数据,存储数据,统计数据的极品神器. 只要你学会了它,上天入地皆可去得.而且以后学sql server,mysql,都类似,没有难度. 带着引号搜本文关键字: "^_^上天入地皆可去^_^" 发文初衷:世界上

  • 一文教你如何用Python轻轻松松操作Excel,Word,CSV

    目录 Python操作Excel 常用工具 xlrd&xlwt&xlutils介绍 安装库 写入Excel 读取Excel 修改excel 格式转换操作 Python操作Word 安装python-docx 写入Word 读取Word文件 Python操作CSV 简介 基本使用 Python 操作 Excel 常用工具 数据处理是 Python 的一大应用场景,而 Excel 又是当前最流行的数据处理软件.因此用 Python 进行数据处理时,很容易会和 Excel 打起交道.得益于前人的

  • 详解免费高效实用的.NET操作Excel组件NPOI(.NET组件介绍之六)

    很多的软件项目几乎都包含着对文档的操作,前面已经介绍过两款操作文档的组件,现在介绍一款文档操作的组件NPOI. NPOI可以生成没有安装在您的服务器上的Microsoft Office套件的Excel报表,并且在后台调用Microsoft Excel ActiveX更有效率;从Office文档中提取文本,以帮助您实现全文索引功能(大多数时候,此功能用于创建搜索引擎): 从Office文档提取图像: 生成包含公式的Excel工作表.  一.NPOI组件概述: NPOI是完全免费使用: 涵盖Exce

  • Java操作Redis详细介绍

    1. 简介 Redis 是一个开源(BSD许可)的,内存中的key-value存储系统,它可以用作数据库.缓存和消息中间件. 2. 对key的操作 首先要建立连接Jedis jedis = new Jedis("127.0.0.1", 6379),然后就可以对string,set,zset,hash进行操作了. //对key的测试 public void keyTest() { System.out.println(jedis.flushDB()); //清空数据 System.out

随机推荐