From d8237619706c72972639c0f3ea81dacd13c0f45e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 22 Sep 2025 11:31:26 +0000 Subject: [PATCH] Implement gradient fill functions to resolve issue #1720 Co-authored-by: dfinke <67258+dfinke@users.noreply.github.com> --- GRADIENT_GUIDE.md | 152 +++++++++++++++++++++ ImportExcel.psd1 | 3 + Public/Copy-ExcelGradientFill.ps1 | 119 ++++++++++++++++ Public/Get-ExcelGradientFill.ps1 | 52 +++++++ Public/Set-ExcelGradientFill.ps1 | 128 +++++++++++++++++ README.md | 10 ++ __tests__/GradientFill.tests.ps1 | 219 ++++++++++++++++++++++++++++++ 7 files changed, 683 insertions(+) create mode 100644 GRADIENT_GUIDE.md create mode 100644 Public/Copy-ExcelGradientFill.ps1 create mode 100644 Public/Get-ExcelGradientFill.ps1 create mode 100644 Public/Set-ExcelGradientFill.ps1 create mode 100644 __tests__/GradientFill.tests.ps1 diff --git a/GRADIENT_GUIDE.md b/GRADIENT_GUIDE.md new file mode 100644 index 0000000..f793e99 --- /dev/null +++ b/GRADIENT_GUIDE.md @@ -0,0 +1,152 @@ +# Working with Gradient Fills in ImportExcel + +## Overview + +ImportExcel now provides enhanced support for working with Excel gradient fills through three new functions that address EPPlus 4.x limitations with gradient color reading. + +## The Issue + +In EPPlus 4.x (used by ImportExcel), while gradient colors can be set using `SetColor()`, they cannot be read back via properties like `Rgb`, `Top`, `Bottom`, `Left`, `Right`. This prevents copying gradients between cells. + +## The Solution + +Three new functions provide a complete gradient workflow: + +### Set-ExcelGradientFill +Sets gradient fill properties for Excel ranges. + +```powershell +# Basic linear gradient +Set-ExcelGradientFill -Range $ws.Cells["A1"] -Type Linear -Degree 90 -Color1 Blue -Color2 Green + +# Path gradient +Set-ExcelGradientFill -Range $ws.Cells["B1"] -Type Path -Color1 Red -Color2 Yellow + +# Advanced linear gradient with positioning +Set-ExcelGradientFill -Range $ws.Cells["C1"] -Type Linear -Degree 45 -Color1 Purple -Color2 Orange -Top 0.1 -Bottom 0.9 +``` + +### Get-ExcelGradientFill +Reads gradient properties that can be reliably extracted from EPPlus. + +```powershell +$gradient = Get-ExcelGradientFill -Range $ws.Cells["A1"] +# Returns: Type, Degree, Top, Bottom, Left, Right +# Note: Color1 and Color2 are null due to EPPlus limitations +``` + +### Copy-ExcelGradientFill +Copies gradient fills between ranges using two approaches: + +#### Approach 1: Copy Geometric Properties Only +```powershell +# Copies Type, Degree, and positioning but warns about colors +Copy-ExcelGradientFill -SourceRange $ws.Cells["A1"] -TargetRange $ws.Cells["B1"] +``` + +#### Approach 2: Complete Gradient Definition +```powershell +# Create a complete gradient definition +$gradientDef = @{ + Type = "Linear" + Degree = 45 + Color1 = [System.Drawing.Color]::Blue + Color2 = [System.Drawing.Color]::Green + Top = 0.2 + Bottom = 0.8 +} + +Copy-ExcelGradientFill -TargetRange $ws.Cells["C1:E3"] -GradientDefinition $gradientDef +``` + +## Complete Example + +```powershell +Import-Module ImportExcel + +$xl = Open-ExcelPackage -Path "gradients.xlsx" -Create +$ws = Add-WorkSheet -ExcelPackage $xl -WorksheetName "Gradients" + +# Set original gradient +Set-ExcelGradientFill -Range $ws.Cells["A1"] -Type Linear -Degree 90 -Color1 Blue -Color2 Green + +# Get gradient properties (geometric only) +$gradientInfo = Get-ExcelGradientFill -Range $ws.Cells["A1"] + +# Create complete definition for copying +$completeDef = @{ + Type = $gradientInfo.Type + Degree = $gradientInfo.Degree + Top = $gradientInfo.Top + Bottom = $gradientInfo.Bottom + Left = $gradientInfo.Left + Right = $gradientInfo.Right + Color1 = [System.Drawing.Color]::Blue # Must specify colors + Color2 = [System.Drawing.Color]::Green +} + +# Copy to other cells +Copy-ExcelGradientFill -TargetRange $ws.Cells["B1:D3"] -GradientDefinition $completeDef + +Close-ExcelPackage -ExcelPackage $xl -SaveAs "gradients.xlsx" +``` + +## Migration from Direct EPPlus Access + +### Before (Limited by EPPlus 4.x): +```powershell +# Setting worked +$Sheet.Cells["A1"].Style.Fill.Gradient.Color1.SetColor("BLUE") +$Sheet.Cells["A1"].Style.Fill.Gradient.Color2.SetColor("GREEN") + +# Reading failed - returned empty values +$rgb = $Sheet.Cells["A1"].Style.Fill.Gradient.Color1.Rgb # Empty! +``` + +### After (Using ImportExcel functions): +```powershell +# Setting is easier and more robust +Set-ExcelGradientFill -Range $Sheet.Cells["A1"] -Type Linear -Degree 90 -Color1 Blue -Color2 Green + +# Reading works for geometric properties +$gradient = Get-ExcelGradientFill -Range $Sheet.Cells["A1"] +# $gradient.Type, $gradient.Degree work; colors need to be specified separately + +# Copying now possible with complete definitions +$gradientDef = @{ + Type = $gradient.Type + Degree = $gradient.Degree + Color1 = [System.Drawing.Color]::Blue + Color2 = [System.Drawing.Color]::Green +} +Copy-ExcelGradientFill -TargetRange $Sheet.Cells["B1"] -GradientDefinition $gradientDef +``` + +## Parameters Reference + +### Set-ExcelGradientFill Parameters +- **Range**: Target Excel range (required) +- **Type**: "Linear" or "Path" (required) +- **Degree**: Angle for linear gradients (0-360, default 90) +- **Color1**: First color - Color object or string name (required) +- **Color2**: Second color - Color object or string name (required) +- **Top/Bottom/Left/Right**: Position values (0-1, optional) + +### Copy-ExcelGradientFill Parameters +- **SourceRange**: Source range (for copying geometric properties) +- **TargetRange**: Target range (required) +- **GradientDefinition**: Hashtable with gradient properties (alternative to SourceRange) + +## Limitations + +- Color properties cannot be read from existing gradients due to EPPlus 4.x limitations +- When copying gradients, colors must be specified manually in the gradient definition +- Functions provide warnings when color limitations affect operations + +## Benefits + +- Clean, PowerShell-friendly interface for gradient operations +- Comprehensive parameter validation +- Clear error messages and warnings +- Supports both string color names and Color objects +- Enables gradient copying workflows that weren't possible before \ No newline at end of file diff --git a/ImportExcel.psd1 b/ImportExcel.psd1 index b9a6148..7df89f2 100644 --- a/ImportExcel.psd1 +++ b/ImportExcel.psd1 @@ -46,6 +46,7 @@ Check out the How To Videos https://www.youtube.com/watch?v=U3Ne_yX4tYo&list=PL5 'ConvertFrom-ExcelSheet', 'ConvertFrom-ExcelToSQLInsert', 'ConvertTo-ExcelXlsx', + 'Copy-ExcelGradientFill', 'Copy-ExcelWorksheet', 'DoChart', 'Enable-ExcelAutoFilter', @@ -56,6 +57,7 @@ Check out the How To Videos https://www.youtube.com/watch?v=U3Ne_yX4tYo&list=PL5 'Get-ExcelColumnName', 'Get-ExcelFileSchema', 'Get-ExcelFileSummary', + 'Get-ExcelGradientFill', 'Get-ExcelSheetDimensionAddress', 'Get-ExcelSheetInfo', 'Get-ExcelWorkbookInfo', @@ -92,6 +94,7 @@ Check out the How To Videos https://www.youtube.com/watch?v=U3Ne_yX4tYo&list=PL5 'Set-CellComment', 'Set-CellStyle', 'Set-ExcelColumn', + 'Set-ExcelGradientFill', 'Set-ExcelRange', 'Set-ExcelRow', 'Set-WorksheetProtection', diff --git a/Public/Copy-ExcelGradientFill.ps1 b/Public/Copy-ExcelGradientFill.ps1 new file mode 100644 index 0000000..3f75e3d --- /dev/null +++ b/Public/Copy-ExcelGradientFill.ps1 @@ -0,0 +1,119 @@ +function Copy-ExcelGradientFill { + <# + .SYNOPSIS + Copies gradient fill settings from one Excel range to another. + + .DESCRIPTION + Due to limitations in EPPlus 4.x, gradient color properties cannot be read directly. + This function provides a workaround by storing gradient definitions and applying them + to target ranges. + + .PARAMETER SourceRange + The source range with the gradient fill to copy. + + .PARAMETER TargetRange + The target range where the gradient fill should be applied. + + .PARAMETER GradientDefinition + A hashtable containing gradient definition with properties: + - Type: Linear or Path + - Degree: Angle for linear gradients (0-360) + - Top, Bottom, Left, Right: Position values (0-1) + - Color1: First color (System.Drawing.Color or color name) + - Color2: Second color (System.Drawing.Color or color name) + + .EXAMPLE + # Copy gradient from A1 to B1:C2 + Copy-ExcelGradientFill -SourceRange $ws.Cells["A1"] -TargetRange $ws.Cells["B1:C2"] + + .EXAMPLE + # Apply a custom gradient definition + $gradient = @{ + Type = "Linear" + Degree = 45 + Color1 = [System.Drawing.Color]::Blue + Color2 = [System.Drawing.Color]::Green + Top = 0 + Bottom = 1 + Left = 0 + Right = 1 + } + Copy-ExcelGradientFill -TargetRange $ws.Cells["A1:B2"] -GradientDefinition $gradient + + .NOTES + This function works around EPPlus 4.x limitations with gradient color reading. + #> + [CmdletBinding(DefaultParameterSetName = 'CopyFromSource')] + param( + [Parameter(ParameterSetName = 'CopyFromSource', Mandatory)] + $SourceRange, + + [Parameter(Mandatory)] + $TargetRange, + + [Parameter(ParameterSetName = 'ApplyDefinition', Mandatory)] + [hashtable]$GradientDefinition + ) + + if ($PSCmdlet.ParameterSetName -eq 'CopyFromSource') { + # Extract gradient properties from source + $sourceGradient = $SourceRange.Style.Fill.Gradient + + # Create gradient definition from source + $GradientDefinition = @{ + Type = $sourceGradient.Type + Degree = $sourceGradient.Degree + Top = $sourceGradient.Top + Bottom = $sourceGradient.Bottom + Left = $sourceGradient.Left + Right = $sourceGradient.Right + } + + # Note: Colors cannot be copied due to EPPlus limitation + Write-Warning "Gradient colors cannot be copied due to EPPlus 4.x limitations. Only geometric properties (Type, Degree, positioning) are copied. Please use Set-ExcelGradientFill to set colors." + } + + # Apply gradient definition to target + $targetGradient = $TargetRange.Style.Fill.Gradient + + if ($GradientDefinition.Type) { + $targetGradient.Type = [OfficeOpenXml.Style.ExcelFillGradientType]::$($GradientDefinition.Type) + } + + if ($GradientDefinition.ContainsKey('Degree')) { + $targetGradient.Degree = $GradientDefinition.Degree + } + + if ($GradientDefinition.ContainsKey('Top')) { + $targetGradient.Top = $GradientDefinition.Top + } + + if ($GradientDefinition.ContainsKey('Bottom')) { + $targetGradient.Bottom = $GradientDefinition.Bottom + } + + if ($GradientDefinition.ContainsKey('Left')) { + $targetGradient.Left = $GradientDefinition.Left + } + + if ($GradientDefinition.ContainsKey('Right')) { + $targetGradient.Right = $GradientDefinition.Right + } + + # Set colors if provided + if ($GradientDefinition.Color1) { + $color1 = $GradientDefinition.Color1 + if ($color1 -is [string]) { + $color1 = [System.Drawing.Color]::$color1 + } + $targetGradient.Color1.SetColor($color1) + } + + if ($GradientDefinition.Color2) { + $color2 = $GradientDefinition.Color2 + if ($color2 -is [string]) { + $color2 = [System.Drawing.Color]::$color2 + } + $targetGradient.Color2.SetColor($color2) + } +} \ No newline at end of file diff --git a/Public/Get-ExcelGradientFill.ps1 b/Public/Get-ExcelGradientFill.ps1 new file mode 100644 index 0000000..ffbd5a6 --- /dev/null +++ b/Public/Get-ExcelGradientFill.ps1 @@ -0,0 +1,52 @@ +function Get-ExcelGradientFill { + <# + .SYNOPSIS + Gets gradient fill properties from an Excel range. + + .DESCRIPTION + This function extracts gradient fill properties that can be reliably read from EPPlus 4.x. + Due to EPPlus limitations, gradient colors cannot be read directly and will return $null. + + .PARAMETER Range + The Excel range to read gradient properties from. + + .EXAMPLE + # Get gradient properties from a cell + $gradientInfo = Get-ExcelGradientFill -Range $ws.Cells["A1"] + + .EXAMPLE + # Get gradient properties and use them to copy to another range + $gradient = Get-ExcelGradientFill -Range $ws.Cells["A1"] + # Add colors since they can't be read + $gradient.Color1 = [System.Drawing.Color]::Blue + $gradient.Color2 = [System.Drawing.Color]::Green + Copy-ExcelGradientFill -TargetRange $ws.Cells["B1:C2"] -GradientDefinition $gradient + + .NOTES + Due to EPPlus 4.x limitations, Color1 and Color2 properties will always be $null. + This function is provided for completeness and to work with Copy-ExcelGradientFill. + #> + [CmdletBinding()] + param( + [Parameter(Mandatory, ValueFromPipeline)] + $Range + ) + + process { + $gradient = $Range.Style.Fill.Gradient + + $result = [PSCustomObject]@{ + Type = $gradient.Type + Degree = $gradient.Degree + Top = $gradient.Top + Bottom = $gradient.Bottom + Left = $gradient.Left + Right = $gradient.Right + Color1 = $null # Cannot be read due to EPPlus 4.x limitation + Color2 = $null # Cannot be read due to EPPlus 4.x limitation + ColorLimitationNote = "Color properties cannot be read due to EPPlus 4.x limitations" + } + + return $result + } +} \ No newline at end of file diff --git a/Public/Set-ExcelGradientFill.ps1 b/Public/Set-ExcelGradientFill.ps1 new file mode 100644 index 0000000..6e6e5e0 --- /dev/null +++ b/Public/Set-ExcelGradientFill.ps1 @@ -0,0 +1,128 @@ +function Set-ExcelGradientFill { + <# + .SYNOPSIS + Sets gradient fill properties for an Excel range. + + .DESCRIPTION + This function provides a complete interface for setting gradient fills in Excel ranges, + working around EPPlus 4.x limitations with gradient handling. + + .PARAMETER Range + The Excel range to apply the gradient fill to. + + .PARAMETER Type + The gradient type: Linear or Path. + + .PARAMETER Degree + The angle for linear gradients (0-360 degrees). + + .PARAMETER Color1 + The first gradient color. Can be a System.Drawing.Color object or color name. + + .PARAMETER Color2 + The second gradient color. Can be a System.Drawing.Color object or color name. + + .PARAMETER Top + The top position for gradient positioning (0-1). + + .PARAMETER Bottom + The bottom position for gradient positioning (0-1). + + .PARAMETER Left + The left position for gradient positioning (0-1). + + .PARAMETER Right + The right position for gradient positioning (0-1). + + .EXAMPLE + # Set a simple blue to green linear gradient + Set-ExcelGradientFill -Range $ws.Cells["A1"] -Type Linear -Degree 90 -Color1 Blue -Color2 Green + + .EXAMPLE + # Set a more complex gradient with positioning + Set-ExcelGradientFill -Range $ws.Cells["A1:C3"] -Type Linear -Degree 45 -Color1 ([System.Drawing.Color]::Red) -Color2 ([System.Drawing.Color]::Yellow) -Top 0.2 -Bottom 0.8 + + .EXAMPLE + # Set a path gradient + Set-ExcelGradientFill -Range $ws.Cells["B1:D3"] -Type Path -Color1 "DarkBlue" -Color2 "LightBlue" + + .NOTES + This function addresses the EPPlus 4.x limitation where gradient colors cannot be read back. + #> + [CmdletBinding()] + [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '', Justification = 'Does not change system state')] + param( + [Parameter(Mandatory, ValueFromPipeline)] + $Range, + + [Parameter(Mandatory)] + [ValidateSet('Linear', 'Path')] + [string]$Type, + + [Parameter()] + [ValidateRange(0, 360)] + [double]$Degree = 90, + + [Parameter(Mandatory)] + $Color1, + + [Parameter(Mandatory)] + $Color2, + + [Parameter()] + [ValidateRange(0, 1)] + [double]$Top, + + [Parameter()] + [ValidateRange(0, 1)] + [double]$Bottom, + + [Parameter()] + [ValidateRange(0, 1)] + [double]$Left, + + [Parameter()] + [ValidateRange(0, 1)] + [double]$Right + ) + + process { + $gradient = $Range.Style.Fill.Gradient + + # Set gradient type + $gradient.Type = [OfficeOpenXml.Style.ExcelFillGradientType]::$Type + + # Set degree for linear gradients + if ($Type -eq 'Linear') { + $gradient.Degree = $Degree + } + + # Set positioning if provided + if ($PSBoundParameters.ContainsKey('Top')) { + $gradient.Top = $Top + } + + if ($PSBoundParameters.ContainsKey('Bottom')) { + $gradient.Bottom = $Bottom + } + + if ($PSBoundParameters.ContainsKey('Left')) { + $gradient.Left = $Left + } + + if ($PSBoundParameters.ContainsKey('Right')) { + $gradient.Right = $Right + } + + # Set colors + if ($Color1 -is [string]) { + $Color1 = [System.Drawing.Color]::$Color1 + } + $gradient.Color1.SetColor($Color1) + + if ($Color2 -is [string]) { + $Color2 = [System.Drawing.Color]::$Color2 + } + $gradient.Color2.SetColor($Color2) + } +} \ No newline at end of file diff --git a/README.md b/README.md index 01b50a2..b9dea6a 100644 --- a/README.md +++ b/README.md @@ -191,4 +191,14 @@ ForEach-Object { $_.Value | Export-Csv ($_.key + '.csv') } ## Contributing Contributions are welcome! Open a pull request to fix a bug, or open an issue to discuss a new feature or change. +## New Features + +### Gradient Fill Support +ImportExcel now includes enhanced gradient fill support with three new functions: +- `Set-ExcelGradientFill` - Apply gradient fills to Excel ranges +- `Get-ExcelGradientFill` - Read gradient properties from ranges +- `Copy-ExcelGradientFill` - Copy gradients between ranges + +These functions work around EPPlus 4.x limitations with gradient color reading. See [GRADIENT_GUIDE.md](GRADIENT_GUIDE.md) for detailed usage examples. + Original [README.md](./README.original.md) \ No newline at end of file diff --git a/__tests__/GradientFill.tests.ps1 b/__tests__/GradientFill.tests.ps1 new file mode 100644 index 0000000..c013db8 --- /dev/null +++ b/__tests__/GradientFill.tests.ps1 @@ -0,0 +1,219 @@ +Describe "Gradient Fill Functions" { + BeforeAll { + $script:testPath = "TestDrive:\GradientTest.xlsx" + Remove-Item -Path $testPath -ErrorAction SilentlyContinue + + # Import the module + Import-Module "$PSScriptRoot\..\ImportExcel.psd1" -Force + } + + Context "Set-ExcelGradientFill Tests" { + BeforeEach { + $script:xl = Open-ExcelPackage -Path $testPath -Create + $script:ws = Add-WorkSheet -ExcelPackage $xl -WorksheetName "GradientTest" + } + + AfterEach { + Close-ExcelPackage -ExcelPackage $xl + Remove-Item -Path $testPath -ErrorAction SilentlyContinue + } + + It "Should set linear gradient with basic properties" { + Set-ExcelGradientFill -Range $ws.Cells["A1"] -Type Linear -Degree 90 -Color1 Blue -Color2 Green + + $gradient = $ws.Cells["A1"].Style.Fill.Gradient + $gradient.Type | Should -Be "Linear" + $gradient.Degree | Should -Be 90 + } + + It "Should set path gradient" { + Set-ExcelGradientFill -Range $ws.Cells["A1"] -Type Path -Color1 Red -Color2 Yellow + + $gradient = $ws.Cells["A1"].Style.Fill.Gradient + $gradient.Type | Should -Be "Path" + } + + It "Should set linear gradient with positioning" { + Set-ExcelGradientFill -Range $ws.Cells["A1"] -Type Linear -Degree 45 -Color1 Blue -Color2 Green -Top 0.2 -Bottom 0.8 -Left 0.1 -Right 0.9 + + $gradient = $ws.Cells["A1"].Style.Fill.Gradient + $gradient.Type | Should -Be "Linear" + $gradient.Degree | Should -Be 45 + $gradient.Top | Should -Be 0.2 + $gradient.Bottom | Should -Be 0.8 + $gradient.Left | Should -Be 0.1 + $gradient.Right | Should -Be 0.9 + } + + It "Should accept System.Drawing.Color objects" { + Set-ExcelGradientFill -Range $ws.Cells["A1"] -Type Linear -Color1 ([System.Drawing.Color]::Red) -Color2 ([System.Drawing.Color]::Blue) + + $gradient = $ws.Cells["A1"].Style.Fill.Gradient + $gradient.Type | Should -Be "Linear" + } + + It "Should work with ranges" { + Set-ExcelGradientFill -Range $ws.Cells["A1:C3"] -Type Linear -Degree 135 -Color1 "Purple" -Color2 "Orange" + + $gradient = $ws.Cells["A1"].Style.Fill.Gradient + $gradient.Type | Should -Be "Linear" + $gradient.Degree | Should -Be 135 + } + + It "Should validate degree range" { + { Set-ExcelGradientFill -Range $ws.Cells["A1"] -Type Linear -Degree 400 -Color1 Blue -Color2 Green } | Should -Throw + } + + It "Should validate position range" { + { Set-ExcelGradientFill -Range $ws.Cells["A1"] -Type Linear -Color1 Blue -Color2 Green -Top 1.5 } | Should -Throw + } + } + + Context "Get-ExcelGradientFill Tests" { + BeforeEach { + $script:xl = Open-ExcelPackage -Path $testPath -Create + $script:ws = Add-WorkSheet -ExcelPackage $xl -WorksheetName "GradientTest" + } + + AfterEach { + Close-ExcelPackage -ExcelPackage $xl + Remove-Item -Path $testPath -ErrorAction SilentlyContinue + } + + It "Should get gradient properties that can be read" { + # Set a gradient first + Set-ExcelGradientFill -Range $ws.Cells["A1"] -Type Linear -Degree 45 -Color1 Blue -Color2 Green -Top 0.3 -Bottom 0.7 + + $result = Get-ExcelGradientFill -Range $ws.Cells["A1"] + + $result.Type | Should -Be "Linear" + $result.Degree | Should -Be 45 + $result.Top | Should -Be 0.3 + $result.Bottom | Should -Be 0.7 + $result.Color1 | Should -BeNullOrEmpty + $result.Color2 | Should -BeNullOrEmpty + $result.ColorLimitationNote | Should -Match "EPPlus.*limitation" + } + + It "Should return PSCustomObject with expected properties" { + Set-ExcelGradientFill -Range $ws.Cells["A1"] -Type Path -Color1 Red -Color2 Blue + + $result = Get-ExcelGradientFill -Range $ws.Cells["A1"] + + $result | Should -BeOfType [PSCustomObject] + $result.PSObject.Properties.Name | Should -Contain "Type" + $result.PSObject.Properties.Name | Should -Contain "Degree" + $result.PSObject.Properties.Name | Should -Contain "Color1" + $result.PSObject.Properties.Name | Should -Contain "Color2" + $result.PSObject.Properties.Name | Should -Contain "ColorLimitationNote" + } + } + + Context "Copy-ExcelGradientFill Tests" { + BeforeEach { + $script:xl = Open-ExcelPackage -Path $testPath -Create + $script:ws = Add-WorkSheet -ExcelPackage $xl -WorksheetName "GradientTest" + } + + AfterEach { + Close-ExcelPackage -ExcelPackage $xl + Remove-Item -Path $testPath -ErrorAction SilentlyContinue + } + + It "Should copy gradient geometric properties from source to target" { + # Set up source + Set-ExcelGradientFill -Range $ws.Cells["A1"] -Type Linear -Degree 60 -Color1 Blue -Color2 Green -Top 0.1 -Bottom 0.9 + + # Copy to target (should warn about colors) + $warningVar = $null + Copy-ExcelGradientFill -SourceRange $ws.Cells["A1"] -TargetRange $ws.Cells["B1"] -WarningVariable warningVar + + $targetGradient = $ws.Cells["B1"].Style.Fill.Gradient + $targetGradient.Type | Should -Be "Linear" + $targetGradient.Degree | Should -Be 60 + $targetGradient.Top | Should -Be 0.1 + $targetGradient.Bottom | Should -Be 0.9 + + $warningVar | Should -Match "cannot be copied" + } + + It "Should apply custom gradient definition" { + $gradientDef = @{ + Type = "Linear" + Degree = 120 + Color1 = [System.Drawing.Color]::Purple + Color2 = [System.Drawing.Color]::Yellow + Top = 0.25 + Bottom = 0.75 + Left = 0.2 + Right = 0.8 + } + + Copy-ExcelGradientFill -TargetRange $ws.Cells["C1"] -GradientDefinition $gradientDef + + $gradient = $ws.Cells["C1"].Style.Fill.Gradient + $gradient.Type | Should -Be "Linear" + $gradient.Degree | Should -Be 120 + $gradient.Top | Should -Be 0.25 + $gradient.Bottom | Should -Be 0.75 + $gradient.Left | Should -Be 0.2 + $gradient.Right | Should -Be 0.8 + } + + It "Should apply gradient definition with string colors" { + $gradientDef = @{ + Type = "Path" + Color1 = "Red" + Color2 = "Blue" + } + + Copy-ExcelGradientFill -TargetRange $ws.Cells["D1:F3"] -GradientDefinition $gradientDef + + $gradient = $ws.Cells["D1"].Style.Fill.Gradient + $gradient.Type | Should -Be "Path" + } + } + + Context "Integration Tests" { + BeforeEach { + $script:xl = Open-ExcelPackage -Path $testPath -Create + $script:ws = Add-WorkSheet -ExcelPackage $xl -WorksheetName "GradientTest" + } + + AfterEach { + Close-ExcelPackage -ExcelPackage $xl + Remove-Item -Path $testPath -ErrorAction SilentlyContinue + } + + It "Should work with the original issue scenario" { + # Reproduce the original issue scenario but with new functions + Set-ExcelGradientFill -Range $ws.Cells["A1"] -Type Linear -Degree 90 -Color1 Blue -Color2 Green + + # Get gradient info (which will have limited color info) + $gradientInfo = Get-ExcelGradientFill -Range $ws.Cells["A1"] + + # Should be able to copy geometric properties + $gradientInfo.Type | Should -Be "Linear" + $gradientInfo.Degree | Should -Be 90 + + # Should be able to create a complete gradient definition for copying + $completeDef = @{ + Type = $gradientInfo.Type + Degree = $gradientInfo.Degree + Top = $gradientInfo.Top + Bottom = $gradientInfo.Bottom + Left = $gradientInfo.Left + Right = $gradientInfo.Right + Color1 = [System.Drawing.Color]::Blue # Need to specify colors + Color2 = [System.Drawing.Color]::Green + } + + # Should be able to copy to another cell + Copy-ExcelGradientFill -TargetRange $ws.Cells["B1"] -GradientDefinition $completeDef + + $targetGradient = $ws.Cells["B1"].Style.Fill.Gradient + $targetGradient.Type | Should -Be "Linear" + $targetGradient.Degree | Should -Be 90 + } + } +} \ No newline at end of file