Merge pull request #1300 from thkn-hofa/master

Add TotalSettings parameter to Export-Excel
This commit is contained in:
Doug Finke
2022-11-11 10:01:17 -05:00
committed by GitHub
7 changed files with 143 additions and 4 deletions

View File

@@ -0,0 +1,28 @@
try { Import-Module $PSScriptRoot\..\..\ImportExcel.psd1 } catch { throw ; return }
$data = ConvertFrom-Csv @"
OrderId,Category,Sales,Quantity,Discount
1,Cosmetics,744.01,07,0.7
2,Grocery,349.13,25,0.3
3,Apparels,535.11,88,0.2
4,Electronics,524.69,60,0.1
5,Electronics,439.10,41,0.0
6,Apparels,56.84,54,0.8
7,Electronics,326.66,97,0.7
8,Cosmetics,17.25,74,0.6
9,Grocery,199.96,39,0.4
10,Grocery,731.77,20,0.3
"@
$xlfile = "$PSScriptRoot\TotalsRow.xlsx"
Remove-Item $xlfile -ErrorAction SilentlyContinue
$TotalSettings = @{
Quantity = 'Sum'
Category = @{
# Count the number of categories not equal to Electronics
Custom = '=COUNTIF([Category],"<>Electronics")'
}
}
$data | Export-Excel -Path $xlfile -TableName Sales -TableStyle Medium10 -TotalSettings $TotalSettings -AutoSize -Show

View File

