Examples/Subtotals.ps1
$Data = ConvertFrom-Csv @'
Product, City, Gross, Net Apple, London , 300, 250 Orange, London , 400, 350 Banana, London , 300, 200 Grape, Munich, 100, 100 Orange, Paris, 600, 500 Banana, Paris, 300, 200 Apple, New York, 1200,700 '@ $ExcelPath = "$env:temp\subtotal.xlsx" $SheetName = 'Sheet1' Remove-Item -Path $ExcelPath -ErrorAction SilentlyContinue $GroupByFieldName = 'City' $TotalSingleRows = $false $GrandTotal = $false $SubtotalRowHeight = 0 #If non zero will set subtotals to this height $Subtotals =@{ 'Net' = {"=SUBTOTAL(3,D{0}:D{1})" -f $from, $to} } $SubtotalFieldName = 'Net' $SubtotalFormula = '=SUBTOTAL(3,D{0}:D{1})' # {0} and {1} are placeholders for the first and last row. D is the column to total in # 1=AVERAGE; 2=COUNT; 3=COUNTA; 4=MAX; 5=MIN; 6=PRODUCT; 7=STDEV; 8=STDEVP; 9=SUM; 10=VAR; 11=VARP add 100 to ignore hidden values #at each change in the Group by field, insert a subtotal (count) formula in the title column & send to excel - list those rows and make them half height after export $currentRow = 2 $lastChangeRow = 2 $insertedRows = @() #$hideRows = @() $lastValue = $Data[0].$GroupByFieldName $excel = $Data | ForEach-Object -Process { if ($_.$GroupByFieldName -ne $lastvalue) { if ($lastChangeRow -lt ($currentrow - 1) -or $totalSingleRows) { $formula = $SubtotalFormula -f $lastChangeRow, ($currentrow - 1) $insertedRows += $currentRow [pscustomobject]@{$SubtotalFieldName = $formula} $currentRow += 1 } $lastChangeRow = $currentRow $lastValue = $_.$GroupByFieldName } $_ $currentRow += 1 } -end { $formula = $SubtotalFormula -f $lastChangeRow, ($currentrow - 1) [pscustomobject]@{$SubtotalFieldName=$formula} if ($GrandTotal) { $formula = $SubtotalFormula -f $lastChangeRow, ($currentrow - 1) [pscustomobject]@{$SubtotalFieldName=$formula} } } | Export-Excel -Path $ExcelPath -PassThru -AutoSize -AutoFilter -BoldTopRow -WorksheetName $sheetName #We kept a lists of the total rows. Since single rows won't get expanded/collapsed hide them. if ($subtotalrowHeight) { foreach ($r in $insertedrows) { $excel.WorkItems.Row($r).Height = $SubtotalRowHeight} } #foreach ($r in $hideRows) { $excel.$SheetName.Row($r).hidden = $true} $range = $excel.$SheetName.Dimension.Address $sheetIndex = $excel.Sheet1.Index Close-ExcelPackage -ExcelPackage $excel try { $excelApp = New-Object -ComObject "Excel.Application" } catch { Write-Warning "Could not start Excel application - which usually means it is not installed." ; return } try { $excelWorkBook = $excelApp.Workbooks.Open($ExcelPath) } catch { Write-Warning -Message "Could not Open $ExcelPath." ; return } $ws = $excelWorkBook.Worksheets.Item($sheetIndex) $null = $ws.Range($range).Select() $null = $excelapp.Selection.AutoOutline() $excelWorkBook.Save() $excelWorkBook.Close() $excelApp.Quit() Start-Process $ExcelPath |