Performance powershell脚本中excel com对象的性能降低

Performance powershell脚本中excel com对象的性能降低,performance,excel,object,powershell,com,Performance,Excel,Object,Powershell,Com,我编写了一个powershell脚本,该脚本创建一个excel com对象,以重复读取*.csv文件,生成一个图形,然后将图形另存为*.pdf文件。代码段如下所示。脚本启动时,每个文件需要2-4秒。脚本运行的时间越长,处理单个csv文件所需的时间就越长。大约1000个文件之后,每个文件大约需要60秒。所有csv文件都是2列70行的小文件。当我要生成215个图形时,运行大约需要12分钟。当我有1522张图表时,需要20个多小时。我能做些什么来加快速度吗 蒂亚, 马克K # # Create an

我编写了一个powershell脚本,该脚本创建一个excel com对象,以重复读取*.csv文件,生成一个图形,然后将图形另存为*.pdf文件。代码段如下所示。脚本启动时,每个文件需要2-4秒。脚本运行的时间越长,处理单个csv文件所需的时间就越长。大约1000个文件之后,每个文件大约需要60秒。所有csv文件都是2列70行的小文件。当我要生成215个图形时,运行大约需要12分钟。当我有1522张图表时,需要20个多小时。我能做些什么来加快速度吗

蒂亚, 马克K

#
#  Create an Excell object and use it to generate the graphs.  
#

$ex = New-Object -ComObject Excel.Application
$chartType = "microsoft.office.interop.excel.xlChartType" -as [type]
$xlFixedFormat = "Microsoft.Office.Interop.Excel.xlFixedFormatType" -as [type]
$ex.DisplayAlerts = $False
$ex.Visible = $False
$wb = $ex.Workbooks.Add()
$ws = $wb.worksheets
$ws1 = $ws.Item(1)

try {                                            # Delete unneeded worksheets, if present
   $ws.item(3).delete()
   $ws.item(2).delete()
}
catch [Exception] {
   Out-Null
}

$i = 0

foreach ($p in $pdfs) {                       # $p is a csv file to be the source for a pdf

    Try {
        $ws1.Name = $p.Substring(0,$p.IndexOf('.'))
        $Connector = ("text;http://xxxxxxxxxxxxx/" + $lpar + "/" + $p) 
        $CellRef = $ws1.Range("A1")
        $Conn = $ws1.QueryTables.Add($Connector,$CellRef)
        $ws1.QueryTables.item($Conn.name).TextFileCommaDelimiter = $True
        $ws1.QueryTables.item($Conn.name).TextFileParseType = 1
        $ws1.QueryTables.item($Conn.name).Refresh() | Out-Null
        $ws2 = $ex.charts.add()
        $ws2.chartType = $chartType::xlLine
        $ws2.Name = $ws1.Name + " Graph"
        $ws2.HasTitle = $True
        $ws2.ChartTitle.Text = $ws1.Range("A1").text
        $Data = $ws1.range("b2:b71")
        $ws2.setSourceData($Data) | Out-Null
        $ws2.SeriesCollection(1).XValues = $ws1.Range("A2:A71")
        $wb.ExportAsFixedFormat($xlFixedFormat::xlTypePDF,"$drive`:\captrendGraphs\$lpar\" + $ws1.Name + ".pdf",0,$True,$True,1,1)
        $ws2.Delete() | Out-Null
        $ws1.UsedRange.ClearContents() | Out-Null
    }
    catch [Exception] {
        Write-Host $_.Exception.toString()
        Write-Log $($_.Exception.toString())
        Write-Host $_.Exception.message
        Write-Log $($_.Exception.message)
        Write-Host $_.Exception.source
        Write-Log $($_.Exception.source)
        Write-Host $_.Exception.StackTrace
        Write-Log $($_.Exception.StackTrace)
        Write-Host "Error occured with: " $p
        Write-Log $("Error occured with: " + $p)
    }

    $i++
    $rptP = $("{0:D4}" -f $i + " " + $p)
    Write-Host $rptP
    Write-Log $rptP
}

您可以按时间间隔(15分钟)或图形创建间隔(每1000分钟)打开和关闭一个新的excel会话,看看这是否有帮助。

尝试为每个文件创建一个新的Com对象。通过这种方式,您可以处理该文件,并让垃圾收集器清理它。否则,您将重复使用同一会话,并在内存中进行所有这些更改。终止和重新创建Excel COM对象的成本也很高(按时间计算)-在我的系统上执行100次大约54秒(没有执行其他工作)。首先尝试为循环的每个迭代创建(并“关闭”)一个新工作簿。这一代价高昂的原因是由于数据增长不受控制,例如单元格格式、撤消数据和查询表未被正确处理。也可能是PowerShell在释放COM接口指针方面效率不高,您可以直接使用
$Conn
,而不是
$ws1.QueryTables.item($Conn.name)
。但是一般来说,你能创建一个新的工作表并删除以前的工作表吗?这可能会为您省去很多麻烦。首先,我尝试为每个文件/图形创建一个新工作簿。这运行得更快,但由于内存问题(据我所知),它可能会爆炸600多个文件。然后我尝试为每个文件/图形创建一个新的工作表,效果很好,需要20小时。现在大约需要1.25小时。Excel进程仍在逐渐使用更多内存,但至少到目前为止还不足以失败。谢谢你的帮助。