Skip to content

Commit c05fb6e

Browse files
authored
Merge pull request #2755 from PHPOffice/Ods-Writer-Freeze-Pane
Ods writer freeze pane
2 parents 0afec91 + f024259 commit c05fb6e

File tree

5 files changed

+92
-29
lines changed

5 files changed

+92
-29
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org).
99

1010
### Added
1111

12+
- Ods Writer support for Freeze Pane [Issue #2013](https://github.com/PHPOffice/PhpSpreadsheet/issues/2013) [PR #2755](https://github.com/PHPOffice/PhpSpreadsheet/pull/2755)
1213
- Ods Writer support for setting column width/row height (including the use of AutoSize) [Issue #2346](https://github.com/PHPOffice/PhpSpreadsheet/issues/2346) [PR #2753](https://github.com/PHPOffice/PhpSpreadsheet/pull/2753)
1314
- Introduced CellAddress, CellRange, RowRange and ColumnRange value objects that can be used as an alternative to a string value (e.g. `'C5'`, `'B2:D4'`, `'2:2'` or `'B:C'`) in appropriate contexts.
1415
- Implementation of the FILTER(), SORT(), SORTBY() and UNIQUE() Lookup/Reference (array) functions.

phpstan-baseline.neon

-5
Original file line numberDiff line numberDiff line change
@@ -4690,11 +4690,6 @@ parameters:
46904690
count: 1
46914691
path: src/PhpSpreadsheet/Writer/Ods/Formula.php
46924692

4693-
-
4694-
message: "#^Parameter \\#1 \\$content of method XMLWriter\\:\\:text\\(\\) expects string, int given\\.$#"
4695-
count: 2
4696-
path: src/PhpSpreadsheet/Writer/Ods/Settings.php
4697-
46984693
-
46994694
message: "#^Cannot call method getHashCode\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#"
47004695
count: 1

src/PhpSpreadsheet/Writer/Ods.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -132,10 +132,11 @@ public function save($filename, int $flags = 0): void
132132

133133
$zip->addFile('META-INF/manifest.xml', $this->getWriterPartMetaInf()->write());
134134
$zip->addFile('Thumbnails/thumbnail.png', $this->getWriterPartthumbnails()->write());
135+
// Settings always need to be written before Content; Styles after Content
136+
$zip->addFile('settings.xml', $this->getWriterPartsettings()->write());
135137
$zip->addFile('content.xml', $this->getWriterPartcontent()->write());
136138
$zip->addFile('meta.xml', $this->getWriterPartmeta()->write());
137139
$zip->addFile('mimetype', $this->getWriterPartmimetype()->write());
138-
$zip->addFile('settings.xml', $this->getWriterPartsettings()->write());
139140
$zip->addFile('styles.xml', $this->getWriterPartstyles()->write());
140141

141142
// Close file

src/PhpSpreadsheet/Writer/Ods/Content.php

+3-1
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,9 @@ private function writeXfStyles(XMLWriter $writer, Spreadsheet $spreadsheet): voi
294294
$worksheet = $spreadsheet->getSheet($i);
295295
$worksheet->calculateColumnWidths();
296296
foreach ($worksheet->getColumnDimensions() as $columnDimension) {
297-
$styleWriter->writeColumnStyles($columnDimension, $i);
297+
if ($columnDimension->getWidth() !== -1.0) {
298+
$styleWriter->writeColumnStyles($columnDimension, $i);
299+
}
298300
}
299301
}
300302
for ($i = 0; $i < $sheetCount; ++$i) {

src/PhpSpreadsheet/Writer/Ods/Settings.php

+86-22
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@
22

33
namespace PhpOffice\PhpSpreadsheet\Writer\Ods;
44

5+
use PhpOffice\PhpSpreadsheet\Cell\CellAddress;
56
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
67
use PhpOffice\PhpSpreadsheet\Shared\XMLWriter;
8+
use PhpOffice\PhpSpreadsheet\Spreadsheet;
9+
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
710

811
class Settings extends WriterPart
912
{
@@ -45,28 +48,9 @@ public function write(): string
4548
$objWriter->text('view1');
4649
$objWriter->endElement(); // ViewId
4750
$objWriter->startElement('config:config-item-map-named');
48-
$objWriter->writeAttribute('config:name', 'Tables');
49-
foreach ($spreadsheet->getWorksheetIterator() as $ws) {
50-
$objWriter->startElement('config:config-item-map-entry');
51-
$objWriter->writeAttribute('config:name', $ws->getTitle());
52-
$selected = $ws->getSelectedCells();
53-
if (preg_match('/^([a-z]+)([0-9]+)/i', $selected, $matches) === 1) {
54-
$colSel = Coordinate::columnIndexFromString($matches[1]) - 1;
55-
$rowSel = (int) $matches[2] - 1;
56-
$objWriter->startElement('config:config-item');
57-
$objWriter->writeAttribute('config:name', 'CursorPositionX');
58-
$objWriter->writeAttribute('config:type', 'int');
59-
$objWriter->text($colSel);
60-
$objWriter->endElement();
61-
$objWriter->startElement('config:config-item');
62-
$objWriter->writeAttribute('config:name', 'CursorPositionY');
63-
$objWriter->writeAttribute('config:type', 'int');
64-
$objWriter->text($rowSel);
65-
$objWriter->endElement();
66-
}
67-
$objWriter->endElement(); // config:config-item-map-entry
68-
}
69-
$objWriter->endElement(); // config:config-item-map-named
51+
52+
$this->writeAllWorksheetSettings($objWriter, $spreadsheet);
53+
7054
$wstitle = $spreadsheet->getActiveSheet()->getTitle();
7155
$objWriter->startElement('config:config-item');
7256
$objWriter->writeAttribute('config:name', 'ActiveTable');
@@ -85,4 +69,84 @@ public function write(): string
8569

8670
return $objWriter->getData();
8771
}
72+
73+
private function writeAllWorksheetSettings(XMLWriter $objWriter, Spreadsheet $spreadsheet): void
74+
{
75+
$objWriter->writeAttribute('config:name', 'Tables');
76+
77+
foreach ($spreadsheet->getWorksheetIterator() as $worksheet) {
78+
$this->writeWorksheetSettings($objWriter, $worksheet);
79+
}
80+
81+
$objWriter->endElement(); // config:config-item-map-entry Tables
82+
}
83+
84+
private function writeWorksheetSettings(XMLWriter $objWriter, Worksheet $worksheet): void
85+
{
86+
$objWriter->startElement('config:config-item-map-entry');
87+
$objWriter->writeAttribute('config:name', $worksheet->getTitle());
88+
89+
$this->writeSelectedCells($objWriter, $worksheet);
90+
if ($worksheet->getFreezePane() !== null) {
91+
$this->writeFreezePane($objWriter, $worksheet);
92+
}
93+
94+
$objWriter->endElement(); // config:config-item-map-entry Worksheet
95+
}
96+
97+
private function writeSelectedCells(XMLWriter $objWriter, Worksheet $worksheet): void
98+
{
99+
$selected = $worksheet->getSelectedCells();
100+
if (preg_match('/^([a-z]+)([0-9]+)/i', $selected, $matches) === 1) {
101+
$colSel = Coordinate::columnIndexFromString($matches[1]) - 1;
102+
$rowSel = (int) $matches[2] - 1;
103+
$objWriter->startElement('config:config-item');
104+
$objWriter->writeAttribute('config:name', 'CursorPositionX');
105+
$objWriter->writeAttribute('config:type', 'int');
106+
$objWriter->text((string) $colSel);
107+
$objWriter->endElement();
108+
$objWriter->startElement('config:config-item');
109+
$objWriter->writeAttribute('config:name', 'CursorPositionY');
110+
$objWriter->writeAttribute('config:type', 'int');
111+
$objWriter->text((string) $rowSel);
112+
$objWriter->endElement();
113+
}
114+
}
115+
116+
private function writeSplitValue(XMLWriter $objWriter, string $splitMode, string $type, string $value): void
117+
{
118+
$objWriter->startElement('config:config-item');
119+
$objWriter->writeAttribute('config:name', $splitMode);
120+
$objWriter->writeAttribute('config:type', $type);
121+
$objWriter->text($value);
122+
$objWriter->endElement();
123+
}
124+
125+
private function writeFreezePane(XMLWriter $objWriter, Worksheet $worksheet): void
126+
{
127+
$freezePane = CellAddress::fromCellAddress($worksheet->getFreezePane());
128+
if ($freezePane->cellAddress() === 'A1') {
129+
return;
130+
}
131+
132+
$columnId = $freezePane->columnId();
133+
$columnName = $freezePane->columnName();
134+
$row = $freezePane->rowId();
135+
136+
$this->writeSplitValue($objWriter, 'HorizontalSplitMode', 'short', '2');
137+
$this->writeSplitValue($objWriter, 'HorizontalSplitPosition', 'int', (string) ($columnId - 1));
138+
$this->writeSplitValue($objWriter, 'PositionLeft', 'short', '0');
139+
$this->writeSplitValue($objWriter, 'PositionRight', 'short', (string) ($columnId - 1));
140+
141+
for ($column = 'A'; $column !== $columnName; ++$column) {
142+
$worksheet->getColumnDimension($column)->setAutoSize(true);
143+
}
144+
145+
$this->writeSplitValue($objWriter, 'VerticalSplitMode', 'short', '2');
146+
$this->writeSplitValue($objWriter, 'VerticalSplitPosition', 'int', (string) ($row - 1));
147+
$this->writeSplitValue($objWriter, 'PositionTop', 'short', '0');
148+
$this->writeSplitValue($objWriter, 'PositionBottom', 'short', (string) ($row - 1));
149+
150+
$this->writeSplitValue($objWriter, 'ActiveSplitRange', 'short', '3');
151+
}
88152
}

0 commit comments

Comments
 (0)