Skip to content

Commit

Permalink
Problems With Panes
Browse files Browse the repository at this point in the history
These glitches were probably due to PR PHPOffice#3622.
- Excel may not properly identify the selected cell on a sheet if freeze panes is in effect, even though the Xml points to the correct pane and the correct selected cell is specified for that pane.
- Worksheet::calculateColumnWidths may alter activePane.
  • Loading branch information
oleibman committed Dec 23, 2023
1 parent 9f87d7c commit 421a15a
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 17 deletions.
2 changes: 2 additions & 0 deletions src/PhpSpreadsheet/Worksheet/Worksheet.php
Original file line number Diff line number Diff line change
Expand Up @@ -745,6 +745,7 @@ public function calculateColumnWidths(): static

// There is only something to do if there are some auto-size columns
if (!empty($autoSizes)) {
$holdActivePane = $this->activePane;
// build list of cells references that participate in a merge
$isMergeCell = [];
foreach ($this->getMergeCells() as $cells) {
Expand Down Expand Up @@ -829,6 +830,7 @@ public function calculateColumnWidths(): static
}
$this->getColumnDimension($columnIndex)->setWidth($width);
}
$this->activePane = $holdActivePane;
}

return $this;
Expand Down
53 changes: 38 additions & 15 deletions src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php
Original file line number Diff line number Diff line change
Expand Up @@ -315,16 +315,26 @@ private function writeSheetViews(XMLWriter $objWriter, PhpspreadsheetWorksheet $
$ySplit = $worksheet->getYSplit();
$pane = $worksheet->getActivePane();
$paneTopLeftCell = $worksheet->getPaneTopLeftCell();
$paneState = $worksheet->getPaneState();
$normalFreeze = '';
if ($paneState === PhpSpreadsheetWorksheet::PANE_FROZEN) {
if ($ySplit > 0) {
$normalFreeze = ($xSplit <= 0) ? 'bottomLeft' : 'bottomRight';
} else {
$normalFreeze = 'topRight';
}
}
if ($xSplit > 0) {
$objWriter->writeAttribute('xSplit', "$xSplit");
}
if ($ySplit > 0) {
$objWriter->writeAttribute('ySplit', "$ySplit");
}
if ($pane !== '') {
if ($normalFreeze !== '') {
$objWriter->writeAttribute('activePane', $normalFreeze);
} elseif ($pane !== '') {
$objWriter->writeAttribute('activePane', $pane);
}
$paneState = $worksheet->getPaneState();
if ($paneState !== '') {
$objWriter->writeAttribute('state', $paneState);
}
Expand All @@ -333,20 +343,33 @@ private function writeSheetViews(XMLWriter $objWriter, PhpspreadsheetWorksheet $
}
$objWriter->endElement(); // pane

foreach ($worksheet->getPanes() as $panex) {
if ($panex !== null) {
$sqref = $activeCell = '';
$objWriter->startElement('selection');
$objWriter->writeAttribute('pane', $panex->getPosition());
$activeCellPane = $panex->getActiveCell();
if ($activeCellPane !== '') {
$objWriter->writeAttribute('activeCell', $activeCellPane);
}
$sqrefPane = $panex->getSqref();
if ($sqrefPane !== '') {
$objWriter->writeAttribute('sqref', $sqrefPane);
if ($normalFreeze !== '') {
$objWriter->startElement('selection');
$objWriter->writeAttribute('pane', $normalFreeze);
if ($activeCell !== '') {
$objWriter->writeAttribute('activeCell', $activeCell);
}
if ($sqref !== '') {
$objWriter->writeAttribute('sqref', $sqref);
}
$objWriter->endElement(); // selection
$sqref = $activeCell = '';
} else {
foreach ($worksheet->getPanes() as $panex) {
if ($panex !== null) {
$sqref = $activeCell = '';
$objWriter->startElement('selection');
$objWriter->writeAttribute('pane', $panex->getPosition());
$activeCellPane = $panex->getActiveCell();
if ($activeCellPane !== '') {
$objWriter->writeAttribute('activeCell', $activeCellPane);
}
$sqrefPane = $panex->getSqref();
if ($sqrefPane !== '') {
$objWriter->writeAttribute('sqref', $sqrefPane);
}
$objWriter->endElement(); // selection
}
$objWriter->endElement(); // selection
}
}
}
Expand Down
45 changes: 43 additions & 2 deletions tests/PhpSpreadsheetTests/Functional/FreezePaneTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Worksheet\Pane;
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx as XlsxWriter;

class FreezePaneTest extends AbstractFunctional
{
Expand Down Expand Up @@ -94,8 +95,23 @@ public function testFreezePaneUserSelectedCell(string $format): void
// Read written file
$reloadedActive = $reloadedSpreadsheet->getActiveSheet();

$expected = 'C3';
self::assertSame($expected, $reloadedActive->getSelectedCells());
self::assertSame('C3', $reloadedActive->getSelectedCells());
self::assertSame('A2', $reloadedActive->getFreezePane());
if ($format === 'Xlsx') {
$writer = new XlsxWriter($reloadedSpreadsheet);
$writerSheet = new XlsxWriter\Worksheet($writer);
$data = $writerSheet->writeWorksheet($reloadedActive);
$expectedString = '<pane ySplit="1" activePane="bottomLeft" state="frozen" topLeftCell="A2"/><selection pane="bottomLeft" activeCell="C3" sqref="C3"/>';
self::assertStringContainsString($expectedString, $data);

$reloadedActive->freezePane('C1');
$reloadedActive->setSelectedCells('A2');
$writer = new XlsxWriter($reloadedSpreadsheet);
$writerSheet = new XlsxWriter\Worksheet($writer);
$data = $writerSheet->writeWorksheet($reloadedActive);
$expectedString = '<pane xSplit="2" activePane="topRight" state="frozen" topLeftCell="C1"/><selection pane="topRight" activeCell="A2" sqref="A2"/>';
self::assertStringContainsString($expectedString, $data);
}
$reloadedSpreadsheet->disconnectWorksheets();
}

Expand Down Expand Up @@ -256,4 +272,29 @@ public function testFreezePaneViaPaneState(): void

$spreadsheet->disconnectWorksheets();
}

public function testAutoWidthDoesNotCorruptActivePane(): void
{
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$sheet->fromArray(
[
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
]
);
$sheet->freezePane('A2');
$sheet->setSelectedCell('B1');
$paneBefore = $sheet->getActivePane();
self::assertSame('topLeft', $paneBefore);
$sheet->getColumnDimension('A')->setAutoSize(true);
$sheet->getColumnDimension('B')->setAutoSize(true);
$sheet->getColumnDimension('C')->setAutoSize(true);
$sheet->getColumnDimension('D')->setAutoSize(true);
$sheet->calculateColumnWidths();
$paneAfter = $sheet->getActivePane();
self::assertSame('topLeft', $paneAfter);
$spreadsheet->disconnectWorksheets();
}
}

0 comments on commit 421a15a

Please sign in to comment.