powershell - 将数据粘贴到excel中

时间:2011-04-28 14:11:50

标签: excel powershell

今天我刚刚将这个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

3 个答案:

答案 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; 
        }

    }