Compare commits

..

40 Commits

Author SHA1 Message Date
dfinke
abdd37b09e Updated readme and bumped version 2019-07-04 16:20:19 -04:00
Doug Finke
e1e855a823 Merge pull request #628 from dfinke/RelativePath
Added resolve-path and tests. #627; Commented out write-warning
2019-07-04 16:18:14 -04:00
dfinke
585d9686a6 Remove firstTimeThru check 2019-07-04 16:14:36 -04:00
dfinke
e87a6bdaf5 Add extension test back in 2019-07-04 12:16:44 -04:00
dfinke
5ded5111b4 Rename test 2019-07-04 12:16:34 -04:00
dfinke
914c61048b Moved back, CI has issues with $psscriptroot for xlsx 2019-07-04 12:03:05 -04:00
dfinke
25fb76d9b7 Remove test, put check in begin block 2019-07-04 11:59:15 -04:00
dfinke
7faa27a3b3 create xlsx before all in cwd 2019-07-04 11:53:59 -04:00
dfinke
5700be0684 works locally, not in the CI tho 2019-07-04 11:45:42 -04:00
dfinke
6d86108060 wip: remove param validation 2019-07-04 11:40:02 -04:00
dfinke
4581c2b3e9 Added resolve-path and tests. #627; Commented out write-warning 2019-07-04 11:18:28 -04:00
dfinke
142c31ccc1 Added image to readme 2019-06-18 14:56:00 -04:00
dfinke
b99b7ba799 Added chart trendline example 2019-06-18 14:47:14 -04:00
dfinke
17b5d2caec bump version 2019-06-18 14:47:14 -04:00
Doug Finke
6add16aa9f Merge pull request #615 from dfinke/EnableTrendLine
Initial pass at adding ChartTrendLine
2019-06-18 10:55:37 -04:00
dfinke
9aa0192ee6 Added and chart trendline example 2019-06-18 10:44:07 -04:00
dfinke
fa25d1ac06 Added tests for trendlines on charts 2019-06-18 10:31:37 -04:00
dfinke
8131eee50f Check if trendline was requested 2019-06-15 14:21:37 -04:00
dfinke
3ce485a144 Initial pass at adding ChartTrendLine 2019-06-13 15:38:28 -04:00
dfinke
bb1b413ada Updated 2019-06-11 17:24:28 -04:00
dfinke
08078410dc Added 2019-06-11 17:23:21 -04:00
dfinke
3edcc0bdfb Added pic link 2019-06-11 17:23:11 -04:00
dfinke
25081f84c1 Updated readme 2019-06-11 17:12:16 -04:00
dfinke
668e3c982c Image of New-ExcelStyle 2019-06-11 17:12:03 -04:00
dfinke
98cf7e03c1 Add Excel style example 2019-06-11 17:11:42 -04:00
dfinke
5b5c1c6fce Bump version 2019-06-11 17:11:22 -04:00
Doug Finke
4383916090 Merge pull request #610 from jhoneill/master
Style and read only
2019-06-11 16:13:22 -04:00
jhoneill
7c2bbf9595 Read-only imports + small test fix 2019-06-11 15:09:36 +01:00
jhoneill
48ca35b9ff Added -Style to export-Excel and -merge to set-excelRange 2019-06-05 21:17:35 +01:00
dfinke
68be3c3483 try again later 2019-05-31 12:43:45 -04:00
dfinke
78326b4258 again 2019-05-31 12:42:31 -04:00
dfinke
94b10b6f51 again 2019-05-31 12:41:25 -04:00
dfinke
8ac9815e83 test exclude again 2019-05-31 12:37:44 -04:00
dfinke
b3184d36a9 try exclude again 2019-05-31 12:36:45 -04:00
dfinke
e58265075a test exclude trigger 2019-05-31 12:32:19 -04:00
dfinke
453b2d8963 update trigger 2019-05-31 12:29:01 -04:00
dfinke
bc816851c9 Shouldn't trigger a build 2019-05-31 11:32:55 -04:00
dfinke
b0a68e3445 Don't trigger a build if examples get checked in 2019-05-31 11:29:28 -04:00
dfinke
8a1d0b0cf8 Added simple vba example 2019-05-31 11:21:44 -04:00
Doug Finke
26f55251e2 Update CustomReport.ps1 2019-05-31 10:13:03 -04:00
22 changed files with 498 additions and 99 deletions

View File

@@ -1,4 +1,9 @@
Function Add-ConditionalFormatting { try {
#ensure that color and font lookups are available
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
}
catch {}
Function Add-ConditionalFormatting {
<# <#
.Synopsis .Synopsis
Adds conditional formatting to all or part of a worksheet. Adds conditional formatting to all or part of a worksheet.
@@ -105,7 +110,7 @@
[OfficeOpenXml.ConditionalFormatting.eExcelConditionalFormattingRuleType]$RuleType , [OfficeOpenXml.ConditionalFormatting.eExcelConditionalFormattingRuleType]$RuleType ,
#Text color for matching objects #Text color for matching objects
[Parameter(ParameterSetName = "NamedRule")] [Parameter(ParameterSetName = "NamedRule")]
[Alias("ForegroundColour")] [Alias("ForegroundColour","FontColor")]
$ForegroundColor, $ForegroundColor,
#Color for databar type charts #Color for databar type charts
[Parameter(Mandatory = $true, ParameterSetName = "DataBar")] [Parameter(Mandatory = $true, ParameterSetName = "DataBar")]

View File

@@ -27,6 +27,10 @@ if (Get-Command -Name register-argumentCompleter -ErrorAction SilentlyContinue)
Register-ArgumentCompleter -CommandName New-ConditionalText -ParameterName PatternColor -ScriptBlock $Function:ColorCompletion Register-ArgumentCompleter -CommandName New-ConditionalText -ParameterName PatternColor -ScriptBlock $Function:ColorCompletion
Register-ArgumentCompleter -CommandName New-ConditionalText -ParameterName BackgroundColor -ScriptBlock $Function:ColorCompletion Register-ArgumentCompleter -CommandName New-ConditionalText -ParameterName BackgroundColor -ScriptBlock $Function:ColorCompletion
Register-ArgumentCompleter -CommandName New-ConditionalText -ParameterName ConditionalTextColor -ScriptBlock $Function:ColorCompletion Register-ArgumentCompleter -CommandName New-ConditionalText -ParameterName ConditionalTextColor -ScriptBlock $Function:ColorCompletion
Register-ArgumentCompleter -CommandName New-ExcelStyle -ParameterName BackgroundColor -ScriptBlock $Function:ColorCompletion
Register-ArgumentCompleter -CommandName New-ExcelStyle -ParameterName FontColor -ScriptBlock $Function:ColorCompletion
Register-ArgumentCompleter -CommandName New-ExcelStyle -ParameterName BorderColor -ScriptBlock $Function:ColorCompletion
Register-ArgumentCompleter -CommandName New-ExcelStyle -ParameterName PatternColor -ScriptBlock $Function:ColorCompletion
Register-ArgumentCompleter -CommandName Set-ExcelRange -ParameterName BackgroundColor -ScriptBlock $Function:ColorCompletion Register-ArgumentCompleter -CommandName Set-ExcelRange -ParameterName BackgroundColor -ScriptBlock $Function:ColorCompletion
Register-ArgumentCompleter -CommandName Set-ExcelRange -ParameterName FontColor -ScriptBlock $Function:ColorCompletion Register-ArgumentCompleter -CommandName Set-ExcelRange -ParameterName FontColor -ScriptBlock $Function:ColorCompletion
Register-ArgumentCompleter -CommandName Set-ExcelRange -ParameterName BorderColor -ScriptBlock $Function:ColorCompletion Register-ArgumentCompleter -CommandName Set-ExcelRange -ParameterName BorderColor -ScriptBlock $Function:ColorCompletion
@@ -37,5 +41,4 @@ if (Get-Command -Name register-argumentCompleter -ErrorAction SilentlyContinue)
Register-ArgumentCompleter -CommandName Set-ExcelRow -ParameterName BackgroundColor -ScriptBlock $Function:ColorCompletion Register-ArgumentCompleter -CommandName Set-ExcelRow -ParameterName BackgroundColor -ScriptBlock $Function:ColorCompletion
Register-ArgumentCompleter -CommandName Set-ExcelRow -ParameterName FontColor -ScriptBlock $Function:ColorCompletion Register-ArgumentCompleter -CommandName Set-ExcelRow -ParameterName FontColor -ScriptBlock $Function:ColorCompletion
Register-ArgumentCompleter -CommandName Set-ExcelRow -ParameterName PatternColor -ScriptBlock $Function:ColorCompletion Register-ArgumentCompleter -CommandName Set-ExcelRow -ParameterName PatternColor -ScriptBlock $Function:ColorCompletion
} }