@@ -0,0 +1,15 @@
try {Import-Module $PSScriptRoot\..\..\ImportExcel.psd1} catch {throw ; return}
$r = Get-ChildItem C:\WINDOWS\system32 -File
$TotalSettings = @{
Length = "Sum"
Name = "Count"
Extension = @{
# You can create the formula in an Excel workbook first and copy-paste it here
# This syntax can only be used for the Custom type
Custom = "=COUNTIF([Extension];`".exe`")"
}
}
$r | Export-Excel -TableName system32files -TableStyle Medium10 -TotalSettings $TotalSettings -Show

View File

@@ -6,7 +6,7 @@
RootModule = 'ImportExcel.psm1'
# Version number of this module.
ModuleVersion = '7.8.2'
ModuleVersion = '7.8.3'
# ID used to uniquely identify this module
GUID = '60dd4136-feff-401a-ba27-a84458c57ede'

View File

@@ -55,6 +55,31 @@ function Add-ExcelTable {
$tbl.ShowTotal = $true
foreach ($k in $TotalSettings.keys) {
if (-not $tbl.Columns[$k]) {Write-Warning -Message "Table does not have a Column '$k'."}
elseif ($TotalSettings[$k] -is [HashTable] -and $TotalSettings[$k].Keys.Count -eq 1 -and $TotalSettings[$k].Keys[0] -eq "Custom") {
$formula = $TotalSettings[$k][($TotalSettings[$k].Keys[0])] | Select -First 1
### A function in Excel uses ";" between parameters but the OpenXML parameter separator is ","
### Only replace semicolon when it's NOT somewhere between quotes quotes.
# Get all text between quotes
$QuoteMatches = [Regex]::Matches($formula,"`"[^`"]*`"|'[^']*'")
# Create array with all indexes of characters between quotes (and the quotes themselves)
$QuoteCharIndexes = $(
Foreach ($QuoteMatch in $QuoteMatches) {
(($QuoteMatch.Index)..($QuoteMatch.Index + $QuoteMatch.Length - 1))
}
)
# Get all semicolons
$SemiColonMatches = [Regex]::Matches($formula, ";")
# Replace the semicolons of which the index is not in the list of quote-text indexes
Foreach ($SemiColonMatch in $SemiColonMatches.Index) {
If ($QuoteCharIndexes -notcontains $SemiColonMatch) {
$formula = $formula.remove($SemiColonMatch,1).Insert($SemiColonMatch,",")
}
}
# Configure the formula. The TotalsRowFunction is automatically set to "Custom" when the TotalsRowFormula is set.
$tbl.Columns[$k].TotalsRowFormula = $formula
}
elseif ($TotalSettings[$k] -notin @("Average", "Count", "CountNums", "Max", "Min", "None", "StdDev", "Sum", "Var") ) {
Write-Warning -Message "'$($TotalSettings[$k])' is not a valid total function."
}

View File

@@ -56,6 +56,7 @@
[Alias('Table')]
$TableName,
[OfficeOpenXml.Table.TableStyles]$TableStyle = [OfficeOpenXml.Table.TableStyles]::Medium6,
[HashTable]$TotalSettings,
[Switch]$BarChart,
[Switch]$PieChart,
[Switch]$LineChart ,
@@ -211,7 +212,12 @@
$row ++
$null = $ws.Cells[$row, $StartColumn].LoadFromDataTable($InputObject, $false )
if ($TableName -or $PSBoundParameters.ContainsKey('TableStyle')) {
Add-ExcelTable -Range $ws.Cells[$ws.Dimension] -TableName $TableName -TableStyle $TableStyle
if ($PSBoundParameters.ContainsKey('TotalSettings')) {
Add-ExcelTable -Range $ws.Cells[$ws.Dimension] -TableName $TableName -TableStyle $TableStyle -TotalSettings $TotalSettings
}
Else {
Add-ExcelTable -Range $ws.Cells[$ws.Dimension] -TableName $TableName -TableStyle $TableStyle
}
}
}
else {
@@ -424,7 +430,12 @@
if ($null -ne $TableName -or $PSBoundParameters.ContainsKey('TableStyle')) {
#Already inserted Excel table if input was a DataTable
if ($InputObject -isnot [System.Data.DataTable]) {
Add-ExcelTable -Range $ws.Cells[$dataRange] -TableName $TableName -TableStyle $TableStyle
if ($PSBoundParameters.ContainsKey('TotalSettings')) {
Add-ExcelTable -Range $ws.Cells[$dataRange] -TableName $TableName -TableStyle $TableStyle -TotalSettings $TotalSettings
}
else {
Add-ExcelTable -Range $ws.Cells[$dataRange] -TableName $TableName -TableStyle $TableStyle
}
}
}
elseif ($AutoFilter) {

View File

@@ -1,4 +1,4 @@
#Requires -Modules Pester
#Requires -Modules @{ ModuleName="Pester"; ModuleVersion="4.0.0" }
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '', Justification = 'False Positives')]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidAssignmentToAutomaticVariable', '', Justification = 'Only executes on versions without the automatic variable')]
param()
@@ -683,6 +683,62 @@ Describe ExportExcel -Tag "ExportExcel" {
}
}
Context "#Example 10 # Creates a file with a table with a 'totals' row".PadRight(87) {
BeforeEach {
$path = "TestDrive:\test.xlsx"
Remove-item -Path $path -ErrorAction SilentlyContinue
#Test with a maximum of 50 processes for speed; export limited set of properties.
$processes = Get-Process | Where-Object { $_.StartTime } | Select-Object -First 50
# Export as table with a totals row with a set of possibilities
$TotalSettings = @{
Id = "COUNT"
WS = "SUM"
Handles = "AVERAGE"
CPU = @{
Custom = '=COUNTIF([CPU];"<1")'
}
}
$Processes | Export-Excel $path -TableName "processes" -TotalSettings $TotalSettings
$TotalRows = $Processes.count + 2 # Column header + Data (50 processes) + Totals row
$Excel = Open-ExcelPackage -Path $path
$ws = $Excel.Workbook.Worksheets[1]
}
it "Totals row was created".PadRight(87) {
$ws.Tables[0].Address.Rows | Should -Be $TotalRows
$ws.tables[0].ShowTotal | Should -Be $True
}
it "Added four calculations in the totals row".PadRight(87) {
$IDcolumn = $ws.Tables[0].Columns | Where-Object { $_.Name -eq "id" }
$WScolumn = $ws.Tables[0].Columns | Where-Object { $_.Name -eq "WS" }
$HandlesColumn = $ws.Tables[0].Columns | Where-Object { $_.Name -eq "Handles" }
$CPUColumn = $ws.Tables[0].Columns | Where-Object { $_.Name -eq "CPU" }
$IDcolumn | Select-Object -ExpandProperty TotalsRowFunction | Should -Be "Count"
$WScolumn | Select-Object -ExpandProperty TotalsRowFunction | Should -Be "Sum"
$HandlesColumn | Select-Object -ExpandProperty TotalsRowFunction | Should -Be "Average"
$CPUColumn | Select-Object -ExpandProperty TotalsRowFunction | Should -Be "Custom"
$CPUColumn | Select-Object -ExpandProperty TotalsRowFormula | Should -Be 'COUNTIF([CPU],"<1")'
$CountAddress = "{0}{1}" -f (Get-ExcelColumnName -ColumnNumber $IDcolumn.Id).ColumnName, $TotalRows
$SumAddress = "{0}{1}" -f (Get-ExcelColumnName -ColumnNumber $WScolumn.Id).ColumnName, $TotalRows
$AverageAddress = "{0}{1}" -f (Get-ExcelColumnName -ColumnNumber $HandlesColumn.Id).ColumnName, $TotalRows
$CustomAddress = "{0}{1}" -f (Get-ExcelColumnName -ColumnNumber $CPUColumn.Id).ColumnName, $TotalRows
$ws.Cells[$CountAddress].Formula | Should -Be "SUBTOTAL(103,processes[Id])"
$ws.Cells[$SumAddress].Formula | Should -Be "SUBTOTAL(109,processes[Ws])"
$ws.Cells[$AverageAddress].Formula | Should -Be "SUBTOTAL(101,processes[Handles])"
$ws.Cells[$CustomAddress].Formula | Should -Be 'COUNTIF([CPU],"<1")'
}
AfterEach {
Close-ExcelPackage -ExcelPackage $Excel
}
}
# Context "#Example 11 # Create and append with title, inc ranges and Pivot table" {
# $path = "TestDrive:\test.xlsx"
# #Test New-PivotTableDefinition builds definition using -Pivotfilter and -PivotTotals options.

View File

@@ -1,3 +1,7 @@
# 7.8.3
- Extended Export-Excel with parameter TotalSettings. [Thomas Hofkens](https://github.com/thkn-hofa/ImportExcel)
# 7.8.2
- Fix docs [#1254](https://github.com/dfinke/ImportExcel/pull/1251)`Add-Worksheet` warning. Thank you [Wilson Stewart](https://github.com/WilsonStewart)