Merge pull request #416 from jhoneill/master

Fix for #415, auto extend ranges/tables on append, password fixes, wildcards in Exclude property
This commit is contained in:
Doug Finke
2018-08-16 13:23:30 -04:00
committed by GitHub
15 changed files with 533 additions and 251 deletions

View File

@@ -121,14 +121,14 @@
if ($PSBoundParameters.ContainsKey("ConditionValue") -and
$RuleType -match "StdDev" ) {$rule.StdDev = $ConditionValue }
if ($PSBoundParameters.ContainsKey("ConditionValue") -and
$RuleType -match "Than|Equal|Expression" ) {$rule.Formula = $ConditionValue }
$RuleType -match "Than|Equal|Expression" ) {$rule.Formula = ($ConditionValue -replace '^=','') }
if ($PSBoundParameters.ContainsKey("ConditionValue") -and
$RuleType -match "Text|With" ) {$rule.Text = $ConditionValue }
$RuleType -match "Text|With" ) {$rule.Text = ($ConditionValue -replace '^=','') }
if ($PSBoundParameters.ContainsKey("ConditionValue") -and
$PSBoundParameters.ContainsKey("ConditionValue") -and
$RuleType -match "Between" ) {
$rule.Formula = $ConditionValue;
$rule.Formula2 = $ConditionValue2
$rule.Formula = ($ConditionValue -replace '^=','');
$rule.Formula2 = ($ConditionValue2 -replace '^=','')
}
#endregion
#region set the rule format

View File