View File

@@ -0,0 +1,21 @@
# Creates a worksheet, addes a chart and then a Linear trendline
$xlfile = "$env:TEMP\trendLine.xlsx"
Remove-Item $xlfile -ErrorAction SilentlyContinue
$data = ConvertFrom-Csv @"
Region,Item,TotalSold
West,screws,60
South,lemon,48
South,apple,71
East,screwdriver,70
East,kiwi,32
West,screwdriver,1
South,melon,21
East,apple,79
South,apple,68
South,avocado,73
"@
$cd = New-ExcelChartDefinition -XRange Region -YRange TotalSold -ChartType ColumnClustered -ChartTrendLine Linear
$data | Export-Excel $xlfile -ExcelChartDefinition $cd -AutoNameRange -Show

View File

@@ -0,0 +1,27 @@
$xlfile = "$env:TEMP\visitors.xlsx"
Remove-Item $xlfile -ErrorAction SilentlyContinue
$data = ConvertFrom-Csv @"
Week, TotalVisitors
1,11916
2,11665
3,13901
4,15444
5,21592
6,15057
7,26187
8,20662
9,28935
10,32443
"@
$cd = New-ExcelChartDefinition `
-XRange Week `
-YRange TotalVisitors `
-Title "No. Of Visitors" `
-ChartType ColumnClustered `
-NoLegend `
-ChartTrendLine Linear
$data | Export-Excel $xlfile -Show -AutoNameRange -AutoSize -TableName Visitors -ExcelChartDefinition $cd

View File

@@ -1,6 +1,6 @@
try {. $PSScriptRoot\..\..\LoadPSD1.ps1} catch {} try {. $PSScriptRoot\..\..\LoadPSD1.ps1} catch {}
$f = ".\dashboard.xlsx" $f = "$env:temp\dashboard.xlsx"
Remove-Item $f -ErrorAction Ignore Remove-Item $f -ErrorAction Ignore
$data = @" $data = @"
@@ -69,4 +69,4 @@ Set-Format -Address $sheet1.Cells["I10"] -Formula "=Sum(I3:I8)" -Bold
Set-Format -Address $sheet1.Cells["M10"] -Formula "=Sum(M3:M8)" -Bold Set-Format -Address $sheet1.Cells["M10"] -Formula "=Sum(M3:M8)" -Bold
Set-Format -Address $sheet1.Cells["O10"] -Formula "=Sum(O3:O8)" -Bold Set-Format -Address $sheet1.Cells["O10"] -Formula "=Sum(O3:O8)" -Bold
Close-ExcelPackage $excel -Show Close-ExcelPackage $excel -Show

View File

@@ -0,0 +1,35 @@
try { . $PSScriptRoot\..\..\LoadPSD1.ps1 } catch { }
$xlfile = "$env:TEMP\test.xlsx"
Remove-Item $xlfile -ErrorAction SilentlyContinue
$data = ConvertFrom-Csv @"
Region,Item,TotalSold
North,melon,38
South,screwdriver,21
South,peach,33
South,saw,81
South,kiwi,70
North,orange,59
North,avocado,25
South,lime,48
South,nail,83
North,apple,2
"@
$styleParams = @{
FontSize = 13
Bold = $true
}
$styles = $(
New-ExcelStyle -BackgroundColor LightBlue -FontSize 14 -Bold -Range "A1:H1" -HorizontalAlignment Center -Merge
New-ExcelStyle -BackgroundColor LimeGreen -Range "B10" @styleParams
New-ExcelStyle -BackgroundColor PeachPuff -Range "B5" @styleParams
New-ExcelStyle -BackgroundColor Orange -Range "B8" @styleParams
New-ExcelStyle -BackgroundColor Red -Range "B12" @styleParams
)
$reportTitle = "This is a report Title"
$data | Export-Excel $xlfile -Show -AutoSize -AutoFilter -Title $reportTitle -Style $styles

View File

@@ -0,0 +1,23 @@
# https://raw.githubusercontent.com/dfinke/ImportExcel/master/images/NewExcelStyle.png
try { . $PSScriptRoot\..\..\LoadPSD1.ps1 } catch { }
$xlfile = "$env:TEMP\test.xlsx"
Remove-Item $xlfile -ErrorAction SilentlyContinue
$data = ConvertFrom-Csv @"
Region,Item,TotalSold
North,melon,38
South,screwdriver,21
South,peach,33
South,saw,81
South,kiwi,70
North,orange,59
North,avocado,25
South,lime,48
South,nail,83
North,apple,2
"@
$reportTitle = "This is a report Title"
$style = New-ExcelStyle -BackgroundColor LightBlue -FontSize 14 -Bold -Range "A1:H1" -HorizontalAlignment Center -Merge
$data | Export-Excel $xlfile -Show -AutoSize -AutoFilter -Title $reportTitle -Style $style

View File

@@ -0,0 +1,38 @@
$xlfile = "$env:temp\test.xlsm"
Remove-Item $xlfile -ErrorAction SilentlyContinue
$Excel = ConvertFrom-Csv @"
Region,Item,TotalSold
West,screwdriver,98
West,kiwi,19
North,kiwi,47
West,screws,48
West,avocado,52
East,avocado,40
South,drill,61
North,orange,92
South,drill,29
South,saw,36
"@ | Export-Excel $xlfile -PassThru -AutoSize
$wb = $Excel.Workbook
$sheet = $wb.Worksheets["Sheet1"]
$wb.CreateVBAProject()
$code = @"
Public Function HelloWorld() As String
HelloWorld = "Hello World"
End Function
Public Function DoSum() As Integer
DoSum = Application.Sum(Range("C:C"))
End Function
"@
$module = $wb.VbaProject.Modules.AddModule("PSExcelModule")
$module.Code = $code
Set-Format -WorkSheet $sheet -Range "h7" -Formula "HelloWorld()" -AutoSize
Set-Format -WorkSheet $sheet -Range "h8" -Formula "DoSum()" -AutoSize
Close-ExcelPackage $Excel -Show

View File

