diff --git a/Charting.ps1 b/Charting.ps1 index cebbb87..95d841d 100644 --- a/Charting.ps1 +++ b/Charting.ps1 @@ -1,15 +1,12 @@ function DoChart { - param( - $targetData, + param( + $targetData, $title, - [OfficeOpenXml.Drawing.Chart.eChartType]$ChartType, - [Switch]$NoLegend, - [Switch]$ShowCategory, - [Switch]$ShowPercent + $chartType ) if($targetData[0] -is [System.ValueType]) { - $chart = New-ExcelChart -YRange "A1:A$($targetData.count)" -Title $title -ChartType $ChartType + $chart = New-ExcelChart -YRange "A1:A$($targetData.count)" -Title $title -ChartType $chartType } else { $xyRange = Get-XYRange $targetData @@ -19,8 +16,7 @@ function DoChart { $Y = $xyRange.YRange.ExcelColumn $YRange = "{0}2:{0}{1}" -f $Y,($targetData.count+1) - $chart = New-ExcelChart -XRange $xRange -YRange $yRange -Title $title -ChartType $ChartType ` - -NoLegend:$NoLegend -ShowCategory:$ShowCategory -ShowPercent:$ShowPercent + $chart = New-ExcelChart -XRange $xRange -YRange $yRange -Title $title -ChartType $chartType } $xlFile = (New-TemporaryFile).fullname -replace "tmp","xlsx" @@ -28,59 +24,26 @@ function DoChart { } -function BarChart { - param( - $targetData, - $title, - [OfficeOpenXml.Drawing.Chart.eChartType]$ChartType="BarStacked", - [Switch]$NoLegend, - [Switch]$ShowCategory, - [Switch]$ShowPercent - ) - - DoChart $targetData $title -ChartType $ChartType ` - -NoLegend:$NoLegend -ShowCategory:$ShowCategory -ShowPercent:$ShowPercent + function BarChart { + param($targetData,$title) + DoChart $targetData $title BarStacked } -function PieChart { - param( - $targetData, - $title, - [OfficeOpenXml.Drawing.Chart.eChartType]$ChartType="PieExploded3D", - [Switch]$NoLegend, - [Switch]$ShowCategory, - [Switch]$ShowPercent - ) - - DoChart $targetData $title -ChartType $ChartType ` - -NoLegend:$NoLegend -ShowCategory:$ShowCategory -ShowPercent:$ShowPercent + function PieChart { + param($targetData,$title) + + DoChart $targetData $title Pie } -function LineChart { - param( - $targetData, - $title, - [OfficeOpenXml.Drawing.Chart.eChartType]$ChartType="Line", - [Switch]$NoLegend, - [Switch]$ShowCategory, - [Switch]$ShowPercent - ) - - DoChart $targetData $title -ChartType $ChartType ` - -NoLegend:$NoLegend -ShowCategory:$ShowCategory -ShowPercent:$ShowPercent -} + function LineChart { + param($targetData,$title) -function ColumnChart { - param( - $targetData, - $title, - [OfficeOpenXml.Drawing.Chart.eChartType]$ChartType="ColumnStacked", - [Switch]$NoLegend, - [Switch]$ShowCategory, - [Switch]$ShowPercent - ) - - DoChart $targetData $title -ChartType $ChartType ` - -NoLegend:$NoLegend -ShowCategory:$ShowCategory -ShowPercent:$ShowPercent -} + DoChart $targetData $title Line + } + + function ColumnChart { + param($targetData,$title) + + DoChart $targetData $title ColumnStacked + } diff --git a/Export-Excel.ps1 b/Export-Excel.ps1 new file mode 100644 index 0000000..329ae63 --- /dev/null +++ b/Export-Excel.ps1 @@ -0,0 +1,327 @@ +function Export-Excel { + <# + .Synopsis + .Example + gsv | Export-Excel .\test.xlsx + .Example + ps | Export-Excel .\test.xlsx -show\ + .Example + ps | Export-Excel .\test.xlsx -WorkSheetname Processes -IncludePivotTable -Show -PivotRows Company -PivotData PM + .Example + ps | Export-Excel .\test.xlsx -WorkSheetname Processes -ChartType PieExploded3D -IncludePivotChart -IncludePivotTable -Show -PivotRows Company -PivotData PM + .Example + Remove-Item "c:\temp\test.xlsx" -ErrorAction Ignore + Get-Service | Export-Excel "c:\temp\test.xlsx" -Show -IncludePivotTable -PivotRows status -PivotData @{status='count'} + #> + param( + [Parameter(Mandatory=$true)] + $Path, + [Parameter(ValueFromPipeline=$true)] + $TargetData, + [string]$WorkSheetname="Sheet1", + [string]$Title, + [OfficeOpenXml.Style.ExcelFillStyle]$TitleFillPattern="None", + [bool]$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, + [OfficeOpenXml.Table.TableStyles]$TableStyle="Medium6", + [Object[]]$ConditionalFormat, + [Object[]]$ExcelChartDefinition, + [string[]]$HideSheet, + [Switch]$KillExcel, + [Switch]$AutoNameRange, + $StartRow=1, + $StartColumn=1 + ) + + Begin { + if($KillExcel) { + Get-Process excel -ErrorAction Ignore | Stop-Process + while (Get-Process excel -ErrorAction Ignore) {} + } + + try { + $Path = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($Path) + if (Test-Path $path) { + 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($format.Address, $format.IconType) + $rule.Reverse = $format.Reverse + } + + # Force at least one cell value + #$ws.Cells[1, 1].Value = "" + + + $Row = $StartRow + if($Title) { + $ws.Cells[$Row, $StartColumn].Value = $Title + + $ws.Cells[$Row, $StartColumn].Style.Font.Size = $TitleSize + $ws.Cells[$Row, $StartColumn].Style.Font.Bold = $TitleBold + $ws.Cells[$Row, $StartColumn].Style.Fill.PatternType = $TitleFillPattern + if($TitleBackgroundColor) { + $ws.Cells[$Row, $StartColumn].Style.Fill.BackgroundColor.SetColor($TitleBackgroundColor) + } + + $Row += 1 + } + + } 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 = $StartColumn + + $targetCell = $ws.Cells[$Row, $ColumnIndex] + + $r=$null + $cellValue=$TargetData + 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 = $StartColumn + + $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 = $StartColumn + + foreach ($Name in $Header) { + + $targetCell = $ws.Cells[$Row, $ColumnIndex] + + $cellValue=$TargetData.$Name + + if($cellValue -is [string] -and $cellValue.StartsWith('=')) { + $targetCell.Formula = $cellValue + } else { + + $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"} + } + + #[ref]$uriResult=$null + #if ([uri]::TryCreate($cellValue, [System.UriKind]::Absolute, $uriResult)) { + + # $targetCell.Hyperlink = [uri]$cellValue + + # $namedStyle=$ws.Workbook.Styles.NamedStyles | where {$_.Name -eq 'HyperLink'} + # if(!$namedStyle) { + # $namedStyle=$ws.Workbook.Styles.CreateNamedStyle("HyperLink") + # $namedStyle.Style.Font.UnderLine = $true + # $namedStyle.Style.Font.Color.SetColor("Blue") + # } + + # $targetCell.StyleName = "HyperLink" + #} + + $ColumnIndex += 1 + } + } + } + + End { + if($AutoNameRange) { + $totalRows=$ws.Dimension.Rows + $totalColumns=$ws.Dimension.Columns + + foreach($c in 0..($totalColumns-1)) { + $targetRangeName = "$($Header[$c])" + $targetColumn = $c+1 + $theCell = $ws.Cells[2,$targetColumn,$totalRows,$targetColumn ] + $ws.Names.Add($targetRangeName, $theCell) | Out-Null + } + } + + $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 + #"$($StartRow),$($StartColumn),$($ws.Dimension.End.Row-$StartRow),$($Header.Count)" + + $csr=$StartRow + $csc=$StartColumn + $cer=$ws.Dimension.End.Row #-$StartRow+1 + $cec=$Header.Count + + $targetRange=$ws.Cells[$csr, $csc, $cer,$cec] + + $tbl = $ws.Tables.Add($targetRange, $TableName) + + $tbl.TableStyle=$TableStyle + + $idx + } + + if($IncludePivotTable) { + $pivotTableName = $WorkSheetname + "PivotTable" + $wsPivot = $pkg | Add-WorkSheet -WorkSheetname $pivotTableName -NoClobber:$NoClobber + + $wsPivot.View.TabSelected = $true + + $pivotTableDataName=$WorkSheetname + "PivotTableData" + + if($Title) {$startAddress="A2"} + $pivotTable = $wsPivot.PivotTables.Add($wsPivot.Cells["A1"], $ws.Cells[$dataRange], $pivotTableDataName) + + 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 | % { + $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" + + } + + $chartCount=0 + foreach ($chartDef in $ExcelChartDefinition) { + $ChartName = "Chart"+(Split-Path -Leaf ([System.IO.path]::GetTempFileName())) -replace 'tmp|\.','' + $chart = $ws.Drawings.AddChart($ChartName, $chartDef.ChartType) + $chart.Title.Text = $chartDef.Title + $chart.SetPosition($chartDef.Row, $chartDef.RowOffsetPixels,$chartDef.Column, $chartDef.ColumnOffsetPixels) + $chart.SetSize($chartDef.Width, $chartDef.Height) + + $chartDefCount = @($chartDef.XRange).Count + if($chartDefCount -eq 1) { + $Series=$chart.Series.Add($chartDef.YRange, $chartDef.XRange) + $Series.Header = $chartDef.Header + } else { + for($idx=0; $idx -lt $chartDefCount; $idx+=1) { + $Series=$chart.Series.Add($chartDef.YRange[$idx], $chartDef.XRange) + $Series.Header = $chartDef.Header[$idx] + } + } + } + + $pkg.Save() + $pkg.Dispose() + + if($Show) {Invoke-Item $Path} + } +} diff --git a/New-ExcelChart.ps1 b/New-ExcelChart.ps1 new file mode 100644 index 0000000..f427949 --- /dev/null +++ b/New-ExcelChart.ps1 @@ -0,0 +1,30 @@ +function New-ExcelChart { + param( + $Title="Chart Title", + $Header, + [OfficeOpenXml.Drawing.Chart.eChartType]$ChartType="ColumnStacked", + $XRange, + $YRange, + $Width=500, + $Height=350, + $Row=0, + $RowOffSetPixels=10, + $Column=6, + $ColumnOffSetPixels=5 + ) + + [PSCustomObject]@{ + Title=$Title + Header=$Header + ChartType=$ChartType + XRange=$XRange + YRange=$YRange + Width=$Width + Height=$Height + + Row=$Row + RowOffSetPixels=$RowOffSetPixels + Column=$Column + ColumnOffSetPixels=$ColumnOffSetPixels + } +} \ No newline at end of file