Merge pull request #389 from jhoneill/master

Latest bunch of changes
This commit is contained in:
Doug Finke
2018-07-19 09:48:54 -04:00
committed by GitHub
9 changed files with 590 additions and 250 deletions

View File

@@ -63,6 +63,14 @@
[Parameter(Mandatory = $true, ParameterSetName = "FiveIconSet")]
[Parameter(Mandatory = $true, ParameterSetName = "FiveIconSetAddress")]
[OfficeOpenXml.ConditionalFormatting.eExcelconditionalFormatting5IconsSetType]$FiveIconsSet,
#Use the icon set in reverse order
[Parameter(ParameterSetName = "ThreeIconSet")]
[Parameter(ParameterSetName = "ThreeIconSetAddress")]
[Parameter(ParameterSetName = "FourIconSet")]
[Parameter(ParameterSetName = "FourIconSetAddress")]
[Parameter(ParameterSetName = "FiveIconSet")]
[Parameter(ParameterSetName = "FiveIconSetAddress")]
[switch]$Reverse,
#A value for the condition (e.g. "2000" if the test is 'lessthan 2000')
[string]$ConditionValue,
#A second value for the conditions like "between x and Y"
@@ -82,36 +90,39 @@
#Underline matching items
[switch]$Underline,
#Strikethrough text of matching items
[switch]$StrikeThru
[switch]$StrikeThru,
#If specified pass the rule back to the caller to allow additional customization.
[switch]$Passthru
)
#Allow conditional formatting to work like Set-Format (with single ADDRESS parameter), split it to get worksheet and range of cells.
If ($Address -and -not $WorkSheet -and -not $Range) {
$WorkSheet = $Address.Worksheet[0]
$Range = $Address.Address
}
If ($ThreeIconsSet) {$rule = $WorkSheet.ConditionalFormatting.AddThreeIconSet($Range , $ThreeIconsSet)}
elseif ($FourIconsSet) {$rule = $WorkSheet.ConditionalFormatting.AddFourIconSet( $Range , $FourIconsSet) }
elseif ($FiveIconsSet) {$rule = $WorkSheet.ConditionalFormatting.AddFiveIconSet( $Range , $IconType) }
elseif ($DataBarColor) {$rule = $WorkSheet.ConditionalFormatting.AddDatabar( $Range , $DataBarColor) }
else { $rule = ($WorkSheet.ConditionalFormatting)."Add$RuleType"($Range)}
if ($ConditionValue -and $RuleType -match "Top|Botom") {$rule.Rank = $ConditionValue }
if ($ConditionValue -and $RuleType -match "StdDev") {$rule.StdDev = $ConditionValue }
if ($ConditionValue -and $RuleType -match "Than|Equal|Expression") {$rule.Formula = $ConditionValue }
if ($ConditionValue -and $RuleType -match "Text|With") {$rule.Text = $ConditionValue }
if ($ConditionValue -and
If ($ThreeIconsSet) {$rule = $WorkSheet.ConditionalFormatting.AddThreeIconSet($Range , $ThreeIconsSet)}
elseif ($FourIconsSet) {$rule = $WorkSheet.ConditionalFormatting.AddFourIconSet( $Range , $FourIconsSet) }
elseif ($FiveIconsSet) {$rule = $WorkSheet.ConditionalFormatting.AddFiveIconSet( $Range , $IconType) }
elseif ($DataBarColor) {$rule = $WorkSheet.ConditionalFormatting.AddDatabar( $Range , $DataBarColor) }
else {$rule = ($WorkSheet.ConditionalFormatting)."Add$RuleType"($Range)}
if ($reverse) {$rule.reverse = $true}
if ($ConditionValue -and $RuleType -match "Top|Botom") {$rule.Rank = $ConditionValue }
if ($ConditionValue -and $RuleType -match "StdDev") {$rule.StdDev = $ConditionValue }
if ($ConditionValue -and $RuleType -match "Than|Equal|Expression") {$rule.Formula = $ConditionValue }
if ($ConditionValue -and $RuleType -match "Text|With") {$rule.Text = $ConditionValue }
if ($ConditionValue -and
$ConditionValue2 -and $RuleType -match "Between") {
$rule.Formula = $ConditionValue
$rule.Formula = $ConditionValue
$rule.Formula2 = $ConditionValue2
}
if ($NumberFormat) {$rule.Style.NumberFormat.Format = $NumberFormat }
if ($Underline) {$rule.Style.Font.Underline = [OfficeOpenXml.Style.ExcelUnderLineType]::Single }
if ($Bold) {$rule.Style.Font.Bold = $true}
if ($Italic) {$rule.Style.Font.Italic = $true}
if ($StrikeThru) {$rule.Style.Font.Strike = $true}
if ($ForeGroundColor) {$rule.Style.Font.Color.color = $ForeGroundColor }
if ($BackgroundColor) {$rule.Style.Fill.BackgroundColor.color = $BackgroundColor }
if ($BackgroundPattern) {$rule.Style.Fill.PatternType = $BackgroundPattern }
if ($PatternColor) {$rule.Style.Fill.PatternColor.color = $PatternColor }
if ($NumberFormat) {$rule.Style.NumberFormat.Format = $NumberFormat }
if ($Underline) {$rule.Style.Font.Underline = [OfficeOpenXml.Style.ExcelUnderLineType]::Single }
if ($Bold) {$rule.Style.Font.Bold = $true }
if ($Italic) {$rule.Style.Font.Italic = $true }
if ($StrikeThru) {$rule.Style.Font.Strike = $true }
if ($ForeGroundColor) {$rule.Style.Font.Color.color = $ForeGroundColor }
if ($BackgroundColor) {$rule.Style.Fill.BackgroundColor.color = $BackgroundColor }
if ($BackgroundPattern) {$rule.Style.Fill.PatternType = $BackgroundPattern }
if ($PatternColor) {$rule.Style.Fill.PatternColor.color = $PatternColor }
if ($Passthru) {$rule}
}

View File

