2016-09-07 4 views
0

У меня есть сценарий powershell, который читается в csv, а затем добавляется к листу Excel. Он работает довольно болезненно медленно. Я искал, и, похоже, это ограничение использования ком для записи в excel. Некоторые предложения, которые я нашел, чтобы ускорить это, - это выписывать целые диапазоны вместо ячейки по ячейке. Однако мне нужно отформатировать ячейки, и, похоже, это невозможно сделать при записи диапазонов. Любые предложения по оптимизации приведенного ниже кода будут приветствоваться. У меня нет возможности использовать БД.Ускоренный способ записи в excel в powershell

$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

Существует Powershell командлет можно установить под названием Export-XLSX, который работает очень похоже на родной 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' 

UPDATE: Сопоставив этот вариант с полным модулем PSExcel, представленным в другом ответе, я предпочитаю модуль PSExcel. По сравнению с моим тестированием скорость передачи данных во многом одинакова, но модуль PSExcel создает гораздо меньшие файлы.

Например, используя приведенный выше список каталогов Windows, выдает файл 53KB с помощью Export-XLSX.ps1 на моей машине. Однако модуль PSExcel выводит файл 7 КБ. Учитывая его простоту использования, я бы пошел с ним.