2016-09-07 9 views
0

私はcsvで読み込んだ後、Excelワークシートに追加するpowershellスクリプトを用意しています。 これはかなり痛いほど遅く実行されます。私は検索しましたが、これはcomを使ってExcelに書き込むための制限だと思われます。私がこれをスピードアップするために見つけたいくつかの提案は、セルごとにではなく、全体の範囲を書き出すことです。しかし、私はセルをフォーマットする必要があり、範囲を書き出すときにこれを行うことは可能ではないようです。以下のコードを最適化する方法に関する提案は歓迎されます。 DBを使用するオプションがありません。PowerShellで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" 
} 

答えて

1

遅い部分はすべてCOMオブジェクトのパフォーマンスに関するものです。悲しいことに、COMオブジェクトで作業を続けるなら、これを十分にスピードアップすることはできません。

戻る私はExcelに関連するいくつかのプロジェクトを持っていたと私は外部のDLLを使用していくつかの素晴らしいモジュールを見つけた日で、あなたはそれを見てみることができます。PSExcel

最良の部分は、あなたがExcelがインストールされている必要はありませんということですCOMオブジェクトの場合と同様です。

+0

面白そうに見える私はそれに行くだろう –

0

ネイティブ輸出-CSVと非常によく似た働きをしますが、輸出XLSXと呼ばれるインストールすることができますPowerShellコマンドレットがあります: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' 

UPDATEは:他の回答で提示フルPSExcelモジュールでは、このオプションを比較したので、私は実際にPSExcelモジュールを好みます。私のテストではスピードワイズのパフォーマンスはほとんど同じですが、PSExcelモジュールははるかに小さいファイルを作成するようです。

たとえば、上記のWindowsディレクトリのリストを使用すると、マシン上のExport-XLSX.ps1を使用して53KBのファイルが出力されます。ただし、PSExcelモジュールは7KBのファイルを出力します。その使い易さを考えると、私はそれと一緒に行くだろう。

関連する問題