Merge remote-tracking branch 'upstream/master'

This commit is contained in:
jhoneill
2020-03-16 11:43:10 +00:00
8 changed files with 251 additions and 154 deletions

View File

@@ -0,0 +1,27 @@
<#
To see this written up with example screenshots, head over to the IT Splat blog
URL: http://bit.ly/2SxieeM
#>
## Create an Excel file with multiple worksheets
# Get a list of processes on the system
$processes = Get-Process | Sort-Object -Property ProcessName | Group-Object -Property ProcessName | Where-Object {$_.Count -gt 2}
# Export the processes to Excel, each process on its own sheet
$processes | ForEach-Object { $_.Group | Export-Excel -Path MultiSheetExample.xlsx -WorksheetName $_.Name -AutoSize -AutoFilter }
# Show the completed file
Invoke-Item .\MultiSheetExample.xlsx
## Add an additional sheet to the new workbook
# Use Open-ExcelPackage to open the workbook
$excelPackage = Open-ExcelPackage -Path .\MultiSheetExample.xlsx
# Create a new worksheet and give it a name, set MoveToStart to make it the first sheet
$ws = Add-Worksheet -ExcelPackage $excelPackage -WorksheetName 'All Services' -MoveToStart
# Get all the running services on the system
Get-Service | Export-Excel -ExcelPackage $excelPackage -WorksheetName $ws -AutoSize -AutoFilter
# Close the package and show the final result
Close-ExcelPackage -ExcelPackage $excelPackage -Show

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

View File

@@ -0,0 +1,31 @@
# DSUM
# Adds the numbers in a field (column) of records in a list or database that match conditions that you specify.
$xlfile = "$env:TEMP\test.xlsx"
Remove-Item $xlfile -ErrorAction SilentlyContinue
$data = ConvertFrom-Csv @"
Color,Date,Sales
Red,1/15/2018,250
Blue,1/15/2018,200
Red,1/16/2018,175
Blue,1/16/2018,325
Red,1/17/2018,150
Blue,1/17/2018,300
"@
$xl = Export-Excel -InputObject $data -Path $xlfile -AutoSize -AutoFilter -TableName SalesInfo -AutoNameRange -PassThru
$databaseAddress = $xl.Sheet1.Dimension.Address
Set-Format -Worksheet $xl.Sheet1 -Range C:C -NumberFormat '$##0'
Set-Format -Worksheet $xl.Sheet1 -Range E1 -Value Color
Set-Format -Worksheet $xl.Sheet1 -Range F1 -Value Date
Set-Format -Worksheet $xl.Sheet1 -Range G1 -Value Sales
Set-Format -Worksheet $xl.Sheet1 -Range E2 -Value Red
Set-Format -Worksheet $xl.Sheet1 -Range E4 -Value Sales
Set-Format -Worksheet $xl.Sheet1 -Range F4 -Formula ('=DSUM({0},"Sales",E1:G2)' -f $databaseAddress) -NumberFormat '$##0'
Close-ExcelPackage $xl -Show

View File

@@ -0,0 +1,19 @@
$xlfile = "$env:TEMP\test.xlsx"
Remove-Item $xlfile -ErrorAction SilentlyContinue
$data = ConvertFrom-Csv @"
Fruit,Amount
Apples,50
Oranges,20
Bananas,60
Lemons,40
"@
$xl = Export-Excel -InputObject $data -Path $xlfile -PassThru -AutoSize
Set-ExcelRange -Worksheet $xl.Sheet1 -Range D2 -BackgroundColor LightBlue -Value Apples
$Rows = $xl.Sheet1.Dimension.Rows
Set-ExcelRange -Worksheet $xl.Sheet1 -Range E2 -Formula "=VLookup(D2,A2:B$($Rows),2,FALSE)"
Close-ExcelPackage $xl -Show

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

View File

