更快捷地写出在PowerShell中表现出色的方式

时间:2016-09-07 12:53:39

标签: excel powershell

我有一个PowerShell脚本,它读入csv然后附加到excel工作表。 它的运行非常缓慢。我搜索过,似乎这是使用com写入excel的限制。我发现加快这一点的一些建议是写出整个范围而不是逐个单元格。但是我需要格式化单元格,在写出范围时似乎不可能这样做。有关如何优化以下代码的任何建议都将受到欢迎。 我没有选择使用数据库。

$csvPath = "Z:\script_test\"
$outputFile = "Z:\script_test\exceltest.xlsx"

foreach($csvFile in Get-ChildItem $csvPath -Filter "STATS*.txt" ){
$csvFilePath = [io.path]::combine($csvPath, $csvFile)
$rawcsvData = Import-Csv -Delimiter ";" -Path $csvFilePath 

$Excel = New-Object -ComObject excel.application 
$Excel.visible = $false 
$workbook = $Excel.workbooks.Open($outputFile)
$ExcelWorkSheet = $Excel.WorkSheets.item("2016")
$ExcelWorkSheet.activate()

$excel.cells.item(1,1) = “PEX” 
$excel.cells.item(1,2) = “RUN DATE” 
$excel.cells.item(1,3) = “EXECS” 
$excel.cells.item(1,4) = “CPU AV.” 
$excel.cells.item(1,5) = “CPU HI.” 
$excel.cells.item(1,6) = “CPU TOT.” 
$excel.cells.item(1,7) = “#VALUE!” 
$excel.cells.item(1,8) = “ELAPS AV.” 
$excel.cells.item(1,9) = “ELAPSE HI.” 
$excel.cells.item(1,10) = “ELAPSE TOT”


$i = $ExcelWorkSheet.UsedRange.rows.count + 1

foreach($rawcsv in $rawcsvData) 

{ 

$RUNDATE = $rawcsv.“RUN DATE     ”.replace("--1","") 
$EXECS = $rawcsv."EXECS ".replace("?","") 
$CPUAV = $rawcsv.“CPU AV.   ”.replace("-",":") 
$CPUHI = $rawcsv.“CPU HI.   ”.replace("-",":")   
$CPUTOT = $rawcsv.“CPU TOT.  ”.replace("-",":")  
$ELAPSEAV = $rawcsv.“ELAPSE AV.”.replace("-",":") 
$ELAPSEHI = $rawcsv.“ELAPSE HI.”.replace("-",":")  
$ELPASETOT = $rawcsv.“ELPASE TOT”.replace("-",":") 
Write-Output("working" + $i)
$excel.cells.item($i,1) = $rawcsv."PEX " 
$excel.cells.item($i,2) = $RUNDATE    
$excel.cells.item($i,2).NumberFormat = “yyyy/mm/dd”
$excel.cells.item($i,3) = $EXECS 
$excel.cells.item($i,4) = $CPUAV  
$excel.cells.item($i,4).NumberFormat = “hh:mm:ss.00”
$excel.cells.item($i,5) = $CPUHI   
$excel.cells.item($i,5).NumberFormat = “hh:mm:ss.00”
$excel.cells.item($i,6) = $CPUTOT 
$excel.cells.item($i,6).NumberFormat = “hh:mm:ss.00”
$excel.cells.item($i,7) = “=((HOUR(F"+$i+")*3600)+(MINUTE(F"+$i+")*60)+SECOND(F"+$i+"))*21” 
$excel.cells.item($i,8) = $ELAPSEAV
$excel.cells.item($i,8).NumberFormat = “hh:mm:ss.00”
$excel.cells.item($i,9) = $ELAPSEHI 
$excel.cells.item($i,9).NumberFormat = “hh:mm:ss.00”
$excel.cells.item($i,10) = $ELPASETOT
$excel.cells.item($i,10).NumberFormat = “hh:mm:ss.00”

$i++
}
$ExcelWorkSheet.UsedRange.RemoveDuplicates()
#$workbook.saveas($outputFile) 
$workbook.save()
$Excel.Quit() 
Remove-Variable -Name excel 
[gc]::collect() 
[gc]::WaitForPendingFinalizers() 
Move-Item -Path $csvFilePath -Destination "Z:\script_test\used files"
}

2 个答案:

答案 0 :(得分:1)

慢速部分是关于COM对象性能的。如果你继续使用COM对象,你将无法加快速度,遗憾的是。

早在几天我有一些与Excel相关的项目,我发现了一些使用外部DLL的很棒的模块,你可以看看它:PSExcel

最重要的是,您不需要安装Excel,就像使用COM对象一样。

答案 1 :(得分:0)

您可以安装名为Export-XLSX的Powershell cmdlet,其工作方式与原生Export-CSV非常相似:https://gallery.technet.microsoft.com/office/Export-XLSX-PowerShell-f2f0c035

这里的文档非常好,但这里有一个如何使用它的例子:

# 1. Define path of Export-XLSX.ps1 script:
$ExportXLSX = "C:\YourFilePath\Export-XLSX\Export-XLSX.ps1"

# 2. Call script same as any other function by preceding filename with a period (.$ExportXLSX) and following it with parameters:
Get-ChildItem $env:windir | Select-Object Mode,LastWriteTime,Length,Name | .$ExportXLSX -Path 'c:\temp\PSExcel.xlsx' -WorkSheetName 'Files'

更新:将此选项与其他答案中提供的完整PSExcel模块进行比较后,我实际上更喜欢PSExcel模块。在我的测试中,速度方面的性能几乎相同,但PSExcel模块似乎创建了更小的文件。

例如,使用上面的windows目录列表,使用我机器上的Export-XLSX.ps1输出53KB文件。但是,PSExcel模块输出7KB文件。鉴于其易用性,我会继续使用它。