Я знаю, что это старая нить. Для таких, как я, у кого до сих пор есть эта проблема, используя офис 2013 через объект powershell com, можно использовать метод oppextext . Проблема в том, что этот метод имеет много аргументов, которые иногда взаимно исключают друг друга. Чтобы решить эту проблему, вы можете использовать метод invoke-namedparameter, введенный в этой записи . Примером может быть
$ex = New-Object -com "Excel.Application"
$ex.visible = $true
$csv = "path\to\your\csv.csv"
Invoke-NamedParameter ($ex.workbooks) "opentext" @{"filename"=$csv; "Semicolon"= $true}
К сожалению, я только что обнаружил, что этот метод каким-то образом нарушает синтаксический анализ csv, когда ячейки содержат разрывы строк. Это поддерживается csv, но реализация микрософт, по-видимому, прослушивается. Также он каким-то образом не обнаружил специфические немецкие символы. Придание ему правильной культуры не изменило этого поведения. Все файлы (csv и script) сохраняются с помощью кодировки utf8. Сначала я написал следующий код для вставки ячейки csv по ячейке.
$ex = New-Object -com "Excel.Application"
$ex.visible = $true;
$csv = "path\to\your\csv.csv";
$ex.workbooks.add();
$ex.activeWorkbook.activeSheet.Cells.NumberFormat = "@";
$data = import-csv $csv -encoding utf8 -delimiter ";";
$row = 1;
$data | %{ $obj = $_; $col = 1; $_.psobject.properties.Name |%{if($row -eq1){$ex.ActiveWorkbook.activeSheet.Cells.item($row,$col).Value2= $_ };$ex.ActiveWorkbook.activeSheet.Cells.item($row+1,$col).Value2 =$obj.$_; $col++ }; $row++;}
Но это очень медленно, поэтому я искал альтернативу. Очевидно, что Excel позволяет вам устанавливать значения диапазона ячеек с матрицей. Поэтому я использовал алгоритм в в этом блоге , чтобы преобразовать csv в multiarray.
function csvToExcel($csv,$delimiter){
$a = New-Object -com "Excel.Application"
$a.visible = $true
$a.workbooks.add()
$a.activeWorkbook.activeSheet.Cells.NumberFormat = "@"
$data = import-csv -delimiter $delimiter $csv;
$array = ($data |ConvertTo-MultiArray).Value
$starta = [int][char]'a' - 1
if ($array.GetLength(1) -gt 26) {
$col = [char]([int][math]::Floor($array.GetLength(1)/26) + $starta) + [char](($array.GetLength(1)%26) + $Starta)
} else {
$col = [char]($array.GetLength(1) + $starta)
}
$range = $a.activeWorkbook.activeSheet.Range("a1:"+$col+""+$array.GetLength(0))
$range.value2 = $array;
$range.Columns.AutoFit();
$range.Rows.AutoFit();
$range.Cells.HorizontalAlignment = -4131
$range.Cells.VerticalAlignment = -4160
}
function ConvertTo-MultiArray {
param(
[Parameter(Mandatory=$true, Position=1, ValueFromPipeline=$true)]
[PSObject[]]$InputObject
)
BEGIN {
$objects = @()
[ref]$array = [ref]$null
}
Process {
$objects += $InputObject
}
END {
$properties = $objects[0].psobject.properties |%{$_.name}
$array.Value = New-Object 'object[,]' ($objects.Count+1),$properties.count
# i = row and j = column
$j = 0
$properties |%{
$array.Value[0,$j] = $_.tostring()
$j++
}
$i = 1
$objects |% {
$item = $_
$j = 0
$properties | % {
if ($item.($_) -eq $null) {
$array.value[$i,$j] = ""
}
else {
$array.value[$i,$j] = $item.($_).tostring()
}
$j++
}
$i++
}
$array
}
}
csvToExcel "storage_stats.csv" ";"
Вы можете использовать вышеуказанный код, так как он должен преобразовывать любые csvs в excel. Просто измените путь к символу csv и разделителю внизу.