Files
ImportExcel/Export-Excel.ps1
DarkLite1 97a2f369a6 Improved code formatting and added 'Path' parameter validation
Improved code formatting and added 'Path' parameter validation. When a
path doesn't exist we throw an error. When the file extension provided
by the user isn't correct, we throw an error.
2015-10-21 11:01:33 +02:00

411 lines
15 KiB
PowerShell

Function Export-Excel {
<#
.SYNOPSIS
Write objects and strings to an Excel worksheet.
.DESCRIPTION
The Export-Excel cmdlet creates an Excel worksheet of the objects or strings you commit. This is done without using Microsoft Excel in the background but by using the .NET EPPLus.dll. You can also automate the creation of Pivot Tables and Charts.
.PARAMETER Path
Specifies the path to the Excel file. This parameter is required.
.PARAMETER TargetData
.PARAMETER WorksheetName
Specifies the name of the worksheet in the Excel workbook.
.PARAMETER Title
Specifies the title used in the worksheet. The title is placed on the first line of the worksheet.
.PARAMETER TitleFillPattern
.PARAMETER TitleBold
Sets the title to bold. By default the title is not bold.
.PARAMETER TitleSize
Specifies the size of the title. The default value is 22.
.PARAMETER TitleBackgroundColor
.PARAMETER PivotRows
Specifies the rows in the pivot table.
.PARAMETER PivotColumns
Specifies the columns in the pivot table.
.PARAMETER PivotData
Specifies the source data in the pivot table.
.PARAMETER Password
Specifies the password to use to protect the Excel workbook from unauthorized access.
.PARAMETER ChartType
Specifies the type of chart to use. The default is a pie chart.
.PARAMETER IncludePivotTable
Adds a pivot table worksheet to the workbook. In data processing, a pivot table is a data summarization tool found in data visualization programs such as Excel worksheets. Among other functions, a pivot table can automatically sort, count total or give the average of the data stored in one table or spreadsheet, displaying the results in a second table showing the summarized data. Pivot tables are also useful for quickly creating unweighted cross tabulations. The user sets up and changes the summary's structure by dragging and dropping fields graphically in Excel or by using the paramaters 'PivotRows', 'PivotColumns', and 'PivotData'.
.PARAMETER IncludePivotChart
Has to be used together with 'IncludePivotTable' and adds an extra chart next to the pivot table.
.PARAMETER AutoSize
Adjusts the column width to the content of the cells. By default columns have a fixed width.
.PARAMETER Show
Opens the Excel file after creation, so you can view its content.
.PARAMETER NoClobber
Do not overwrite (replace the contents) of an existing worksheet. By default, if a file exists in the specified path, Export-Excel overwrites the worksheet without warning.
.PARAMETER FreezeTopRow
Freezes the first row of the Excel worksheet. This is convenient when working with lots of rows, so the headers will always be visible when scrolling downwards in the worksheet.
.PARAMETER AutoFilter
Sets the auto filter on the first row. This allows you to view specific rows in an Excel spreadsheet, while hiding other rows in the worksheet. When the auto filter is added to the header row of a worksheet, a drop-down menu appears on each cell of the header row. This provides you with a number of filter options that can be used to specify which rows of the worksheet are to be displayed.
.PARAMETER BoldTopRow
Sets the top row of the worksheet to bold. By default the top row is not bold.
.PARAMETER NoHeader
Omits the header fields so the worksheet will not contain column headers.
.PARAMETER RangeName
.PARAMETER TableName
Sets the content of the worksheet as a data table. Which makes it easier to sort, filter and maniuplate data in Excel.
.PARAMETER ConditionalFormat
.PARAMETER HideSheet
Specifies which worksheets will be hidden in the workbook. By default, all worksheets are visible.
.EXAMPLE
Get-Service | Export-Excel .\Test.xlsx -WorksheetName 'Services' -TableName 'Services'
Generates an Excel worksheet containing all the services on the system. The worksheet content will be presented in the Excel data table format for easy filtering, sorting and manipulation.
.EXAMPLE
Get-Service | Select-Object Status, Name, DisplayName | Export-Excel .\Test.xlsx -AutoSize -BoldTopRow -FreezeTopRow -Show
Generates an Excel worksheet containing all the services on the system. The worksheet will contain the headers 'Status', 'DisplayName' and 'Name' in bold, this row will be frozen so it's always visible. The column width will be adjusted to the cells content and the worksheet will be opened automatically once it's created.
It will look like this:
Sheet1:
-------
Status Name DisplayName
Running BITS Background Intelligent Transfer Ser...
Stopped Browser Computer Browser
.EXAMPLE
Get-Service | Export-Excel .\Test.xlsx -Show -NoHeader
Generates an Excel worksheet containing all the services on the system. The worksheet will not contain any headers like 'Status', 'DisplayName' or 'Name' because we used the switch 'NoHeader'.
It will look like this:
Sheet1:
-------
Running BITS Background Intelligent Transfer Ser...
Stopped Browser Computer Browser
.EXAMPLE
Get-Process | Export-Excel .\Test.xlsx -WorksheetName 'Processes'
Get-Service | Export-Excel .\Test.xlsx -WorksheetName 'Services' -HideSheet 'Services'
Creates an Excel workbook where only the worksheet 'Processes' is visible. The worksheet 'Services' is hidden.
.EXAMPLE
Get-Process | Export-Excel .\Test.xlsx -WorksheetName Processes -IncludePivotTable -Show -PivotRows Company -PivotData PM
Creates an Excel workbook containing two worksheets, one with a pivot table and one with the source data.
.EXAMPLE
$Params = @{
Path = '.\Test.xlsx'
IncludePivotTable = $true
PivotRows = 'Status'
PivotData = @{Status='Count'}
WorksheetName = 'Services'
HideSheet = 'Services'
Show = $true
}
Get-Service | Export-Excel @Params
Creates two Excel worksheets, one with a pivot table named 'ServicesPivotTable' and one with the source worksheet named 'Services'. The last one will be hidden and the Excel file will be opened when the command finishes. You will only see the worksheet 'ServicesPivotTable' with the pivot table as the other one is hidden with the 'HideSheet' switch.
It will look like this:
ServicesPivotTable:
-------------------
Count of Status
Row Labels | Total
----------- | -----
Running | 87
Stopped | 96
Grand Total | 183
.EXAMPLE
Get-Process | Export-Excel .\Test.xlsx -WorksheetName Processes -ChartType PieExploded3D -IncludePivotChart -IncludePivotTable -PivotRows Company -PivotData PM -Show
Creates an Excel workbook containing two worksheets, one worksheet with a PieExploded3D chart and a pivot table, and one worksheet with the source data. After the file is generated it will be opened.
.NOTES
CHANGELOG
2015/10/20 Added help text
2015/10/20 Changed 'TitleBold' from [BOOL] to [Switch]
(Makes more sense than providing $true or $false)
2015/10/21 Reformatted code to be consistent
2015/10/21 Added 'ValidateScript' for the 'Path' parameter
.LINK
https://github.com/dfinke/ImportExcel
#>
[CmdletBinding()]
Param (
[Parameter(Mandatory=$true)]
[ValidateScript({
if (-not (Test-Path (Split-Path -Path $_))) {
throw "Could not find a part of the path '$_'"}
else {
$true
}
if ($_ -notmatch '[\w]\.xlsx$|[\w]\.xls$') {
throw "File extension not valid, valid file extension for Excel files are '.xls' or '.xlsx' - '$_'"}
else {
$true
}
})]
[String]$Path,
[Parameter(ValueFromPipeline=$true)]
$TargetData,
[String]$WorksheetName = 'Sheet1',
[String]$Title,
[OfficeOpenXml.Style.ExcelFillStyle]$TitleFillPattern = 'None',
[Switch]$TitleBold,
[Int]$TitleSize = 22,
[System.Drawing.Color]$TitleBackgroundColor,
[String[]]$PivotRows,
[String[]]$PivotColumns,
$PivotData,
[String]$Password,
[OfficeOpenXml.Drawing.Chart.eChartType]$ChartType = 'Pie',
[Switch]$IncludePivotTable,
[Switch]$IncludePivotChart,
[Switch]$AutoSize,
[Switch]$Show,
[Switch]$NoClobber,
[Switch]$FreezeTopRow,
[Switch]$AutoFilter,
[Switch]$BoldTopRow,
[Switch]$NoHeader,
[String]$RangeName,
[String]$TableName,
[Object[]]$ConditionalFormat,
[String[]]$HideSheet
)
Begin {
Try {
$Path = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($Path)
if (Test-Path -Path $path -PathType Leaf) {
Write-Debug "File `"$Path`" already exists"
}
$pkg = New-Object OfficeOpenXml.ExcelPackage $Path
$ws = $pkg | Add-WorkSheet -WorksheetName $WorksheetName -NoClobber:$NoClobber
foreach ($format in $ConditionalFormat ) {
$target = "Add$($format.Formatter)"
$rule = ($ws.ConditionalFormatting).$target.Invoke($format.Address, $format.IconType)
$rule.Reverse = $format.Reverse
}
# Force at least one cell value
$ws.Cells[1, 1].Value = ''
$Row = 1
if($Title) {
$ws.Cells[$Row, 1].Value = $Title
$ws.Cells[$Row, 1].Style.Font.Size = $TitleSize
$ws.Cells[$Row, 1].Style.Font.Bold = $TitleBold
$ws.Cells[$Row, 1].Style.Fill.PatternType = $TitleFillPattern
if ($TitleBackgroundColor) {
$ws.Cells[$Row, 1].Style.Fill.BackgroundColor.SetColor($TitleBackgroundColor)
}
$Row = 2
}
}
Catch {
if ($AlreadyExists) {
throw "$WorksheetName already exists."
}
else {
throw $Error[0].Exception.Message
}
}
$firstTimeThru = $true
$isDataTypeValueType = $false
$pattern = 'string|bool|byte|char|decimal|double|float|int|long|sbyte|short|uint|ulong|ushort'
}
Process {
if ($firstTimeThru) {
$firstTimeThru = $false
$isDataTypeValueType = $TargetData.GetType().name -match 'string|bool|byte|char|decimal|double|float|int|long|sbyte|short|uint|ulong|ushort'
}
if ($isDataTypeValueType) {
$ColumnIndex = 1
$targetCell = $ws.Cells[$Row, $ColumnIndex]
$cellValue = $TargetData
$r = $null
if ([Double]::TryParse($cellValue, [Ref]$r)) {
$targetCell.Value = $r
}
else {
$targetCell.Value = $cellValue
}
switch ($TargetData.$Name) {
{$_ -is [DateTime]} {$targetCell.Style.Numberformat.Format = 'm/d/yy h:mm'}
}
$ColumnIndex += 1
$Row += 1
}
else {
if (!$Header) {
$ColumnIndex = 1
$Header = $TargetData.psobject.properties.name
if ($NoHeader) {
# Don't push the headers to the spread sheet
$Row -= 1
}
else {
foreach ($Name in $Header) {
$ws.Cells[$Row, $ColumnIndex].Value = $name
$ColumnIndex += 1
}
}
}
$Row += 1
$ColumnIndex = 1
foreach ($Name in $Header) {
$targetCell = $ws.Cells[$Row, $ColumnIndex]
$cellValue = $TargetData.$Name
$r = $null
if ([Double]::TryParse($cellValue, [Ref]$r)) {
$targetCell.Value = $r
}
else {
$targetCell.Value = $cellValue
}
switch ($TargetData.$Name) {
{$_ -is [DateTime]} {
$targetCell.Style.Numberformat.Format = 'm/d/yy h:mm'
}
}
$ColumnIndex += 1
}
}
}
End {
$startAddress = $ws.Dimension.Start.Address
$dataRange = '{0}:{1}' -f $startAddress, $ws.Dimension.End.Address
Write-Debug "Data Range $dataRange"
if (-not [string]::IsNullOrEmpty($RangeName)) {
$ws.Names.Add($RangeName, $ws.Cells[$dataRange]) | Out-Null
}
if (-not [string]::IsNullOrEmpty($TableName)) {
$ws.Tables.Add($ws.Cells[$dataRange], $TableName) | Out-Null
}
if ($IncludePivotTable) {
$wsPivot = $pkg | Add-WorkSheet -WorksheetName ($WorksheetName + 'PivotTable') -NoClobber:$NoClobber
$wsPivot.View.TabSelected = $true
if ($Title) {
$startAddress = 'A2'
}
$pivotTable = $wsPivot.PivotTables.Add($wsPivot.Cells['A1'], $ws.Cells[$dataRange], ($WorksheetName + 'PivotTableData'))
if ($PivotRows) {
foreach ($Row in $PivotRows) {
$null = $pivotTable.RowFields.Add($pivotTable.Fields[$Row])
}
}
if ($PivotColumns) {
foreach ($Column in $PivotColumns) {
$null = $pivotTable.ColumnFields.Add($pivotTable.Fields[$Column])
}
}
if ($PivotData) {
if($PivotData -is [HashTable]) {
$PivotData.Keys | ForEach-Object {
$df = $pivotTable.DataFields.Add($pivotTable.Fields[$_])
$df.Function = $PivotData.$_
}
}
else {
foreach ($Item in $PivotData) {
$df = $pivotTable.DataFields.Add($pivotTable.Fields[$Item])
$df.Function = 'Count'
}
}
}
if ($IncludePivotChart) {
$chart = $wsPivot.Drawings.AddChart('PivotChart', $ChartType, $pivotTable)
$chart.SetPosition(1, 0, 6, 0)
$chart.SetSize(600, 400)
}
}
if ($Password) {
$ws.Protection.SetPassword($Password)
}
if ($AutoFilter) {
$ws.Cells[$dataRange].AutoFilter = $true
}
if ($FreezeTopRow) {
$ws.View.FreezePanes(2,1)
}
if ($BoldTopRow) {
$range=$ws.Dimension.Address -replace $ws.Dimension.Rows, '1'
$ws.Cells[$range].Style.Font.Bold = $true
}
if ($AutoSize) {
$ws.Cells.AutoFitColumns()
}
#$pkg.Workbook.View.ActiveTab = $ws.SheetID
foreach ($Sheet in $HideSheet) {
$pkg.Workbook.WorkSheets[$Sheet].Hidden = 'Hidden'
}
$pkg.Save()
$pkg.Dispose()
if ($Show) {
Invoke-Item $Path
}
}
}