@@ -1,22 +1,110 @@
function Copy-ExcelWorkSheet {
[CmdletBinding()]
<#
.SYNOPSIS
Copies a worksheet between workbooks or within the same workbook.
.DESCRIPTION
Copy-ExcelWorkSheet takes Source and Destination workbook parameters; each can be the path to an XLSx file, an ExcelPackage object or an ExcelWorkbook object.
The Source worksheet is specified by name or number (starting from 1), and the destination worksheet can be explicitly named,
or will follow the name of the source if no name is specified.
.EXAMPLE
C:\> Copy-ExcelWorkSheet -SourceWorkbook Test1.xlsx -DestinationWorkbook Test2.xlsx
This is the simplest version of the command: no source worksheet is specified so Copy-ExcelWorksheet uses the first sheet in the workbook
No Destination sheet is specified so the new worksheet will be the same as the one which is being copied.
.EXAMPLE
C:\> Copy-ExcelWorkSheet -SourceWorkbook Server1.xlsx -sourceWorksheet "Settings" -DestinationWorkbook Settings.xlsx -DestinationWorkSheet "Server1"
Here the Settings page from Server1's workbook is copied to the 'Server1" page of a "Settings" workbook.
.EXAMPLE
C:\> $excel = Open-ExcelPackage .\test.xlsx
C:\> Copy-ExcelWorkSheet -SourceWorkbook $excel -SourceWorkSheet "first" -DestinationWorkbook $excel -Show -DestinationWorkSheet Duplicate
This opens the workbook test.xlsx and copies the worksheet named "first" to a new worksheet named "Duplicate",
because -Show is specified the file is saved and opened in Excel
.EXAMPLE
C:\> $excel = Open-ExcelPackage .\test.xlsx
C:\> Copy-ExcelWorkSheet -SourceWorkbook $excel -SourceWorkSheet 1 -DestinationWorkbook $excel -DestinationWorkSheet Duplicate
C:\> Close-ExcelPackage $excel
This is almost the same as the previous example, except source sheet is specified by position rather than name and
because -Show is not specified, so other steps can be carried using the package object, at the end the file is saved by Close-ExcelPackage
#>
param(
#An ExcelWorkbook or ExcelPackage object or the path to an XLSx file where the data is found.
[Parameter(Mandatory=$true)]
$SourceWorkbook,
[Parameter(Mandatory=$true)]
$SourceWorkSheet,
#Name or number (starting from 1) of the worksheet in the source workbook (defaults to 1).
$SourceWorkSheet = 1 ,
#An ExcelWorkbook or ExcelPackage object or the path to an XLSx file where the data should be copied.
[Parameter(Mandatory=$true)]
$DestinationWorkbook,
#Name of the worksheet in the destination workbook; by default the same as the source worksheet's name. If the sheet exists it will be deleted and re-copied.
$DestinationWorkSheet,
#if the destination is an excel package or a path, launch excel and open the file on completion.
[Switch]$Show
)
Write-Verbose "Copying $($SourceWorkSheet) from $($SourceWorkbook) to $($DestinationWorkSheet) in $($DestinationWorkbook)"
if(!$DestinationWorkSheet) {
$DestinationWorkSheet = $SourceWorkSheet
#Special case - give the same path for source and destination worksheet
if ($SourceWorkbook -is [System.String] -and $SourceWorkbook -eq $DestinationWorkbook) {
if (-not $DestinationWorkSheet) {Write-Warning -Message "You must specify a destination worksheet name if copying within the same workbook."; return}
else {
Write-Verbose -Message "Copying "
$excel = Open-ExcelPackage -Path $SourceWorkbook
if (-not $excel.Workbook.Worksheets[$Sourceworksheet]) {
Write-Warning -Message "Could not find Worksheet $sourceWorksheet in $sourceWorkbook"
Close-ExcelPackage -ExcelPackage $excel -NoSave
return
}
elseif ($excel.Workbook.Worksheets[$Sourceworksheet].name -eq $DestinationWorkSheet) {
Write-Warning -Message "The destination worksheet name is the same as the source. "
Close-ExcelPackage -ExcelPackage $excel -NoSave
return
}
else {
$null = Add-WorkSheet -ExcelPackage $Excel -WorkSheetname $DestinationWorkSheet -CopySource ($excel.Workbook.Worksheets[$SourceWorkSheet])
Close-ExcelPackage -ExcelPackage $excel -Show:$Show
return
}
}
}
else {
if ($SourceWorkbook -is [OfficeOpenXml.ExcelWorkbook]) {$sourcews=$SourceWorkbook.Worksheets[$SourceWorkSheet]}
elseif ($SourceWorkbook -is [OfficeOpenXml.ExcelPackage] ) {$sourcews=$SourceWorkbook.Workbook.Worksheets[$SourceWorkSheet]}
else {
$SourceWorkbook = (Resolve-Path $SourceWorkbook).ProviderPath
try {
Write-Verbose "Opening worksheet '$Worksheetname' in Excel workbook '$SourceWorkbook'."
$Stream = New-Object -TypeName System.IO.FileStream -ArgumentList $SourceWorkbook, 'Open', 'Read' ,'ReadWrite'
$Package1 = New-Object -TypeName OfficeOpenXml.ExcelPackage -ArgumentList $Stream
$sourceWs = $Package1.Workbook.Worksheets[$SourceWorkSheet]
}
catch {Write-Warning -Message "Could not open $SourceWorkbook" ; return}
}
if (-not $sourceWs) {Write-Warning -Message "Could not find worksheet '$Sourceworksheet' in the source workbook." ; return}
else {
try {
if ($DestinationWorkbook -is [OfficeOpenXml.ExcelWorkbook]) {
$wb = $DestinationWorkbook
}
elseif ($DestinationWorkbook -is [OfficeOpenXml.ExcelPackage] ) {
$wb = $DestinationWorkbook.workbook
if ($show) {$package2 =$DestinationWorkbook}
}
else {
$package2 = Open-ExcelPackage -Create -Path $DestinationWorkbook
$wb = $package2.Workbook
}
if (-not $DestinationWorkSheet) {$DestinationWorkSheet = $SourceWs.Name}
if ($wb.Worksheets[$DestinationWorkSheet]) {
Write-Verbose "Destination workbook already has a sheet named '$DestinationWorkSheet', deleting it."
$wb.Worksheets.Delete($DestinationWorkSheet)
}
Write-Verbose "Copying $($SourceWorkSheet) from $($SourceWorkbook) to $($DestinationWorkSheet) in $($DestinationWorkbook)"
$null = Add-WorkSheet -ExcelWorkbook $wb -WorkSheetname $DestinationWorkSheet -CopySource $sourceWs
if ($package1) {Close-ExcelPackage -ExcelPackage $Package1 -NoSave }
if ($package2) {Close-ExcelPackage -ExcelPackage $Package2 -Show:$show }
if ($show -and $DestinationWorkbook -is [OfficeOpenXml.ExcelWorkbook]) {
Write-Warning -Message "-Show only works if the Destination workbook is given as a file path or an ExcelPackage object."
}
}
catch {Write-Warning -Message "Could not write to sheet '$DestinationWorkSheet' in the destination workbook" ; return}
}
}
Import-Excel -Path $SourceWorkbook -WorkSheetname $SourceWorkSheet |
Export-Excel -Path $DestinationWorkbook -WorkSheetname $DestinationWorkSheet -Show:$Show
}

View File

@@ -545,18 +545,20 @@
}
Else { $pkg = Open-ExcelPackage -Path $Path -Create -KillExcel:$KillExcel}
$params = @{}
$params = @{WorkSheetname=$worksheetName}
if ($NoClobber) {Write-Warning -Message "-NoClobber parameter is no longer used" }
foreach ($p in @("WorkSheetname", "ClearSheet", "MoveToStart", "MoveToEnd", "MoveBefore", "MoveAfter")) {if ($PSBoundParameters[$p]) {$params[$p] = $PSBoundParameters[$p]}}
foreach ($p in @("ClearSheet", "MoveToStart", "MoveToEnd", "MoveBefore", "MoveAfter")) {if ($PSBoundParameters[$p]) {$params[$p] = $PSBoundParameters[$p]}}
$ws = $pkg | Add-WorkSheet @params
foreach ($format in $ConditionalFormat ) {
$target = "Add$($format.Formatter)"
$rule = ($ws.ConditionalFormatting).PSObject.Methods[$target].Invoke($format.Range, $format.IconType)
$rule.Reverse = $format.Reverse
switch ($format.formatter) {
"ThreeIconSet" {Add-ConditionalFormatting -WorkSheet $ws -ThreeIconsSet $format.IconType -range $format.range -reverse:$format.reverse }
"FourIconSet" {Add-ConditionalFormatting -WorkSheet $ws -FourIconsSet $format.IconType -range $format.range -reverse:$format.reverse }
"FiveIconSet" {Add-ConditionalFormatting -WorkSheet $ws -FiveIconsSet $format.IconType -range $format.range -reverse:$format.reverse }
}
}
if ($append -and $ws.Dimension) {
if ($Append -and $ws.Dimension) {
#if there is a title or anything else above the header row, append needs to be combined wih a suitable startrow parameter
$headerRange = $ws.Dimension.Address -replace "\d+$", $StartRow
#using a slightly odd syntax otherwise header ends up as a 2D array
@@ -864,22 +866,21 @@
Column = ($lastCol +1) ;
Width = 1200
}
if ($NoHeader) {$params["NoHeader"] = $true}
if ($NoHeader) {$params["NoHeader"] = $true}
else {$Params["SeriesHeader"] = $ws.Cells[$startRow, $YCol].Value}
if ($ColumnChart) {$Params["chartType"] = "ColumnStacked" }
elseif ($Barchart) {$Params["chartType"] = "BarStacked" }
elseif ($PieChart) {$Params["chartType"] = "PieExploded3D" }
elseif ($LineChart) {$Params["chartType"] = "Line" }
elseif ($LineChart) {$Params["chartType"] = "Line" }
Add-ExcelChart -Worksheet $ws @params
}
foreach ($ct in $ConditionalText) {
try {
$cfParams = @{RuleType = $ct.ConditionalType; ConditionValue = $ct.text ;
BackgroundColor = $ct.BackgroundColor; BackgroundPattern = $ct.PatternType ;
ForeGroundColor = $ct.ConditionalTextColor
$cfParams = @{RuleType = $ct.ConditionalType; ConditionValue = $ct.text ;
BackgroundColor = $ct.BackgroundColor; BackgroundPattern = $ct.PatternType ;
ForeGroundColor = $ct.ConditionalTextColor
}
if ($ct.Range) {$cfParams.range = $ct.range} else { $cfParams.Range = $ws.Dimension.Address }
Add-ConditionalFormatting -WorkSheet $ws @cfParams
@@ -1029,7 +1030,7 @@ function Add-WorkSheet {
[Parameter(Mandatory = $true, ParameterSetName = "WorkBook")]
[OfficeOpenXml.ExcelWorkbook]$ExcelWorkbook,
#The name of the worksheet 'Sheet1' by default.
[string]$WorkSheetname = 'Sheet1',
[string]$WorkSheetname ,
#If the worksheet already exists, by default it will returned, unless -ClearSheet is specified in which case it will be deleted and re-created.
[switch]$ClearSheet,
#If specified, the worksheet will be moved to the start of the workbook.
@@ -1049,21 +1050,30 @@ function Add-WorkSheet {
#Ignored but retained for backwards compatibility.
[Switch] $NoClobber
)
#if we were given a workbook use it, if we were given a package, use its workbook
if ($ExcelPackage -and -not $ExcelWorkbook) {$ExcelWorkbook = $ExcelPackage.Workbook}
if ($ExcelPackage -and -not $ExcelWorkbook) {$ExcelWorkbook = $ExcelPackage.Workbook}
# If worksheetName was given, try to use that worksheet. If it wasn't, and we are copying an existing sheet, try to use the sheet name
# if we are not copying a sheet or the name is in use, use the name "SheetX" where X is the number of the new sheet
if (-not $WorkSheetname -and $CopySource -and -not $ExcelWorkbook[$CopySource.Name]) {$WorkSheetname = $CopySource.Name}
elseif (-not $WorkSheetname) {$WorkSheetname = "Sheet" + (1 + $ExcelWorkbook.Worksheets.Count)}
else {$ws = $ExcelWorkbook.Worksheets[$WorkSheetname]}
$ws = $ExcelWorkbook.Worksheets[$WorkSheetname]
if ( $ws -and $ClearSheet) { $ExcelWorkbook.Worksheets.Delete($WorkSheetname) ; $ws = $null }
if (!$ws -and $CopySource) {
Write-Verbose -Message "Copying into worksheet '$WorkSheetname'."
$ws = $ExcelWorkbook.Worksheets.Add($WorkSheetname, $CopySource)
#If -clearsheet was specified and the named sheet exists, delete it
if ($ws -and $ClearSheet) { $ExcelWorkbook.Worksheets.Delete($WorkSheetname) ; $ws = $null }
#copy or create new sheet as needed
if (-not $ws -and $CopySource) {
Write-Verbose -Message "Copying into worksheet '$WorkSheetname'."
$ws = $ExcelWorkbook.Worksheets.Add($WorkSheetname, $CopySource)
}
elseif (!$ws) {
Write-Verbose -Message "Adding worksheet '$WorkSheetname'."
$ws = $ExcelWorkbook.Worksheets.Add($WorkSheetname)
elseif (-not $ws) {
$ws = $ExcelWorkbook.Worksheets.Add($WorkSheetname)
Write-Verbose -Message "Adding worksheet '$WorkSheetname'."
}
else {Write-Verbose -Message "Worksheet '$WorkSheetname' already existed."}
if ($MoveToStart) {$ExcelWorkbook.Worksheets.MoveToStart($worksheetName) }
#region Move sheet if needed
if ($MoveToStart) {$ExcelWorkbook.Worksheets.MoveToStart($worksheetName) }
elseif ($MoveToEnd ) {$ExcelWorkbook.Worksheets.MoveToEnd($worksheetName) }
elseif ($MoveBefore ) {
if ($ExcelWorkbook.Worksheets[$MoveBefore]) {
@@ -1075,7 +1085,7 @@ function Add-WorkSheet {
else {Write-Warning "Can't find worksheet '$MoveBefore'; worsheet '$WorkSheetname' will not be moved."}
}
elseif ($MoveAfter ) {
if ($MoveAfter = "*") {
if ($MoveAfter -eq "*") {
if ($WorkSheetname -lt $ExcelWorkbook.Worksheets[1].Name) {$ExcelWorkbook.Worksheets.MoveToStart($worksheetName)}
else {
$i = 1
@@ -1093,6 +1103,7 @@ function Add-WorkSheet {
}
else {Write-Warning "Can't find worksheet '$MoveAfter'; worsheet '$WorkSheetname' will not be moved."}
}
#endregion
return $ws
}
function Add-PivotTable {

View File

@@ -406,8 +406,9 @@ Function Merge-MultipleSheets {
#if the process didn't return data then abandon now.
if (-not $merged) {Write-Warning -Message "The merge operation did not return any data."; return }
$orderByProperties = $merged[0].psobject.properties.where({$_.name -match "row$"}).name
Write-Progress -Activity "Merging sheets" -CurrentOperation "Creating output sheet '$OutputSheetName' in $OutputFile"
$excel = $merged | Sort-Object "_row" | Update-FirstObjectProperties |
$excel = $merged | Sort-Object -Property $orderByProperties | Update-FirstObjectProperties |
Export-Excel -Path $OutputFile -WorkSheetname $OutputSheetName -ClearSheet -BoldTopRow -AutoFilter -PassThru
$sheet = $excel.Workbook.Worksheets[$OutputSheetName]

View File

@@ -1,17 +1,3 @@
<p align="center">
<a href="https://ci.appveyor.com/project/dfinke/importexcel/branch/master"><img src="https://ci.appveyor.com/api/projects/status/21hko6eqtpccrkba/branch/master?svg=true"></a>
<a href="https://dougfinke.visualstudio.com/ImportExcel/_build/latest?definitionId=8"><img src="https://dougfinke.visualstudio.com/ImportExcel/_apis/build/status/ImportExcel-CI"></a>
</p>
<p align="center">
<a href="./LICENSE.txt"><img
src="https://img.shields.io/badge/License-Apache%202.0-blue.svg"></a>
<a href="https://www.powershellgallery.com/packages/ImportExcel"><img
src="https://img.shields.io/powershellgallery/dt/ImportExcel.svg"></a>
<a href="https://www.powershellgallery.com/packages/ImportExcel"><img
src="https://img.shields.io/powershellgallery/v/ImportExcel.svg"></a>
</p>
PowerShell Import-Excel
-
@@ -21,7 +7,7 @@ This PowerShell Module allows you to read and write Excel files without installi
![](https://raw.githubusercontent.com/dfinke/ImportExcel/master/images/testimonial.png)
# How to Videos
# How to Vidoes
* [PowerShell Excel Module - ImportExcel](https://www.youtube.com/watch?v=U3Ne_yX4tYo&list=PL5uoqS92stXioZw-u-ze_NtvSo0k0K0kq)
Installation
@@ -45,13 +31,17 @@ To install to your personal modules folder (e.g. ~\Documents\WindowsPowerShell\M
iex (new-object System.Net.WebClient).DownloadString('https://raw.github.com/dfinke/ImportExcel/master/Install.ps1')
```
# What's new to 14th July 18
- Moved chart creation into its own function (Add-Excel chart) within Export-Excel.ps1. Renamed New-ExcelChart to New-ExcelChartDefinition to make it clearer that it is not making anything in the workbook (but for compatibility put an alias of New-ExcelChart in so existing code does not break). Found that -Header does nothing, so it isn't Add-Excel chart and there is a message that does nothing in New-ExcelChartDefinition .
# What's new to 18th July 18
- Moved chart creation into its own function (Add-Excel chart) within Export-Excel.ps1. Renamed New-Excelchart to New-ExcelChartDefinition to make it clearer that it is not making anything in the workbook (but for compatiblity put an alias of New-ExcelChart in so existing code does not break). Found that -Header does nothing, so it isn't Add-Excel chart and there is a message that does nothing in New-ExcelChartDefinition .
- Added -BarChart -ColumnChart -LineChart -PieChart parameters to Export-Excel for quick charts without giving a full chart definition.
- Added parameters for managing chart Axes and legend
- Added some chart tests to Export-Excel.tests.ps1. (but tests & examples for quick charts , axes or legends still on the to do list )
- Fixed some bad code which had been checked-in in-error and caused adding charts to break. (This was not seen outside GitHub #377)
- Fixed a bug introduced into Compare-Worksheet by the change described in the June changes below, this meant the font color was only being set in one sheet, when a row was changed. Also found that the PowerShell ISE and shell return Compare-Object results in different sequences which broke some tests. Applied a sort to ensure things are in a predictable order. (#375)
- Fixed some bad code which had been checked-in in-error and caused adding charts to break. (This was not seen outside Github #377)
- Added "Revese" parameter to Add-ConditionalFormatting ; and added -PassThru to make it easier to modify details of conditional formating rules after creation (#396)
- Refactored ConditionalFormatting code in Export excel to use Add-ConditionalFormatting.
- Rewrote Copy-ExcelWorksheet to use copy functionality rather than import | export (395)
- Found sorts could be inconsitent in Merge-MultipleWorksheet, so now sort on more columns.
- Fixed a bug introduced into Compare-Worksheet by the change descibed in the June changes below, this meant the font color was only being set in one sheet, when a row was changed. Also found that the PowerShell ISE and shell return Compare-Object resuls in different sequences which broke some tests. Applied a sort to ensure things are in a predictable order. (#375)
- Removed (2) calls to Get-ExcelColumnName (Removed and then restored function itself)
- Fixed an issue in Export-Excel where formulas were inserted as strings if "NoNumberConversion" is applied (#374), and made sure formatting is applied to formula cells
- Fixed an issue with parameter sets in Export-Excel not being determined correctly in some cases (I think this had been resolved before and might have regressed)
@@ -61,14 +51,15 @@ iex (new-object System.Net.WebClient).DownloadString('https://raw.github.com/dfi
- Added more of the Parameters from Export-Excel to Send-SQLDataToExcel, send just calls export-excel with these parameters...
- Added support for passing a System.Data.DataTable directly to Send-SQLDataToExcel
- Fixed a bug in Merge-MultipleSheets where if the key was "name", columns like "displayName" would not be processed correctly, nor would names like "something_ROW". Added tests for Compare, Merge and Join Worksheet
- Add-Worksheet , fixed a regression with move-after (#392), changed way default worksheet name is decided, so if none is specified, and an existing worksheet is copied (see June additions) and the name doesn't already exist, the orginal sheet name will be kept. (#393) If no name is given an a blank sheet is created, then it will be named sheetX where X is the number of the sheet (so if you have sheets FOO and BAR the new sheet will be Sheet3).
# New in June 18
- New commands - Diff , Merge and Join
- `Compare-Worksheet` (introduced in 5.0) uses the built in `Compare-object` command, to output a command-line DIFF and/or color the worksheet to show differences. For example, if my sheets are Windows services the *extra* rows or rows where the startup status has changed get highlighted
- `Compare-Worksheet` (introduced in 5.0) uses the built in `Compare-object` command, to output a command-line DIFF and/or colour the worksheet to show differences. For example, if my sheets are Windows services the *extra* rows or rows where the startup status has changed get highlighted
- `Merge-Worksheet` (also introduced in 5.0) joins two lumps, side by highlighting the differences. So now I can have server A's services and Server Bs Services on the same page. I figured out a way to do multiple sheets. So I can have Server A,B,C,D on one page :-) that is `Merge-MultpleSheets`
For this release I've fixed heaven only knows how many typos and proof reading errors in the help for these two, the only code change is to fix a bug if two worksheets have different names, are in different files and the Comparison sends the delta in the second back before the one in first, then highlighting changed properties could throw an error. Correcting the spelling of Merge-MultipleSheets is potentially a breaking change (and it is still plural!)
also fixed a bug in compare worksheet where color might not be applied correctly when the worksheets came from different files and had different name.
- `Join-Worksheet` is **new** for this release. At it's simplest it copies all the data in Worksheet A to the end of Worksheet B
- `Join-Worksheet` is **new** for ths release. At it's simplest it copies all the data in Worksheet A to the end of Worksheet B
- Add-Worksheet
- I have moved this from ImportExcel.psm1 to ExportExcel.ps1 and it now can move a new worksheet to the right place, and can copy an existing worksheet (from the same or a different workbook) to a new one, and I set the Set return-type to aid intellisense
- New-PivotTableDefinition
@@ -80,9 +71,9 @@ iex (new-object System.Net.WebClient).DownloadString('https://raw.github.com/dfi
1. I "flattened out" small "called-once" functions , add-title, convert-toNumber and Stop-ExcelProcess.
2. It now uses Add-Worksheet, Open-ExcelPackage and Add-ConditionalFormat instead of duplicating their functionality.
3. I've moved the PivotTable functionality (which was doubled up) out to a new function "Add-PivotTable" which supports some extra parameters PivotFilter and PivotDataToColumn, ChartHeight/width ChartRow/Column, ChartRow/ColumnPixelOffsets.
4. I've made the try{} catch{} blocks cover smaller blocks of code to give a better idea where a failure happened, some of these now Warn instead of throwing - I'd rather save the data with warnings than throw it away because we can't add a chart. Along with this I've added some extra write-verbose messages
4. I've made the try{} catch{} blocks cover smaller blocks of code to give a better idea where a failure happend, some of these now Warn instead of throwing - I'd rather save the data with warnings than throw it away because we can't add a chart. Along with this I've added some extra write-verbose messages
- Bad column-names specified for Pivots now generate warnings instead of throwing.
- Fixed issues when pivot tables / charts already exist and an export tries to create them again.
- Fixed issues when pivottables / charts already exist and an export tries to create them again.
- Fixed issue where AutoNamedRange, NamedRange, and TableName do not work when appending to a sheet which already contains the range(s) / table
- Fixed issue where AutoNamedRange may try to create ranges with an illegal name.
- Added check for illegal characters in RangeName or Table Name (replace them with "_"), changed tablename validation to allow spaces and applied same validation to RangeName
@@ -92,13 +83,13 @@ iex (new-object System.Net.WebClient).DownloadString('https://raw.github.com/dfi
- Removed the need to specify a fill type when specifying a title background color
- Added MoveToStart, MoveToEnd, MoveBefore and MoveAfter Parameters - these go straight through to Add worksheet
- Added "NoScriptOrAliasProperties" "DisplayPropertySet" switches (names subject to change) - combined with ExcludeProperty these are a quick way to reduce the data exported (and speed things up)
- Added PivotTableName String (in line with 5.0.1 release)
- Added PivotTableName Switch (in line with 5.0.1 release)
- Add-CellValue now understands URI item properties. If a property is of type URI it is created as a hyperlink to speed up Add-CellValue
- Commented out the write verbose statements even if verbose is silenced they cause a significant performance impact and if it's on they will cause a flood of messages.
- Commented out the write verbose statements even if verbose is silenced they cause a significiant performance impact and if it's on they will cause a flood of messages.
- Re-ordered the choices in the switch and added an option to say "If it is numeric already post it as is"
- Added an option to only set the number format if doesn't match the default for the sheet.
- Export-Excel Pester Tests
- I have converted examples 1-9, 11 and 13 from Export-Excel help into tests and have added some additional tests, and extra parameters to the example command to get better test coverage. The test so far has 184 "should" conditions grouped as 58 "IT" statements; but is still a work in progress.
- I have converted examples 1-9, 11 and 13 from Export-Excel help into tests and have added some additional tests, and extra parameters to the example command to ge better test coverage. The test so far has 184 "should" conditions grouped as 58 "IT" statements; but is still a work in progress.
- Compare-Worksheet pester tests
---
@@ -112,7 +103,7 @@ Thanks to the community yet again
- [ili101](https://github.com/ili101) for fixes and features
- Removed `[PSPlot]` as OutputType. Fixes it throwing an error
- [Nasir Zubair](https://github.com/nzubair) added `ConvertEmptyStringsToNull` to the function `ConvertFrom-ExcelToSQLInsert`
- If specified, cells without any data are replaced with NULL, instead of an empty string. This is to address behaviors in certain DBMS where an empty string is insert as 0 for INT column, instead of a NULL value.
- If specified, cells without any data are replaced with NULL, instead of an empty string. This is to address behviors in certain DBMS where an empty string is insert as 0 for INT column, instead of a NULL value.
#### 4/10/2018
@@ -124,7 +115,7 @@ Super helpful!
#### 3/31/2018
- Updated `Set-Format`
* Added parameters to set borders for cells, including top, bottom, left and right
* Added parameters to set borders for cells, including top, bottm, left and right
* Added parameters to set `value` and `formula`
```powershell
@@ -167,7 +158,7 @@ North,A1,Grape,140,2.5
* Add example to set the background color of a column
* Supports excluding Row Grand Totals for PivotTables
* Allow xlsm files to be read
* Fix `Set-Column.ps1`, `Set-Row.ps1`, `SetFormat.ps1`, `formatting.ps1` **$false** and **$BorderRound**
* Fix `Set-Column.ps1`, `Set-Row.ps1`, `SetFormat.ps1`, `formatting.ps1` **$falsee** and **$BorderRound**
#### 1/1/2018
* Added switch `[Switch]$NoTotalsInPivot`. Allows hiding of the row totals in the pivot table.
Thanks you to [jameseholt](https://github.com/jameseholt) for the request.
@@ -193,7 +184,7 @@ More great additions and thanks to [James O'Neill](https://twitter.com/jamesonei
* Corrected a typo PivotTableName was PivtoTableName in definition of New-PivotTableDefinition
* Add-ConditionalFormat and Set-Format added to the parameters so each has the choice of working more like the other.
* Added Set-Row and Set-Column - fill a formula down or across.
* Added Send-SQLDataToExcel. Insert a rowset and then call Export-Excel for ranges, charts, pivots etc.
* Added Send-SQLDataToExcel. Insert a rowset and then call Export-Excel for ranges, charts, pivots etc
#### 10/30/2017
Huge thanks to [James O'Neill](https://twitter.com/jamesoneill). PowerShell aficionado. He always brings a flare when working with PowerShell. This is no exception.
@@ -211,8 +202,8 @@ Huge thanks to [James O'Neill](https://twitter.com/jamesoneill). PowerShell afic
(Check out the examples `help Export-Excel -Examples`)
* New function `Export-Charts` (requires Excel to be installed) - Export Excel charts out as JPG files
* New function `Add-ConditionalFormatting` Adds conditional formatting to worksheet
* New function `Set-Format` Applies Number, font, alignment and color formatting to a range of Excel Cells
* New function `Add-ConditionalFormatting` Adds contitional formatting to worksheet
* New function `Set-Format` Applies Number, font, alignment and colour formatting to a range of Excel Cells
* `ColorCompletion` an argument completer for `Colors` for params across functions
I also worked out the parameters so you can do this, which is the same as passing `-Now`. It creates an Excel file name for you, does an auto fit and sets up filters.
@@ -222,7 +213,7 @@ I also worked out the parameters so you can do this, which is the same as passin
#### 10/13/2017
Added `New-PivotTableDefinition`. You can create and wire up a PivotTable to a WorkSheet. You can also create as many PivotTable Worksheets to point a one Worksheet. Or, you create many Worksheets and many corresponding PivotTable Worksheets.
Here you can create a WorkSheet with the data from `Get-Service`. Then create four PivotTables, pointing to the data each pivoting on a different dimension and showing a different chart
Here you can create a WorkSheet with the data from `Get-Service`. Then create four PivotTables, pointing to the data each pivoting on a differnt dimension and showing a differnet chart
```powershell
$base = @{
@@ -404,7 +395,7 @@ Get-Process |
![](https://github.com/dfinke/ImportExcel/blob/master/images/CellFormatting.png?raw=true)
#### 9/28/2016
[Fixed](https://github.com/dfinke/ImportExcel/pull/126) PowerShell 3.0 compatibility. Thanks to [headsphere](https://github.com/headsphere). He used `$obj.PSObject.Methods[$target]` syntax to make it backward compatible. PS v4.0 and later allow `$obj.$target`.
[Fixed](https://github.com/dfinke/ImportExcel/pull/126) PowerShell 3.0 compatibility. Thanks to [headsphere](https://github.com/headsphere). He used `$obj.PSObject.Methods[$target]` snytax to make it backward compatible. PS v4.0 and later allow `$obj.$target`.
Thank you to [xelsirko](https://github.com/xelsirko) for fixing - *Import-module importexcel gives version warning if started inside background job*
@@ -440,7 +431,7 @@ Thanks Attila.
#### 4/30/2016
Huge thank you to [Willie Möller](https://github.com/W1M0R)
* He added a version check so the PowerShell Classes don't cause issues for down-level version of PowerShell
* He added a version check so the PowerShell Classes don't cause issues for downlevel version of PowerShell
* He also contributed the first Pester tests for the module. Super! Check them out, they'll be the way tests will be implemented going forward
#### 4/18/2016
@@ -667,7 +658,7 @@ Or
#### 9/25/2015
**Hide worksheets**
Got a great request from [forensicsguy20012004](https://github.com/forensicsguy20012004) to hide worksheets. You create a few pivotables, generate charts and then pivot table worksheets don't need to be visible.
Got a great request from [forensicsguy20012004](https://github.com/forensicsguy20012004) to hide worksheets. You create a few pivotables, generate charts and then pivotable worksheets don't need to be visible.
`Export-Excel` now has a `-HideSheet` parameter that takes and array of worksheet names and hides them.

View File

@@ -8,4 +8,4 @@
- [ ] Examples and tests for new "Quick charts" in Export Excel
- [ ] Charting.ps1,GetXYRange.ps1, InferData.PS1 move to deprecated. (replace examples)
- [ ] Refactor Set-Row and Set-Column to use set-format and add conditional format support.
- [ ] Examples and tests for set-Row and Set-column; review test coverage and examples for Set-Format adn Add-Conditional formatting
- [ ] Examples and tests for set-Row and Set-column; review test coverage and examples for Set-Format and Add-Conditional formatting

View File

@@ -1,184 +1,336 @@
#Requires -Modules Pester
# $here = Split-Path -Parent $MyInvocation.MyCommand.Path
# Import-Module $here -Force -Verbose
#Requires -Modules Pester
Import-Module $PSScriptRoot\..\ImportExcel.psd1 -Force
Describe "Compare Worksheet" {
Remove-Item -Path "$env:temp\server*.xlsx"
[System.Collections.ArrayList]$s = get-service | Select-Object -Property *
$s | Export-Excel -Path $env:temp\server1.xlsx
#$s is a zero based array, excel rows are 1 based and excel has a header row so Excel rows will be 2 + index in $s
$row4Displayname = $s[2].DisplayName
$s[2].DisplayName = "Changed from the orginal"
$d = $s[-1] | Select-Object -Property *
$d.DisplayName = "Dummy Service"
$d.Name = "Dummy"
$s.Insert(3,$d)
$row6Name = $s[5].name
$s.RemoveAt(5)
$s | Export-Excel -Path $env:temp\server2.xlsx
#Assume default worksheet name, (sheet1) and column header for key ("name")
$comp = compare-WorkSheet "$env:temp\Server1.xlsx" "$env:temp\Server2.xlsx" | Sort-Object -Property _row, _file
Context "Simple comparison output" {
it "Found the right number of differences " {
$comp | should not beNullOrEmpty
$comp.Count | should be 4
BeforeAll {
Remove-Item -Path "$env:temp\server*.xlsx"
[System.Collections.ArrayList]$s = get-service | Select-Object -Property *
$s | Export-Excel -Path $env:temp\server1.xlsx
#$s is a zero based array, excel rows are 1 based and excel has a header row so Excel rows will be 2 + index in $s
$row4Displayname = $s[2].DisplayName
$s[2].DisplayName = "Changed from the orginal"
$d = $s[-1] | Select-Object -Property *
$d.DisplayName = "Dummy Service"
$d.Name = "Dummy"
$s.Insert(3,$d)
$row6Name = $s[5].name
$s.RemoveAt(5)
$s | Export-Excel -Path $env:temp\server2.xlsx
#Assume default worksheet name, (sheet1) and column header for key ("name")
$comp = compare-WorkSheet "$env:temp\Server1.xlsx" "$env:temp\Server2.xlsx" | Sort-Object -Property _row, _file
}
it "Found the data row with a changed property " {
$comp | should not beNullOrEmpty
$comp[0]._Side | should not be $comp[1]._Side
$comp[0]._Row | should be 4
$comp[1]._Row | should be 4
$comp[1].Name | should be $comp[0].Name
$comp[0].DisplayName | should be $row4Displayname
$comp[1].DisplayName | should be "Changed from the orginal"
it "Found the right number of differences " {
$comp | should not beNullOrEmpty
$comp.Count | should be 4
}
it "Found the inserted data row " {
$comp | should not beNullOrEmpty
$comp[2]._Side | should be '=>'
$comp[2]._Row | should be 5
$comp[2].Name | should be "Dummy"
it "Found the data row with a changed property " {
$comp | should not beNullOrEmpty
$comp[0]._Side | should not be $comp[1]._Side
$comp[0]._Row | should be 4
$comp[1]._Row | should be 4
$comp[1].Name | should be $comp[0].Name
$comp[0].DisplayName | should be $row4Displayname
$comp[1].DisplayName | should be "Changed from the orginal"
}
it "Found the deleted data row " {
$comp | should not beNullOrEmpty
$comp[3]._Side | should be '<='
$comp[3]._Row | should be 6
$comp[3].Name | should be $row6Name
it "Found the inserted data row " {
$comp | should not beNullOrEmpty
$comp[2]._Side | should be '=>'
$comp[2]._Row | should be 5
$comp[2].Name | should be "Dummy"
}
it "Found the deleted data row " {
$comp | should not beNullOrEmpty
$comp[3]._Side | should be '<='
$comp[3]._Row | should be 6
$comp[3].Name | should be $row6Name
}
}
$null = compare-WorkSheet "$env:temp\Server1.xlsx" "$env:temp\Server2.xlsx" -BackgroundColor LightGreen
$xl1 = Open-ExcelPackage -Path "$env:temp\Server1.xlsx"
$xl2 = Open-ExcelPackage -Path "$env:temp\Server2.xlsx"
$s1Sheet = $xl1.Workbook.Worksheets[1]
$s2Sheet = $xl2.Workbook.Worksheets[1]
Context "Setting the background to highlight different rows" {
it "set the background on the right rows " {
$s1Sheet.Cells["4:4"].Style.Fill.BackgroundColor.Rgb | should be "FF90EE90"
$s1Sheet.Cells["6:6"].Style.Fill.BackgroundColor.Rgb | should be "FF90EE90"
$s2Sheet.Cells["4:4"].Style.Fill.BackgroundColor.Rgb | should be "FF90EE90"
$s2Sheet.Cells["5:5"].Style.Fill.BackgroundColor.Rgb | should be "FF90EE90"
BeforeAll {
$null = compare-WorkSheet "$env:temp\Server1.xlsx" "$env:temp\Server2.xlsx" -BackgroundColor LightGreen
$xl1 = Open-ExcelPackage -Path "$env:temp\Server1.xlsx"
$xl2 = Open-ExcelPackage -Path "$env:temp\Server2.xlsx"
$s1Sheet = $xl1.Workbook.Worksheets[1]
$s2Sheet = $xl2.Workbook.Worksheets[1]
}
it "Didn't set other cells " {
$s1Sheet.Cells["3:3"].Style.Fill.BackgroundColor.Rgb | should not be "FF90EE90"
$s1Sheet.Cells["F4"].Style.Font.Color.Rgb | should beNullOrEmpty
$s2Sheet.Cells["F4"].Style.Font.Color.Rgb | should beNullOrEmpty
$s2Sheet.Cells["3:3"].Style.Fill.BackgroundColor.Rgb | should not be "FF90EE90"
it "Set the background on the right rows " {
$s1Sheet.Cells["4:4"].Style.Fill.BackgroundColor.Rgb | should be "FF90EE90"
$s1Sheet.Cells["6:6"].Style.Fill.BackgroundColor.Rgb | should be "FF90EE90"
$s2Sheet.Cells["4:4"].Style.Fill.BackgroundColor.Rgb | should be "FF90EE90"
$s2Sheet.Cells["5:5"].Style.Fill.BackgroundColor.Rgb | should be "FF90EE90"
}
it "Didn't set other cells " {
$s1Sheet.Cells["3:3"].Style.Fill.BackgroundColor.Rgb | should not be "FF90EE90"
$s1Sheet.Cells["F4"].Style.Font.Color.Rgb | should beNullOrEmpty
$s2Sheet.Cells["F4"].Style.Font.Color.Rgb | should beNullOrEmpty
$s2Sheet.Cells["3:3"].Style.Fill.BackgroundColor.Rgb | should not be "FF90EE90"
}
AfterAll {
Close-ExcelPackage -ExcelPackage $xl1 -NoSave
Close-ExcelPackage -ExcelPackage $xl2 -NoSave
}
}
Close-ExcelPackage -ExcelPackage $xl1 -NoSave
Close-ExcelPackage -ExcelPackage $xl2 -NoSave
$null = compare-WorkSheet "$env:temp\Server1.xlsx" "$env:temp\Server2.xlsx" -AllDataBackgroundColor white -BackgroundColor LightGreen -FontColor DarkRed
$xl1 = Open-ExcelPackage -Path "$env:temp\Server1.xlsx"
$xl2 = Open-ExcelPackage -Path "$env:temp\Server2.xlsx"
$s1Sheet = $xl1.Workbook.Worksheets[1]
$s2Sheet = $xl2.Workbook.Worksheets[1]
Context "Setting the forgound to highlight changed properties" {
it "Added foreground colour to the right cells " {
$s1Sheet.Cells["4:4"].Style.Fill.BackgroundColor.Rgb | should be "FF90EE90"
$s1Sheet.Cells["6:6"].Style.Fill.BackgroundColor.Rgb | should be "FF90EE90"
$s2Sheet.Cells["4:4"].Style.Fill.BackgroundColor.Rgb | should be "FF90EE90"
$s2Sheet.Cells["5:5"].Style.Fill.BackgroundColor.Rgb | should be "FF90EE90"
# $s1Sheet.Cells["F4"].Style.Font.Color.Rgb | should be "FF8B0000"
$s2Sheet.Cells["F4"].Style.Font.Color.Rgb | should be "FF8B0000"
BeforeAll {
$null = compare-WorkSheet "$env:temp\Server1.xlsx" "$env:temp\Server2.xlsx" -AllDataBackgroundColor white -BackgroundColor LightGreen -FontColor DarkRed
$xl1 = Open-ExcelPackage -Path "$env:temp\Server1.xlsx"
$xl2 = Open-ExcelPackage -Path "$env:temp\Server2.xlsx"
$s1Sheet = $xl1.Workbook.Worksheets[1]
$s2Sheet = $xl2.Workbook.Worksheets[1]
}
it "Didn't set the foreground on other cells " {
$s1Sheet.Cells["F5"].Style.Font.Color.Rgb | should beNullOrEmpty
$s2Sheet.Cells["F5"].Style.Font.Color.Rgb | should beNullOrEmpty
$s1Sheet.Cells["G4"].Style.Font.Color.Rgb | should beNullOrEmpty
$s2Sheet.Cells["G4"].Style.Font.Color.Rgb | should beNullOrEmpty
it "Added foreground colour to the right cells " {
$s1Sheet.Cells["4:4"].Style.Fill.BackgroundColor.Rgb | should be "FF90EE90"
$s1Sheet.Cells["6:6"].Style.Fill.BackgroundColor.Rgb | should be "FF90EE90"
$s2Sheet.Cells["4:4"].Style.Fill.BackgroundColor.Rgb | should be "FF90EE90"
$s2Sheet.Cells["5:5"].Style.Fill.BackgroundColor.Rgb | should be "FF90EE90"
# $s1Sheet.Cells["F4"].Style.Font.Color.Rgb | should be "FF8B0000"
$s2Sheet.Cells["F4"].Style.Font.Color.Rgb | should be "FF8B0000"
}
it "Didn't set the foreground on other cells " {
$s1Sheet.Cells["F5"].Style.Font.Color.Rgb | should beNullOrEmpty
$s2Sheet.Cells["F5"].Style.Font.Color.Rgb | should beNullOrEmpty
$s1Sheet.Cells["G4"].Style.Font.Color.Rgb | should beNullOrEmpty
$s2Sheet.Cells["G4"].Style.Font.Color.Rgb | should beNullOrEmpty
}
AfterAll {
Close-ExcelPackage -ExcelPackage $xl1 -NoSave
Close-ExcelPackage -ExcelPackage $xl2 -NoSave
}
}
Close-ExcelPackage -ExcelPackage $xl1 -NoSave
Close-ExcelPackage -ExcelPackage $xl2 -NoSave
[System.Collections.ArrayList]$s = get-service | Select-Object -Property * -ExcludeProperty Name
$s | Export-Excel -Path $env:temp\server1.xlsx -WorkSheetname Server1
#$s is a zero based array, excel rows are 1 based and excel has a header row so Excel rows will be 2 + index in $s
$row4Displayname = $s[2].DisplayName
$s[2].DisplayName = "Changed from the orginal"
$d = $s[-1] | Select-Object -Property *
$d.DisplayName = "Dummy Service"
$d.ServiceName = "Dummy"
$s.Insert(3,$d)
$row6Name = $s[5].ServiceName
$s.RemoveAt(5)
$s[10].ServiceType = "Changed should not matter"
$s | Select-Object -Property ServiceName, DisplayName, StartType, ServiceType | Export-Excel -Path $env:temp\server2.xlsx -WorkSheetname server2
#Assume default worksheet name, (sheet1) and column header for key ("name")
$comp = compare-WorkSheet "$env:temp\Server1.xlsx" "$env:temp\Server2.xlsx" -WorkSheetName Server1,Server2 -Key ServiceName -Property DisplayName,StartType -AllDataBackgroundColor AliceBlue -BackgroundColor White -FontColor Red | Sort-Object _row,_file
$xl1 = Open-ExcelPackage -Path "$env:temp\Server1.xlsx"
$xl2 = Open-ExcelPackage -Path "$env:temp\Server2.xlsx"
$s1Sheet = $xl1.Workbook.Worksheets["server1"]
$s2Sheet = $xl2.Workbook.Worksheets["server2"]
Context "More complex comparison: output check and different worksheet names " {
it "Found the right number of differences " {
$comp | should not beNullOrEmpty
$comp.Count | should be 4
BeforeAll {
[System.Collections.ArrayList]$s = get-service | Select-Object -Property * -ExcludeProperty Name
$s | Export-Excel -Path $env:temp\server1.xlsx -WorkSheetname Server1
#$s is a zero based array, excel rows are 1 based and excel has a header row so Excel rows will be 2 + index in $s
$row4Displayname = $s[2].DisplayName
$s[2].DisplayName = "Changed from the orginal"
$d = $s[-1] | Select-Object -Property *
$d.DisplayName = "Dummy Service"
$d.ServiceName = "Dummy"
$s.Insert(3,$d)
$row6Name = $s[5].ServiceName
$s.RemoveAt(5)
$s[10].ServiceType = "Changed should not matter"
$s | Select-Object -Property ServiceName, DisplayName, StartType, ServiceType | Export-Excel -Path $env:temp\server2.xlsx -WorkSheetname server2
#Assume default worksheet name, (sheet1) and column header for key ("name")
$comp = compare-WorkSheet "$env:temp\Server1.xlsx" "$env:temp\Server2.xlsx" -WorkSheetName Server1,Server2 -Key ServiceName -Property DisplayName,StartType -AllDataBackgroundColor AliceBlue -BackgroundColor White -FontColor Red | Sort-Object _row,_file
$xl1 = Open-ExcelPackage -Path "$env:temp\Server1.xlsx"
$xl2 = Open-ExcelPackage -Path "$env:temp\Server2.xlsx"
$s1Sheet = $xl1.Workbook.Worksheets["server1"]
$s2Sheet = $xl2.Workbook.Worksheets["server2"]
}
it "Found the data row with a changed property " {
$comp | should not beNullOrEmpty
$comp[0]._Side | should not be $comp[1]._Side
$comp[0]._Row | should be 4
$comp[1]._Row | should be 4
$comp[1].ServiceName | should be $comp[0].ServiceName
$comp[0].DisplayName | should be $row4Displayname
$comp[1].DisplayName | should be "Changed from the orginal"
it "Found the right number of differences " {
$comp | should not beNullOrEmpty
$comp.Count | should be 4
}
it "Found the inserted data row " {
$comp | should not beNullOrEmpty
$comp[2]._Side | should be '=>'
$comp[2]._Row | should be 5
$comp[2].ServiceName | should be "Dummy"
it "Found the data row with a changed property " {
$comp | should not beNullOrEmpty
$comp[0]._Side | should not be $comp[1]._Side
$comp[0]._Row | should be 4
$comp[1]._Row | should be 4
$comp[1].ServiceName | should be $comp[0].ServiceName
$comp[0].DisplayName | should be $row4Displayname
$comp[1].DisplayName | should be "Changed from the orginal"
}
it "Found the deleted data row " {
$comp | should not beNullOrEmpty
$comp[3]._Side | should be '<='
$comp[3]._Row | should be 6
$comp[3].ServiceName | should be $row6Name
it "Found the inserted data row " {
$comp | should not beNullOrEmpty
$comp[2]._Side | should be '=>'
$comp[2]._Row | should be 5
$comp[2].ServiceName | should be "Dummy"
}
it "Found the deleted data row " {
$comp | should not beNullOrEmpty
$comp[3]._Side | should be '<='
$comp[3]._Row | should be 6
$comp[3].ServiceName | should be $row6Name
}
it "Set the background on the right rows " {
$s1Sheet.Cells["4:4"].Style.Fill.BackgroundColor.Rgb | should be "FFFFFFFF"
$s1Sheet.Cells["6:6"].Style.Fill.BackgroundColor.Rgb | Should be "FFFFFFFF"
$s2Sheet.Cells["4:4"].Style.Fill.BackgroundColor.Rgb | Should be "FFFFFFFF"
$s2Sheet.Cells["5:5"].Style.Fill.BackgroundColor.Rgb | Should be "FFFFFFFF"
it "set the background on the right rows " {
$s1Sheet.Cells["4:4"].Style.Fill.BackgroundColor.Rgb | should be "FFFFFFFF"
$s1Sheet.Cells["6:6"].Style.Fill.BackgroundColor.Rgb | should be "FFFFFFFF"
$s2Sheet.Cells["4:4"].Style.Fill.BackgroundColor.Rgb | should be "FFFFFFFF"
$s2Sheet.Cells["5:5"].Style.Fill.BackgroundColor.Rgb | should be "FFFFFFFF"
$s1Sheet.Cells["E4"].Style.Font.Color.Rgb | should be "FFFF0000"
$s2Sheet.Cells["E4"].Style.Font.Color.Rgb | should be "FFFF0000"
$s1Sheet.Cells["E4"].Style.Font.Color.Rgb | Should be "FFFF0000"
$s2Sheet.Cells["E4"].Style.Font.Color.Rgb | Should be "FFFF0000"
}
it "Didn't set other cells " {
$s1Sheet.Cells["3:3"].Style.Fill.BackgroundColor.Rgb | should not be "FFFFFFFF"
$s2Sheet.Cells["3:3"].Style.Fill.BackgroundColor.Rgb | should not be "FFFFFFFF"
$s1Sheet.Cells["E5"].Style.Font.Color.Rgb | should beNullOrEmpty
$s2Sheet.Cells["E5"].Style.Font.Color.Rgb | should beNullOrEmpty
$s1Sheet.Cells["F4"].Style.Font.Color.Rgb | should beNullOrEmpty
$s2Sheet.Cells["F4"].Style.Font.Color.Rgb | should beNullOrEmpty
it "Didn't set other cells " {
$s1Sheet.Cells["3:3"].Style.Fill.BackgroundColor.Rgb | Should not be "FFFFFFFF"
$s2Sheet.Cells["3:3"].Style.Fill.BackgroundColor.Rgb | Should not be "FFFFFFFF"
$s1Sheet.Cells["E5"].Style.Font.Color.Rgb | Should beNullOrEmpty
$s2Sheet.Cells["E5"].Style.Font.Color.Rgb | Should beNullOrEmpty
$s1Sheet.Cells["F4"].Style.Font.Color.Rgb | Should beNullOrEmpty
$s2Sheet.Cells["F4"].Style.Font.Color.Rgb | Should beNullOrEmpty
}
AfterAll {
Close-ExcelPackage -ExcelPackage $xl1 -NoSave -Show
Close-ExcelPackage -ExcelPackage $xl2 -NoSave -Show
}
}
Close-ExcelPackage -ExcelPackage $xl1 -NoSave -Show
Close-ExcelPackage -ExcelPackage $xl2 -NoSave -Show
}
Describe "Merge Worksheet" {
Context "Merge with 3 properties" {
BeforeAll {
Remove-Item -Path "$env:temp\server*.xlsx" , "$env:temp\Combined*.xlsx" -ErrorAction SilentlyContinue
[System.Collections.ArrayList]$s = get-service | Select-Object -Property *
$s | Export-Excel -Path $env:temp\server1.xlsx
#$s is a zero based array, excel rows are 1 based and excel has a header row so Excel rows will be 2 + index in $s
$s[2].DisplayName = "Changed from the orginal"
$d = $s[-1] | Select-Object -Property *
$d.DisplayName = "Dummy Service"
$d.Name = "Dummy"
$s.Insert(3,$d)
$s.RemoveAt(5)
$s | Export-Excel -Path $env:temp\server2.xlsx
#Assume default worksheet name, (sheet1) and column header for key ("name")
Merge-Worksheet -Referencefile "$env:temp\server1.xlsx" -Differencefile "$env:temp\Server2.xlsx" -OutputFile "$env:temp\combined1.xlsx" -Property name,displayname,startType -Key name
$excel = Open-ExcelPackage -Path "$env:temp\combined1.xlsx"
$ws = $excel.Workbook.Worksheets["sheet1"]
}
it "Created a worksheet with the correct headings " {
$ws | should not beNullOrEmpty
$ws.Cells[ 1,1].Value | Should be "name"
$ws.Cells[ 1,2].Value | Should be "DisplayName"
$ws.Cells[ 1,3].Value | Should be "StartType"
$ws.Cells[ 1,4].Value | Should be "Server2 DisplayName"
$ws.Cells[ 1,5].Value | Should be "Server2 StartType"
}
it "Joined the two sheets correctly " {
$ws.Cells[ 2,2].Value | Should be $ws.Cells[ 2,4].Value
$ws.Cells[ 2,3].Value | Should be $ws.Cells[ 2,5].Value
$ws.cells[ 4,4].value | Should be "Changed from the orginal"
$ws.cells[ 5,1].value | Should be "Dummy"
$ws.cells[ 5,2].value | Should beNullOrEmpty
$ws.cells[ 5,3].value | Should beNullOrEmpty
$ws.cells[ 5,4].value | Should be "Dummy Service"
$ws.cells[ 7,4].value | Should beNullOrEmpty
$ws.cells[ 7,5].value | Should beNullOrEmpty
$ws.Cells[12,2].Value | Should be $ws.Cells[12,4].Value
$ws.Cells[12,3].Value | Should be $ws.Cells[12,5].Value
}
it "Highlighted the keys in the added / deleted / changed rows " {
$ws.cells[4,1].Style.font.color.rgb | Should be "FF8b0000"
$ws.cells[5,1].Style.font.color.rgb | Should be "FF8b0000"
$ws.cells[7,1].Style.font.color.rgb | Should be "FF8b0000"
}
it "Set the background for the added / deleted /changed rows " {
$ws.cells["A3:E3"].style.Fill.BackgroundColor.Rgb | Should beNullOrEmpty
$ws.cells["A4:E4"].style.Fill.BackgroundColor.Rgb | Should be "FFFFA500"
$ws.cells["A5" ].style.Fill.BackgroundColor.Rgb | Should be "FF98FB98"
$ws.cells["B5:C5"].style.Fill.BackgroundColor.rgb | Should beNullOrEmpty
$ws.cells["D5:E5"].style.Fill.BackgroundColor.Rgb | Should be "FF98FB98"
$ws.cells["A7:C7"].style.Fill.BackgroundColor.Rgb | Should be "FFFFB6C1"
$ws.cells["D7:E7"].style.Fill.BackgroundColor.rgb | Should beNullOrEmpty
}
}
Context "Wider data set" {
it "Copes with more columns beyond Z in the Output sheet " {
{ Merge-Worksheet -Referencefile "$env:temp\server1.xlsx" -Differencefile "$env:temp\Server2.xlsx" -OutputFile "$env:temp\combined2.xlsx" } | Should not throw
}
}
}
Describe "Merge Multiple sheets" {
Context "Merge 3 sheets with 3 properties" {
BeforeAll {
Remove-Item -Path "$env:temp\server*.xlsx" , "$env:temp\Combined*.xlsx" -ErrorAction SilentlyContinue
[System.Collections.ArrayList]$s = get-service | Select-Object -Property Name,DisplayName,StartType
$s | Export-Excel -Path $env:temp\server1.xlsx
#$s is a zero based array, excel rows are 1 based and excel has a header row so Excel rows will be 2 + index in $s
$row4Displayname = $s[2].DisplayName
$s[2].DisplayName = "Changed from the orginal"
$d = $s[-1] | Select-Object -Property *
$d.DisplayName = "Dummy Service"
$d.Name = "Dummy"
$s.Insert(3,$d)
$s.RemoveAt(5)
$s | Export-Excel -Path $env:temp\server2.xlsx
$s[2].displayname = $row4Displayname
$d = $s[-1] | Select-Object -Property *
$d.DisplayName = "Second Service"
$d.Name = "Service2"
$s.Insert(6,$d)
$s.RemoveAt(8)
$s | Export-Excel -Path $env:temp\server3.xlsx
Merge-MultipleSheets -Path "$env:temp\server1.xlsx", "$env:temp\Server2.xlsx","$env:temp\Server3.xlsx" -OutputFile "$env:temp\combined3.xlsx" -Property name,displayname,startType -Key name
$excel = Open-ExcelPackage -Path "$env:temp\combined3.xlsx"
$ws = $excel.Workbook.Worksheets["sheet1"]
}
it "Created a worksheet with the correct headings " {
$ws | Should not beNullOrEmpty
$ws.Cells[ 1,2 ].Value | Should be "name"
$ws.Cells[ 1,3 ].Value | Should be "Server1 DisplayName"
$ws.Cells[ 1,4 ].Value | Should be "Server1 StartType"
$ws.Cells[ 1,5 ].Value | Should be "Server2 DisplayName"
$ws.Cells[ 1,6 ].Value | Should be "Server2 StartType"
$ws.Column(7).hidden | Should be $true
$ws.Cells[ 1,8].Value | Should be "Server2 Row"
$ws.Cells[ 1,9 ].Value | Should be "Server3 DisplayName"
$ws.Cells[ 1,10].Value | Should be "Server3 StartType"
$ws.Column(11).hidden | Should be $true
$ws.Cells[ 1,12].Value | Should be "Server3 Row"
}
it "Joined the three sheets correctly " {
$ws.Cells[ 2,3 ].Value | Should be $ws.Cells[ 2,5 ].Value
$ws.Cells[ 2,4 ].Value | Should be $ws.Cells[ 2,6 ].Value
$ws.Cells[ 2,5 ].Value | Should be $ws.Cells[ 2,9 ].Value
$ws.Cells[ 2,6 ].Value | Should be $ws.Cells[ 2,10].Value
$ws.cells[ 4,5 ].value | Should be "Changed from the orginal"
$ws.cells[ 4,9 ].value | Should be $ws.Cells[ 4,3 ].Value
$ws.cells[ 5,2 ].value | Should be "Dummy"
$ws.cells[ 5,3 ].value | Should beNullOrEmpty
$ws.cells[ 5,4 ].value | Should beNullOrEmpty
$ws.cells[ 5,5 ].value | Should be "Dummy Service"
$ws.cells[ 5,8 ].value | Should be ($ws.cells[ 4,1].value +1)
$ws.cells[ 5,9 ].value | Should be $ws.cells[ 5,5 ].value
$ws.cells[ 7,5 ].value | Should beNullOrEmpty
$ws.cells[ 7,6 ].value | Should beNullOrEmpty
$ws.cells[ 7,9 ].value | Should beNullOrEmpty
$ws.cells[ 7,10].value | Should beNullOrEmpty
$ws.cells[ 8,3 ].value | Should beNullOrEmpty
$ws.cells[ 8,4 ].value | Should beNullOrEmpty
$ws.cells[ 8,5 ].value | Should beNullOrEmpty
$ws.cells[ 8,6 ].value | Should beNullOrEmpty
$ws.cells[11,9 ].value | Should beNullOrEmpty
$ws.cells[11,10].value | Should beNullOrEmpty
$ws.Cells[12,3 ].Value | Should be $ws.Cells[12,5].Value
$ws.Cells[12,4 ].Value | Should be $ws.Cells[12,6].Value
$ws.Cells[12,9 ].Value | Should be $ws.Cells[12,5].Value
$ws.Cells[12,10].Value | Should be $ws.Cells[12,6].Value
}
it "Creared Conditional formatting rules " {
$cf=$ws.ConditionalFormatting
$cf.Count | Should be 15
$cf[14].Address.Address | Should be 'B2:B1048576'
$cf[14].Type | Should be 'Expression'
$cf[14].Formula | Should be 'OR(G2<>"Same",K2<>"Same")'
$cf[14].Style.Font.Color.Color.Name | Should be "FFFF0000"
$cf[13].Address.Address | Should be 'D2:D1048576'
$cf[13].Type | Should be 'Expression'
$cf[13].Formula | Should be 'OR(G2="Added",K2="Added")'
$cf[13].Style.Fill.BackgroundColor.Color.Name | Should be 'ffffb6c1'
$cf[ 0].Address.Address | Should be 'F1:F1048576'
$cf[ 0].Type | Should be 'Expression'
$cf[ 0].Formula | Should be 'G1="Added"'
$cf[ 0].Style.Fill.BackgroundColor.Color.Name | Should be 'ffffa500'
}
}
}

View File

@@ -0,0 +1,86 @@
$path1 = "$env:TEMP\Test1.xlsx"
$path2 = "$env:TEMP\Test2.xlsx"
Remove-item -Path $path1, $path2 # -ErrorAction SilentlyContinue
$ProcRange = Get-Process | Export-Excel $path1 -DisplayPropertySet -WorkSheetname Processes -ReturnRange
if ((Get-Culture).NumberFormat.CurrencySymbol -eq "£") {$OtherCurrencySymbol = "$"}
else {$OtherCurrencySymbol = "£"}
[PSCustOmobject][Ordered]@{
Date = Get-Date
Formula1 = '=SUM(F2:G2)'
String1 = 'My String'
Float = [math]::pi
IPAddress = '10.10.25.5'
StrLeadZero = '07670'
StrComma = '0,26'
StrEngThousand = '1,234.56'
StrEuroThousand = '1.555,83'
StrDot = '1.2'
StrNegInt = '-31'
StrTrailingNeg = '31-'
StrParens = '(123)'
strLocalCurrency = ('{0}123.45' -f (Get-Culture).NumberFormat.CurrencySymbol )
strOtherCurrency = ('{0}123.45' -f $OtherCurrencySymbol )
StrE164Phone = '+32 (444) 444 4444'
StrAltPhone1 = '+32 4 4444 444'
StrAltPhone2 = '+3244444444'
StrLeadSpace = ' 123'
StrTrailSpace = '123 '
Link1 = [uri]"https://github.com/dfinke/ImportExcel"
Link2 = "https://github.com/dfinke/ImportExcel" # Links are not copied correctly, hopefully this will be fixed at some future date
} | Export-Excel -NoNumberConversion IPAddress, StrLeadZero, StrAltPhone2 -WorkSheetname MixedTypes -Path $path2
Describe "Copy-Worksheet" {
Context "Simplest copy"{
BeforeAll {
Copy-ExcelWorkSheet -SourceWorkbook $path1 -DestinationWorkbook $path2
$excel = Open-ExcelPackage -Path $path2
$ws = $excel.Workbook.Worksheets["Processes"]
}
it "inserted a worksheet " {
$Excel.Workbook.Worksheets.count | Should be 2
$ws | Should not benullorEmpty
$ws.Dimension.Address | should be $ProcRange
}
}
Context "Mixed types using a package object"{
BeforeAll {
Copy-ExcelWorkSheet -SourceWorkbook $excel -DestinationWorkbook $excel -DestinationWorkSheet "CopyOfMixedTypes"
Close-ExcelPackage -ExcelPackage $excel
$excel = Open-ExcelPackage -Path $path2
$ws = $Excel.Workbook.Worksheets[3]
}
it "inserted a worksheet with the expected name, number of rows and number of columns " {
$Excel.Workbook.Worksheets.count | Should be 3
$ws | Should not benullorEmpty
$ws.Name | Should be "CopyOfMixedTypes"
$ws.Dimension.Columns | Should be 22
$ws.Dimension.Rows | Should be 2
$ws.Cells[2, 1].Value.Gettype().name | Should be 'DateTime'
$ws.Cells[2, 2].Formula | Should be '=SUM(F2:G2)'
$ws.Cells[2, 5].Value.GetType().name | Should be 'String'
$ws.Cells[2, 6].Value.GetType().name | Should be 'String'
$ws.Cells[2, 18].Value.GetType().name | Should be 'String'
($ws.Cells[2, 11].Value -is [valuetype] ) | Should be $true
($ws.Cells[2, 12].Value -is [valuetype] ) | Should be $true
($ws.Cells[2, 13].Value -is [valuetype] ) | Should be $true
$ws.Cells[2, 11].Value | Should beLessThan 0
$ws.Cells[2, 12].Value | Should beLessThan 0
$ws.Cells[2, 13].Value | Should beLessThan 0
if ((Get-Culture).NumberFormat.NumberGroupSeparator -EQ ",") {
($ws.Cells[2, 8].Value -is [valuetype] ) | Should be $true
$ws.Cells[2, 9].Value.GetType().name | Should be 'String'
}
elseif ((Get-Culture).NumberFormat.NumberGroupSeparator -EQ ".") {
($ws.Cells[2, 9].Value -is [valuetype] ) | Should be $true
$ws.Cells[2, 8].Value.GetType().name | Should be 'String'
}
($ws.Cells[2, 14].Value -is [valuetype] ) | Should be $true
$ws.Cells[2, 15].Value.GetType().name | Should be 'String'
$ws.Cells[2, 16].Value.GetType().name | Should be 'String'
$ws.Cells[2, 17].Value.GetType().name | Should be 'String'
($ws.Cells[2, 19].Value -is [valuetype] ) | Should be $true
($ws.Cells[2, 20].Value -is [valuetype] ) | Should be $true
}
}
}

View File

@@ -66,7 +66,7 @@ Describe ExportExcel {
Context " # NoAliasOrScriptPropeties -ExcludeProperty and -DisplayPropertySet work" {
$path = "$env:TEMP\Test.xlsx"
Remove-item -Path $path -ErrorAction SilentlyContinue
Remove-item -Path $path -ErrorAction SilentlyContinue
$processes = Get-Process
$propertyNames = $Processes[0].psobject.properties.where( {$_.MemberType -eq 'Property'}).name
$rowcount = $Processes.Count
@@ -454,7 +454,7 @@ Describe ExportExcel {
#At this point Sheets Should be in the order Sheet1, Processes, ProcessesPivotTable
$null = Add-WorkSheet -ExcelPackage $Excel -WorkSheetname "Processes" -MoveToEnd # order now Sheet1, ProcessesPivotTable, Processes
$null = Add-WorkSheet -ExcelPackage $Excel -WorkSheetname "NewSheet" -MoveAfter "*" -CopySource ($excel.Workbook.Worksheets["Sheet1"]) # Now its NewSheet, Sheet1, ProcessesPivotTable, Processes
$null = Add-WorkSheet -ExcelPackage $Excel -WorkSheetname "Sheet1" -MoveAfter "*" # Now its NewSheet, ProcessesPivotTable, Processes, Sheet1
$null = Add-WorkSheet -ExcelPackage $Excel -WorkSheetname "Sheet1" -MoveAfter "Processes" # Now its NewSheet, ProcessesPivotTable, Processes, Sheet1
$null = Add-WorkSheet -ExcelPackage $Excel -WorkSheetname "Another" -MoveToStart # Now its Another, NewSheet, ProcessesPivotTable, Processes, Sheet1
$null = Add-WorkSheet -ExcelPackage $Excel -WorkSheetname "OneLast" -MoveBefore "ProcessesPivotTable" # Now its Another, NewSheet, Onelast, ProcessesPivotTable, Processes, Sheet1
Close-ExcelPackage $Excel