@@ -87,7 +87,6 @@
$Worksheet.Cells[$StartRow, $C] | Where-Object {-not [string]::IsNullOrEmpty($_.Value) } | Select-Object @{N = 'Column'; E = { $C } }, Value
}
}
}
catch {
throw "Failed creating property names: $_" ; return
}
@@ -119,7 +118,6 @@
throw "Worksheet '$WorksheetName' not found, the workbook only contains the worksheets '$($ExcelPackage.Workbook.Worksheets)'. If you only wish to select the first worksheet, please remove the '-WorksheetName' parameter." ; return
}
Write-Debug $sw.Elapsed.TotalMilliseconds
#region Get rows and columns
#If we are doing dataonly it is quicker to work out which rows to ignore before processing the cells.
if (-not $EndRow ) { $EndRow = $Worksheet.Dimension.End.Row }
@@ -145,7 +143,14 @@
$Columns = $StartColumn .. $EndColumn ; if ($StartColumn -gt $EndColumn) { Write-Warning -Message "Selecting columns $StartColumn to $EndColumn might give odd results." }
if ($NoHeader) { $Rows = $StartRow..$EndRow ; if ($StartRow -gt $EndRow) { Write-Warning -Message "Selecting rows $StartRow to $EndRow might give odd results." } }
elseif ($HeaderName) { $Rows = $StartRow..$EndRow }
else { $Rows = (1 + $StartRow)..$EndRow } # ; if ($StartRow -ge $EndRow) { Write-Warning -Message "Selecting $StartRow as the header with data in $(1+$StartRow) to $EndRow might give odd results." } }
else {
$Rows = (1 + $StartRow)..$EndRow
if ($StartRow -eq 1 -and $EndRow -eq 1) {
$Rows = 0
}
}
# ; if ($StartRow -ge $EndRow) { Write-Warning -Message "Selecting $StartRow as the header with data in $(1+$StartRow) to $EndRow might give odd results." } }
}
#endregion
#region Create property names
@@ -156,44 +161,29 @@
throw "Duplicate column headers found on row '$StartRow' in columns '$($Duplicates.Group.Column)'. Column headers must be unique, if this is not a requirement please use the '-NoHeader' or '-HeaderName' parameter."; return
}
#endregion
Write-Debug $sw.Elapsed.TotalMilliseconds
if (-not $Rows) {
Write-Warning "Worksheet '$WorksheetName' in workbook '$Path' contains no data in the rows after top row '$StartRow'"
}
else {
#region Create one object per row
if ($AsText -or $AsDate) {
if ($AsText) {
<#join items in AsText together with ~~~ . Escape any regex special characters...
# which turns "*" into "\*" make it ".*". Convert ~~~ to $|^ and top and tail with ^%;
So if we get "Week", "[Time]" and "*date*" ; make the expression ^week$|^\[Time\]$|^.*Date.*$
$make a regex for this which is case insensitive (option 1) and compiled (option 8)
#>
$TextColExpression = ''
if ($AsText) {
$TextColExpression += '(?<astext>^' + [regex]::Escape($AsText -join '~~~').replace('\*', '.*').replace('~~~', '$|^') + '$)'
}
if ($AsText -and $AsDate) {
$TextColExpression += "|"
}
if ($AsDate) {
$TextColExpression += '(?<asDate>^' + [regex]::Escape($AsDate -join '~~~').replace('\*', '.*').replace('~~~', '$|^') + '$)'
}
$TextColExpression = "^" + [regex]::Escape($AsText -join "~~~").replace("\*", ".*").replace("~~~", "$|^") + "$"
$TextColRegEx = New-Object -TypeName regex -ArgumentList $TextColExpression , 9
}
else {$TextColRegEx = $null}
foreach ($R in $Rows) {
#Disabled write-verbose for speed
# Write-Verbose "Import row '$R'"
$NewRow = [Ordered]@{ }
if ($TextColRegEx) {
foreach ($P in $PropertyNames) {
$MatchTest = $TextColRegEx.Match($P.value)
if ($MatchTest.groups.name -eq "astext") {
if ($TextColRegEx.IsMatch($P.Value)) {
$NewRow[$P.Value] = $Worksheet.Cells[$R, $P.Column].Text
}
elseif ($MatchTest.groups.name -eq "asdate" -and $Worksheet.Cells[$R, $P.Column].Value -is [System.ValueType]) {
$NewRow[$P.Value] = [datetime]::FromOADate(($Worksheet.Cells[$R, $P.Column].Value))
}
else { $NewRow[$P.Value] = $Worksheet.Cells[$R, $P.Column].Value }
}
}
@@ -207,7 +197,6 @@
}
#endregion
}
Write-Debug $sw.Elapsed.TotalMilliseconds
}
catch { throw "Failed importing the Excel workbook '$Path' with worksheet '$Worksheetname': $_"; return }
finally {

View File

@@ -1,4 +1,5 @@
$xlfile = "TestDrive:\testImportExcel.xlsx"
$xlfileHeaderOnly = "TestDrive:\testImportExcelHeaderOnly.xlsx"
Describe "Import-Excel on a sheet with no headings" {
BeforeAll {
@@ -18,6 +19,15 @@ Describe "Import-Excel on a sheet with no headings" {
Set-ExcelRange -Worksheet $xl.Sheet1 -Range C3 -Value 'I'
Close-ExcelPackage $xl
# crate $xlfileHeaderOnly
$xl = "" | Export-excel $xlfileHeaderOnly -PassThru
Set-ExcelRange -Worksheet $xl.Sheet1 -Range A1 -Value 'A'
Set-ExcelRange -Worksheet $xl.Sheet1 -Range B1 -Value 'B'
Set-ExcelRange -Worksheet $xl.Sheet1 -Range C1 -Value 'C'
Close-ExcelPackage $xl
}
It "Import-Excel should have this shape" {
@@ -193,4 +203,25 @@ Describe "Import-Excel on a sheet with no headings" {
# $actual[0].City | Should -BeExactly 'Brussels'
}
It "Should handle data correctly if there is only a single row" {
$actual = Import-Excel $xlfileHeaderOnly
$names = $actual.psobject.properties.Name
$names | should be $null
$actual.Count | should be 0
}
It "Should handle data correctly if there is only a single row and using -NoHeader " {
$actual = @(Import-Excel $xlfileHeaderOnly -WorksheetName Sheet1 -NoHeader)
$names = $actual[0].psobject.properties.Name
$names.count | should be 3
$names[0] | should be 'P1'
$names[1] | should be 'P2'
$names[2] | should be 'P3'
$actual.Count | should be 1
$actual[0].P1 | should be 'A'
$actual[0].P2 | should be 'B'
$actual[0].P3 | should be 'C'
}
}

View File

@@ -194,7 +194,7 @@ Accept wildcard characters: False
```
### -GroupDateRow
The name of a row field which should be grouped by parts of the date/time (ignored if GroupDateRow is not specified)
The name of a row field which should be grouped by parts of the date/time (ignored if GroupDatePart is not specified)
```yaml
Type: String