From 1cbefd6793e317d63c9678d7daec793c06dae25f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ossian=20Edstr=C3=B6m?= Date: Thu, 11 Sep 2025 13:50:57 +0200 Subject: [PATCH] Freezepanes now handles it appropriately if some rows are visible and some hidden before the frozen node --- src/EPPlus/ExcelWorksheetView.cs | 25 +++++++-- src/EPPlusTest/Issues/LegacyTests/Issues.cs | 31 ++++++++--- src/EPPlusTest/Issues/WorksheetIssues.cs | 61 +++++++++++++++++++++ 3 files changed, 104 insertions(+), 13 deletions(-) diff --git a/src/EPPlus/ExcelWorksheetView.cs b/src/EPPlus/ExcelWorksheetView.cs index ac6b1b855..ee462c909 100644 --- a/src/EPPlus/ExcelWorksheetView.cs +++ b/src/EPPlus/ExcelWorksheetView.cs @@ -646,6 +646,9 @@ public void FreezePanes(int Row, int Column) int hiddenCols = 0; int hiddenRows = 0; + int? firstVisibleRow = null; + int? firstVisibleColumn = null; + for (int i = 1; i < Column; i++) { var col = _worksheet.Column(i); @@ -653,16 +656,28 @@ public void FreezePanes(int Row, int Column) { hiddenCols++; } + else if(firstVisibleColumn == null) + { + firstVisibleColumn = i; + } } - foreach (var row in _worksheet.Rows[0, Row]) + for (int i = 1; i < Row; i++) { - if (row.Hidden == true) + if (_worksheet.Row(i).Hidden == true) { hiddenRows++; } + else if(firstVisibleRow == null) + { + firstVisibleRow = i; + } } + firstVisibleColumn = firstVisibleColumn ?? 1 + hiddenCols; + firstVisibleRow = firstVisibleRow ?? 1 + hiddenRows; + + var visibleRows = Row - hiddenRows; var visibleColumns = Column - hiddenCols; @@ -689,11 +704,11 @@ public void FreezePanes(int Row, int Column) //TopLeftCell must be topLeft Visible cell for the topnode if(TopLeftCell == "") { - TopLeftCell = ExcelCellBase.GetAddress(1 + hiddenRows, 1 + hiddenCols); + TopLeftCell = ExcelCellBase.GetAddress(firstVisibleRow.Value, firstVisibleColumn.Value); } - if (Column > 1) PaneSettings.XSplit = visibleColumns - 1; - if (Row > 1) PaneSettings.YSplit = visibleRows - 1; + if (Column > 1) PaneSettings.XSplit = Column - firstVisibleColumn.Value; + if (Row > 1) PaneSettings.YSplit = Row - firstVisibleRow.Value; PaneSettings.TopLeftCell = ExcelCellBase.GetAddress(Row, Column); PaneSettings.State = isSplit ? ePaneState.FrozenSplit : ePaneState.Frozen; diff --git a/src/EPPlusTest/Issues/LegacyTests/Issues.cs b/src/EPPlusTest/Issues/LegacyTests/Issues.cs index 237ae0e8a..fe77b1a36 100644 --- a/src/EPPlusTest/Issues/LegacyTests/Issues.cs +++ b/src/EPPlusTest/Issues/LegacyTests/Issues.cs @@ -2601,31 +2601,46 @@ internal void FreezePaneBase(ExcelPackage p, int sheetNum, int hiddenCol, int hi var hiddenCols = 0; var hiddenRows = 0; - for (int i = 1; i < address.Start.Column; i++) + int? firstVisibleRow = null; + int? firstVisibleColumn = null; + + for (int i = 1; i < col; i++) { - var coVar = ws.Column(i); - if (coVar != null && coVar.Hidden) + var currentCol = ws.Column(i); + if (currentCol != null && currentCol.Hidden) { hiddenCols++; } + else if (firstVisibleColumn == null) + { + firstVisibleColumn = i; + } } - foreach (var rowVar in ws.Rows[0, address.Start.Row]) + for (int i = 1; i < row; i++) { - if (rowVar.Hidden == true) + if (ws.Row(i).Hidden == true) { hiddenRows++; } + else if (firstVisibleRow == null) + { + firstVisibleRow = i; + } } + firstVisibleColumn = firstVisibleColumn ?? 1 + hiddenCols; + firstVisibleRow = firstVisibleRow ?? 1 + hiddenRows; + + var visibleRows = row - hiddenRows; var visibleColumns = col - hiddenCols; - + if(visibleColumns != 1 && visibleRows != 1) { Assert.AreEqual(ws.Cells[1 + hiddenRows, 1 + hiddenCols].Address, ws.View.TopLeftCell); - Assert.AreEqual(visibleColumns - 1d, ws.View.PaneSettings.XSplit); - Assert.AreEqual(visibleRows - 1d, ws.View.PaneSettings.YSplit); + Assert.AreEqual(col - firstVisibleColumn.Value, ws.View.PaneSettings.XSplit); + Assert.AreEqual(row - firstVisibleRow.Value, ws.View.PaneSettings.YSplit); Assert.AreEqual(ePanePosition.BottomRight, ws.View.PaneSettings.ActivePanePosition); } else diff --git a/src/EPPlusTest/Issues/WorksheetIssues.cs b/src/EPPlusTest/Issues/WorksheetIssues.cs index 88daa9a04..cdae9758a 100644 --- a/src/EPPlusTest/Issues/WorksheetIssues.cs +++ b/src/EPPlusTest/Issues/WorksheetIssues.cs @@ -933,6 +933,67 @@ public void GermanCultureFormattingResultsInError() Thread.CurrentThread.CurrentUICulture = new CultureInfo("de-DE"); excelPackage.Workbook.Calculate(); Assert.AreEqual("64.066,27€", excelPackage.Workbook.Worksheets[0].Cells[1, 3].Text); + } + + [TestMethod] + public void s931() + { + using (ExcelPackage xlPackage = OpenPackage("s931.xlsx", true)) + { + ExcelWorksheet sheet = xlPackage.Workbook.Worksheets.Add("test"); + + sheet.Cells[1, 1].Value = "a"; + sheet.Cells[2, 1].Value = "b"; + sheet.Cells[3, 1].Value = "c"; + sheet.Cells[4, 1].Value = "d"; + sheet.Cells[5, 1].Value = "e"; + sheet.Cells[6, 1].Value = "f"; + sheet.Cells[7, 1].Value = "g"; + sheet.Cells[8, 1].Value = "h"; + sheet.Cells[9, 1].Value = "i"; + sheet.Cells[10, 1].Value = "j"; + sheet.Cells[11, 1].Value = "k"; + sheet.Cells[12, 1].Value = "l"; + + sheet.Row(1).Hidden = false; + sheet.Row(2).Hidden = false; + + sheet.Row(3).Hidden = true; + sheet.Row(4).Hidden = true; + sheet.Row(5).Hidden = true; + sheet.Row(6).Hidden = true; + sheet.Row(7).Hidden = true; + sheet.Row(8).Hidden = true; + sheet.Row(9).Hidden = true; + sheet.Row(10).Hidden = true; + + sheet.View.FreezePanes(11, 1); + + sheet.Row(6).Hidden = false; + sheet.Row(7).Hidden = false; + + //sheet.View.PaneSettings.YSplit = 10; + + Assert.AreEqual(10, sheet.View.PaneSettings.YSplit); + + ExcelWorksheet sheet2 = xlPackage.Workbook.Worksheets.Add("test2"); + + sheet2.Column(1).Hidden = true; + sheet2.Row(1).Hidden = true; + var address = sheet2.Cells["C3"]; + + var row = address.Start.Row; + var col = address.Start.Column; + + address.Value = "Freeze here"; + sheet2.View.FreezePanes(address.Start.Row, address.Start.Column); + + var someval = sheet2.View.PaneSettings.YSplit; + + //Assert.AreEqual(2, sheet2.View.PaneSettings.YSplit); + + xlPackage.Save(); + } } } }