Skip to content

Instantly share code, notes, and snippets.

@ellisgeek
Last active September 7, 2023 13:19
Show Gist options
  • Save ellisgeek/bf621e4b10071f789931 to your computer and use it in GitHub Desktop.
Save ellisgeek/bf621e4b10071f789931 to your computer and use it in GitHub Desktop.
Import Excel file into powershell in a manner compatible with Import-Csv
function Import-Excel {
<#
.SYNOPSIS
Creates table-like custom objects from the items in a Excel file.
Requires Excel be installed!
.DESCRIPTION
The Import-Excel cmdlet creates table-like custom objects from the items in Excel
Worksheets.
Each column in the Excel Worksheet becomes a property of the custom object and the items in
rows become the property values. Import-Excel works on any file supported by Excel.
.PARAMETER Path
Specifies the path to the Excel file to import.
.PARAMETER WorksheetName
[OPTIONAL] Specifies the name of the Worksheet to import.
If this parameter is not specified the first Worksheet is imported.
If multiple Worksheets with the same name exist in the Workbook the first matching Worksheet
is Imported.
.PARAMETER Silent
[OPTIONAL] Supress the display of the import progress.
.EXAMPLE
Load the first Worksheet of an Excel Workbook.
Import-Excel -Path ./Example.xlsx
.EXAMPLE
Load a Worksheet named "Example" from an Excel Workbook.
Import-Excel -Path ./Example.xlsx -WorksheetName "Example"
.EXAMPLE
Silently load the first Worksheet of an Excel Workbook.
Import-Excel -Path ./Example.xlsx -Silent
.LINK https://gist.github.com/ellisgeek/bf621e4b10071f789931
.NOTE
Original function written by Roman Podlisk (https://podlisk.wordpress.com)
https://podlisk.wordpress.com/2011/11/20/import-excel-spreadsheet-into-powershell/
I only added better validation to parameters and wrote documentation.
#>
param (
[parameter(Mandatory = $true,
Position = 0,
ValueFromPipeline = $true)]
[ValidateNotNullOrEmpty()]
[ValidateScript({ Resolve-Path $_ | Test-Path})]
[string]
$Path,
[parameter(Mandatory = $false)]
[string]
$WorksheetName,
[parameter(Mandatory = $false)]
[switch]
$Silent
)
$Path = Resolve-Path $Path
$excel = New-Object -com "Excel.Application"
$excel.Visible = $false
$workbook = $excel.workbooks.open($Path)
if (-not $WorksheetName) {
Write-Warning "Defaulting to the first worksheet in workbook."
$sheet = $workbook.ActiveSheet
}
else {
$sheet = $workbook.Sheets.Item($WorksheetName)
}
if (-not $sheet) {
throw "Unable to open worksheet $WorksheetName"
exit
}
$sheetName = $sheet.Name
$columns = $sheet.UsedRange.Columns.Count
$lines = $sheet.UsedRange.Rows.Count
Write-Debug "Worksheet $sheetName contains $columns columns and $lines lines of data"
$fields = @()
for ($column = 1; $column -le $columns; $column++) {
$fieldName = $sheet.Cells.Item.Invoke(1, $column).Value2
if ($fieldName -eq $null) {
$fieldName = "Column" + $column.ToString()
}
$fields += $fieldName
}
$line = 2
for ($line = 2; $line -le $lines; $line++) {
$values = New-Object object[] $columns
for ($column = 1; $column -le $columns; $column++) {
$values[$column - 1] = $sheet.Cells.Item.Invoke($line, $column).Value2
}
$row = New-Object psobject
$fields | foreach-object -begin { $i = 0 } -process {
$row | Add-Member -MemberType noteproperty -Name $fields[$i] -Value $values[$i]; $i++
}
$row
$percents = [math]::round((($line/$lines) * 100), 0)
if (-not $Silent) {
Write-Progress -Activity:"Importing from Excel file $Path" `
-Status:"Imported $line of total $lines lines ($percents%)" -PercentComplete:$percents
}
}
$workbook.Close()
$excel.Quit()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment