今天我刚刚将这个PowerShell脚本放在一起
采用制表符分隔的文本文件
将其读入内存,
根据某列的不同值
创建一个新的空Excel工作簿
将过滤后的数据的每个子集添加到 一个新的Excel工作表
最后一步是我陷入困境。目前,我的代码将几行数据放入工作表中的一个范围内,以展开/转置的“key:value”条目的形式,从而产生水平数据布局。始终覆盖相同范围的数据。
我希望数据采用垂直布局的形式,即列中的数据,就像使用MS Excel的导入文件向导导入csv文件一样。
有没有比下面更简单的方法呢?
我承认,一些powershell功能在这里以编码的货物模式粘贴在这里。请注意,我没有任何PowerShell经验。几年前我做了一些batchfile,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()
}
数据输出示例
WRONG
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
RIGHT
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
答案 0 :(得分:2)
试试Export-Xls,它看起来非常好。从来没有机会使用它,但(实际上)知道使用它的人,我相信你会很乐意使用它。如果您愿意,请提供反馈,我们将不胜感激。
Export-Xls中未定义属性的可能解决方法
可以更改函数Add-Array2Clipboard
,使其接受新的输入参数:一个数组,提供所需的属性名称。
然后您可以更改使用get-member
的部分。愚蠢的例子:
"z", "a", "c" | %{ get-member -name $_ -inputobject $thecurrentobject }
这只是一个关于如何从get-member
获得有序属性的示例。
答案 1 :(得分:2)
我已经使用$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
。
答案 2 :(得分:0)
我使用了修改后的Export-Xls函数,与User empo建议的稍有不同。 这是我对它的呼吁
Export-Xls $filtered -Path $outfile -WorksheetName "$wn" -SheetPosition "end" | Out-Null # -SheetPosition "end";
但是,当前版本的Export-Xls重新排序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;
}
}