PowerShell – 将数据粘贴到Excel中

今天我刚刚把这个powershell脚本扔在一起了

  • 采用制表符分隔的文本文件,

  • 把它读入内存,

  • 根据特定列的不同值进行可变数量的筛选查询

  • 创build一个新的空Excel工作簿

  • 将过滤数据的每个子集添加到新的Excel工作表中

最后一步是我卡住的地方。 目前,我的代码将几行数据放入工作表的一个范围中,以展开/转置的“key:value”条目的forms,产生水平数据布局。 相同范围的数据总是被覆盖。

我想要垂直布局forms的数据,即列中的数据,就像使用MS Excel的导入文件向导导入csv文件一样。

有没有比以下更简单的方法吗?

我承认,一些PowerShellfunction粘贴在这里的货物崇拜模式的编程。 请注意,我没有powershell的经验。 几年前,我做了一些batch file,vbscript和vba编码。 所以,其他批评也是受欢迎的。

PARAM ( [Parameter(ValueFromPipeline = $true)] $infile = ".\04-2011\110404-13.txt" ) PROCESS { echo " $infile" Write-Host "Num Args:" $args.Length; $xl = New-Object -comobject Excel.Application; $xl.Visible = $true; $Workbook = $xl.Workbooks.Add(); $content = import-csv -delimiter "`t" $infile ; $ports = $content | select-object Port# | sort-object Port# -Unique -Descending; $ports | ForEach-Object { $p = $_; Write-Host $p.{Port#}; $Worksheet = $Workbook.Worksheets.Add(); $workSheet.Name = [string]::Format( "{0} {1}", "PortNo" , $p.{Port#}); $filtered = $content | where-object {$_.{Port#} -eq $p.{Port#} }; $filtered | ForEach-Object { Write-Host $_.{ObsDateTime} , $_.{Port#} } $filtered | clip.exe; $range = $Workbook.ActiveSheet.Range("a2", "a$($filtered.count)"); $Workbook.ActiveSheet.Paste($range, $false); } $xl.Quit() } 

数据输出示例

错误

 Port# : 1 Obs# : 1 Exp_Flux : 0,99 IV Cdry : 406.96 IV Tcham : 16.19 IV Pressure : 100.7 IV H2O : 9.748 IV V3 : 11.395 IV V4 : 0.759 IV RH : 53.12 

 Port# Obs# Exp_Flux IV Cdry IV Tcham IV Pressure IV H2O IV V3 IV V4 IV RH 1 1 0,99 406.96 16.19 100.7 9.748 11.395 0.759 53.12 

试试Export-Xls ,它看起来非常好。 从来没有机会使用它,但(实际上)知道谁工作的人,我相信你会很乐意使用它。 如果你愿意,请提供一个反馈在这里将不胜感激。


Export-Xls中的无序属性可能的解决方法

函数Add-Array2Clipboard可以被改变,以便它接受一个新的input参数:一个数组,提供按需要sorting的属性名称。

然后,您可以更改使用get-member的部分。 愚蠢的例子:

 “z”,“a”,“c”|  %{get-member -name $ _ -inputobject $ thecurrentobject}

这只是您如何从get-member获得有序属性的一个例子。

我已经使用了$Workbook.ActiveSheet.Cells.Item($row, $col).Value2函数,以便更精确地指出将数据导出到Excel时将数据放在哪里。

就像是

 $row = 1 Get-Content $file | Foreach-Object { $cols = $_.split("`t") for ($i = 0; $i < $cols.count; $i++) { $Workbook.ActiveSheet.Cells.Item($row, $i+1).Value2 = $cols[$i] } $row++ } 

警告:干编码! 你可能还需要一些try..catch

我使用了一个修改过的Export-Xls函数,与User empobuild议的有些不同。 这是我的电话

 Export-Xls $filtered -Path $outfile -WorksheetName "$wn" -SheetPosition "end" | Out-Null # -SheetPosition "end"; 

但是,当前版本的Export-Xls重新sorting了csv-text -file的内存中表示的列。 我希望文本文件的数据列按原来的顺序排列,所以我不得不破解并简化原始代码,如下所示:

  function Add-Array2Clipboard { param ( [PSObject[]]$ConvertObject, [switch]$Header ) process{ $array = @(); $line ="" if ($Header) { $line = @() $row = $ConvertObject | Select -First 1 $row.psobject.properties | Foreach {$line += "$($_.Name)" } $array += [String]::Join("`t", $line) } else { foreach($row in $ConvertObject){ $line ="" $vals = @() $row.psobject.properties | Foreach {$vals += $_.Value} $array += [String]::Join("`t", $vals) } } $array | clip.exe; } }