且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Powershell在Excel单元格中使用多行文本

更新时间:2023-02-03 20:44:50

我不知道为什么你使用的方法,但我能够在我的系统以及。我在我的一个脚本中做一些类似的操作,构建一个大的Excel工作簿,我已经成功使用了以下方法:

I am not sure why the method you are using does that but I was able to reproduce on my system as well. I do some similar operations in one of my scripts that builds a large Excel workbook and I have used the following method with success:


  1. 导入CSV with Import-CSV

  2. 将它转换为多维数组

  3. 将数组写入范围对象的Value2

例如,替换以下代码:

$TxtConnector = ("TEXT;" + $CSVFullPath)
$CellRef = $worksheet.Range("A1")
$Connector = $worksheet.QueryTables.add($TxtConnector,$CellRef)
$worksheet.QueryTables.item($Connector.name).TextFileCommaDelimiter = $True
$worksheet.QueryTables.item($Connector.name).TextFileParseType  = 1
$worksheet.QueryTables.item($Connector.name).Refresh()
$worksheet.QueryTables.item($Connector.name).delete()

改为:

$CsvContents = Import-Csv $CSVFullPath
$MultiArray = (ConvertTo-MultiArray $CsvContents -Headers).Value
$StartRowNum = 1
$StartColumnNum = 1
$EndRowNum = $CsvContents.Count + 1
$EndColumnNum = ($CsvContents | Get-Member | Where-Object { $_.MemberType -eq 'NoteProperty' }).Count
$Range = $worksheet.Range($worksheet.Cells($StartRowNum, $StartColumnNum), $worksheet.Cells($EndRowNum, $EndColumnNum))
$Range.Value2 = $MultiArray

需要用于将对象转换为多维数组的函数(基于这里,但稍作修改):

For that to work you will also need the function I use for converting an object to a multi-dimensional array (based off the one posted here but with some slight modifications):

function ConvertTo-MultiArray
{
    param (
        $InputObject,
        [switch]$Headers = $false
    )
    begin
    {
        $Objects = @()
        [ref]$Array = [ref]$null
    }
    process
    {
        $Objects += $InputObject
    }
    end
    {
        $Properties = $Objects[0].PSObject.Properties | ForEach-Object{ $_.Name }
        $Array.Value = New-Object 'object[,]' ($Objects.Count + 1), $Properties.Count
        $ColumnNumber = 0
        if ($Headers)
        {
            $Properties | ForEach-Object{
                $Array.Value[0, $ColumnNumber] = $_.ToString()
                $ColumnNumber++
            }
            $RowNumber = 1
        }
        else
        {
            $RowNumber = 0
        }
        $Objects | ForEach-Object{
            $Item = $_
            $ColumnNumber = 0
            $Properties | ForEach-Object{
                if ($Item.($_) -eq $null)
                {
                    $Array.Value[$RowNumber, $ColumnNumber] = ""
                }
                else
                {
                    $Array.Value[$RowNumber, $ColumnNumber] = $Item.($_).ToString()
                }
                $ColumnNumber++
            }
            $RowNumber++
        }
        $Array
    }
}