@@ -499,6 +499,7 @@
[Switch]$AutoNameRange, [Switch]$AutoNameRange,
[Int]$StartRow = 1, [Int]$StartRow = 1,
[Int]$StartColumn = 1, [Int]$StartColumn = 1,
[alias('PT')]
[Switch]$PassThru, [Switch]$PassThru,
[String]$Numberformat = 'General', [String]$Numberformat = 'General',
[string[]]$ExcludeProperty, [string[]]$ExcludeProperty,
@@ -507,6 +508,7 @@
[String[]]$NoNumberConversion, [String[]]$NoNumberConversion,
[Object[]]$ConditionalFormat, [Object[]]$ConditionalFormat,
[Object[]]$ConditionalText, [Object[]]$ConditionalText,
[Object[]]$Style,
[ScriptBlock]$CellStyleSB, [ScriptBlock]$CellStyleSB,
#If there is already content in the workbook the sheet with the PivotTable will not be active UNLESS Activate is specified #If there is already content in the workbook the sheet with the PivotTable will not be active UNLESS Activate is specified
[switch]$Activate, [switch]$Activate,
@@ -1022,7 +1024,10 @@
} }
catch {throw "Error applying conditional formatting to worksheet $_"} catch {throw "Error applying conditional formatting to worksheet $_"}
} }
foreach ($s in $Style) {
if (-not $s.Range) {$s["Range"] = $ws.Dimension.Address }
Set-ExcelRange -WorkSheet $ws @s
}
if ($CellStyleSB) { if ($CellStyleSB) {
try { try {
$TotalRows = $ws.Dimension.Rows $TotalRows = $ws.Dimension.Rows

View File

@@ -4,7 +4,7 @@
RootModule = 'ImportExcel.psm1' RootModule = 'ImportExcel.psm1'
# Version number of this module. # Version number of this module.
ModuleVersion = '6.1.0' ModuleVersion = '6.2.2'
# ID used to uniquely identify this module # ID used to uniquely identify this module
GUID = '60dd4136-feff-401a-ba27-a84458c57ede' GUID = '60dd4136-feff-401a-ba27-a84458c57ede'
@@ -103,6 +103,7 @@ Check out the How To Videos https://www.youtube.com/watch?v=U3Ne_yX4tYo&list=PL5
'New-ConditionalFormattingIconSet', 'New-ConditionalFormattingIconSet',
'New-ConditionalText', 'New-ConditionalText',
'New-ExcelChartDefinition', 'New-ExcelChartDefinition',
'New-ExcelStyle',
'New-PivotTableDefinition', 'New-PivotTableDefinition',
'New-Plot', 'New-Plot',
'New-PSItem', 'New-PSItem',

View File

@@ -48,7 +48,7 @@ if ($PSVersionTable.PSVersion.Major -ge 5) {
. $PSScriptRoot\plot.ps1 . $PSScriptRoot\plot.ps1
Function New-Plot { Function New-Plot {
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '', Justification='New-Plot does not change system state')] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '', Justification = 'New-Plot does not change system state')]
Param() Param()
[PSPlot]::new() [PSPlot]::new()
@@ -269,7 +269,6 @@ function Import-Excel {
[Parameter(ParameterSetName = "PathA", Mandatory, ValueFromPipelineByPropertyName, ValueFromPipeline, Position = 0 )] [Parameter(ParameterSetName = "PathA", Mandatory, ValueFromPipelineByPropertyName, ValueFromPipeline, Position = 0 )]
[Parameter(ParameterSetName = "PathB", Mandatory, ValueFromPipelineByPropertyName, ValueFromPipeline, Position = 0 )] [Parameter(ParameterSetName = "PathB", Mandatory, ValueFromPipelineByPropertyName, ValueFromPipeline, Position = 0 )]
[Parameter(ParameterSetName = "PathC", Mandatory, ValueFromPipelineByPropertyName, ValueFromPipeline, Position = 0 )] [Parameter(ParameterSetName = "PathC", Mandatory, ValueFromPipelineByPropertyName, ValueFromPipeline, Position = 0 )]
[ValidateScript( {(Test-Path -Path $_ -PathType Leaf) -and ($_ -match '.xls$|.xlsx$|.xlsm$')})]
[String]$Path, [String]$Path,
[Parameter(ParameterSetName = "PackageA", Mandatory)] [Parameter(ParameterSetName = "PackageA", Mandatory)]
[Parameter(ParameterSetName = "PackageB", Mandatory)] [Parameter(ParameterSetName = "PackageB", Mandatory)]
@@ -300,12 +299,13 @@ function Import-Excel {
) )
begin { begin {
$sw = [System.Diagnostics.Stopwatch]::StartNew() $sw = [System.Diagnostics.Stopwatch]::StartNew()
Function Get-PropertyNames { Function Get-PropertyNames {
<# <#
.SYNOPSIS .SYNOPSIS
Create objects containing the column number and the column name for each of the different header types. Create objects containing the column number and the column name for each of the different header types.
#> #>
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseSingularNouns', '', Justification="Name would be incorrect, and command is not exported")] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseSingularNouns', '', Justification = "Name would be incorrect, and command is not exported")]
Param ( Param (
[Parameter(Mandatory)] [Parameter(Mandatory)]
[Int[]]$Columns, [Int[]]$Columns,
@@ -318,13 +318,13 @@ function Import-Excel {
$i = 0 $i = 0
foreach ($C in $Columns) { foreach ($C in $Columns) {
$i++ $i++
$C | Select-Object @{N = 'Column'; E = {$_}}, @{N = 'Value'; E = {'P' + $i}} $C | Select-Object @{N = 'Column'; E = { $_ } }, @{N = 'Value'; E = { 'P' + $i } }
} }
} }
elseif ($HeaderName) { elseif ($HeaderName) {
$i = 0 $i = 0
foreach ($H in $HeaderName) { foreach ($H in $HeaderName) {
$H | Select-Object @{N = 'Column'; E = {$Columns[$i]}}, @{N = 'Value'; E = {$H}} $H | Select-Object @{N = 'Column'; E = { $Columns[$i] } }, @{N = 'Value'; E = { $H } }
$i++ $i++
} }
} }
@@ -334,7 +334,7 @@ function Import-Excel {
} }
foreach ($C in $Columns) { foreach ($C in $Columns) {
$Worksheet.Cells[$StartRow, $C] | Where-Object {$_.Value} | Select-Object @{N = 'Column'; E = {$C}}, Value $Worksheet.Cells[$StartRow, $C] | Where-Object { $_.Value } | Select-Object @{N = 'Column'; E = { $C } }, Value
} }
} }
} }
@@ -345,41 +345,57 @@ function Import-Excel {
} }
process { process {
if ($Path -and $Password) {$ExcelPackage = Open-ExcelPackage -Path $Path -Password $Password} if ($path) {
elseif ($Path) {$ExcelPackage = Open-ExcelPackage -Path $Path} $extension = [System.IO.Path]::GetExtension($Path)
if ($extension -notmatch '.xlsx$|.xlsm$') {
throw "Import-Excel does not support reading this extension type $($extension)"
}
$resolvedPath = (Resolve-Path $Path -ErrorAction SilentlyContinue)
if ($resolvedPath) {
$Path = $resolvedPath.ProviderPath
}
else {
throw "'$($Path)' file not found"
}
$stream = New-Object -TypeName System.IO.FileStream -ArgumentList $Path, 'Open', 'Read', 'ReadWrite'
if ($Password) { $ExcelPackage = New-Object -TypeName OfficeOpenXml.ExcelPackage -ArgumentList $stream , $Password }
else { $ExcelPackage = New-Object -TypeName OfficeOpenXml.ExcelPackage -ArgumentList $stream }
}
try { try {
#Select worksheet #Select worksheet
if (-not $WorksheetName) { $Worksheet = $ExcelPackage.Workbook.Worksheets[1] } if (-not $WorksheetName) { $Worksheet = $ExcelPackage.Workbook.Worksheets[1] }
elseif(-not ($Worksheet = $ExcelPackage.Workbook.Worksheets[$WorkSheetName])) { elseif (-not ($Worksheet = $ExcelPackage.Workbook.Worksheets[$WorkSheetName])) {
throw "Worksheet '$WorksheetName' not found, the workbook only contains the worksheets '$($ExcelPackage.Workbook.Worksheets)'. If you only wish to select the first worksheet, please remove the '-WorksheetName' parameter." ; return throw "Worksheet '$WorksheetName' not found, the workbook only contains the worksheets '$($ExcelPackage.Workbook.Worksheets)'. If you only wish to select the first worksheet, please remove the '-WorksheetName' parameter." ; return
} }
Write-Debug $sw.Elapsed.TotalMilliseconds Write-Debug $sw.Elapsed.TotalMilliseconds
#region Get rows and columns #region Get rows and columns
#If we are doing dataonly it is quicker to work out which rows to ignore before processing the cells. #If we are doing dataonly it is quicker to work out which rows to ignore before processing the cells.
if (-not $EndRow ) {$EndRow = $Worksheet.Dimension.End.Row } if (-not $EndRow ) { $EndRow = $Worksheet.Dimension.End.Row }
if (-not $EndColumn) {$EndColumn = $Worksheet.Dimension.End.Column } if (-not $EndColumn) { $EndColumn = $Worksheet.Dimension.End.Column }
$endAddress = [OfficeOpenXml.ExcelAddress]::TranslateFromR1C1("R[$EndRow]C[$EndColumn]", 0, 0) $endAddress = [OfficeOpenXml.ExcelAddress]::TranslateFromR1C1("R[$EndRow]C[$EndColumn]", 0, 0)
if ($DataOnly) { if ($DataOnly) {
#If we are using headers startrow will be the header-row so examine data from startRow + 1, #If we are using headers startrow will be the header-row so examine data from startRow + 1,
if ($NoHeader) {$range = "A" + ($StartRow ) + ":" + $endAddress } if ($NoHeader) { $range = "A" + ($StartRow ) + ":" + $endAddress }
else {$range = "A" + ($StartRow + 1 ) + ":" + $endAddress } else { $range = "A" + ($StartRow + 1 ) + ":" + $endAddress }
#We're going to look at every cell and build 2 hash tables holding rows & columns which contain data. #We're going to look at every cell and build 2 hash tables holding rows & columns which contain data.
#Want to Avoid 'select unique' operations & large Sorts, becuse time time taken increases with square #Want to Avoid 'select unique' operations & large Sorts, becuse time time taken increases with square
#of number of items (PS uses heapsort at large size). Instead keep a list of what we have seen, #of number of items (PS uses heapsort at large size). Instead keep a list of what we have seen,
#using Hash tables: "we've seen it" is all we need, no need to worry about "seen it before" / "Seen it many times". #using Hash tables: "we've seen it" is all we need, no need to worry about "seen it before" / "Seen it many times".
$colHash = @{} $colHash = @{ }
$rowHash = @{} $rowHash = @{ }
foreach ($cell in $Worksheet.Cells[$range]) { foreach ($cell in $Worksheet.Cells[$range]) {
if ($null -ne $cell.Value ) {$colHash[$cell.Start.Column] = 1; $rowHash[$cell.Start.row] = 1 } if ($null -ne $cell.Value ) { $colHash[$cell.Start.Column] = 1; $rowHash[$cell.Start.row] = 1 }
} }
$rows = ( $StartRow..$EndRow ).Where( {$rowHash[$_]}) $rows = ( $StartRow..$EndRow ).Where( { $rowHash[$_] })
$columns = ($StartColumn..$EndColumn).Where( {$colHash[$_]}) $columns = ($StartColumn..$EndColumn).Where( { $colHash[$_] })
} }
else { else {
$Columns = $StartColumn .. $EndColumn ; if ($StartColumn -gt $EndColumn) {Write-Warning -Message "Selecting columns $StartColumn to $EndColumn might give odd results."} $Columns = $StartColumn .. $EndColumn ; if ($StartColumn -gt $EndColumn) { Write-Warning -Message "Selecting columns $StartColumn to $EndColumn might give odd results." }
if ($NoHeader) {$Rows = $StartRow..$EndRow ; if ($StartRow -gt $EndRow) {Write-Warning -Message "Selecting rows $StartRow to $EndRow might give odd results."} } if ($NoHeader) { $Rows = $StartRow..$EndRow ; if ($StartRow -gt $EndRow) { Write-Warning -Message "Selecting rows $StartRow to $EndRow might give odd results." } }
else {$Rows = (1 + $StartRow)..$EndRow ; if ($StartRow -ge $EndRow) {Write-Warning -Message "Selecting $StartRow as the header with data in $(1+$StartRow) to $EndRow might give odd results."}} else { $Rows = (1 + $StartRow)..$EndRow } # ; if ($StartRow -ge $EndRow) { Write-Warning -Message "Selecting $StartRow as the header with data in $(1+$StartRow) to $EndRow might give odd results." } }
} }
#endregion #endregion
#region Create property names #region Create property names
@@ -399,7 +415,7 @@ function Import-Excel {
foreach ($R in $Rows) { foreach ($R in $Rows) {
#Disabled write-verbose for speed #Disabled write-verbose for speed
# Write-Verbose "Import row '$R'" # Write-Verbose "Import row '$R'"
$NewRow = [Ordered]@{} $NewRow = [Ordered]@{ }
foreach ($P in $PropertyNames) { foreach ($P in $PropertyNames) {
$NewRow[$P.Value] = $Worksheet.Cells[$R, $P.Column].Value $NewRow[$P.Value] = $Worksheet.Cells[$R, $P.Column].Value
@@ -414,7 +430,7 @@ function Import-Excel {
} }
catch { throw "Failed importing the Excel workbook '$Path' with worksheet '$Worksheetname': $_"; return } catch { throw "Failed importing the Excel workbook '$Path' with worksheet '$Worksheetname': $_"; return }
finally { finally {
if ($Path) {Close-ExcelPackage -ExcelPackage $ExcelPackage -NoSave } if ($Path) { $stream.close(); $ExcelPackage.Dispose() }
} }
} }
} }
@@ -460,9 +476,9 @@ function ConvertFrom-ExcelSheet {
$xl = New-Object -TypeName OfficeOpenXml.ExcelPackage -ArgumentList $Stream $xl = New-Object -TypeName OfficeOpenXml.ExcelPackage -ArgumentList $Stream
$workbook = $xl.Workbook $workbook = $xl.Workbook
$targetSheets = $workbook.Worksheets | Where-Object {$_.Name -like $SheetName} $targetSheets = $workbook.Worksheets | Where-Object { $_.Name -like $SheetName }
$params = @{} + $PSBoundParameters $params = @{ } + $PSBoundParameters
$params.Remove("OutputPath") $params.Remove("OutputPath")
$params.Remove("SheetName") $params.Remove("SheetName")
$params.Remove('Extension') $params.Remove('Extension')
@@ -493,7 +509,7 @@ function Export-MultipleExcelSheets {
[Switch]$AutoSize [Switch]$AutoSize
) )
$parameters = @{} + $PSBoundParameters $parameters = @{ } + $PSBoundParameters
$parameters.Remove("InfoMap") $parameters.Remove("InfoMap")
$parameters.Remove("Show") $parameters.Remove("Show")
@@ -506,17 +522,17 @@ function Export-MultipleExcelSheets {
& $entry.Value | Export-Excel @parameters & $entry.Value | Export-Excel @parameters
} }
if ($Show) {Invoke-Item $Path} if ($Show) { Invoke-Item $Path }
} }
Function WorksheetArgumentCompleter { Function WorksheetArgumentCompleter {
param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter) param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter)
$xlPath = $fakeBoundParameter['Path'] $xlPath = $fakeBoundParameter['Path']
if (Test-Path -Path $xlPath) { if (Test-Path -Path $xlPath) {
$xlpkg = Open-ExcelPackage -Path $xlPath $xlpkg = Open-ExcelPackage -ReadOnly -Path $xlPath
$WorksheetNames = $xlPkg.Workbook.Worksheets.Name $WorksheetNames = $xlPkg.Workbook.Worksheets.Name
Close-ExcelPackage -nosave -ExcelPackage $xlpkg Close-ExcelPackage -nosave -ExcelPackage $xlpkg
$WorksheetNames.where( {$_ -like "*$wordToComplete*"}) | foreach-object { $WorksheetNames.where( { $_ -like "*$wordToComplete*" }) | foreach-object {
New-Object -TypeName System.Management.Automation.CompletionResult -ArgumentList "'$_'", New-Object -TypeName System.Management.Automation.CompletionResult -ArgumentList "'$_'",
$_ , ([System.Management.Automation.CompletionResultType]::ParameterValue) , $_ $_ , ([System.Management.Automation.CompletionResultType]::ParameterValue) , $_
} }

View File

@@ -39,7 +39,7 @@ function New-ConditionalText {
"Finish Position". The range could be written -Range "C:C" to specify a "Finish Position". The range could be written -Range "C:C" to specify a
named column, or -Range "C2:C102" to specify certain cells in the column. named column, or -Range "C2:C102" to specify certain cells in the column.
.Link .Link
Add-Add-ConditionalFormatting Add-ConditionalFormatting
New-ConditionalFormattingIconSet New-ConditionalFormattingIconSet
#> #>
[cmdletbinding()] [cmdletbinding()]

View File

@@ -97,11 +97,12 @@
#> #>
[Alias("New-ExcelChart")] #This was the former name. The new name reflects that we are defining a chart, not making one in the workbook. [Alias("New-ExcelChart")] #This was the former name. The new name reflects that we are defining a chart, not making one in the workbook.
[cmdletbinding()] [cmdletbinding()]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '',Justification='Does not change system State')] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '', Justification = 'Does not change system State')]
param( param(
$Title = "Chart Title", $Title = "Chart Title",
$Header, $Header,
[OfficeOpenXml.Drawing.Chart.eChartType]$ChartType = "ColumnStacked", [OfficeOpenXml.Drawing.Chart.eChartType]$ChartType = "ColumnStacked",
[OfficeOpenXml.Drawing.Chart.eTrendLine[]]$ChartTrendLine,
$XRange, $XRange,
$YRange, $YRange,
$Width = 500, $Width = 500,
@@ -138,11 +139,12 @@
$YMinValue, $YMinValue,
[OfficeOpenXml.Drawing.Chart.eAxisPosition]$YAxisPosition [OfficeOpenXml.Drawing.Chart.eAxisPosition]$YAxisPosition
) )
if ( $Header ) {Write-Warning "The header parameter is ignored."} #Nothing was done with it when creating a chart. if ( $Header ) { Write-Warning "The header parameter is ignored." } #Nothing was done with it when creating a chart.
#might be able to do [PSCustomObject]$PsboundParameters, the defaults here match those in Add-Excel Chart #might be able to do [PSCustomObject]$PsboundParameters, the defaults here match those in Add-Excel Chart
[PSCustomObject]@{ [PSCustomObject]@{
Title = $Title Title = $Title
ChartType = $ChartType ChartType = $ChartType
ChartTrendLine = $ChartTrendLine
XRange = $XRange XRange = $XRange
YRange = $YRange YRange = $YRange
Width = $Width Width = $Width
@@ -151,14 +153,14 @@
RowOffSetPixels = $RowOffSetPixels RowOffSetPixels = $RowOffSetPixels
Column = $Column Column = $Column
ColumnOffSetPixels = $ColumnOffSetPixels ColumnOffSetPixels = $ColumnOffSetPixels
LegendPosition = $LegendPosition LegendPosition = $LegendPosition
LegendSize = $LegendSize LegendSize = $LegendSize
Legendbold = $LegendBold Legendbold = $LegendBold
NoLegend = $NoLegend -as [Boolean] NoLegend = $NoLegend -as [Boolean]
ShowCategory = $ShowCategory -as [Boolean] ShowCategory = $ShowCategory -as [Boolean]
ShowPercent = $ShowPercent -as [Boolean] ShowPercent = $ShowPercent -as [Boolean]
SeriesHeader = $SeriesHeader SeriesHeader = $SeriesHeader
TitleBold = $TitleBold -as [Boolean] TitleBold = $TitleBold -as [Boolean]
TitleSize = $TitleSize TitleSize = $TitleSize
XAxisTitleText = $XAxisTitleText XAxisTitleText = $XAxisTitleText
XAxisTitleBold = $XAxisTitleBold -as [Boolean] XAxisTitleBold = $XAxisTitleBold -as [Boolean]
@@ -170,7 +172,7 @@
XMinValue = $XMinValue XMinValue = $XMinValue
XAxisPosition = $XAxisPosition XAxisPosition = $XAxisPosition
YAxisTitleText = $YAxisTitleText YAxisTitleText = $YAxisTitleText
YAxisTitleBold = $YAxisTitleBold -as [Boolean] YAxisTitleBold = $YAxisTitleBold -as [Boolean]
YAxisTitleSize = $YAxisTitleSize YAxisTitleSize = $YAxisTitleSize
YAxisNumberformat = $YAxisNumberformat YAxisNumberformat = $YAxisNumberformat
YMajorUnit = $YMajorUnit YMajorUnit = $YMajorUnit
@@ -326,24 +328,25 @@ function Add-ExcelChart {
and is marked off in units of 0.25 shown to two decimal places. and is marked off in units of 0.25 shown to two decimal places.
The key will for the chart will be at the bottom in 8 point bold type and the line will be named "Sin(x)". The key will for the chart will be at the bottom in 8 point bold type and the line will be named "Sin(x)".
#> #>
[cmdletbinding(DefaultParameterSetName='Worksheet')] [cmdletbinding(DefaultParameterSetName = 'Worksheet')]
[OutputType([OfficeOpenXml.Drawing.Chart.ExcelChart])] [OutputType([OfficeOpenXml.Drawing.Chart.ExcelChart])]
param( param(
[Parameter(ParameterSetName='Workshet',Mandatory=$true)] [Parameter(ParameterSetName = 'Workshet', Mandatory = $true)]
[OfficeOpenXml.ExcelWorksheet]$Worksheet, [OfficeOpenXml.ExcelWorksheet]$Worksheet,
[Parameter(ParameterSetName='PivotTable',Mandatory=$true)] [Parameter(ParameterSetName = 'PivotTable', Mandatory = $true)]
[OfficeOpenXml.Table.PivotTable.ExcelPivotTable]$PivotTable , [OfficeOpenXml.Table.PivotTable.ExcelPivotTable]$PivotTable ,
[String]$Title, [String]$Title,
#$Header, Not used but referenced previously #$Header, Not used but referenced previously
[OfficeOpenXml.Drawing.Chart.eChartType]$ChartType = "ColumnStacked", [OfficeOpenXml.Drawing.Chart.eChartType]$ChartType = "ColumnStacked",
[OfficeOpenXml.Drawing.Chart.eTrendLine[]]$ChartTrendLine,
$XRange, $XRange,
$YRange, $YRange,
[int]$Width = 500, [int]$Width = 500,
[int]$Height = 350, [int]$Height = 350,
[int]$Row = 0, [int]$Row = 0,
[int]$RowOffSetPixels = 10, [int]$RowOffSetPixels = 10,
[int]$Column = 6, [int]$Column = 6,
[int]$ColumnOffSetPixels = 5, [int]$ColumnOffSetPixels = 5,
[OfficeOpenXml.Drawing.Chart.eLegendPosition]$LegendPosition, [OfficeOpenXml.Drawing.Chart.eLegendPosition]$LegendPosition,
$LegendSize, $LegendSize,
[Switch]$LegendBold, [Switch]$LegendBold,
@@ -372,11 +375,11 @@ function Add-ExcelChart {
$YMinValue, $YMinValue,
[OfficeOpenXml.Drawing.Chart.eAxisPosition]$YAxisPosition, [OfficeOpenXml.Drawing.Chart.eAxisPosition]$YAxisPosition,
[Switch]$PassThru [Switch]$PassThru
) )
try { try {
if ($PivotTable) { if ($PivotTable) {
$Worksheet = $PivotTable.WorkSheet $Worksheet = $PivotTable.WorkSheet
$chart = $Worksheet.Drawings.AddChart(("Chart" + $PivotTable.Name ),$ChartType,$PivotTable) $chart = $Worksheet.Drawings.AddChart(("Chart" + $PivotTable.Name ), $ChartType, $PivotTable)
} }
else { else {
$ChartName = 'Chart' + (Split-Path -Leaf ([System.IO.path]::GetTempFileName())) -replace 'tmp|\.', '' $ChartName = 'Chart' + (Split-Path -Leaf ([System.IO.path]::GetTempFileName())) -replace 'tmp|\.', ''
@@ -384,75 +387,85 @@ function Add-ExcelChart {
$chartDefCount = @($YRange).Count $chartDefCount = @($YRange).Count
if ($chartDefCount -eq 1) { if ($chartDefCount -eq 1) {
$Series = $chart.Series.Add($YRange, $XRange) $Series = $chart.Series.Add($YRange, $XRange)
if ($SeriesHeader) { $Series.Header = $SeriesHeader} if ($ChartTrendLine) {
else { $Series.Header = 'Series 1'} if ($ChartType -notmatch "stacked|3D$|pie|Doughnut|Cone|Cylinder|Pyramid") {
foreach ($trendLine in $ChartTrendLine) {
$null = $Series.TrendLines.Add($trendLine)
}
}
else {
Write-Warning "Chart trend line is not supported for chart type: $ChartType"
}
}
if ($SeriesHeader) { $Series.Header = $SeriesHeader }
else { $Series.Header = 'Series 1' }
} }
else { else {
for ($idx = 0; $idx -lt $chartDefCount; $idx += 1) { for ($idx = 0; $idx -lt $chartDefCount; $idx += 1) {
if ($Yrange.count -eq $xrange.count) { if ($Yrange.count -eq $xrange.count) {
$Series = $chart.Series.Add($YRange[$idx], $XRange[$idx]) $Series = $chart.Series.Add($YRange[$idx], $XRange[$idx])
} }
else { else {
$Series = $chart.Series.Add($YRange[$idx], $XRange) $Series = $chart.Series.Add($YRange[$idx], $XRange)
} }
if ($SeriesHeader.Count -gt 0) { if ($SeriesHeader.Count -gt 0) {
if ($SeriesHeader[$idx] -match '^=') {$Series.HeaderAddress = $SeriesHeader[$idx] -replace '^=',''} if ($SeriesHeader[$idx] -match '^=') { $Series.HeaderAddress = $SeriesHeader[$idx] -replace '^=', '' }
else {$Series.Header = $SeriesHeader[$idx] } else { $Series.Header = $SeriesHeader[$idx] }
} }
else { $Series.Header = "Series $($idx)"} else { $Series.Header = "Series $($idx)" }
} }
} }
} }
if ($Title) { if ($Title) {
$chart.Title.Text = $Title $chart.Title.Text = $Title
if ($TitleBold) {$chart.Title.Font.Bold = $true} if ($TitleBold) { $chart.Title.Font.Bold = $true }
if ($TitleSize) {$chart.Title.Font.Size = $TitleSize} if ($TitleSize) { $chart.Title.Font.Size = $TitleSize }
} }
if ($NoLegend) { $chart.Legend.Remove() } if ($NoLegend) { $chart.Legend.Remove() }
else { else {
if ($PSBoundParameters.ContainsKey('LegendPosition')) {$chart.Legend.Position = $LegendPosition} if ($PSBoundParameters.ContainsKey('LegendPosition')) { $chart.Legend.Position = $LegendPosition }
if ($PSBoundParameters.ContainsKey('LegendBold')) {$chart.Legend.Font.Bold = [boolean]$LegendBold} if ($PSBoundParameters.ContainsKey('LegendBold')) { $chart.Legend.Font.Bold = [boolean]$LegendBold }
if ($LegendSize) {$chart.Legend.Font.Size = $LegendSize} if ($LegendSize) { $chart.Legend.Font.Size = $LegendSize }
} }
if ($XAxisTitleText) { if ($XAxisTitleText) {
$chart.XAxis.Title.Text = $XAxisTitleText $chart.XAxis.Title.Text = $XAxisTitleText
if ($PSBoundParameters.ContainsKey('XAxisTitleBold')) { if ($PSBoundParameters.ContainsKey('XAxisTitleBold')) {
$chart.XAxis.Title.Font.Bold = [boolean]$XAxisTitleBold $chart.XAxis.Title.Font.Bold = [boolean]$XAxisTitleBold
} }
if ($XAxisTitleSize) {$chart.XAxis.Title.Font.Size = $XAxisTitleSize} if ($XAxisTitleSize) { $chart.XAxis.Title.Font.Size = $XAxisTitleSize }
} }
if ($XAxisPosition) {Write-Warning "X-axis position is not being set propertly at the moment, parameter ignored" } 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)} #$chart.ChartXml.chartSpace.chart.plotArea.catAx.axPos.val = $XAxisPosition.ToString().substring(0,1)}
if ($XMajorUnit) {$chart.XAxis.MajorUnit = $XMajorUnit} if ($XMajorUnit) { $chart.XAxis.MajorUnit = $XMajorUnit }
if ($XMinorUnit) {$chart.XAxis.MinorUnit = $XMinorUnit} if ($XMinorUnit) { $chart.XAxis.MinorUnit = $XMinorUnit }
if ($null -ne $XMinValue) {$chart.XAxis.MinValue = $XMinValue} if ($null -ne $XMinValue) { $chart.XAxis.MinValue = $XMinValue }
if ($null -ne $XMaxValue) {$chart.XAxis.MaxValue = $XMaxValue} if ($null -ne $XMaxValue) { $chart.XAxis.MaxValue = $XMaxValue }
if ($XAxisNumberformat) {$chart.XAxis.Format = (Expand-NumberFormat $XAxisNumberformat)} if ($XAxisNumberformat) { $chart.XAxis.Format = (Expand-NumberFormat $XAxisNumberformat) }
if ($YAxisTitleText) { if ($YAxisTitleText) {
$chart.YAxis.Title.Text = $YAxisTitleText $chart.YAxis.Title.Text = $YAxisTitleText
if ($PSBoundParameters.ContainsKey('YAxisTitleBold')) { if ($PSBoundParameters.ContainsKey('YAxisTitleBold')) {
$chart.YAxis.Title.Font.Bold = [boolean]$YAxisTitleBold $chart.YAxis.Title.Font.Bold = [boolean]$YAxisTitleBold
} }
if ($YAxisTitleSize) {$chart.YAxis.Title.Font.Size = $YAxisTitleSize} if ($YAxisTitleSize) { $chart.YAxis.Title.Font.Size = $YAxisTitleSize }
} }
if ($YAxisPosition) {Write-Warning "Y-axis position is not being set propertly at the moment, parameter ignored" } 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)} #$chart.ChartXml.chartSpace.chart.plotArea.valAx.axPos.val= $YAxisPosition.ToString().substring(0,1)}
if ($YMajorUnit) {$chart.YAxis.MajorUnit = $YMajorUnit} if ($YMajorUnit) { $chart.YAxis.MajorUnit = $YMajorUnit }
if ($YMinorUnit) {$chart.YAxis.MinorUnit = $YMinorUnit} if ($YMinorUnit) { $chart.YAxis.MinorUnit = $YMinorUnit }
if ($null -ne $YMinValue){$chart.YAxis.MinValue = $YMinValue} if ($null -ne $YMinValue) { $chart.YAxis.MinValue = $YMinValue }
if ($null -ne $YMaxValue){$chart.YAxis.MaxValue = $YMaxValue} if ($null -ne $YMaxValue) { $chart.YAxis.MaxValue = $YMaxValue }
if ($YAxisNumberformat) {$chart.YAxis.Format = (Expand-NumberFormat $YAxisNumberformat)} if ($YAxisNumberformat) { $chart.YAxis.Format = (Expand-NumberFormat $YAxisNumberformat) }
if ($null -ne $chart.Datalabel) { if ($null -ne $chart.Datalabel) {
$chart.Datalabel.ShowCategory = [boolean]$ShowCategory $chart.Datalabel.ShowCategory = [boolean]$ShowCategory
$chart.Datalabel.ShowPercent = [boolean]$ShowPercent $chart.Datalabel.ShowPercent = [boolean]$ShowPercent
} }
$chart.SetPosition($Row, $RowOffsetPixels, $Column, $ColumnOffsetPixels) $chart.SetPosition($Row, $RowOffsetPixels, $Column, $ColumnOffsetPixels)
$chart.SetSize($Width, $Height) $chart.SetSize($Width, $Height)
if ($PassThru) {return $chart} if ($PassThru) { return $chart }
} }
catch {Write-Warning -Message "Failed adding Chart to worksheet '$($WorkSheet).name': $_"} catch { Write-Warning -Message "Failed adding Chart to worksheet '$($WorkSheet).name': $_" }
} }