@@ -22,6 +22,8 @@
Some objects duplicate existing properties by adding aliases, or have Script properties which take a long time to return a value and slow the export down, if specified this removes these properties
.PARAMETER ExcludeProperty
Specifies properties which may exist in the target data but should not be placed on the worksheet.
.PARAMETER Calculate
If specified a recalculation of the worksheet will be requested before saving.
.PARAMETER Title
Text of a title to be placed in the top left cell.
.PARAMETER TitleBold
@@ -372,13 +374,14 @@
[OfficeOpenXml.ExcelPackage]$ExcelPackage,
[Parameter(ValueFromPipeline = $true)]
$TargetData,
[Switch]$Calculate,
[Switch]$Show,
[String]$WorksheetName = 'Sheet1',
[String]$Password,
[switch]$ClearSheet,
[switch]$Append,
[String]$Title,
[OfficeOpenXml.Style.ExcelFillStyle]$TitleFillPattern = 'None',
[OfficeOpenXml.Style.ExcelFillStyle]$TitleFillPattern = 'Solid',
[Switch]$TitleBold,
[Int]$TitleSize = 22,
[System.Drawing.Color]$TitleBackgroundColor,
@@ -452,11 +455,16 @@
[Parameter(ParameterSetName = 'Now')]
[Switch]$Now,
[Switch]$ReturnRange,
#By default Pivot tables have Totals for each Row (on the right) and for each column at the bottom. This allows just one or neither to be selected.
[ValidateSet("Both","Columns","Rows","None")]
[String]$PivotTotals = "Both",
#Included for compatibility - equivalent to -PivotTotals "None"
[Switch]$NoTotalsInPivot,
[Switch]$ReZip
)
Begin {
$numberRegex = [Regex]'\d'
function Add-CellValue {
<#
.SYNOPSIS
@@ -478,13 +486,19 @@
#The write-verbose commands have been commented out below - even if verbose is silenced they cause a significiant performance impact and if it's on they will cause a flood of messages.
Switch ($CellValue) {
{ $_ -is [DateTime]} {
# Save a date with an international valid format
# Save a date with one of Excel's built in formats format
$TargetCell.Value = $_
$TargetCell.Style.Numberformat.Format = 'm/d/yy h:mm' # This is not a custom format, but a preset recognized as date and localized.
#Write-Verbose "Cell '$Row`:$ColumnIndex' header '$Name' add value '$_' as date"
break
}
{ $_ -is [TimeSpan]} {
#Save a timespans with a built in format for elapsed hours, minutes and seconds
$TargetCell.Value = $_
$TargetCell.Style.Numberformat.Format = '[h]:mm:ss'
break
}
{ $_ -is [System.ValueType]} {
# Save numerics, setting format if need be.
$TargetCell.Value = $_
@@ -493,8 +507,8 @@
break
}
{($_ -is [String]) -and ($_[0] -eq '=')} {
#region Save an Excel formula
$TargetCell.Formula = $_
#region Save an Excel formula - we need = to spot the formula but the EPPLUS won't like it if we include it (Excel doesn't care if is there or not)
$TargetCell.Formula = ($_ -replace '^=','')
if ($setNumformat) {$targetCell.Style.Numberformat.Format = $Numberformat }
#Write-Verbose "Cell '$Row`:$ColumnIndex' header '$Name' add value '$_' as formula"
break
@@ -523,7 +537,7 @@
Default {
#Save a value as a number if possible
$number = $null
if ([Double]::TryParse($_, [System.Globalization.NumberStyles]::Any, [System.Globalization.NumberFormatInfo]::CurrentInfo, [Ref]$number)) {
if ($numberRegex.IsMatch($_) -and [Double]::TryParse($_, [System.Globalization.NumberStyles]::Any, [System.Globalization.NumberFormatInfo]::CurrentInfo, [Ref]$number)) {
# as simpler version using [Double]::TryParse( $_ , [ref]$number)) was found to cause problems reverted back to the longer version
$TargetCell.Value = $number
if ($setNumformat) {$targetCell.Style.Numberformat.Format = $Numberformat }
@@ -555,16 +569,21 @@
$pkg = $ExcelPackage
$Path = $pkg.File
}
Else { $pkg = Open-ExcelPackage -Path $Path -Create -KillExcel:$KillExcel}
Else { $pkg = Open-ExcelPackage -Path $Path -Create -KillExcel:$KillExcel -Password:$Password}
}
Catch {throw "Could not open Excel Package $path"}
if ($NoClobber) {Write-Warning -Message "-NoClobber parameter is no longer used" }
Try {
$params = @{WorksheetName=$WorksheetName}
if ($NoClobber) {Write-Warning -Message "-NoClobber parameter is no longer used" }
foreach ($p in @("ClearSheet", "MoveToStart", "MoveToEnd", "MoveBefore", "MoveAfter", "Activate")) {if ($PSBoundParameters[$p]) {$params[$p] = $PSBoundParameters[$p]}}
$ws = $pkg | Add-WorkSheet @params
if ($ws.Name -ne $WorksheetName) {
Write-Warning -Message "The Worksheet name has been changed from $WorksheetName to $($ws.Name), this may cause errors later."
$WorksheetName = $ws.Name
}
}
Catch {throw "Could not get worksheet $worksheetname"}
try {
foreach ($format in $ConditionalFormat ) {
switch ($format.formatter) {
"ThreeIconSet" {Add-ConditionalFormatting -WorkSheet $ws -ThreeIconsSet $format.IconType -range $format.range -reverse:$format.reverse }
@@ -572,12 +591,42 @@
"FiveIconSet" {Add-ConditionalFormatting -WorkSheet $ws -FiveIconsSet $format.IconType -range $format.range -reverse:$format.reverse }
}
}
}
catch {throw "Error applying confitional formatting to worksheet"}
try {
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
$ws.Cells[$headerRange].Value | ForEach-Object -Begin {$Script:header = @()} -Process {$Script:header += $_ }
#if we did not get AutoNameRange, but headers have ranges of the same name make autoNameRange True, otherwise make it false
if (-not $AutoNameRange) {
$AutoNameRange = $true ; foreach ($h in $header) {if ($ws.names.name -notcontains $h) {$AutoNameRange = $false} }
}
#if we did not get a Rangename but there is a Range which covers the active part of the sheet, set Rangename to that.
if (-not $RangeName -and $ws.names.where({$_.name[0] -match '[a-z]'})) {
$theRange = $ws.names.where({
($_.Name[0] -match '[a-z]' ) -and
($_.Start.Row -eq $StartRow) -and
($_.Start.Column -eq $StartColumn) -and
($_.End.Row -eq $ws.Dimension.End.Row) -and
($_.End.Column -eq $ws.Dimension.End.column) } , 'First', 1)
if ($theRange) {$rangename = $theRange.name}
}
#if we did not get a table name but there is a table which covers the active part of the sheet, set table name to that, and don't do anything with autofilter
if (-not $TableName -and $ws.Tables.Where({$_.address.address -eq $ws.dimension.address})) {
$TableName = $ws.Tables.Where({$_.address.address -eq $ws.dimension.address},'First', 1).Name
$AutoFilter = $false
}
#if we did not get $autofilter but a filter range is set and it covers the right area, set autofilter to true
elseif (-not $AutoFilter -and $ws.Names["_xlnm._FilterDatabase"]) {
if ( ($ws.Names["_xlnm._FilterDatabase"].Start.Row -eq $StartRow) -and
($ws.Names["_xlnm._FilterDatabase"].Start.Column -eq $StartColumn) -and
($ws.Names["_xlnm._FilterDatabase"].End.Row -eq $ws.Dimension.End.Row) -and
($ws.Names["_xlnm._FilterDatabase"].End.Column -eq $ws.Dimension.End.Column) ) {$AutoFilter = $true}
}
$row = $ws.Dimension.End.Row
Write-Debug -Message ("Appending: headers are " + ($script:Header -join ", ") + " Start row is $row")
}
@@ -592,13 +641,8 @@
#Otherwise the default will be unbolded.
$ws.Cells[$Row, $StartColumn].Style.Font.Bold = $True
}
#Can only set TitleBackgroundColor if TitleFillPattern is something other than None.
if ($TitleBackgroundColor -and ($TitleFillPattern -ne 'None')) {
$TitleFillPattern = [OfficeOpenXml.Style.ExcelFillStyle]::Solid
}
$ws.Cells[$Row, $StartColumn].Style.Fill.PatternType = $TitleFillPattern
if ($TitleBackgroundColor ) {
$ws.Cells[$Row, $StartColumn].Style.Fill.PatternType = $TitleFillPattern
$ws.Cells[$Row, $StartColumn].Style.Fill.BackgroundColor.SetColor($TitleBackgroundColor)
}
$Row ++ ; $startRow ++
@@ -606,12 +650,16 @@
else { $Row = $StartRow }
$ColumnIndex = $StartColumn
$Numberformat = Expand-NumberFormat -NumberFormat $Numberformat
$setNumformat = ($Numberformat -ne $ws.Cells.Style.Numberformat.Format)
if ($row -le 2 -and $ColumnIndex -eq 1 -and $Numberformat -ne $ws.Cells.Style.Numberformat.Format) {
$ws.Cells.Style.Numberformat.Format = $Numberformat
$setNumformat = $false
}
else { $setNumformat = ($Numberformat -ne $ws.Cells.Style.Numberformat.Format) }
$firstTimeThru = $true
$isDataTypeValueType = $false
}
Catch {
}
Catch {
if ($AlreadyExists) {
#Is this set anywhere ?
throw "Failed exporting worksheet '$WorksheetName' to '$Path': The worksheet '$WorksheetName' already exists."
@@ -619,7 +667,7 @@
else {
throw "Failed preparing to export to worksheet '$WorksheetName' to '$Path': $_"
}
}
}
}
Process {
@@ -627,8 +675,8 @@
Try {
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) {$row -= 1} #row incremented before adding values, so it is set to the number of rows inserted at the end
$isDataTypeValueType = $TargetData.GetType().name -match 'string|timespan|datetime|bool|byte|char|decimal|double|float|int|long|sbyte|short|uint|ulong|ushort'
if ($isDataTypeValueType -and -not $Append) {$row -= 1} #row incremented before adding values, so it is set to the number of rows inserted at the end
Write-Debug "DataTypeName is '$($TargetData.GetType().name)' isDataTypeValueType '$isDataTypeValueType'"
}
@@ -639,7 +687,7 @@
catch {Write-Warning "Could not insert value at Row $Row. "}
}
else {
#region Add headers
#region Add headers - if we are appending, or we have been through here once already we will have the headers
if (-not $script:Header) {
$ColumnIndex = $StartColumn
if ($DisplayPropertySet -and $TargetData.psStandardmembers.DefaultDisplayPropertySet.ReferencedPropertyNames) {
@@ -647,8 +695,9 @@
}
else {
if ($NoAliasOrScriptPropeties) {$propType = "Property"} else {$propType = "*"}
$script:Header = $TargetData.PSObject.Properties.where( {$_.MemberType -like $propType -and $_.Name -notin $ExcludeProperty}).Name
$script:Header = $TargetData.PSObject.Properties.where( {$_.MemberType -like $propType}).Name
}
foreach ($exclusion in $ExcludeProperty) {$script:Header = $script:Header -notlike $exclusion}
if ($NoHeader) {
# Don't push the headers to the spreadsheet
$Row -= 1
@@ -662,18 +711,17 @@
}
}
#endregion
#region Add non header values
$Row += 1
$ColumnIndex = $StartColumn
foreach ($Name in $script:Header) {
#region Add non header values
try {Add-CellValue -TargetCell $ws.Cells[$Row, $ColumnIndex] -CellValue $TargetData.$Name}
catch {Write-Warning -Message "Could not insert the $Name property at Row $Row, Column $Column"}
$ColumnIndex += 1
#endregion
}
$ColumnIndex -= 1 # column index will be the last column whether isDataTypeValueType was true or false
#endregion
}
}
Catch {
@@ -691,10 +739,10 @@
else {
$LastRow = $Row
$LastCol = $ColumnIndex
$endAddress = [OfficeOpenXml.ExcelAddress]::TranslateFromR1C1("R[$LastRow]C[$LastCol]", 0, 0)
$endAddress = [OfficeOpenXml.ExcelAddress]::GetAddress($LastRow , $LastCol)
}
$startAddress = [OfficeOpenXml.ExcelAddress]::TranslateFromR1C1("R[$StartRow]C[$StartColumn]", 0, 0)
$dataRange = "{0}:{1}" -f $startAddress, $endAddress
$startAddress = [OfficeOpenXml.ExcelAddress]::GetAddress($StartRow, $StartColumn)
$dataRange = "{0}:{1}" -f $startAddress, $endAddress
Write-Debug "Data Range '$dataRange'"
if ($AutoNameRange) {
@@ -779,7 +827,8 @@
if ($params.keys -notcontains "SourceRange" -and
($params.Keys -notcontains "SourceWorkSheet" -or $params.SourceWorkSheet -eq $WorksheetName)) {$params.SourceRange = $dataRange}
if ($params.Keys -notcontains "SourceWorkSheet") {$params.SourceWorkSheet = $ws }
if ($params.Keys -notcontains "NoTotalsInPivot" -and $NoTotalsInPivot ) {$params.NoTotalsInPivot = $true}
if ($params.Keys -notcontains "NoTotalsInPivot" -and $NoTotalsInPivot ) {$params.PivotTotals = "None"}
if ($params.Keys -notcontains "PivotTotals" -and $PivotTotals ) {$params.PivotTotals = $PivotTotals}
if ($params.Keys -notcontains "PivotDataToColumn" -and $PivotDataToColumn) {$params.PivotDataToColumn = $true}
Add-PivotTable -ExcelPackage $pkg -PivotTableName $item.key @Params
@@ -789,14 +838,15 @@
$params = @{
"SourceRange" = $dataRange
}
if ($PivotTableName) {$params.PivotTableName = $PivotTableName}
if ($PivotTableName) {$params.PivotTableName = $PivotTableName}
else {$params.PivotTableName = $WorksheetName + 'PivotTable'}
if ($Activate) {$params.Activate = $true }
if ($PivotFilter) {$params.PivotFilter = $PivotFilter}
if ($PivotRows) {$params.PivotRows = $PivotRows}
if ($PivotColumns) {$Params.PivotColumns = $PivotColumns}
if ($PivotData) {$Params.PivotData = $PivotData}
if ($NoTotalsInPivot) {$params.NoTotalsInPivot = $true}
if ($Activate) {$params.Activate = $true }
if ($PivotFilter) {$params.PivotFilter = $PivotFilter}
if ($PivotRows) {$params.PivotRows = $PivotRows}
if ($PivotColumns) {$Params.PivotColumns = $PivotColumns}
if ($PivotData) {$Params.PivotData = $PivotData}
if ($NoTotalsInPivot) {$params.PivotTotals = "None" }
Elseif ($PivotTotals) {$params.PivotTotals = $PivotTotals}
if ($PivotDataToColumn) {$params.PivotDataToColumn = $true}
if ($IncludePivotChart) {
$params.IncludePivotChart = $true
@@ -890,13 +940,13 @@
if ($Barchart -or $PieChart -or $LineChart -or $ColumnChart) {
if ($NoHeader) {$FirstDataRow = $startRow}
else {$FirstDataRow = $startRow + 1 }
$range = [OfficeOpenXml.ExcelAddress]::TranslateFromR1C1("R[$FirstDataRow]C[$startColumn]:R[$FirstDataRow]C[$lastCol]",0,0)
$range = [OfficeOpenXml.ExcelAddress]::GetAddress($FirstDataRow, $startColumn, $FirstDataRow, $lastCol )
$xCol = $ws.cells[$range] | Where-Object {$_.value -is [string] } | ForEach-Object {$_.start.column} | Sort-Object | Select-Object -first 1
$yCol = $ws.cells[$range] | Where-Object {$_.value -is [valueType] } | ForEach-Object {$_.start.column} | Sort-Object | Select-Object -first 1
$params = @{
xrange = [OfficeOpenXml.ExcelAddress]::TranslateFromR1C1("R[$FirstDataRow]C[$xcol]:R[$($lastrow)]C[$xcol]",0,0) ;
yrange = [OfficeOpenXml.ExcelAddress]::TranslateFromR1C1("R[$FirstDataRow]C[$ycol]:R[$($lastrow)]C[$ycol]",0,0) ;
title = "";
XRange = [OfficeOpenXml.ExcelAddress]::GetAddress($FirstDataRow, $xcol , $lastrow, $xcol)
YRange = [OfficeOpenXml.ExcelAddress]::GetAddress($FirstDataRow, $ycol , $lastrow, $ycol)
Title = "";
Column = ($lastCol +1) ;
Width = 800
}
@@ -934,6 +984,11 @@
catch {Write-Warning -Message "Failed processing CellStyleSB in worksheet '$WorksheetName': $_"}
}
if ($Calculate) {
try { [OfficeOpenXml.CalculationExtension]::Calculate($ws) }
Catch { Write-Warning "One or more errors occured while calculating, save will continue, but there may be errors in the workbook."}
}
if ($Password) {
try {
$ws.Protection.SetPassword($Password)
@@ -947,7 +1002,8 @@
else {
if ($ReturnRange) {$dataRange }
$pkg.Save()
if ($Password) { $pkg.Save($Password) }
else { $pkg.Save() }
Write-Verbose -Message "Saved workbook $($pkg.File)"
if ($ReZip) {
Write-Verbose -Message "Re-Zipping $($pkg.file) using .NET ZIP library"
@@ -981,7 +1037,7 @@ function New-PivotTableDefinition {
Creates Pivot table definitons for Export-Excel
.Description
Export-Excel allows a single Pivot table to be defined using the parameters -IncludePivotTable, -PivotColumns -PivotRows,
=PivotData, -PivotFilter, -NoTotalsInPivot, -PivotDataToColumn, -IncludePivotChart and -ChartType.
=PivotData, -PivotFilter, -PivotTotals, -PivotDataToColumn, -IncludePivotChart and -ChartType.
Its -PivotTableDefintion paramater allows multiple pivot tables to be defined, with additional parameters.
New-PivotTableDefinition is a convenient way to build these definitions.
.Example
@@ -1011,6 +1067,10 @@ function New-PivotTableDefinition {
#Fields to use to filter in the Pivot table
$PivotFilter,
[Switch]$PivotDataToColumn,
#By default Pivot tables have Totals for each Row (on the right) and for each column at the bottom. This allows just one or neither to be selected.
[ValidateSet("Both","Columns","Rows","None")]
[String]$PivotTotals = "Both",
#Included for compatibility - equivalent to -PivotTotals "None"
[Switch]$NoTotalsInPivot,
#If specified a chart Will be included.
[Switch]$IncludePivotChart,
@@ -1046,6 +1106,10 @@ function New-PivotTableDefinition {
}
$parameters = @{} + $PSBoundParameters
if ($NoTotalsInPivot) {
$parameters.Remove('NoTotalsInPivot')
$parameters["PivotTotals"] = "None"
}
$parameters.Remove('PivotTableName')
@{$PivotTableName = $parameters}
@@ -1174,6 +1238,10 @@ function Add-PivotTable {
#Fields to use to filter in the Pivot table
$PivotFilter,
[Switch]$PivotDataToColumn,
#By default Pivot tables have Totals for each Row (on the right) and for each column at the bottom. This allows just one or neither to be selected.
[ValidateSet("Both","Columns","Rows","None")]
[String]$PivotTotals = "Both",
#Included for compatibility - equivalent to -PivotTotals "None"
[Switch]$NoTotalsInPivot,
#If specified a chart Will be included.
[Switch]$IncludePivotChart,
@@ -1210,13 +1278,13 @@ function Add-PivotTable {
if (-not $wsPivot.PivotTables[$pivotTableDataName] ) {
try {
#Accept a string or a worksheet object as $Source Worksheet.
if ($SourceWorkSheet -is [string]) {
$SourceWorkSheet = $ExcelPackage.Workbook.Worksheets.where( {$_.name -match $SourceWorkSheet})[0]
if ($SourceWorkSheet -is [string]) {
$SourceWorkSheet = $ExcelPackage.Workbook.Worksheets.where( {$_.name -Like $SourceWorkSheet})[0]
}
elseif ($SourceWorkSheet -is [int]) {
elseif ($SourceWorkSheet -is [int]) {
$SourceWorkSheet = $ExcelPackage.Workbook.Worksheets[$SourceWorkSheet]
}
if (-not ($SourceWorkSheet -is [OfficeOpenXml.ExcelWorksheet])) {Write-Warning -Message "Could not find source Worksheet for pivot-table '$pivotTableName'." }
if ($SourceWorkSheet -isnot [OfficeOpenXml.ExcelWorksheet]) {Write-Warning -Message "Could not find source Worksheet for pivot-table '$pivotTableName'." ; return }
else {
if ($PivotFilter) {$PivotTableStartCell = "A3"} else { $PivotTableStartCell = "A1"}
if (-not $SourceRange) { $SourceRange = $SourceWorkSheet.Dimension.Address}
@@ -1252,8 +1320,12 @@ function Add-PivotTable {
try { $null = $pivotTable.PageFields.Add($pivotTable.Fields[$pFilter])}
catch {Write-Warning -message "Could not add '$pFilter' to Filter/Page fields in PivotTable $pivotTableName." }
}
if ($NoTotalsInPivot) { $pivotTable.RowGrandTotals = $false }
if ($PivotDataToColumn ) { $pivotTable.DataOnRows = $false }
if ($NoTotalsInPivot) {$PivotTotals = "None" }
if ($PivotTotals -eq "None" -or $PivotTotals -eq "Columns") { $pivotTable.RowGrandTotals = $false }
elseif ($PivotTotals -eq "Both" -or $PivotTotals -eq "Rows") { $pivotTable.RowGrandTotals = $true }
if ($PivotTotals -eq "None" -or $PivotTotals -eq "Rows") { $pivotTable.ColumGrandTotals = $false } # Epplus spelling mistake, not mine!
elseif ($PivotTotals -eq "Both" -or $PivotTotals -eq "Columns") { $pivotTable.ColumGrandTotals = $true }
if ($PivotDataToColumn ) { $pivotTable.DataOnRows = $false }
}
catch {Write-Warning -Message "Failed adding PivotTable '$pivotTableName': $_"}
}
@@ -1349,7 +1421,8 @@ function Add-ExcelChart {
if ($XAxisTitleBold) {$chart.XAxis.Title.Font.Bold = $true}
if ($XAxisTitleSize) {$chart.XAxis.Title.Font.Size = $XAxisTitleSize}
}
if ($XAxisPosition) {$chart.ChartXml.chartSpace.chart.plotArea.catAx.axPos.val = $XAxisPosition.ToString().substring(0,1)}
if ($XAxisPosition) {Write-Warning "X Axis position is not being set propertly at the moment, parameter ignored" }
#$chart.ChartXml.chartSpace.chart.plotArea.catAx.axPos.val = $XAxisPosition.ToString().substring(0,1)}
if ($XMajorUnit) {$chart.XAxis.MajorUnit = $XMajorUnit}
if ($XMinorUnit) {$chart.XAxis.MinorUnit = $XMinorUnit}
if ($null -ne $XMinValue) {$chart.XAxis.MinValue = $XMinValue}
@@ -1361,7 +1434,8 @@ function Add-ExcelChart {
if ($YAxisTitleBold) {$chart.YAxis.Title.Font.Bold = $true}
if ($YAxisTitleSize) {$chart.YAxis.Title.Font.Size = $YAxisTitleSize}
}
if ($YAxisPosition) {$chart.ChartXml.chartSpace.chart.plotArea.valAx.axPos.val= $YAxisPosition.ToString().substring(0,1)}
if ($YAxisPosition) {Write-Warning "Y Axis position is not being set propertly at the moment, parameter ignored" }
#$chart.ChartXml.chartSpace.chart.plotArea.valAx.axPos.val= $YAxisPosition.ToString().substring(0,1)}
if ($YMajorUnit) {$chart.YAxis.MajorUnit = $YMajorUnit}
if ($YMinorUnit) {$chart.YAxis.MinorUnit = $YMinorUnit}
if ($null -ne $YMinValue){$chart.YAxis.MinValue = $YMinValue}

View File

@@ -321,28 +321,25 @@ function Import-Excel {
}
Process {
Try {
#region Open file
#region Open file
try {
$Path = (Resolve-Path $Path).ProviderPath
Write-Verbose "Import Excel workbook '$Path' with worksheet '$Worksheetname'"
$Stream = New-Object -TypeName System.IO.FileStream -ArgumentList $Path, 'Open', 'Read', 'ReadWrite'
}
Catch {throw "Could not open $Path ; $_ "}
if ($Password) {
$Excel = New-Object -TypeName OfficeOpenXml.ExcelPackage
Try {
$Excel.Load($Stream,$Password)
}
Catch {
throw "Password '$Password' is not correct."
}
}
else {
$Excel = New-Object -TypeName OfficeOpenXml.ExcelPackage -ArgumentList $Stream
}
#endregion
if ($Password) {
Try {$Excel = New-Object -TypeName OfficeOpenXml.ExcelPackage
$excel.Load( $Stream,$Password)}
Catch { throw "Could not read $Path with the provided password." }
}
else {
try {$Excel = New-Object -TypeName OfficeOpenXml.ExcelPackage -ArgumentList $Stream}
Catch {throw "Failed to read $Path"}
}
#endregion
Try {
#region Select worksheet
if ($WorksheetName) {
if (-not ($Worksheet = $Excel.Workbook.Worksheets[$WorkSheetName])) {

View File

@@ -10,12 +10,15 @@
This will open the file at $xlPath, select sheet1 apply formatting to two blocks of the sheet and save the package, and launch it in Excel.
#>
[CmdLetBinding()]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword","")]
[OutputType([OfficeOpenXml.ExcelPackage])]
Param (
#The Path to the file to open
[Parameter(Mandatory=$true)]$Path,
#If specified, any running instances of Excel will be terminated before opening the file.
[switch]$KillExcel,
[String]$Password,
#By default open only opens an existing file; -Create instructs it to create a new file if required.
[switch]$Create
)
@@ -27,7 +30,7 @@
$Path = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($Path)
#If -Create was not specified only open the file if it exists already (send a warning if it doesn't exist).
if ($Create) {
if ($Create -and -not (Test-Path -Path $path)) {
#Create the directory if required.
$targetPath = Split-Path -Parent -Path $Path
if (!(Test-Path -Path $targetPath)) {
@@ -36,7 +39,10 @@
}
New-Object -TypeName OfficeOpenXml.ExcelPackage -ArgumentList $Path
}
elseif (Test-Path -Path $path) {New-Object -TypeName OfficeOpenXml.ExcelPackage -ArgumentList $Path }
elseif (Test-Path -Path $path) {
if ($Password) {New-Object -TypeName OfficeOpenXml.ExcelPackage -ArgumentList $Path , $Password }
else {New-Object -TypeName OfficeOpenXml.ExcelPackage -ArgumentList $Path }
}
else {Write-Warning "Could not find $path" }
}
@@ -45,6 +51,8 @@ Function Close-ExcelPackage {
.Synopsis
Closes an Excel Package, saving, saving under a new name or abandoning changes and opening the file in Excel as required.
#>
[CmdLetBinding()]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword","")]
Param (
#File to close.
[parameter(Mandatory=$true, ValueFromPipeline=$true)]
@@ -54,14 +62,30 @@ Function Close-ExcelPackage {
#Abandon the file without saving.
[Switch]$NoSave,
#Save file with a new name (ignored if -NoSave Specified).
$SaveAs
$SaveAs,
[ValidateNotNullOrEmpty()]
[String]$Password,
#Attempt to recalculation the workbook before saving
[switch]$Calculate
)
if ( $NoSave) {$ExcelPackage.Dispose()}
else {
if ($SaveAs) {$ExcelPackage.SaveAs( $SaveAs ) }
Else {$ExcelPackage.Save(); $SaveAs = $ExcelPackage.File.FullName }
if ($Calculate) {
try { [OfficeOpenXml.CalculationExtension]::Calculate($ExcelPackage.Workbook) }
Catch { Write-Warning "One or more errors occured while calculating, save will continue, but there may be errors in the workbook."}
}
if ($SaveAs) {
$SaveAs = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($SaveAs)
if ($Password) {$ExcelPackage.SaveAs( $SaveAs, $Password ) }
else {$ExcelPackage.SaveAs( $SaveAs)}
}
Else {
if ($Password) {$ExcelPackage.Save($Password) }
else {$ExcelPackage.Save() }
$SaveAs = $ExcelPackage.File.FullName
}
$ExcelPackage.Dispose()
if ($show) {Start-Process -FilePath $SaveAs }
if ($Show) {Start-Process -FilePath $SaveAs }
}
}

View File

@@ -51,16 +51,35 @@ Install-Module ImportExcel -scope CurrentUser
```PowerShell
Install-Module ImportExcel
```
# What's new to Aug 2018
# New to Aug 16th
- Value does not need to be mandatory in Set-Row or Set-Column, also tidied their paramters a little.
- Added support for array formulas in Set-Format (it really should be set range now that it sets values, formulas and hyperlinks - that can go on the to-do list )
- Fixed a bug with -Append in Export-Excel which caused it to overwrite the last row if the new data was a simple type.
- NumberFormat in Export-Excel now sets the default for on a new / blank sheet; but [still] sets individual cells when adding to a sheet
- Added support for timespans in Export excel ; set as elapsed hours, mins, secs [h]:mm:sss
- In Export-Excel improved the catch-all handler for insering values to cope better with nested objects (#419) and reduce the number of parse operations
- Added -Calculate switch to Export-Excel and Close-Excel Package; EPPlus needs formulas to OMIT the leading = sign so where formula is set it now strips a leading = sign
- Added -PivotTotals parameter where there was already -NoTotalsInPivot new one allows None, Both, Rows, Columns. (#415)
- When appending Export-Excel only extended tables and ranges if they were explicitly specified. It now does it automatically.
- Compare and Merge worksheet originally had a problem with > 26 columns, I fixed merge turns out I hadn't fixed compare ... I have now
- Fixed bug where Export-Excel would not recognise it had to set $TitleFillPattern - made the default 'Solid'
- ExcludeProperty in Export-Excel now supports wildcards.
- Added DateTime to the list of types which can be exported as single column.
- Addded Password support to Open- and Close-ExcelPackage (password was not doing anything in Export-Excel)
- Gave Expand-NumberFormat a better grasp of currency layouts - it follows .NET which is not always the same as Excel would set:-(
# What's new in Release 5.1.1
- Set-Row and Set-Column will now create hyperlinks and insert dates correctly
- Import-Excel now has an argument completer for Worksheet name - this can be slow on large files
- The NumberFormat parameter (in Export-Excel, Set-Row, Set-Column, Set-Format and Add-ConditionalFormat) and X&YAxisNumberFormat parameters (in New-ExcelChartDefinition and Add-ExcelChart) now have an argument completer and the names Currency, Number, Percentage, Scientific, Fraction, Short Date ,Short time,Long time, Date-Time and Text will be converted to the correct Excel formatting strings.
- Added new function Select-Worksheet to make a named sheet active: Added -Activate switch to Add-Worksheet, to make current sheet active, Export-Excel and Add-PivotTable support -Activate and pass it to Add-Worksheet, and New-PivotTableDefinition allows it to be part of the Pivot TableDefinition.
- Fixed a bug in Set-Format which caused -Hidden not to work
- Additional tests.
- The NumberFormat parameter (in Export-Excel, Set-Row, Set-Column, Set-Format and Add-ConditionalFormat) and X&YAxisNumberFormat paramaters (in New-ExcelChartDefinition and Add-ExcelChart) now have an argument completer and the names Currency, Number, Percentage, Scientific, Fraction, Short Date ,Short time,Long time, Date-Time and Text will be converted to the correct Excel formatting strings.
- Added new function Select-Worksheet to make a named sheet active: Added -Activate switch to Add-Worksheet, to make current sheet active, Export-Excel and Add-PivotTable support -Activate and pass it to Add-Worksheet, and New-PivotTableDefinition allows it to be part of the Pivot TableDefinition.
- Fixed a bug in Set-Format which caused -Hidden not to work
- Made the same changes to Add-Conditional format as set format so -switch:$false is processed, and 0 enums and values are processed correctly
- In Export-Excel, wraped calls to Add-CellValue in a try catch so a value which causes an issue doesn't crash the whole export but generates a warning instead (#410) .
- Additional tests.
# What's new to July 18
- Changed parameter evaluation in Set-Format to support -bold:$false (and other switches so that if false is specified the attribute will be removed ), and to bug were enums with a value of zero, and other zero parameters were not set.
- Changed parameter evaluation in Set-Format to support -bold:$false (and other switches so that if false is specified the attribute will be removed ), and to bug were enums with a value of zero, and other zero parameters were not set.
- 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 .
- 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

View File

@@ -20,16 +20,16 @@
#The sheet to update can be a given as a name or an Excel Worksheet object - this sets it by name
[Parameter(ParameterSetName="Package")]
#The sheet to update can be a given as a name or an Excel Worksheet object - $workSheet contains the object
$Worksheetname = "Sheet1",
[String]$Worksheetname = "Sheet1",
[Parameter(ParameterSetName="sheet",Mandatory=$true)]
[OfficeOpenXml.ExcelWorksheet]
$Worksheet,
[OfficeOpenXml.ExcelWorksheet]$Worksheet,
#Column to fill down - first column is 1. 0 will be interpreted as first unused column
[ValidateRange(0,16384)]
$Column = 0 ,
#First row to fill data in
[ValidateRange(1,1048576)]
[Int]$StartRow ,
#value, formula or script block for to fill in. Script block can use $row, $column [number], $ColumnName [letter(s)], $startRow, $startColumn, $endRow, $endColumn
[parameter(Mandatory=$true)]
#value, formula or script block to fill in. Script block can use $row, $column [number], $columnName [letter(s)], $startRow, $startColumn, $endRow, $endColumn
$Value ,
#Optional column heading
$Heading ,
@@ -41,15 +41,15 @@
#Colour for the text - if none specified it will be left as it it is
[System.Drawing.Color]$FontColor,
#Make text bold; use -Bold:$false to remove bold
[switch]$Bold,
[Switch]$Bold,
#Make text italic; use -Italic:$false to remove italic
[switch]$Italic,
[Switch]$Italic,
#Underline the text using the underline style in -underline type; use -Underline:$false to remove underlining
[switch]$Underline,
[Switch]$Underline,
#Should Underline use single or double, normal or accounting mode : default is single normal
[OfficeOpenXml.Style.ExcelUnderLineType]$UnderLineType = [OfficeOpenXml.Style.ExcelUnderLineType]::Single,
#Strike through text; use -Strikethru:$false to remove Strike through
[switch]$StrikeThru,
[Switch]$StrikeThru,
#Subscript or superscript (or none)
[OfficeOpenXml.Style.ExcelVerticalAlignmentFont]$FontShift,
#Font to use - Excel defaults to Calibri
@@ -64,7 +64,7 @@
[Alias("PatternColour")]
[System.Drawing.Color]$PatternColor,
#Turn on text wrapping; use -WrapText:$false to turn off word wrapping
[switch]$WrapText,
[Switch]$WrapText,
#Position cell contents to left, right, center etc. default is 'General'
[OfficeOpenXml.Style.ExcelHorizontalAlignment]$HorizontalAlignment,
#Position cell contents to top bottom or centre
@@ -79,38 +79,38 @@
[float]$Width,
#Set the inserted data to be a named range (ignored if header is not specified)
[Switch]$AutoNameRange,
#If Sepecified returns the range of cells which affected
[switch]$ReturnRange,
#If Sepecified returns the range of cells which were affected
[Switch]$ReturnRange,
#If Specified, return an ExcelPackage object to allow further work to be done on the file.
[switch]$PassThru
[Switch]$PassThru
)
#if we were passed a package object and a worksheet name , get the worksheet.
if ($ExcelPackage) {$Worksheet = $ExcelPackage.Workbook.Worksheets[$Worksheetname] }
#In a script block to build a formula, we may want any of corners or the columnname,
#if column and startrow aren't specified, assume first unused column, and first row
#In a script block to build a formula, we may want any of corners or the column name,
#if Column and Startrow aren't specified, assume first unused column, and first row
if (-not $StartRow) {$startRow = $Worksheet.Dimension.Start.Row }
$StartColumn = $Worksheet.Dimension.Start.Column
$startColumn = $Worksheet.Dimension.Start.Column
$endColumn = $Worksheet.Dimension.End.Column
$endRow = $Worksheet.Dimension.End.Row
if ($Column -lt 2 ) {$Column = $endColumn + 1 }
$ColumnName = [OfficeOpenXml.ExcelCellAddress]::new(1,$column).Address -replace "1",""
if ($Column -eq 0 ) {$Column = $endColumn + 1 }
$columnName = [OfficeOpenXml.ExcelCellAddress]::new(1,$column).Address -replace "1",""
Write-Verbose -Message "Updating Column $ColumnName"
Write-Verbose -Message "Updating Column $columnName"
#If there is a heading, insert it and use it as the name for a range (if we're creating one)
if ($Heading) {
$Worksheet.Cells[$StartRow, $Column].Value = $heading
$startRow ++
if ($AutoNameRange) { $Worksheet.Names.Add( $heading, ($Worksheet.Cells[$startrow, $Column, $endRow, $Column]) ) | Out-Null }
$Worksheet.Cells[$StartRow, $Column].Value = $Heading
$StartRow ++
if ($AutoNameRange) { $Worksheet.Names.Add( $Heading, ($Worksheet.Cells[$StartRow, $Column, $endRow, $Column]) ) | Out-Null }
}
#Fill in the data
if ($PSBoundParameters.ContainsKey('value')) { foreach ($row in ($StartRow.. $endRow)) {
if ($PSBoundParameters.ContainsKey('Value')) { foreach ($row in ($StartRow..$endRow)) {
if ($Value -is [scriptblock]) { #re-create the script block otherwise variables from this function are out of scope.
$cellData = & ([scriptblock]::create( $Value ))
Write-Verbose -Message $cellData
}
else { $cellData = $Value}
if ($cellData -match "^=") { $Worksheet.Cells[$Row, $Column].Formula = $cellData }
if ($cellData -match "^=") { $Worksheet.Cells[$Row, $Column].Formula = ($cellData -replace '^=','') } #EPPlus likes formulas with no = sign; Excel doesn't care
elseif ( [System.Uri]::IsWellFormedUriString($cellData , [System.UriKind]::Absolute)) {
# Save a hyperlink : internal links can be in the form xl://sheet!E419 (use A1 as goto sheet), or xl://RangeName
if ($cellData -match "^xl://internal/") {
@@ -123,8 +123,9 @@
$Worksheet.Cells[$Row, $Column].Style.Font.Color.SetColor([System.Drawing.Color]::Blue)
$Worksheet.Cells[$Row, $Column].Style.Font.UnderLine = $true
}
else { $Worksheet.Cells[$Row, $Column].Value = $cellData }
if ($cellData -is [datetime]) { $Worksheet.Cells[$Row, $Column].Style.Numberformat.Format = 'm/d/yy h:mm' } # This is not a custom format, but a preset recognized as date and localized.
else { $Worksheet.Cells[$Row, $Column].Value = $cellData }
if ($cellData -is [datetime]) { $Worksheet.Cells[$Row, $Column].Style.Numberformat.Format = 'm/d/yy h:mm' } # This is not a custom format, but a preset recognized as date and localized.
if ($cellData -is [timespan]) { $Worksheet.Cells[$Row, $Column].Style.Numberformat.Format = '[h]:mm:ss' }
}}
#region Apply formatting
$params = @{}
@@ -133,7 +134,7 @@
'BorderAround', 'BackgroundColor', 'BackgroundPattern', 'PatternColor')) {
if ($PSBoundParameters.ContainsKey($p)) {$params[$p] = $PSBoundParameters[$p]}
}
$theRange = "$ColumnName$startRow`:$ColumnName$endRow"
$theRange = "$columnName$StartRow`:$columnName$endRow"
if ($params.Count) {
Set-Format -WorkSheet $Worksheet -Range $theRange @params
}

View File

@@ -25,15 +25,13 @@
[Parameter(ParameterSetName="Package")]
$Worksheetname = "Sheet1",
#A worksheet object
[Parameter(ParameterSetName="sheet",Mandatory=$true)]
[OfficeOpenXml.Excelworksheet]
$Worksheet,
[Parameter(ParameterSetName="Sheet",Mandatory=$true)]
[OfficeOpenXml.Excelworksheet] $Worksheet,
#Row to fill right - first row is 1. 0 will be interpreted as first unused row
$Row = 0 ,
#Position in the row to start from
[Int]$StartColumn,
#value, formula or script block for to fill in. Script block can use $worksheet, $row, $column [number], $ColumnName [letter(s)], $startRow, $startColumn, $endRow, $endColumn
[parameter(Mandatory=$true)]
[int]$StartColumn,
#Value, formula or script block to fill in. Script block can use $worksheet, $row, $Column [number], $ColumnName [letter(s)], $startRow, $startColumn, $endRow, $endColumn
$Value,
#Optional Row heading
$Heading ,
@@ -45,15 +43,15 @@
#Colour for the text - if none specified it will be left as it it is
[System.Drawing.Color]$FontColor,
#Make text bold; use -Bold:$false to remove bold
[switch]$Bold,
[Switch]$Bold,
#Make text italic; use -Italic:$false to remove italic
[switch]$Italic,
[Switch]$Italic,
#Underline the text using the underline style in -underline type; use -Underline:$false to remove underlining
[switch]$Underline,
[Switch]$Underline,
#Should Underline use single or double, normal or accounting mode : default is single normal
[OfficeOpenXml.Style.ExcelUnderLineType]$UnderLineType = [OfficeOpenXml.Style.ExcelUnderLineType]::Single,
#Strike through text; use -Strikethru:$false to remove Strike through
[switch]$StrikeThru,
[Switch]$StrikeThru,
#Subscript or superscript (or none)
[OfficeOpenXml.Style.ExcelVerticalAlignmentFont]$FontShift,
[String]$FontName,
@@ -67,7 +65,7 @@
[Alias("PatternColour")]
[System.Drawing.Color]$PatternColor,
#Turn on text wrapping; use -WrapText:$false to turn off word wrapping
[switch]$WrapText,
[Switch]$WrapText,
#Position cell contents to left, right, center etc. default is 'General'
[OfficeOpenXml.Style.ExcelHorizontalAlignment]$HorizontalAlignment,
#Position cell contents to top bottom or centre
@@ -77,10 +75,10 @@
[int]$TextRotation ,
#Set cells to a fixed hieght
[float]$Height,
#If Sepecified returns the range of cells which affected
[switch]$ReturnRange,
#If Specified, return a row object to allow further work to be done
[switch]$PassThru
#If Sepecified returns the range of cells which were affected
[Switch]$ReturnRange,
#If Specified, return a row object to allow further work to be done
[Switch]$PassThru
)
#if we were passed a package object and a worksheet name , get the worksheet.
@@ -92,7 +90,7 @@
$startRow = $Worksheet.Dimension.Start.Row + 1
$endColumn = $Worksheet.Dimension.End.Column
$endRow = $Worksheet.Dimension.End.Row
if ($Row -lt 2 ) {$Row = $endRow + 1 }
if ($Row -eq 0 ) {$Row = $endRow + 1 }
Write-Verbose -Message "Updating Row $Row"
#Add a row label
if ($Heading) {
@@ -100,16 +98,16 @@
$StartColumn ++
}
#Fill in the data
if ($PSBoundParameters.ContainsKey('Value')) {foreach ($column in ($StartColumn..$EndColumn)) {
if ($PSBoundParameters.ContainsKey('Value')) {foreach ($column in ($StartColumn..$endColumn)) {
#We might want the column name in a script block
$ColumnName = [OfficeOpenXml.ExcelCellAddress]::new(1,$column).Address -replace "1",""
$columnName = [OfficeOpenXml.ExcelCellAddress]::new(1,$column).Address -replace "1",""
if ($Value -is [scriptblock] ) {
#re-create the script block otherwise variables from this function are out of scope.
$cellData = & ([scriptblock]::create( $Value ))
Write-Verbose -Message $cellData
}
else{$cellData = $Value}
if ($cellData -match "^=") { $Worksheet.Cells[$Row, $column].Formula = $cellData }
if ($cellData -match "^=") { $Worksheet.Cells[$Row, $column].Formula = ($cellData -replace '^=','') } #EPPlus likes formulas with no = sign; Excel doesn't care
elseif ( [System.Uri]::IsWellFormedUriString($cellData , [System.UriKind]::Absolute)) {
# Save a hyperlink : internal links can be in the form xl://sheet!E419 (use A1 as goto sheet), or xl://RangeName
if ($cellData -match "^xl://internal/") {
@@ -122,8 +120,9 @@
$Worksheet.Cells[$Row, $Column].Style.Font.Color.SetColor([System.Drawing.Color]::Blue)
$Worksheet.Cells[$Row, $Column].Style.Font.UnderLine = $true
}
else { $Worksheet.Cells[$Row, $column].Value = $cellData }
if ($cellData -is [datetime]) { $Worksheet.Cells[$Row, $column].Style.Numberformat.Format = 'm/d/yy h:mm' } # This is not a custom format, but a preset recognized as date and localized.
else { $Worksheet.Cells[$Row, $column].Value = $cellData }
if ($cellData -is [datetime]) { $Worksheet.Cells[$Row, $column].Style.Numberformat.Format = 'm/d/yy h:mm' } #This is not a custom format, but a preset recognized as date and localized.
if ($cellData -is [timespan]) { $Worksheet.Cells[$Row, $Column].Style.Numberformat.Format = '[h]:mm:ss' }
}}
#region Apply formatting
$params = @{}
@@ -132,7 +131,7 @@
'BorderAround', 'BackgroundColor', 'BackgroundPattern', 'PatternColor')) {
if ($PSBoundParameters.ContainsKey($p)) {$params[$p] = $PSBoundParameters[$p]}
}
$theRange = [OfficeOpenXml.ExcelAddress]::TranslateFromR1C1("R[$Row]C[$StartColumn]:R[$Row]C[$EndColumn]",0,0)
$theRange = [OfficeOpenXml.ExcelAddress]::New($Row, $StartColumn, $Row, $endColumn)
if ($params.Count) {
Set-Format -WorkSheet $Worksheet -Range $theRange @params
}

View File

@@ -20,7 +20,7 @@
#The area of the worksheet where the format is to be applied
[Parameter(ParameterSetName="SheetAndRange",Mandatory=$True)]
[OfficeOpenXml.ExcelAddress]$Range,
#Number format to apply to cells e.g. "dd/MM/yyyy HH:mm", "£#,##0.00;[Red]-£#,##0.00", "0.00%" , "##/##" , "0.0E+0" etc
#Number format to apply to cells e.g. "dd/MM/yyyy HH:mm", "£#,##0.00;[Red]-£#,##0.00", "0.00%" , "##/##" , "0.0E+0" etc
[Alias("NFormat")]
$NumberFormat,
#Style of border to draw around the range
@@ -36,18 +36,20 @@
$Value,
#Formula for the cell
$Formula,
#Specifies formula should be an array formula (a.k.a CSE [ctrl-shift-enter] formula )
[Switch]$ArrayFormula,
#Clear Bold, Italic, StrikeThrough and Underline and set colour to black
[switch]$ResetFont,
[Switch]$ResetFont,
#Make text bold; use -Bold:$false to remove bold
[switch]$Bold,
[Switch]$Bold,
#Make text italic; use -Italic:$false to remove italic
[switch]$Italic,
[Switch]$Italic,
#Underline the text using the underline style in -underline type; use -Underline:$false to remove underlining
[switch]$Underline,
[Switch]$Underline,
#Should Underline use single or double, normal or accounting mode : default is single normal
[OfficeOpenXml.Style.ExcelUnderLineType]$UnderLineType = [OfficeOpenXml.Style.ExcelUnderLineType]::Single,
#Strike through text; use -Strikethru:$false to remove Strike through
[switch]$StrikeThru,
[Switch]$StrikeThru,
#Subscript or superscript (or none)
[OfficeOpenXml.Style.ExcelVerticalAlignmentFont]$FontShift,
#Font to use - Excel defaults to Calibri
@@ -62,7 +64,7 @@
[Alias("PatternColour")]
[System.Drawing.Color]$PatternColor,
#Turn on text wrapping; use -WrapText:$false to turn off word wrapping
[switch]$WrapText,
[Switch]$WrapText,
#Position cell contents to left, right, center etc. default is 'General'
[OfficeOpenXml.Style.ExcelHorizontalAlignment]$HorizontalAlignment,
#Position cell contents to top bottom or center
@@ -78,7 +80,7 @@
#Set cells to a fixed hieght (rows or ranges only)
[float]$Height,
#Hide a row or column (not a range); use -Hidden:$false to unhide
[switch]$Hidden
[Switch]$Hidden
)
begin {
#Allow Set-Format to take Worksheet and range parameters (like Add Contitional formatting) - convert them to an address
@@ -133,17 +135,16 @@
$Address.Style.VerticalAlignment = $VerticalAlignment
}
if ($PSBoundParameters.ContainsKey('Value')) {
if ($Value -like '=*') {$Address.Formula = $Value}
if ($Value -like '=*') {$PSBoundParameters["Formula"] = $Value }
else {
$Address.Value = $Value
if ($Value -is [DateTime]) {
$Address.Style.Numberformat.Format = 'm/d/yy h:mm' # This is not a custom format, but a preset recognized as date and localized. It might be overwritten in a moment
}
if ($Value -is [datetime]) { $Address.Style.Numberformat.Format = 'm/d/yy h:mm' }# This is not a custom format, but a preset recognized as date and localized. It might be overwritten in a moment
if ($Value -is [timespan]) { $Address.Style.Numberformat.Format = '[h]:mm:ss' }
}
}
if ($PSBoundParameters.ContainsKey('Formula')) {
$Address.Formula = $Formula
if ($ArrayFormula) {$Address.CreateArrayFormula(($Formula -replace '^=','')) }
else {$Address.Formula = ($Formula -replace '^=','') }
}
if ($PSBoundParameters.ContainsKey('NumberFormat')) {
$Address.Style.Numberformat.Format = (Expand-NumberFormat $NumberFormat)
@@ -206,7 +207,6 @@
$Address -is [OfficeOpenXml.ExcelColumn] ) {$Address.Hidden = [boolean]$Hidden}
else {Write-Warning -Message ("Can hide a row or a column but not a {0} object" -f ($Address.GetType().name)) }
}
}
}
}
@@ -266,10 +266,37 @@ if (Get-Command -ErrorAction SilentlyContinue -name Register-ArgumentCompleter)
Function Expand-NumberFormat {
param ($NumberFormat)
switch ($NumberFormat) {
"Currency" {return [cultureinfo]::CurrentCulture.NumberFormat.CurrencySymbol + "#,##0.00"}
"Currency" {
#https://msdn.microsoft.com/en-us/library/system.globalization.numberformatinfo.currencynegativepattern(v=vs.110).aspx
$sign = [cultureinfo]::CurrentCulture.NumberFormat.CurrencySymbol
switch ([cultureinfo]::CurrentCulture.NumberFormat.CurrencyPositivePattern) {
0 {$pos = "$Sign#,##0.00" ; break }
1 {$pos = "#,##0.00$Sign" ; break }
2 {$pos = "$Sign #,##0.00" ; break }
3 {$pos = "#,##0.00 $Sign" ; break }
}
switch ([cultureinfo]::CurrentCulture.NumberFormat.CurrencyPositivePattern) {
0 {return "$pos;($Sign#,##0.00)" }
1 {return "$pos;-$Sign#,##0.00" }
2 {return "$pos;$Sign-#,##0.00" }
3 {return "$pos;$Sign#,##0.00-" }
4 {return "$pos;(#,##0.00$Sign)" }
5 {return "$pos;-#,##0.00$Sign" }
6 {return "$pos;#,##0.00-$Sign" }
7 {return "$pos;#,##0.00$Sign-" }
8 {return "$pos;-#,##0.00 $Sign" }
9 {return "$pos;-$Sign #,##0.00" }
10 {return "$pos;#,##0.00 $Sign-" }
11 {return "$pos;$Sign #,##0.00-" }
12 {return "$pos;$Sign -#,##0.00" }
13 {return "$pos;#,##0.00- $Sign" }
14 {return "$pos;($Sign #,##0.00)" }
15 {return "$pos;(#,##0.00 $Sign)" }
}
}
"Number" {return "0.00" } # format id 2
"Percentage" {return "0.00%" } # format id 10
"Scientific" {return "0.00E+00" } # format id 11
"Scientific" {return "0.00E+00" } # format id 11
"Fraction" {return "# ?/?" } # format id 12
"Short Date" {return "mm-dd-yy" } # format id 14 localized on load by Excel.
"Short Time" {return "h:mm" } # format id 20 localized on load by Excel.
@@ -278,4 +305,4 @@ Function Expand-NumberFormat {
"Text" {return "@" } # format ID 49
Default {return $NumberFormat}
}
}
}

View File

@@ -1,12 +1,14 @@
- [x] Create an autocomplete for WorkSheetName param on ImportExcel and for number format ; where number format exists Translate "Date", "DateTime", "Currency"
- [x] Support "make worksheet active"
- [X] Add checks for valid worksheet names
- [x] Allow Exclude property to take wildcards
- [ ] Improve checking of worksheet, pivot names, range names and table names
- [ ] Investigate regional support for number conversion & possible date conversion. Also investigate feasablity of preserving number format when converting string to number
- [ ] Add help text for parmaters which don't have it ( PivotDataToColumn , NoClobber and CellStyleSB ) in Export Excel, copy to Send-SQLDataToExcel
- [ ] Add help in ConvertToExcelXLSx.ps1, Get-HTMLTable.ps1, GetRange.PS1, GetExcelTable.Ps1, Import-HTML.PS1, New-ConditionalFormattingIconSet.Ps1, NewConditionalText.PS1, New-Psitem.PS1, Remove-Worksheet.ps1 and Add-ExcelChart - Copy parameter help from function Add-ExcelChart into New-ExcelChart.ps1
- [ ] Add examples to add-ConditionalFormat, set-format,set-Row and Set-column (e.g. from tests)
- [ ] Add Examples and tests for new "Quick charts" in Export Excel (replace examples) that use Charting.ps1, GetXYRange.ps1, InferData.PS1 (move these to deprecated).
- [X] Test password behaviour in Export-Excel Open & Close-Excel Package
- [X] Test Add PivotTable selecting source sheet by position
-[X] Test UnhideSheet, and Wildcard support for hideSheet
- [X] Test return range support for Set-Row

View File

@@ -1,6 +1,8 @@
#Requires -Modules Pester
Import-Module $PSScriptRoot\..\ImportExcel.psd1 -Force
Add-Type -AssemblyName System.Windows.Forms
Describe "Compare Worksheet" {
Context "Simple comparison output" {
BeforeAll {

View File

@@ -4,8 +4,8 @@ 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 = "£"}
if ((Get-Culture).NumberFormat.CurrencySymbol -eq "<EFBFBD>") {$OtherCurrencySymbol = "$"}
else {$OtherCurrencySymbol = "<EFBFBD>"}
[PSCustOmobject][Ordered]@{
Date = Get-Date
Formula1 = '=SUM(F2:G2)'
@@ -25,8 +25,8 @@ else {$OtherCurrencySymbol = "
StrE164Phone = '+32 (444) 444 4444'
StrAltPhone1 = '+32 4 4444 444'
StrAltPhone2 = '+3244444444'
StrLeadSpace = ' 123'
StrTrailSpace = '123 '
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
@@ -50,14 +50,16 @@ Describe "Copy-Worksheet" {
$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 " {
it "Copied a worksheet, giving 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
}
it "Copied the expected data into the worksheet " {
$ws.Cells[2, 1].Value.Gettype().name | Should be 'DateTime'
$ws.Cells[2, 2].Formula | Should be '=SUM(F2:G2)'
$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'

View File

@@ -1,8 +1,6 @@
#Requires -Modules Pester
# $here = Split-Path -Parent $MyInvocation.MyCommand.Path
# Import-Module $here -Force -Verbose
Import-Module $PSScriptRoot\..\ImportExcel.psd1 -Force
#Import-Module $PSScriptRoot\..\ImportExcel.psd1 -Force
if (Get-process -Name Excel,xlim -ErrorAction SilentlyContinue) { Write-Warning -Message "You need to close Excel before running the tests." ; return}
Describe ExportExcel {
@@ -10,7 +8,8 @@ Describe ExportExcel {
Context "#Example 1 # Creates and opens a file with the right number of rows and columns" {
$path = "$env:TEMP\Test.xlsx"
Remove-item -Path $path -ErrorAction SilentlyContinue
$processes = Get-Process
#Test with a maximum of 100 processes for speed; export all properties, then export smaller subsets.
$processes = Get-Process | select-object -first 100
$propertyNames = $Processes[0].psobject.properties.name
$rowcount = $Processes.Count
$Processes | Export-Excel $path #-show
@@ -50,7 +49,7 @@ Describe ExportExcel {
}
}
it "Formatted the process StartTime field as 'localized Date-Time' " {
it "Formatted the process StartTime field as 'localized Date-Time' " {
$STHeader = $ws.cells["1:1"].where( {$_.Value -eq "StartTime"})[0]
$STCell = $STHeader.Address -replace '1$', '2'
$ws.cells[$stcell].Style.Numberformat.NumFmtID | Should be 22
@@ -66,16 +65,16 @@ Describe ExportExcel {
Context " # NoAliasOrScriptPropeties -ExcludeProperty and -DisplayPropertySet work" {
$path = "$env:TEMP\Test.xlsx"
Remove-item -Path $path -ErrorAction SilentlyContinue
$processes = Get-Process
$processes = Get-Process | Select-Object -First 100
$propertyNames = $Processes[0].psobject.properties.where( {$_.MemberType -eq 'Property'}).name
$rowcount = $Processes.Count
#TestCreating a range with a name which needs illegal chars removing
#Test -NoAliasOrScriptPropeties option and creating a range with a name which needs illegal chars removing - check this sends back a warning
$warnVar = $null
$Processes | Export-Excel $path -NoAliasOrScriptPropeties -RangeName "No Spaces" -WarningVariable warnvar -WarningAction SilentlyContinue
$Excel = Open-ExcelPackage -Path $path
$ws = $Excel.Workbook.Worksheets[1]
it "Created a new file with alias & Script Properties removed. " {
it "Created a new file with Alias & Script Properties removed. " {
$ws.Name | Should be "sheet1"
$ws.Dimension.Columns | Should be $propertyNames.Count
$ws.Dimension.Rows | Should be ($rowcount + 1 ) # +1 for the header.
@@ -86,19 +85,20 @@ Describe ExportExcel {
$ws.names["No_spaces"].End.Row | Should be ($rowcount + 1 ) # +1 for the header.
$warnVar.Count | Should be 1
}
#This time use clearsheet instead of deleting the file
$Processes | Export-Excel $path -NoAliasOrScriptPropeties -ExcludeProperty SafeHandle, modules, MainModule, StartTime, Threads -ClearSheet
#This time use clearsheet instead of deleting the file test -Exclude properties, including wildcards.
$Processes | Export-Excel $path -ClearSheet -NoAliasOrScriptPropeties -ExcludeProperty SafeHandle, threads, modules, MainModule, StartInfo, MachineName, MainWindow*, M*workingSet
$Excel = Open-ExcelPackage -Path $path
$ws = $Excel.Workbook.Worksheets[1]
it "Created a new file with a further 5 properties excluded and cleared the old sheet " {
it "Created a new file with further properties excluded and cleared the old sheet " {
$ws.Name | Should be "sheet1"
$ws.Dimension.Columns | Should be ($propertyNames.Count - 5)
$ws.Dimension.Columns | Should be ($propertyNames.Count - 10)
$ws.Dimension.Rows | Should be ($rowcount + 1) # +1 for the header
}
$propertyNames = $Processes[0].psStandardmembers.DefaultDisplayPropertySet.ReferencedPropertyNames
Remove-item -Path $path -ErrorAction SilentlyContinue
#Test -DisplayPropertySet
$Processes | Export-Excel $path -DisplayPropertySet
$Excel = Open-ExcelPackage -Path $path
@@ -114,7 +114,7 @@ Describe ExportExcel {
$path = "$env:TEMP\Test.xlsx"
Remove-item -Path $path -ErrorAction SilentlyContinue
#testing -ReturnRange switch
#testing -ReturnRange switch and applying number format to Formulas as well as values.
$returnedRange = Write-Output -1 668 34 777 860 -0.5 119 -0.1 234 788,"=A9+A10" | Export-Excel -NumberFormat '[Blue]$#,##0.00;[Red]-$#,##0.00' -Path $path -ReturnRange
it "Created a new file and returned the expected range " {
Test-Path -Path $path -ErrorAction SilentlyContinue | Should be $true
@@ -143,15 +143,38 @@ Describe ExportExcel {
}
}
Context " # Number format parameter" {
BeforeAll {
$path = "$env:temp\test.xlsx"
Remove-Item -Path $path -ErrorAction SilentlyContinue
1..10 | Export-Excel -Path $path -Numberformat 'Number'
1..10 | Export-Excel -Path $path -Numberformat 'Percentage' -Append
21..30 | Export-Excel -Path $path -Numberformat 'Currency' -StartColumn 3
$excel = Open-ExcelPackage -Path $path
$ws = $excel.Workbook.Worksheets[1]
}
it "Set the worksheet default number format correctly " {
$ws.Cells.Style.Numberformat.Format | Should be "0.00"
}
it "Set number formats on specific blocks of cells " {
$ws.Cells["A2" ].Style.Numberformat.Format | Should be "0.00"
$ws.Cells["c19"].Style.Numberformat.Format | Should be "0.00"
$ws.Cells["A20"].Style.Numberformat.Format | Should be "0.00%"
$ws.Cells["C6" ].Style.Numberformat.Format | Should be (Expand-NumberFormat "currency")
}
}
Context "#Examples 3 & 4 # Setting cells for different data types Also added test for URI type" {
if ((Get-Culture).NumberFormat.CurrencySymbol -eq "£") {$OtherCurrencySymbol = "$"}
else {$OtherCurrencySymbol = "£"}
$path = "$env:TEMP\Test.xlsx"
$warnVar = $null
#Test correct export of different data types and number formats; test hyperlinks, test -NoNumberConversion test object is converted to a string with no warnings, test calcuation of formula
Remove-item -Path $path -ErrorAction SilentlyContinue
[PSCustOmobject][Ordered]@{
Date = Get-Date
Formula1 = '=SUM(F2:G2)'
Formula1 = '=SUM(S2:T2)'
String1 = 'My String'
Float = [math]::pi
IPAddress = '10.10.25.5'
@@ -163,8 +186,8 @@ Describe ExportExcel {
StrNegInt = '-31'
StrTrailingNeg = '31-'
StrParens = '(123)'
strLocalCurrency = ('{0}123.45' -f (Get-Culture).NumberFormat.CurrencySymbol )
strOtherCurrency = ('{0}123.45' -f $OtherCurrencySymbol )
strLocalCurrency = ('{0}123{1}45' -f (Get-Culture).NumberFormat.CurrencySymbol,(Get-Culture).NumberFormat.CurrencyDecimalSeparator)
strOtherCurrency = ('{0}123{1}45' -f $OtherCurrencySymbol ,(Get-Culture).NumberFormat.CurrencyDecimalSeparator)
StrE164Phone = '+32 (444) 444 4444'
StrAltPhone1 = '+32 4 4444 444'
StrAltPhone2 = '+3244444444'
@@ -174,30 +197,36 @@ Describe ExportExcel {
Link2 = "https://github.com/dfinke/ImportExcel"
Link3 = "xl://internal/sheet1!A1"
Link4 = "xl://internal/sheet1!C5"
} | Export-Excel -NoNumberConversion IPAddress, StrLeadZero, StrAltPhone2 -Path $path
Process = (Get-Process -Id $PID)
TimeSpan = [datetime]::Now.Subtract([datetime]::Today)
} | Export-Excel -NoNumberConversion IPAddress, StrLeadZero, StrAltPhone2 -Path $path -Calculate -WarningVariable $warnVar
it "Created a new file " {
Test-Path -Path $path -ErrorAction SilentlyContinue | Should be $true
}
$Excel = Open-ExcelPackage -Path $path
it "Created 1 worksheet " {
it "Created 1 worksheet with no warnings " {
$Excel.Workbook.Worksheets.count | Should be 1
$warnVar | Should beNullorEmpty
}
$ws = $Excel.Workbook.Worksheets[1]
it "Created the worksheet with the expected name, number of rows and number of columns " {
$ws.Name | Should be "sheet1"
$ws.Dimension.Columns | Should be 24
$ws.Dimension.Columns | Should be 26
$ws.Dimension.Rows | Should be 2
}
it "Set a date in Cell A2 " {
$ws.Cells[2, 1].Value.Gettype().name | Should be 'DateTime'
}
it "Set a formula in Cell B2 " {
$ws.Cells[2, 2].Formula | Should be '=SUM(F2:G2)'
$ws.Cells[2, 2].Formula | Should be 'SUM(S2:T2)'
}
it "Forced a successful calculation of the Value in Cell B2 " {
$ws.Cells[2, 2].Value | Should be 246
}
it "Set strings in Cells E2, F2 and R2 (no number conversion) " {
$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, 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'
}
it "Set numbers in Cells K2,L2,M2 (diferent Negative integer formats) " {
($ws.Cells[2, 11].Value -is [valuetype] ) | Should be $true
@@ -241,12 +270,21 @@ Describe ExportExcel {
($ws.Cells[2, 19].Value -is [valuetype] ) | Should be $true
($ws.Cells[2, 20].Value -is [valuetype] ) | Should be $true
}
it "Converted a nested object to a string (Y2) " {
$ws.Cells[2, 25].Value | should match '^System\.Diagnostics\.Process\s+\(.*\)$'
}
it "Processed a timespan object (Z2) " {
$ws.cells[2, 26].Value.ToOADate() | should beGreaterThan 0
$ws.cells[2, 26].Value.ToOADate() | should beLessThan 1
$ws.cells[2, 26].Style.Numberformat.Format | should be '[h]:mm:ss'
}
}
Context "# # Setting cells for different data types with -noHeader" {
$path = "$env:TEMP\Test.xlsx"
Remove-item -Path $path -ErrorAction SilentlyContinue
#Test -NoHeader & -NoNumberConversion
[PSCustOmobject][Ordered]@{
Date = Get-Date
Formula1 = '=SUM(F1:G1)'
@@ -280,11 +318,11 @@ Describe ExportExcel {
}
it "Set a date in Cell A1 " {
$ws.Cells[1, 1].Value.Gettype().name | Should be 'DateTime'
$ws.Cells[1, 1].Value.Gettype().name | Should be 'DateTime'
}
it "Set a formula in Cell B1 " {
$ws.Cells[1, 2].Formula | Should be '=SUM(F1:G1)'
$ws.Cells[1, 2].Formula | Should be 'SUM(F1:G1)'
}
it "Set strings in Cells E1 and F1 " {
@@ -302,23 +340,25 @@ Describe ExportExcel {
}
Context "#Example 5 # Adding a single conditional format " {
#Test New-ConditionalText builds correctly
$ct = New-ConditionalText -ConditionalType GreaterThan 525 -ConditionalTextColor DarkRed -BackgroundColor LightPink
it "Created a Conditional format description " {
$ct.BackgroundColor -is [System.Drawing.Color] | Should be $true
$ct.BackgroundColor -is [System.Drawing.Color] | Should be $true
$ct.ConditionalTextColor -is [System.Drawing.Color] | Should be $true
$ct.ConditionalType -in [enum]::GetNames( [OfficeOpenXml.ConditionalFormatting.eExcelConditionalFormattingRuleType] ) |
Should be $true
Should be $true
}
$path = "$env:TEMP\Test.xlsx"
Remove-item -Path $path -ErrorAction SilentlyContinue
#Test -ConditionalText with a single conditional spec.
Write-Output 489 668 299 777 860 151 119 497 234 788 | Export-Excel -Path $path -ConditionalText $ct
it "Created a new file " {
Test-Path -Path $path -ErrorAction SilentlyContinue | Should be $true
}
#ToDo need to test applying conitional formatting to a pre-existing worksheet
#ToDo need to test applying conitional formatting to a pre-existing worksheet and removing = from formula
$Excel = Open-ExcelPackage -Path $path
$ws = $Excel.Workbook.Worksheets[1]
@@ -333,13 +373,11 @@ Describe ExportExcel {
$cf.Type.ToString() | Should be $ct.ConditionalType
#$cf.Style.Fill.BackgroundColor | Should be $ct.BackgroundColor
# $cf.Style.Font.Color | Should be $ct.ConditionalTextColor - have to compare r.g.b
}
}
Context "#Example 6 # Adding multiple conditional formats using short form syntax. " {
#this is a test of adding more than one conditional block and using the minimal syntax for new-ConditionalText =
#Test adding mutliple conditional blocks and using the minimal syntax for new-ConditionalText
$path = "$env:TEMP\Test.xlsx"
Remove-item -Path $path -ErrorAction SilentlyContinue
@@ -387,6 +425,7 @@ Describe ExportExcel {
}
$Array = $Obj1, $Obj2, $Obj3
#test Update-FirstObjectProperties
$newarray = $Array | Update-FirstObjectProperties
it "Outputs as many objects as it input " {
$newarray.Count | Should be $Array.Count
@@ -402,9 +441,9 @@ Describe ExportExcel {
Context "#Examples 8 & 9 # Adding Pivot tables and charts from parameters" {
$path = "$env:TEMP\Test.xlsx"
#This time we are not deleting the XLSX file so this Should create a new, named, sheet.
$Excel = Get-Process | Select-Object -first 50 -Property Name, cpu, pm, handles, company | Export-Excel $path -WorkSheetname Processes -PassThru
#Testing -passthru and adding the Pivot as a second step. Want to save and re-open it ...
#Test -passthru and -worksheetName creating a new, named, sheet in an existing file.
$Excel = Get-Process | Select-Object -first 20 -Property Name, cpu, pm, handles, company | Export-Excel $path -WorkSheetname Processes -PassThru
#Testing -Excel Pacakage and adding a Pivot-table as a second step. Want to save and re-open it ...
Export-Excel -ExcelPackage $Excel -WorkSheetname Processes -IncludePivotTable -PivotRows Company -PivotData PM -NoTotalsInPivot
$Excel = Open-ExcelPackage $path
@@ -415,7 +454,7 @@ Describe ExportExcel {
$PTws.PivotTables.Count | Should be 1
$Excel.Workbook.Worksheets["Processes"] | Should not beNullOrEmpty
$Excel.Workbook.Worksheets.Count | Should beGreaterThan 2
# $excel.Workbook.Worksheets["Processes"].Dimension.rows | Should be 51 #50 data + 1 header
$excel.Workbook.Worksheets["Processes"].Dimension.rows | Should be 21 #20 data + 1 header
}
$pt = $PTws.PivotTables[0]
it "Built the expected Pivot table " {
@@ -426,7 +465,7 @@ Describe ExportExcel {
$pt.DataFields[0].Field.Name | Should be "PM"
$PTws.Drawings.Count | Should be 0
}
#using the already open sheet add the pivot chart
#test adding pivot chart using the already open sheet
$warnvar = $null
Export-Excel -ExcelPackage $Excel -WorkSheetname Processes -IncludePivotTable -PivotRows Company -PivotData PM -IncludePivotChart -ChartType PieExploded3D -ShowCategory -NoLegend -WarningAction SilentlyContinue -WarningVariable warnvar
$Excel = Open-ExcelPackage $path
@@ -439,15 +478,16 @@ Describe ExportExcel {
it "Generated a message on re-processing the Pivot table " {
$warnVar | Should not beNullOrEmpty
}
#Test appending data extends pivot chart (with a warning) .
$warnVar = $null
Get-Process | Select-Object -Last 50 -Property Name, cpu, pm, handles, company | Export-Excel $path -WorkSheetname Processes -Append -IncludePivotTable -PivotRows Company -PivotData PM -IncludePivotChart -ChartType PieExploded3D -WarningAction SilentlyContinue -WarningVariable warnvar
Get-Process | Select-Object -Last 20 -Property Name, cpu, pm, handles, company | Export-Excel $path -WorkSheetname Processes -Append -IncludePivotTable -PivotRows Company -PivotData PM -IncludePivotChart -ChartType PieExploded3D -WarningAction SilentlyContinue -WarningVariable warnvar
$Excel = Open-ExcelPackage $path
$pt = $Excel.Workbook.Worksheets["ProcessesPivotTable"].PivotTables[0]
it "Appended to the Worksheet and Extended the Pivot table " {
$Excel.Workbook.Worksheets.Count | Should be $wCount
# $excel.Workbook.Worksheets["Processes"].Dimension.rows | Should be 101 #appended 50 rows to the previous total
# $pt.CacheDefinition.CacheDefinitionXml.pivotCacheDefinition.cacheSource.worksheetSource.ref |
# Should be "A1:E101"
$excel.Workbook.Worksheets["Processes"].Dimension.rows | Should be 41 #appended 20 rows to the previous total
$pt.CacheDefinition.CacheDefinitionXml.pivotCacheDefinition.cacheSource.worksheetSource.ref |
Should be "A1:E41"
}
it "Generated a message on extending the Pivot table " {
$warnVar | Should not beNullOrEmpty
@@ -456,7 +496,7 @@ Describe ExportExcel {
Context " # Add-Worksheet inserted sheets, moved them correctly, and copied a sheet" {
$path = "$env:TEMP\Test.xlsx"
#Test the -CopySource and -Movexxxx parameters for Add-WorkSheet
$Excel = Open-ExcelPackage $path
#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
@@ -489,11 +529,12 @@ Describe ExportExcel {
Context " # Create and append with Start row and Start Column, inc ranges and Pivot table. " {
$path = "$env:TEMP\Test.xlsx"
remove-item -Path $path -ErrorAction SilentlyContinue
#Catch warning
$warnVar = $null
#Test Append with no existing sheet. Test adding a named pivot table from a command line parameter
Get-Process | Select-Object -first 10 -Property Name, cpu, pm, handles, company | Export-Excel -StartRow 3 -StartColumn 3 -AutoFilter -AutoNameRange -BoldTopRow -IncludePivotTable -PivotRows Company -PivotData PM -PivotTableName 'PTOffset' -Path $path -WorkSheetname withOffset -Append -PivotFilter Name -NoTotalsInPivot
Get-Process | Select-Object -last 10 -Property Name, cpu, pm, handles, company | Export-Excel -StartRow 3 -StartColumn 3 -AutoFilter -AutoNameRange -BoldTopRow -IncludePivotTable -PivotRows Company -PivotData PM -PivotTableName 'PTOffset' -Path $path -WorkSheetname withOffset -Append -WarningAction SilentlyContinue -WarningVariable warnvar
#Test -Append with no existing sheet. Test adding a named pivot table from command line parameters and extending ranges when they're not specified explictly
Get-Process | Select-Object -first 10 -Property Name, cpu, pm, handles, company | Export-Excel -StartRow 3 -StartColumn 3 -BoldTopRow -IncludePivotTable -PivotRows Company -PivotData PM -PivotTableName 'PTOffset' -Path $path -WorkSheetname withOffset -Append -PivotFilter Name -NoTotalsInPivot -RangeName procs -AutoFilter -AutoNameRange
Get-Process | Select-Object -last 10 -Property Name, cpu, pm, handles, company | Export-Excel -StartRow 3 -StartColumn 3 -BoldTopRow -IncludePivotTable -PivotRows Company -PivotData PM -PivotTableName 'PTOffset' -Path $path -WorkSheetname withOffset -Append -WarningAction SilentlyContinue -WarningVariable warnvar
$Excel = Open-ExcelPackage $path
$dataWs = $Excel.Workbook.Worksheets["withOffset"]
$pt = $Excel.Workbook.Worksheets["PTOffset"].PivotTables[0]
@@ -505,21 +546,71 @@ Describe ExportExcel {
$dataWs.Dimension.End.Row | Should be 23
$dataWs.names[0].end.row | Should be 23
$dataWs.names[0].name | Should be 'Name'
$dataWs.names.Count | Should be 6
$dataWs.names.Count | Should be 7 # Name, cpu, pm, handles & company + Named Range "Procs" + xl one for autofilter
$dataWs.cells[$dataws.Dimension].AutoFilter | Should be true
}
it "Applied and auto-extended an autofilter " {
$dataWs.Names["_xlnm._FilterDatabase"].Start.Row | should be 3 #offset
$dataWs.Names["_xlnm._FilterDatabase"].Start.Column | should be 3
$dataWs.Names["_xlnm._FilterDatabase"].Rows | should be 21 #2 x 10 data + 1 header
$dataWs.Names["_xlnm._FilterDatabase"].Columns | should be 5 #Name, cpu, pm, handles & company
$dataWs.Names["_xlnm._FilterDatabase"].AutoFilter | should be $true
}
it "Created and auto-extended the named ranges " {
$dataWs.names["procs"].rows | should be 21
$dataWs.names["procs"].Columns | should be 5
$dataWs.Names["CPU"].Rows | should be 20
$dataWs.Names["CPU"].Columns | should be 1
}
it "Created and extended the pivot table " {
$pt.CacheDefinition.CacheDefinitionXml.pivotCacheDefinition.cacheSource.worksheetSource.ref |
Should be "C3:G23"
Should be "C3:G23"
$pt.ColumGrandTotals | should be $false
$pt.RowGrandTotals | should be $false
$pt.Fields["Company"].IsRowField | should be $true
$pt.Fields["PM"].IsDataField | should be $true
$pt.Fields["Name"].IsPageField | should be $true
}
it "Generated a message on extending the Pivot table " {
$warnVar | Should not beNullOrEmpty
}
}
Context " # Create and append explicit and auto table and range extension" {
$path = "$env:TEMP\Test.xlsx"
#Test -Append automatically extends a table, even when it is not specified in the append command
Get-Process | Select-Object -first 10 -Property Name, cpu, pm, handles, company | Export-Excel -Path $path -TableName ProcTab -AutoNameRange -WorkSheetname NoOffset -ClearSheet
Get-Process | Select-Object -last 10 -Property Name, cpu, pm, handles, company | Export-Excel -Path $path -AutoNameRange -WorkSheetname NoOffset -Append
$Excel = Open-ExcelPackage $path
$dataWs = $Excel.Workbook.Worksheets["NoOffset"]
it "Created a new sheet and auto-extended a table and explicitly extended named ranges " {
$dataWs.Tables["ProcTab"].Address.Address | should be "A1:E21"
$dataWs.Names["CPU"].Rows | should be 20
$dataWs.Names["CPU"].Columns | should be 1
}
#Test extneding autofilter and range when explicitly specified in the append
$excel = Get-Process | Select-Object -first 10 -Property Name, cpu, pm, handles, company | Export-Excel -ExcelPackage $excel -RangeName procs -AutoFilter -WorkSheetname NoOffset -ClearSheet -PassThru
Get-Process | Select-Object -last 10 -Property Name, cpu, pm, handles, company | Export-Excel -ExcelPackage $excel -RangeName procs -AutoFilter -WorkSheetname NoOffset -Append
$Excel = Open-ExcelPackage $path
$dataWs = $Excel.Workbook.Worksheets["NoOffset"]
it "Created a new sheet and explicitly extended named range and autofilter " {
$dataWs.names["procs"].rows | should be 21
$dataWs.names["procs"].Columns | should be 5
$dataWs.Names["_xlnm._FilterDatabase"].Rows | should be 21 #2 x 10 data + 1 header
$dataWs.Names["_xlnm._FilterDatabase"].Columns | should be 5 #Name, cpu, pm, handles & company
$dataWs.Names["_xlnm._FilterDatabase"].AutoFilter | should be $true
}
}
Context "#Example 11 # Create and append with title, inc ranges and Pivot table" {
$path = "$env:TEMP\Test.xlsx"
#Test New-PivotTableDefinition builds definition using -Pivotfilter and -PivotTotals options.
$ptDef = [ordered]@{}
$ptDef += New-PivotTableDefinition -PivotTableName "PT1" -SourceWorkSheet 'Sheet1' -PivotRows "Status" -PivotData @{'Status' = 'Count'} -PivotFilter "StartType" -IncludePivotChart -ChartType BarClustered3D -ChartTitle "Services by status" -ChartHeight 512 -ChartWidth 768 -ChartRow 10 -ChartColumn 0 -NoLegend
$ptDef += New-PivotTableDefinition -PivotTableName "PT2" -SourceWorkSheet 'Sheet2' -PivotRows "Company" -PivotData @{'Company' = 'Count'} -IncludePivotChart -ChartType PieExploded3D -ShowPercent -WarningAction SilentlyContinue
$ptDef += New-PivotTableDefinition -PivotTableName "PT1" -SourceWorkSheet 'Sheet1' -PivotRows "Status" -PivotData @{'Status' = 'Count'} -PivotTotals Columns -PivotFilter "StartType" -IncludePivotChart -ChartType BarClustered3D -ChartTitle "Services by status" -ChartHeight 512 -ChartWidth 768 -ChartRow 10 -ChartColumn 0 -NoLegend -PivotColumns CanPauseAndContinue
$ptDef += New-PivotTableDefinition -PivotTableName "PT2" -SourceWorkSheet 'Sheet2' -PivotRows "Company" -PivotData @{'Company' = 'Count'} -PivotTotalS Rows -IncludePivotChart -ChartType PieExploded3D -ShowPercent -WarningAction SilentlyContinue
it "Built a pivot definition using New-PivotTableDefinition " {
$ptDef.PT1.SourceWorkSheet | Should be 'Sheet1'
@@ -528,11 +619,13 @@ Describe ExportExcel {
$ptDef.PT1.PivotFilter | Should be 'StartType'
$ptDef.PT1.IncludePivotChart | Should be $true
$ptDef.PT1.ChartType.tostring() | Should be 'BarClustered3D'
$ptDef.PT1.PivotTotals | Should be 'Columns'
}
Remove-Item -Path $path
#Catch warning
$warnvar = $null
Get-Service | Select-Object -Property Status, Name, DisplayName, StartType | Export-Excel -Path $path -AutoSize -TableName "All Services" -TableStyle Medium1 -WarningAction SilentlyContinue -WarningVariable warnvar
#Test create two data pages; as part of adding the second give both their own pivot table, test -autosize switch
Get-Service | Select-Object -Property Status, Name, DisplayName, StartType, CanPauseAndContinue | Export-Excel -Path $path -AutoSize -TableName "All Services" -TableStyle Medium1 -WarningAction SilentlyContinue -WarningVariable warnvar
Get-Process | Select-Object -Property Name, Company, Handles, CPU, VM | Export-Excel -Path $path -AutoSize -WorkSheetname 'sheet2' -TableName "Processes" -TableStyle Light1 -Title "Processes" -TitleFillPattern Solid -TitleBackgroundColor AliceBlue -TitleBold -TitleSize 22 -PivotTableDefinition $ptDef
$Excel = Open-ExcelPackage $path
$ws1 = $Excel.Workbook.Worksheets["Sheet1"]
@@ -567,17 +660,21 @@ Describe ExportExcel {
$PT2 = $ptsheet2.PivotTables[0]
$PC1 = $ptsheet1.Drawings[0]
$PC2 = $ptsheet2.Drawings[0]
it "Created the correct pivot tables and charts from the definitions. " {
it "Created the pivot tables linked to the right data. " {
$PT1.CacheDefinition.CacheDefinitionXml.pivotCacheDefinition.cacheSource.worksheetSource.ref |
Should be ("A1:" + $ws1.Dimension.End.Address)
$PT2.CacheDefinition.CacheDefinitionXml.pivotCacheDefinition.cacheSource.worksheetSource.ref |
Should be ("A2:" + $ws2.Dimension.End.Address) #Title in row 1
}
it "Set the other pivot tables and chart options from the definitions. " {
$pt1.PageFields[0].Name | Should be 'StartType'
$pt1.RowFields[0].Name | Should be 'Status'
$pt1.DataFields[0].Field.name | Should be 'Status'
$pt1.DataFields[0].Function | Should be 'Count'
$pt1.ColumGrandTotals | should be $true
$pt1.RowGrandTotals | should be $false
$pt2.ColumGrandTotals | should be $false
$pt2.RowGrandTotals | should be $true
$pc1.ChartType | Should be 'BarClustered3D'
$pc1.From.Column | Should be 0 #chart 1 at 0,10 chart 2 at 4,0 (default)
$pc2.From.Column | Should be 4
@@ -593,6 +690,7 @@ Describe ExportExcel {
Context "#Example 13 # Formatting and another way to do a pivot. " {
$path = "$env:TEMP\Test.xlsx"
Remove-Item $path
#Test freezing top row/first column, adding formats and a pivot table - from Add-Pivot table not a specification variable - after the export
$excel = Get-Process | Select-Object -Property Name, Company, Handles, CPU, PM, NPM, WS | Export-Excel -Path $path -ClearSheet -WorkSheetname "Processes" -FreezeTopRowFirstColumn -PassThru
$sheet = $excel.Workbook.Worksheets["Processes"]
$sheet.Column(1) | Set-Format -Bold -AutoFit
@@ -659,14 +757,15 @@ Describe ExportExcel {
Context " # Chart from MultiSeries.ps1 in the Examples\charts Directory" {
$path = "$env:TEMP\Test.xlsx"
Remove-Item -Path $path -ErrorAction SilentlyContinue
$data = invoke-sum (Get-Process) Company Handles, PM, VirtualMemorySize
#Test Invoke-Sum
$data = Invoke-Sum (Get-Process) Company Handles, PM, VirtualMemorySize
it "used Invoke-Sum to create a data set " {
$data | Should not beNullOrEmpty
$data.count | Should beGreaterThan 1
$data[1].Name | Should not beNullOrEmpty
$data[1].Handles | Should not beNullOrEmpty
$data[1].PM | Should not beNullOrEmpty
$data[1].VirtualMemorySize | Should not beNullOrEmpty
$data[1].Name | Should not beNullOrEmpty
$data[1].Handles | Should not beNullOrEmpty
$data[1].PM | Should not beNullOrEmpty
$data[1].VirtualMemorySize | Should not beNullOrEmpty
}
$c = New-ExcelChartDefinition -Title Stats -ChartType LineMarkersStacked -XRange "Processes[Name]" -YRange "Processes[PM]", "Processes[VirtualMemorySize]" -SeriesHeader 'PM', 'VMSize'
@@ -684,6 +783,7 @@ Describe ExportExcel {
$c.ShowCategory | Should not be $true
$c.ShowPercent | Should not be $true
}
#Test creating a chart using -ExcelChartDefinition.
$data | Export-Excel $path -AutoSize -TableName Processes -ExcelChartDefinition $c
$excel = Open-ExcelPackage -Path $path
$drawings = $excel.Workbook.Worksheets[1].drawings
@@ -702,11 +802,16 @@ Describe ExportExcel {
Context " # variation of plot.ps1 from Examples Directory using Add chart outside ExportExcel" {
$path = "$env:TEMP\Test.xlsx"
#Test inserting a fomual
$excel = 0..360 | ForEach-Object {[pscustomobject][ordered]@{x = $_; Sinx = "=Sin(Radians(x)) "}} | Export-Excel -AutoNameRange -Path $path -WorkSheetname SinX -ClearSheet -FreezeFirstColumn -PassThru
#Test-Add Excel Chart to existing data. Test add Conditional formatting with a formula
Add-ExcelChart -Worksheet $excel.Workbook.Worksheets["Sinx"] -ChartType line -XRange "X" -YRange "Sinx" -SeriesHeader "Sin(x)" -Title "Graph of Sine X" -TitleBold -TitleSize 14 `
-Column 2 -ColumnOffSetPixels 35 -Width 800 -XAxisTitleText "Degrees" -XAxisTitleBold -XAxisTitleSize 12 -XMajorUnit 30 -XMinorUnit 10 -XMinValue 0 -XMaxValue 361 -XAxisNumberformat "000" -XAxisPosition Bottom `
-YMinValue -1.25 -YMaxValue 1.25 -YMajorUnit 0.25 -YAxisNumberformat "0.00" -YAxisTitleText "Sine" -YAxisTitleBold -YAxisTitleSize 12 -YAxisPosition Left -LegendPostion Bottom -LegendSize 8 -legendBold
$d = $excel.Workbook.Worksheets["Sinx"].Drawings[0]
-Column 2 -ColumnOffSetPixels 35 -Width 800 -XAxisTitleText "Degrees" -XAxisTitleBold -XAxisTitleSize 12 -XMajorUnit 30 -XMinorUnit 10 -XMinValue 0 -XMaxValue 361 -XAxisNumberformat "000" `
-YMinValue -1.25 -YMaxValue 1.25 -YMajorUnit 0.25 -YAxisNumberformat "0.00" -YAxisTitleText "Sine" -YAxisTitleBold -YAxisTitleSize 12 `
-LegendSize 8 -legendBold -LegendPostion Bottom
Add-ConditionalFormatting -WorkSheet $excel.Workbook.Worksheets["Sinx"] -Range "B2:B362" -RuleType LessThan -ConditionValue "=B1" -ForeGroundColor Red
$ws = $Excel.Workbook.Worksheets["Sinx"]
$d = $ws.Drawings[0]
It "Controled the axes and title and legend of the chart " {
$d.XAxis.MaxValue | Should be 361
$d.XAxis.MajorUnit | Should be 30
@@ -731,6 +836,9 @@ Describe ExportExcel {
$d.ChartType.tostring() | Should be "line"
$d.From.Column | Should be 2
}
It "Appplied conditional formatting to the data " {
$ws.ConditionalFormatting[0].Formula | Should be "B1"
}
Close-ExcelPackage -ExcelPackage $excel -nosave
}
@@ -753,7 +861,7 @@ Describe ExportExcel {
$ct.ConditionalType | Should be "ContainsText"
$ct.Text | Should be "Microsoft"
}
#Test -ConditionalFormat & -ConditionalText
Export-Excel -Path $path -ConditionalFormat $cf -ConditionalText $ct
$excel = Open-ExcelPackage -Path $path
$rows = $range -replace "^.*?(\d+)$", '$1'
@@ -774,6 +882,7 @@ Describe ExportExcel {
Context " # Awkward multiple tables" {
$path = "$Env:TEMP\test.xlsx"
#Test creating 3 on overlapping tables on the same page. Create rightmost the left most then middle.
remove-item -Path $path -ErrorAction SilentlyContinue
$r = Get-ChildItem -path C:\WINDOWS\system32 -File
@@ -798,7 +907,7 @@ Describe ExportExcel {
$ws.Tables["FileSize"].StyleName | should be "TableStyleMedium2"
}
it "Created the ExtSize table in the right place with the right size " {
$ws.Tables["ExtSize"].Address.Address | should be "A2:B14" #tile, then 12 rows x 2 columns of data
$ws.Tables["ExtSize"].Address.Address | should be "A2:B14" #tile, then 12 rows x 2 columns of data
}
it "Created the ExtCount table in the right place with the right size " {
$ws.Tables["ExtCount"].Address.Address | should be "D2:E12" #title, then 10 rows x 2 columns of data

View File

@@ -0,0 +1,24 @@
Describe "Password Support" {
Context "Password protected sheet" {
BeforeAll {
$password = "YouMustRememberThis"
$path = "$env:TEMP\Test.xlsx"
Remove-Item $path -ErrorAction SilentlyContinue
Get-Service | Select-Object -First 10 | Export-excel -password $password -Path $Path -DisplayPropertySet
}
it "Threw an error when the password was omitted " {
{Open-ExcelPackage -Path $path } | should throw
}
it "Was able to append when the password was included " {
{Get-Service | Select-Object -First 10 |
Export-excel -password $password -Path $Path -Append } | should not throw
}
it "Kept the password on the file when it was saved " {
{Import-Excel $Path } | should throw
}
it "Could read the file when the password was included " {
(import-excel $path -Password $password).count | should be 20
}
}
}

View File

@@ -36,16 +36,18 @@ Describe "Number format expansion and setting" {
}
Context "Expand-NumberFormat function" {
It "Expanded named number formats as expected " {
Expand-NumberFormat 'Number' | Should be "0.00"
Expand-NumberFormat 'Percentage' | Should be "0.00%"
Expand-NumberFormat 'Scientific' | Should be "0.00E+00"
Expand-NumberFormat 'Currency' | Should be ([cultureinfo]::CurrentCulture.NumberFormat.CurrencySymbol + "#,##0.00")
Expand-NumberFormat 'Fraction' | Should be "# ?/?"
Expand-NumberFormat 'Short Date' | Should be "mm-dd-yy"
Expand-NumberFormat 'Short Time' | Should be "h:mm"
Expand-NumberFormat 'Long Time' | Should be "h:mm:ss"
Expand-NumberFormat 'Date-Time' | Should be "m/d/yy h:mm"
Expand-NumberFormat 'Text' | Should be "@"
$r = [regex]::Escape([cultureinfo]::CurrentCulture.NumberFormat.CurrencySymbol)
Expand-NumberFormat 'Currency' | Should match "^[$r\(\)\[\]RED0#\?\-;,.]+$"
Expand-NumberFormat 'Number' | Should be "0.00"
Expand-NumberFormat 'Percentage' | Should be "0.00%"
Expand-NumberFormat 'Scientific' | Should be "0.00E+00"
Expand-NumberFormat 'Fraction' | Should be "# ?/?"
Expand-NumberFormat 'Short Date' | Should be "mm-dd-yy"
Expand-NumberFormat 'Short Time' | Should be "h:mm"
Expand-NumberFormat 'Long Time' | Should be "h:mm:ss"
Expand-NumberFormat 'Date-Time' | Should be "m/d/yy h:mm"
Expand-NumberFormat 'Text' | Should be "@"
}
}
Context "Apply-NumberFormat" {
@@ -53,7 +55,7 @@ Describe "Number format expansion and setting" {
Remove-Item -Path $path -ErrorAction SilentlyContinue
$n = [datetime]::Now.ToOADate()
$excel = 1..32 | ForEach-Object {$n} | Export-Excel -Path $path -PassThru
$excel = 1..32 | ForEach-Object {$n} | Export-Excel -Path $path -show -WorksheetName s2 -PassThru
$ws = $excel.Workbook.Worksheets[1]
Set-Format -WorkSheet $ws -Range "A1" -numberFormat 'General'
Set-Format -WorkSheet $ws -Range "A2" -numberFormat 'Number'
@@ -94,8 +96,6 @@ Describe "Number format expansion and setting" {
}
It "Set formats which translate to the correct format ID " {
$ws.Cells[10,1].Style.Numberformat.format | # Set as "Currency"
Should match ("^" + ([regex]::Escape([cultureinfo]::CurrentCulture.NumberFormat.CurrencySymbol)))
$ws.Cells[ 1,1].Style.Numberformat.NumFmtID | Should be 0 # Set as General
$ws.Cells[20,1].Style.Numberformat.NumFmtID | Should be 1 # Set as 0
$ws.Cells[ 2,1].Style.Numberformat.NumFmtID | Should be 2 # Set as "Number"
@@ -137,7 +137,7 @@ Describe "Set-Column, Set-Row and Set Format" {
$ws = $excel.Workbook.Worksheets["Sheet1"]
$c = Set-Column -PassThru -Worksheet $ws -Heading "Total" -Value "=Quantity*Price" -NumberFormat "£#,###.00" -FontColor Blue -Bold -HorizontalAlignment Right -VerticalAlignment Top
$r = Set-Row -PassThru -Worksheet $ws -StartColumn 3 -BorderAround Thin -Italic -Underline -FontSize 14 -Value {"=sum($columnName`2:$columnName$endrow)" } -VerticalAlignment Bottom
$r = Set-Row -PassThru -Worksheet $ws -StartColumn 3 -BorderAround Thin -Italic -Underline -FontSize 14 -Value {"=sum($columnName`2:$columnName$endrow)" } -VerticalAlignment Bottom
Set-Format -Address $excel.Workbook.Worksheets["Sheet1"].cells["b3"] -HorizontalAlignment Right -VerticalAlignment Center -BorderAround Thick -BorderColor Red -StrikeThru
Set-Format -Address $excel.Workbook.Worksheets["Sheet1"].cells["c3"] -BorderColor Red -BorderTop DashDot -BorderLeft DashDotDot -BorderBottom Dashed -BorderRight Dotted
Set-Format -WorkSheet $ws -Range "E3" -Bold:$false -FontShift Superscript -HorizontalAlignment Left
@@ -153,7 +153,7 @@ Describe "Set-Column, Set-Row and Set Format" {
Set-Format -WorkSheet $ws -Range "D$rr" -Formula "=E$rr/C$rr" -Hidden -WarningVariable "BadHideWarnvar" -WarningAction SilentlyContinue
$rr ++
Set-Format -WorkSheet $ws -Range "B$rr" -Value ([datetime]::Now)
Close-ExcelPackage $excel
Close-ExcelPackage $excel -Calculate
$excel = Open-ExcelPackage $path
@@ -167,7 +167,8 @@ Describe "Set-Column, Set-Row and Set Format" {
$ws.Row(5).height | Should be 0
}
it "Set a column formula, with numberformat, color, bold face and alignment " {
$ws.cells["e2"].Formula | Should be "=Quantity*Price"
$ws.cells["e2"].Formula | Should be "Quantity*Price"
$ws.cells["e2"].Value | Should be 147.63
$ws.cells["e2"].Style.Font.Color.rgb | Should be "FF0000FF"
$ws.cells["e2"].Style.Font.Bold | Should be $true
$ws.cells["e2"].Style.Font.VerticalAlign | Should be "None"
@@ -189,7 +190,8 @@ Describe "Set-Column, Set-Row and Set Format" {
$ws.cells["E7"].style.Border.Left.Style | Should be "None"
$ws.cells["E7"].style.Border.Right.Style | Should be "Thin"
$ws.cells["C7"].style.Font.size | Should be 14
$ws.cells["C7"].Formula | Should be "=sum(C2:C6)"
$ws.cells["C7"].Formula | Should be "sum(C2:C6)"
$ws.cells["C7"].value | Should be 81
$ws.cells["C7"].style.Font.UnderLine | Should be $true
$ws.cells["C6"].style.Font.UnderLine | Should be $false
}
@@ -214,7 +216,7 @@ Describe "Set-Column, Set-Row and Set Format" {
Context "Set-Format value setting " {
it "Inserted a formula " {
$ws.Cells["D7"].Formula | Should be "=E7/C7"
$ws.Cells["D7"].Formula | Should be "E7/C7"
}
it "Inserted a value " {
$ws.Cells["B7"].Value | Should be "Total"
@@ -243,7 +245,7 @@ Describe "Set-Column, Set-Row and Set Format" {
Set-Column -Worksheet $ws -Heading "Age" -Value "=INT((NOW()-DateOfBirth)/365)"
Set-Format -Address $c,$ws.column(3) -NumberFormat 'Short Date' -AutoSize
Close-ExcelPackage -ExcelPackage $excel
Close-ExcelPackage -ExcelPackage $excel -Calculate
$excel = Open-ExcelPackage $path
$ws = $excel.Workbook.Worksheets["Sheet1"]
}

View File

@@ -93,29 +93,29 @@ Function Compare-WorkSheet {
try { $oneFile = ((Resolve-Path -Path $Referencefile -ErrorAction Stop).path -eq (Resolve-Path -Path $Differencefile -ErrorAction Stop).path)}
Catch { Write-Warning -Message "Could not Resolve the filenames." ; return }
#If we have one file , we mush have two different worksheet names. If we have two files we can a single string or two strings.
#If we have one file , we must have two different worksheet names. If we have two files we can have a single string or two strings.
if ($onefile -and ( ($WorkSheetName.count -ne 2) -or $WorkSheetName[0] -eq $WorkSheetName[1] ) ) {
Write-Warning -Message "If both the Reference and difference file are the same then worksheet name must provide 2 different names"
return
}
if ($WorkSheetName.count -eq 2) {$worksheet1 = $WorkSheetName[0] ; $WorkSheet2 = $WorkSheetName[1]}
elseif ($WorkSheetName -is [string]) {$worksheet1 = $WorkSheet2 = $WorkSheetName}
if ($WorkSheetName.count -eq 2) {$worksheet1 = $WorkSheetName[0] ; $workSheet2 = $WorkSheetName[1]}
elseif ($WorkSheetName -is [string]) {$worksheet1 = $workSheet2 = $WorkSheetName}
else {Write-Warning -Message "You must provide either a single worksheet name or two names." ; return }
$params= @{ ErrorAction = [System.Management.Automation.ActionPreference]::Stop }
foreach ($p in @("HeaderName","NoHeader","StartRow")) {if ($PSBoundParameters[$p]) {$params[$p] = $PSBoundParameters[$p]}}
try {
$Sheet1 = Import-Excel -Path $Referencefile -WorksheetName $WorkSheet1 @params
$Sheet2 = Import-Excel -Path $Differencefile -WorksheetName $WorkSheet2 @Params
$sheet1 = Import-Excel -Path $Referencefile -WorksheetName $WorkSheet1 @params
$sheet2 = Import-Excel -Path $Differencefile -WorksheetName $WorkSheet2 @Params
}
Catch {Write-Warning -Message "Could not read the worksheet from $Referencefile and/or $Differencefile." ; return }
#Get Column headings and create a hash table of Name to column letter.
$headings = $Sheet1[-1].psobject.Properties.name # This preserves the sequence - using get-member would sort them alphabetically!
$headings | ForEach-Object -Begin {$columns = @{} ; $i=65 } -Process {$Columns[$_] = [char]($i ++) }
$headings | ForEach-Object -Begin {$columns = @{} ; $i= 1 } -Process {$Columns[$_] = [OfficeOpenXml.ExcelAddress]::GetAddress(1,($i ++)) -replace "\d","" }
#Make a list of property headings using the Property (default "*") and ExcludeProperty parameters
if ($Key -eq "Name" -and $NoHeader) {$key = "p1"}
if ($Key -eq "Name" -and $NoHeader) {$Key = "p1"}
$propList = @()
foreach ($p in $Property) {$propList += ($headings.where({$_ -like $p}) )}
foreach ($p in $ExcludeProperty) {$propList = $propList.where({$_ -notlike $p}) }
@@ -124,12 +124,12 @@ Function Compare-WorkSheet {
if ($propList.Count -eq 0) {Write-Warning -Message "No Columns are selected with -Property = '$Property' and -excludeProperty = '$ExcludeProperty'." ; return}
#Add RowNumber, Sheetname and file name to every row
$FirstDataRow = $startRow + 1
if ($Headername -or $NoHeader) {$FirstDataRow -- }
$i = $FirstDataRow ; foreach ($row in $Sheet1) {Add-Member -InputObject $row -MemberType NoteProperty -Name "_Row" -Value ($i ++)
$firstDataRow = $startRow + 1
if ($Headername -or $NoHeader) {$firstDataRow -- }
$i = $firstDataRow ; foreach ($row in $Sheet1) {Add-Member -InputObject $row -MemberType NoteProperty -Name "_Row" -Value ($i ++)
Add-Member -InputObject $row -MemberType NoteProperty -Name "_Sheet" -Value $worksheet1
Add-Member -InputObject $row -MemberType NoteProperty -Name "_File" -Value $Referencefile}
$i = $FirstDataRow ; foreach ($row in $Sheet2) {Add-Member -InputObject $row -MemberType NoteProperty -Name "_Row" -Value ($i ++)
$i = $firstDataRow ; foreach ($row in $Sheet2) {Add-Member -InputObject $row -MemberType NoteProperty -Name "_Row" -Value ($i ++)
Add-Member -InputObject $row -MemberType NoteProperty -Name "_Sheet" -Value $worksheet2
Add-Member -InputObject $row -MemberType NoteProperty -Name "_File" -Value $Differencefile}
@@ -198,7 +198,7 @@ Function Compare-WorkSheet {
#if nothing was found write a message which wont be redirected
if (-not $diff) {Write-Host "Comparison of $Referencefile::$worksheet1 and $Differencefile::$WorkSheet2 returned no results." }
if ($show) {
if ($Show) {
Start-Process -FilePath $Referencefile
if (-not $oneFile) { Start-Process -FilePath $Differencefile }
if ($GridView) { Write-Warning -Message "-GridView is ignored when -Show is specified" }