为什么用Powershell读取Excel文件这么慢?

时间:2015-01-22 13:50:21

标签: excel powershell

我有一个XLSX格式的28 KB小Excel文件,我想用Powershell修改它。该文件包含59行和366列。

我的代码遍历第一列并搜索特定条目,然后遍历找到的列并输出找到的行和第一行的内容。这是代码:

# Define some parameters.
$year = "2015"
$filename = "C:\...\file.xlsx"
$person = "Lastname, Firstname"

# Open Excel file and select worksheet.
$excel = New-Object -ComObject Excel.Application
$excel.Visible = $false
$workbook = $excel.Workbooks.Open($filename)
$worksheet = $workbook.sheets.item($year)
$cells = $worksheet.cells

# Search person name in first column.
$rows = $worksheet.UsedRange.Rows.count
"Rows: $rows"
$row = 1

while ($row -le $rows)
{
  $cell = $cells.item($row,1).value2
  if ($person -eq $cell) {
    break
  }
  $row++
}

# List row
$cols = $worksheet.UsedRange.Columns.count
"Cols: $cols"
foreach ($col in 2..$cols)
{
  $date = $cells.item(1,$col).value2
  $data = $cells.item($row,$col).value2
  $date = [DateTime]::FromOADate($date)
  $msg = $date.ToString("yyyy-MM-dd") + " " + $data
  "$msg"
}

# Close workbook and Excel file and release COM object.
$workbook.close()
$excel.quit()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel)

我的问题:程序很慢。迭代366列需要5分钟以上!

PS C:\...> Measure-Command { .\program.ps1 }

Days              : 0
Hours             : 0
Minutes           : 5
Seconds           : 33
Milliseconds      : 580
Ticks             : 3335806616
TotalDays         : 0,00386088728703704
TotalHours        : 0,0926612948888889
TotalMinutes      : 5,55967769333333
TotalSeconds      : 333,5806616
TotalMilliseconds : 333580,6616

我简直不敢相信这是正常的。相反,我认为我的计划确实存在问题。但我不知道它是什么。

我需要更改什么才能让它更快?

1 个答案:

答案 0 :(得分:0)

使用循环并查找替换Excel中的单元格值将永远带您...我需要替换111个单元格,并且需要大约40秒才能完成。 但是,您可以利用命令Replace,这要快得多。但是要从相对单元格提供值,您必须将Excel应用程序参考样式更改为xlR1c1。 下面是我如何用字符串替换所有单元格"没有注册的主机名"左边的单元格值,这是我的数据的IP地址。 我已经注释掉了之前使用过的while循环 由于您打算进行更新,您可以考虑这个......

$Range=$WorkSheet.Range("B1").EntireColumn
# Replace Cells with No registered hostname
$SearchString="No registered hostname"
# Using Excel reference style xlR1C1 to set the formula for replace
$xls.Application.ReferenceStyle=2 
$Range.Replace($SearchString, "=RC[-1]")
# while ($NoDNS=$Range.find($SearchString))
#   {
#   $NoDNS.Activate()
#   $RefRow=$NoDNS.Row
#   $NoDNS.value()=$WorkSheet.Cells.Item($RefRow, 1).Text
#   }
$xls.Application.ReferenceStyle=1

使用替换只需要一瞬间完成所有必要的更改,与之前的while循环相比。