【问题标题】:Powershell script using Excel running slow使用 Excel 的 Powershell 脚本运行缓慢
【发布时间】:2016-10-21 08:38:24
【问题描述】:

所以我在笔记本电脑上编写了这个脚本,它工作得很好,工作是将两个 .csv 文件合并到一个 .xls 文件中。 使用两个包含几千行的 .csv 文件运行脚本最多需要几秒钟。

但是当我尝试在它应该位于的服务器上运行它时,它需要......几个小时。我还没有完成完整的运行,但是在 .xls 文件中写入一行可能需要 2-3 秒。

所以我想知道是什么导致运行时间大幅增加。我正在监视脚本运行时的 CPU 负载,它的负载为 50-60%。

服务器有大量的内存和两个 CPU 核心。 我怎样才能加快速度?

脚本如下所示:

$path = "C:\test\*"
$path2 = "C:\test"
$date = Get-Date -Format d
$csvs = Get-ChildItem $path -Include *.csv | Sort-Object LastAccessTime -Descending | Select-Object -First 2
$y = $csvs.Count

Write-Host "Detected the following CSV files: ($y)"
foreach ($csv in $csvs) {
    Write-Host " "$csv.Name
}

$outputfilename = "regSCI " + $date
Write-Host Creating: $outputfilename

$excelapp = New-Object -ComObject Excel.Application
$excelapp.sheetsInNewWorkbook = $csvs.Count
$xlsx = $excelapp.Workbooks.Add()
$sheet = 1
$xlleft = -4131

foreach ($csv in $csvs) {
    $row = 1
    $column = 1
    $worksheet = $xlsx.Worksheets.Item($sheet)
    $worksheet.Name = $csv.Name
    $worksheet.Rows.HorizontalAlignment = $xlleft
    $file = (Get-Content $csv)
    Write-Host Worksheet created: $worksheet.Name

    foreach($line in $file) {
        Write-Host Writing Line
        $linecontents = $line -split ',(?!\s*\w+")'

        foreach($cell in $linecontents) {
            Write-Host Writing Cell
            $cell1 = $cell.Trim('"')
            $worksheet.Cells.Item($row, $column) = $cell1
            $column++
        }
        $column = 1
        $row++
        $WorkSheet.UsedRange.Columns.Autofit() | Out-Null
    }
    $sheet++
    $headerRange = $worksheet.Range("a1", "q1") 
    $headerRange.AutoFilter() | Out-Null 
}

$output = $path2 + "\" + $outputfilename
Write-Host $output
$xlsx.SaveAs($output)
$excelapp.Quit()

【问题讨论】:

    标签: excel csv powershell com automation


    【解决方案1】:

    要加快现有代码的速度,请在创建 Excel 对象后添加:

    $excelapp.ScreenUpdating = $false
    $excelapp.DisplayStatusBar = $false
    $excelapp.EnableEvents = $false
    $excelapp.Visible = $false
    

    这些就在 SaveAs 之前:

    $excelapp.ScreenUpdating = $true
    $excelapp.DisplayStatusBar = $true
    $excelapp.EnableEvents = $true
    

    这会导致 excel 不会在您每次更改内容时实时呈现工作表并触发事件。很可能DisplayStatusBarScreenUpdating 无关紧要,如果您使应用程序不可见,但我将其包括在内以防万一。

    此外,您在每一行之后都运行Autofit()。这当然对性能没有帮助。

    【讨论】:

    • 感谢回复,一定会试试这个。你能否澄清Autofit()-部分,因为我刚刚偷了excel代码,我不确定它是做什么的
    • @AndersEkelund AutoFit() 将列宽调整为单元格内容。如果需要,请在每张纸上执行一次,而不是在插入每一行之后。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-05-06
    • 2011-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多