PowerShell DataTable删除空行

时间:2015-03-09 14:15:35

标签: excel powershell

在使用Excel.Application对象时,我偶然发现了一些(DCOM)问题。因此,我已使用AccessDatabaseEngine_x64中提供的OleDbConnectionOleDbCommand对象重写了我的函数来阅读Excel文件。因此,不再需要在服务器上安装MS Office,而且我认为它也更可靠。

效果很好但唯一缺少的是我似乎无法弄清楚如何从函数的输出中删除空行。我知道可以使用$DataTable[0].Delete()来完成,但我不知道如何确定完整的行是否为空。因为它可以根据输入而变化。

XLSX-File示例:

Name     | Sir name
Bob Lee  | Swagger
         |
Jake     | Thornton

在上面的示例中,我希望输出只有2(或3行,具体取决于$Header开关),但我不想在输出中看到空行。

我在另一种语言中找到了solution,但我无法将其翻译为PowerShell。

代码:

Function Import-Excel {
    [CmdletBinding()]
    Param (
        [parameter(Mandatory=$true,Position=0)]
        [ValidateScript({Test-Path $_ -PathType Leaf})]
        [String]$FileName, 
        [parameter(Mandatory=$true,Position=1)]
        [String]$WorksheetName,
        [Switch]$Header
    )

    Begin {
        # We can't read open XLSX-Files
        Copy-Item -LiteralPath $FileName -Destination $env:TEMP
    }

    Process {
        $OleDbConnection = New-Object 'System.Data.OleDb.OleDbConnection'
        $OleDbCommand    = New-Object 'System.Data.OleDb.OleDbCommand'
        $ConnString = 'Provider=Microsoft.ACE.OLEDB.12.0;Data Source='
        $ConnString += "$env:TEMP\$(Split-Path $FileName -Leaf)"

        if ($header) {
            $ConnString += ';Extended Properties="Excel 12.0;HDR=YES;IMEX=1";'
        }
        else {
            $ConnString += ';Extended Properties="Excel 12.0;HDR=NO;IMEX=1";'
        }

        $OleDbConnection.ConnectionString = $ConnString
        $OleDbConnection.Open()

        $OleDbCommand.Connection = $OleDbConnection
        $OleDbCommand.CommandText = "SELECT * FROM [$WorksheetName$]"

        $OleDbAdapter = New-Object "System.Data.OleDb.OleDbDataAdapter"
        $OleDbAdapter.SelectCommand = $OleDbCommand

        $DataTable = New-Object "System.Data.DataTable"
        $OleDbAdapter.Fill($DataTable)

        $OleDbConnection.Close() 
        Write-Output $DataTable
    }
    End {
        Remove-Item "$env:TEMP\$(Split-Path $FileName -Leaf)"
    }
}

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

在此期间找到答案,对于遇到相同问题的人:

Function Import-Excel {
    [CmdletBinding()]
    Param (
        [parameter(Mandatory=$true,Position=0)]
        [ValidateScript({Test-Path -LiteralPath $_ -PathType Leaf})]
        [String]$FileName, 
        [parameter(Mandatory=$true,Position=1)]
        [String]$WorksheetName,
        [Switch]$Header
    )

    Begin {
        # We can't read open XLSX-Files
        Copy-Item -LiteralPath $FileName -Destination $env:TEMP
    }

    Process {
        $OleDbConnection = New-Object 'System.Data.OleDb.OleDbConnection'
        $OleDbCommand    = New-Object 'System.Data.OleDb.OleDbCommand'
        $OleDbAdapter    = New-Object 'System.Data.OleDb.OleDbDataAdapter'
        $DataTable       = New-Object 'System.Data.DataTable'

        $ConnString = 'Provider=Microsoft.ACE.OLEDB.12.0;Data Source='
        $ConnString += "$env:TEMP\$(Split-Path $FileName -Leaf)"

        if ($header) {
            $ConnString += ';Extended Properties="Excel 12.0;HDR=YES;IMEX=1";'
        }
        else {
            $ConnString += ';Extended Properties="Excel 12.0;HDR=NO;IMEX=1";'
        }

        $OleDbConnection.ConnectionString = $ConnString
        $OleDbConnection.Open()

        $OleDbCommand.Connection = $OleDbConnection
        $OleDbCommand.CommandText = "SELECT * FROM [$WorksheetName$]"

        $OleDbAdapter.SelectCommand = $OleDbCommand
        $OleDbAdapter.Fill($DataTable)

        $OleDbConnection.Close()

        # Remove empty lines
        $Columns = $DataTable.Columns.Count
        $Rows    = $DataTable.Rows.Count

        for ($r = 0; $r -lt $Rows; $r++) {    
            $Empty = 0
             for ($c = 0; $c -lt $Columns; $c++) {

                if ($DataTable.Rows[$r].IsNull($c)) {
                    $Empty++
                }
             }
             if ($Empty -eq $Columns) {
                # Mark row for deletion:
                $DataTable.Rows[$r].Delete()
             }
        }
        # Delete marked rows:
        $DataTable.AcceptChanges()

        Write-Output $DataTable
    }

    End {
        Remove-Item "$env:TEMP\$(Split-Path $FileName -Leaf)"
    }
}