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的其它應用。
如有錯誤,歡迎指正,謝謝!
作者:
zhoujie出處:
http://www.cnblogs.com/zhoujie/本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,不然我擔心部落格園找你算賬
如果您覺得本文對你有幫助,請豎起您的大拇指右下角點推薦,也可以關注我