View File

@@ -53,6 +53,26 @@ Install-Module ImportExcel -scope CurrentUser
Install-Module ImportExcel Install-Module ImportExcel
``` ```
# What's new 6.2.1
- Added requested feature, chart trendlines.
- [Example PowerShell script](https://github.com/dfinke/ImportExcel/blob/master/Examples/Charts/NumberOfVisitors.ps1)
![](/images/ChartTrendlines.png)
# What's new 6.2.2
- Fixed Import-Excel and relative path issue, added unit tests.
# What's new 6.2.0
Thank you to [James O'Neill](https://github.com/jhoneill)
- Fixed, Import-Excel can read xlsx files even if already open in Excel
- Added `New-ExcelStyle`, plus `-Style` to `Export-Excel` and `-Merge` to `Set-ExcelRange`
- Added [Style Examples](https://github.com/dfinke/ImportExcel/tree/master/Examples/Styles)
![](https://raw.githubusercontent.com/dfinke/ImportExcel/master/images/NewExcelStyle.png)
# What's new 6.1.0 # What's new 6.1.0
Thank you to [James O'Neill](https://github.com/jhoneill) Thank you to [James O'Neill](https://github.com/jhoneill)

View File

@@ -1,4 +1,4 @@
Function Set-ExcelRange { function Set-ExcelRange {
<# <#
.SYNOPSIS .SYNOPSIS
Applies number, font, alignment and/or color formatting, values or formulas to a range of Excel cells. Applies number, font, alignment and/or color formatting, values or formulas to a range of Excel cells.
@@ -56,6 +56,7 @@
#Style for the right border. #Style for the right border.
[OfficeOpenXml.Style.ExcelBorderStyle]$BorderRight, [OfficeOpenXml.Style.ExcelBorderStyle]$BorderRight,
#Colour for the text - if none is specified it will be left as it is. #Colour for the text - if none is specified it will be left as it is.
[Alias('ForegroundColor')]
$FontColor, $FontColor,
#Value for the cell. #Value for the cell.
$Value, $Value,
@@ -107,7 +108,9 @@
#Hide a row or column (not a range); use -Hidden:$false to unhide. #Hide a row or column (not a range); use -Hidden:$false to unhide.
[Switch]$Hidden, [Switch]$Hidden,
#Locks cells. Cells are locked by default use -locked:$false on the whole sheet and then lock specific ones, and enable protection on the sheet. #Locks cells. Cells are locked by default use -locked:$false on the whole sheet and then lock specific ones, and enable protection on the sheet.
[Switch]$Locked [Switch]$Locked,
#Merges cells - it is recommended that you explicitly set -HorizontalAlignment
[Switch]$Merge
) )
process { process {
if ($Range -is [Array]) { if ($Range -is [Array]) {
@@ -168,6 +171,9 @@
if ($PSBoundParameters.ContainsKey('VerticalAlignment')) { if ($PSBoundParameters.ContainsKey('VerticalAlignment')) {
$Range.Style.VerticalAlignment = $VerticalAlignment $Range.Style.VerticalAlignment = $VerticalAlignment
} }
if ($PSBoundParameters.ContainsKey('Merge')) {
$Range.Merge = [boolean]$Merge
}
if ($PSBoundParameters.ContainsKey('Value')) { if ($PSBoundParameters.ContainsKey('Value')) {
if ($Value -match '^=') {$PSBoundParameters["Formula"] = $Value -replace '^=','' } if ($Value -match '^=') {$PSBoundParameters["Formula"] = $Value -replace '^=','' }
else { else {
@@ -251,7 +257,7 @@
} }
} }
Function NumberFormatCompletion { function NumberFormatCompletion {
param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter) param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter)
$numformats = [ordered]@{ $numformats = [ordered]@{
"General" = "General" # format ID 0 "General" = "General" # format ID 0
@@ -294,6 +300,7 @@ Function NumberFormatCompletion {
if (Get-Command -ErrorAction SilentlyContinue -name Register-ArgumentCompleter) { if (Get-Command -ErrorAction SilentlyContinue -name Register-ArgumentCompleter) {
Register-ArgumentCompleter -CommandName Add-ConditionalFormatting -ParameterName NumberFormat -ScriptBlock $Function:NumberFormatCompletion Register-ArgumentCompleter -CommandName Add-ConditionalFormatting -ParameterName NumberFormat -ScriptBlock $Function:NumberFormatCompletion
Register-ArgumentCompleter -CommandName Export-Excel -ParameterName NumberFormat -ScriptBlock $Function:NumberFormatCompletion Register-ArgumentCompleter -CommandName Export-Excel -ParameterName NumberFormat -ScriptBlock $Function:NumberFormatCompletion
Register-ArgumentCompleter -CommandName New-ExcelStyle -ParameterName NumberFormat -ScriptBlock $Function:NumberFormatCompletion
Register-ArgumentCompleter -CommandName Set-ExcelRange -ParameterName NumberFormat -ScriptBlock $Function:NumberFormatCompletion Register-ArgumentCompleter -CommandName Set-ExcelRange -ParameterName NumberFormat -ScriptBlock $Function:NumberFormatCompletion
Register-ArgumentCompleter -CommandName Set-ExcelColumn -ParameterName NumberFormat -ScriptBlock $Function:NumberFormatCompletion Register-ArgumentCompleter -CommandName Set-ExcelColumn -ParameterName NumberFormat -ScriptBlock $Function:NumberFormatCompletion
Register-ArgumentCompleter -CommandName Set-ExcelRow -ParameterName NumberFormat -ScriptBlock $Function:NumberFormatCompletion Register-ArgumentCompleter -CommandName Set-ExcelRow -ParameterName NumberFormat -ScriptBlock $Function:NumberFormatCompletion
@@ -305,7 +312,27 @@ if (Get-Command -ErrorAction SilentlyContinue -name Register-ArgumentCompleter)
Register-ArgumentCompleter -CommandName Add-ExcelChart -ParameterName YAxisNumberformat -ScriptBlock $Function:NumberFormatCompletion Register-ArgumentCompleter -CommandName Add-ExcelChart -ParameterName YAxisNumberformat -ScriptBlock $Function:NumberFormatCompletion
} }
Function Expand-NumberFormat { function ListFonts {
param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter)
if (-not $script:FontFamilies) {
$script:FontFamilies = @("","")
try {
$script:FontFamilies = (New-Object System.Drawing.Text.InstalledFontCollection).Families.Name
}
catch {}
}
$script:FontFamilies.where({$_ -Gt "" -and $_ -like "$wordToComplete*"} ) | ForEach-Object {
New-Object -TypeName System.Management.Automation.CompletionResult -ArgumentList "'$_'" , $_ ,
([System.Management.Automation.CompletionResultType]::ParameterValue) , $_
}
}
if (Get-Command -ErrorAction SilentlyContinue -name Register-ArgumentCompleter) {
Register-ArgumentCompleter -CommandName New-ExcelStyle -ParameterName FontName -ScriptBlock $Function:ListFonts
Register-ArgumentCompleter -CommandName Set-ExcelColumn -ParameterName FontName -ScriptBlock $Function:ListFonts
Register-ArgumentCompleter -CommandName Set-ExcelRange -ParameterName FontName -ScriptBlock $Function:ListFonts
Register-ArgumentCompleter -CommandName Set-ExcelRow -ParameterName FontName -ScriptBlock $Function:ListFonts
}
function Expand-NumberFormat {
<# <#
.SYNOPSIS .SYNOPSIS
Converts short names for number formats to the formatting strings used in Excel Converts short names for number formats to the formatting strings used in Excel
@@ -381,3 +408,81 @@ Function Expand-NumberFormat {
Default {return $NumberFormat} Default {return $NumberFormat}
} }
} }
function New-ExcelStyle {
param (
[Alias("Address")]
$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.
[Alias("NFormat")]
$NumberFormat,
#Style of border to draw around the range.
[OfficeOpenXml.Style.ExcelBorderStyle]$BorderAround,
#Color of the border.
$BorderColor=[System.Drawing.Color]::Black,
#Style for the bottom border.
[OfficeOpenXml.Style.ExcelBorderStyle]$BorderBottom,
#Style for the top border.
[OfficeOpenXml.Style.ExcelBorderStyle]$BorderTop,
#Style for the left border.
[OfficeOpenXml.Style.ExcelBorderStyle]$BorderLeft,
#Style for the right border.
[OfficeOpenXml.Style.ExcelBorderStyle]$BorderRight,
#Colour for the text - if none is specified it will be left as it is.
[Alias('ForegroundColor')]
$FontColor,
#Value for the cell.
$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 color to Black.
[Switch]$ResetFont,
#Make text bold; use -Bold:$false to remove bold.
[Switch]$Bold,
#Make text italic; use -Italic:$false to remove italic.
[Switch]$Italic,
#Underline the text using the underline style in -UnderlineType; use -Underline:$false to remove underlining.
[Switch]$Underline,
#Specifies whether underlining should be single or double, normal or accounting mode. The default is "Single".
[OfficeOpenXml.Style.ExcelUnderLineType]$UnderLineType = [OfficeOpenXml.Style.ExcelUnderLineType]::Single,
#Strike through text; use -Strikethru:$false to remove Strike through
[Switch]$StrikeThru,
#Subscript or Superscript (or none).
[OfficeOpenXml.Style.ExcelVerticalAlignmentFont]$FontShift,
#Font to use - Excel defaults to Calibri.
[String]$FontName,
#Point size for the text.
[float]$FontSize,
#Change background color.
$BackgroundColor,
#Background pattern - Solid by default.
[OfficeOpenXml.Style.ExcelFillStyle]$BackgroundPattern = [OfficeOpenXml.Style.ExcelFillStyle]::Solid ,
#Secondary color for background pattern.
[Alias("PatternColour")]
$PatternColor,
#Turn on Text-Wrapping; use -WrapText:$false to turn off wrapping.
[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.
[OfficeOpenXml.Style.ExcelVerticalAlignment]$VerticalAlignment,
#Degrees to rotate text. Up to +90 for anti-clockwise ("upwards"), or to -90 for clockwise.
[ValidateRange(-90, 90)]
[int]$TextRotation ,
#Autofit cells to width (columns or ranges only).
[Alias("AutoFit")]
[Switch]$AutoSize,
#Set cells to a fixed width (columns or ranges only), ignored if Autosize is specified.
[float]$Width,
#Set cells to a fixed height (rows or ranges only).
[float]$Height,
#Hide a row or column (not a range); use -Hidden:$false to unhide.
[Switch]$Hidden,
#Locks cells. Cells are locked by default use -locked:$false on the whole sheet and then lock specific ones, and enable protection on the sheet.
[Switch]$Locked,
[Switch]$Merge
)
$PSBoundParameters
}

View File

@@ -0,0 +1,49 @@
Describe "Test adding trendlines to charts" {
BeforeAll {
$script:data = ConvertFrom-Csv @"
Region,Item,TotalSold
West,screws,60
South,lemon,48
South,apple,71
East,screwdriver,70
East,kiwi,32
West,screwdriver,1
South,melon,21
East,apple,79
South,apple,68
South,avocado,73
"@
}
BeforeEach {
$xlfile = "$env:TEMP\trendLine.xlsx"
Remove-Item $xlfile -ErrorAction SilentlyContinue
}
It "Should add a linear trendline" {
$cd = New-ExcelChartDefinition -XRange Region -YRange TotalSold -ChartType ColumnClustered -ChartTrendLine Linear
$data | Export-Excel $xlfile -ExcelChartDefinition $cd -AutoNameRange
$excel = Open-ExcelPackage -Path $xlfile
$ws = $excel.Workbook.Worksheets["Sheet1"]
$ws.Drawings[0].Series.TrendLines.Type | Should Be 'Linear'
Close-ExcelPackage $excel
}
It "Should add a MovingAvgerage trendline" {
$cd = New-ExcelChartDefinition -XRange Region -YRange TotalSold -ChartType ColumnClustered -ChartTrendLine MovingAvgerage
$data | Export-Excel $xlfile -ExcelChartDefinition $cd -AutoNameRange
$excel = Open-ExcelPackage -Path $xlfile
$ws = $excel.Workbook.Worksheets["Sheet1"]
$ws.Drawings[0].Series.TrendLines.Type | Should Be 'MovingAvgerage'
Close-ExcelPackage $excel
}
}

View File

@@ -1,6 +1,6 @@
Import-Module $PSScriptRoot\..\ImportExcel.psd1 -Force Import-Module $PSScriptRoot\..\ImportExcel.psd1 -Force
$xlFile = ".\testSQL.xlsx" $xlFile = "$env:TEMP\testSQL.xlsx"
Describe "ConvertFrom-ExcelToSQLInsert" { Describe "ConvertFrom-ExcelToSQLInsert" {

38
__tests__/Path.tests.ps1 Normal file
View File

@@ -0,0 +1,38 @@
Describe "Test reading relative paths" {
BeforeAll {
$script:xlfileName = "TestR.xlsx"
@{data = 1 } | Export-Excel "$pwd\TestR.xlsx"
}
AfterAll {
Remove-Item "$pwd\$($script:xlfileName)"
}
It "Should read local file" {
$actual = Import-Excel -Path ".\$($script:xlfileName)"
$actual | Should Not Be $null
$actual.Count | Should Be 1
}
It "Should read with pwd" {
$actual = Import-Excel -Path "$pwd\$($script:xlfileName)"
$actual | Should Not Be $null
}
It "Should read with just a file name and resolve to cwd" {
$actual = Import-Excel -Path "$($script:xlfileName)"
$actual | Should Not Be $null
}
It "Should fail for not found" {
{ Import-Excel -Path "ExcelFileDoesNotExist.xlsx" } | Should Throw "'ExcelFileDoesNotExist.xlsx' file not found"
}
It "Should fail for xls extension" {
{ Import-Excel -Path "ExcelFileDoesNotExist.xls" } | Should Throw "Import-Excel does not support reading this extension type .xls"
}
It "Should fail for xlsxs extension" {
{ Import-Excel -Path "ExcelFileDoesNotExist.xlsxs" } | Should Throw "Import-Excel does not support reading this extension type .xlsxs"
}
}

BIN
__tests__/testRelative.xlsx Normal file

Binary file not shown.

View File

@@ -12,4 +12,4 @@ steps:
trigger: trigger:
paths: paths:
exclude: exclude:
- README.md - README.md

BIN
images/ChartTrendlines.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

BIN
images/NewExcelStyle.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB