Initial work on supporting Freeze Pane for Ods Writer

This commit is contained in:
MarkBaker 2022-04-18 13:58:35 +02:00
parent f426889571
commit 76f486d8e3
5 changed files with 92 additions and 29 deletions

View File

@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org).
### Added ### Added
- Ods Writer support for Freeze Pane [Issue #2013](https://github.com/PHPOffice/PhpSpreadsheet/issues/2013) [PR #2755](https://github.com/PHPOffice/PhpSpreadsheet/pull/2755)
- 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) - 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)
- 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. - 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.
- Implementation of the FILTER(), SORT(), SORTBY() and UNIQUE() Lookup/Reference (array) functions. - Implementation of the FILTER(), SORT(), SORTBY() and UNIQUE() Lookup/Reference (array) functions.

View File

@ -4690,11 +4690,6 @@ parameters:
count: 1 count: 1
path: src/PhpSpreadsheet/Writer/Ods/Formula.php path: src/PhpSpreadsheet/Writer/Ods/Formula.php
-
message: "#^Parameter \\#1 \\$content of method XMLWriter\\:\\:text\\(\\) expects string, int given\\.$#"
count: 2
path: src/PhpSpreadsheet/Writer/Ods/Settings.php
- -
message: "#^Cannot call method getHashCode\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#" message: "#^Cannot call method getHashCode\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#"
count: 1 count: 1

View File

@ -132,10 +132,11 @@ class Ods extends BaseWriter
$zip->addFile('META-INF/manifest.xml', $this->getWriterPartMetaInf()->write()); $zip->addFile('META-INF/manifest.xml', $this->getWriterPartMetaInf()->write());
$zip->addFile('Thumbnails/thumbnail.png', $this->getWriterPartthumbnails()->write()); $zip->addFile('Thumbnails/thumbnail.png', $this->getWriterPartthumbnails()->write());
// Settings always need to be written before Content; Styles after Content
$zip->addFile('settings.xml', $this->getWriterPartsettings()->write());
$zip->addFile('content.xml', $this->getWriterPartcontent()->write()); $zip->addFile('content.xml', $this->getWriterPartcontent()->write());
$zip->addFile('meta.xml', $this->getWriterPartmeta()->write()); $zip->addFile('meta.xml', $this->getWriterPartmeta()->write());
$zip->addFile('mimetype', $this->getWriterPartmimetype()->write()); $zip->addFile('mimetype', $this->getWriterPartmimetype()->write());
$zip->addFile('settings.xml', $this->getWriterPartsettings()->write());
$zip->addFile('styles.xml', $this->getWriterPartstyles()->write()); $zip->addFile('styles.xml', $this->getWriterPartstyles()->write());
// Close file // Close file

View File

@ -294,9 +294,11 @@ class Content extends WriterPart
$worksheet = $spreadsheet->getSheet($i); $worksheet = $spreadsheet->getSheet($i);
$worksheet->calculateColumnWidths(); $worksheet->calculateColumnWidths();
foreach ($worksheet->getColumnDimensions() as $columnDimension) { foreach ($worksheet->getColumnDimensions() as $columnDimension) {
if ($columnDimension->getWidth() !== -1.0) {
$styleWriter->writeColumnStyles($columnDimension, $i); $styleWriter->writeColumnStyles($columnDimension, $i);
} }
} }
}
for ($i = 0; $i < $sheetCount; ++$i) { for ($i = 0; $i < $sheetCount; ++$i) {
$worksheet = $spreadsheet->getSheet($i); $worksheet = $spreadsheet->getSheet($i);
foreach ($worksheet->getRowDimensions() as $rowDimension) { foreach ($worksheet->getRowDimensions() as $rowDimension) {

View File

@ -2,8 +2,11 @@
namespace PhpOffice\PhpSpreadsheet\Writer\Ods; namespace PhpOffice\PhpSpreadsheet\Writer\Ods;
use PhpOffice\PhpSpreadsheet\Cell\CellAddress;
use PhpOffice\PhpSpreadsheet\Cell\Coordinate; use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
use PhpOffice\PhpSpreadsheet\Shared\XMLWriter; use PhpOffice\PhpSpreadsheet\Shared\XMLWriter;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
class Settings extends WriterPart class Settings extends WriterPart
{ {
@ -45,28 +48,9 @@ class Settings extends WriterPart
$objWriter->text('view1'); $objWriter->text('view1');
$objWriter->endElement(); // ViewId $objWriter->endElement(); // ViewId
$objWriter->startElement('config:config-item-map-named'); $objWriter->startElement('config:config-item-map-named');
$objWriter->writeAttribute('config:name', 'Tables');
foreach ($spreadsheet->getWorksheetIterator() as $ws) { $this->writeAllWorksheetSettings($objWriter, $spreadsheet);
$objWriter->startElement('config:config-item-map-entry');
$objWriter->writeAttribute('config:name', $ws->getTitle());
$selected = $ws->getSelectedCells();
if (preg_match('/^([a-z]+)([0-9]+)/i', $selected, $matches) === 1) {
$colSel = Coordinate::columnIndexFromString($matches[1]) - 1;
$rowSel = (int) $matches[2] - 1;
$objWriter->startElement('config:config-item');
$objWriter->writeAttribute('config:name', 'CursorPositionX');
$objWriter->writeAttribute('config:type', 'int');
$objWriter->text($colSel);
$objWriter->endElement();
$objWriter->startElement('config:config-item');
$objWriter->writeAttribute('config:name', 'CursorPositionY');
$objWriter->writeAttribute('config:type', 'int');
$objWriter->text($rowSel);
$objWriter->endElement();
}
$objWriter->endElement(); // config:config-item-map-entry
}
$objWriter->endElement(); // config:config-item-map-named
$wstitle = $spreadsheet->getActiveSheet()->getTitle(); $wstitle = $spreadsheet->getActiveSheet()->getTitle();
$objWriter->startElement('config:config-item'); $objWriter->startElement('config:config-item');
$objWriter->writeAttribute('config:name', 'ActiveTable'); $objWriter->writeAttribute('config:name', 'ActiveTable');
@ -85,4 +69,84 @@ class Settings extends WriterPart
return $objWriter->getData(); return $objWriter->getData();
} }
private function writeAllWorksheetSettings(XMLWriter $objWriter, Spreadsheet $spreadsheet): void
{
$objWriter->writeAttribute('config:name', 'Tables');
foreach ($spreadsheet->getWorksheetIterator() as $worksheet) {
$this->writeWorksheetSettings($objWriter, $worksheet);
}
$objWriter->endElement(); // config:config-item-map-entry Tables
}
private function writeWorksheetSettings(XMLWriter $objWriter, Worksheet $worksheet): void
{
$objWriter->startElement('config:config-item-map-entry');
$objWriter->writeAttribute('config:name', $worksheet->getTitle());
$this->writeSelectedCells($objWriter, $worksheet);
if ($worksheet->getFreezePane() !== null) {
$this->writeFreezePane($objWriter, $worksheet);
}
$objWriter->endElement(); // config:config-item-map-entry Worksheet
}
private function writeSelectedCells(XMLWriter $objWriter, Worksheet $worksheet): void
{
$selected = $worksheet->getSelectedCells();
if (preg_match('/^([a-z]+)([0-9]+)/i', $selected, $matches) === 1) {
$colSel = Coordinate::columnIndexFromString($matches[1]) - 1;
$rowSel = (int) $matches[2] - 1;
$objWriter->startElement('config:config-item');
$objWriter->writeAttribute('config:name', 'CursorPositionX');
$objWriter->writeAttribute('config:type', 'int');
$objWriter->text((string) $colSel);
$objWriter->endElement();
$objWriter->startElement('config:config-item');
$objWriter->writeAttribute('config:name', 'CursorPositionY');
$objWriter->writeAttribute('config:type', 'int');
$objWriter->text((string) $rowSel);
$objWriter->endElement();
}
}
private function writeSplitValue(XMLWriter $objWriter, string $splitMode, string $type, string $value): void
{
$objWriter->startElement('config:config-item');
$objWriter->writeAttribute('config:name', $splitMode);
$objWriter->writeAttribute('config:type', $type);
$objWriter->text($value);
$objWriter->endElement();
}
private function writeFreezePane(XMLWriter $objWriter, Worksheet $worksheet): void
{
$freezePane = CellAddress::fromCellAddress($worksheet->getFreezePane());
if ($freezePane->cellAddress() === 'A1') {
return;
}
$columnId = $freezePane->columnId();
$columnName = $freezePane->columnName();
$row = $freezePane->rowId();
$this->writeSplitValue($objWriter, 'HorizontalSplitMode', 'short', '2');
$this->writeSplitValue($objWriter, 'HorizontalSplitPosition', 'int', (string) ($columnId - 1));
$this->writeSplitValue($objWriter, 'PositionLeft', 'short', '0');
$this->writeSplitValue($objWriter, 'PositionRight', 'short', (string) ($columnId - 1));
for ($column = 'A'; $column !== $columnName; ++$column) {
$worksheet->getColumnDimension($column)->setAutoSize(true);
}
$this->writeSplitValue($objWriter, 'VerticalSplitMode', 'short', '2');
$this->writeSplitValue($objWriter, 'VerticalSplitPosition', 'int', (string) ($row - 1));
$this->writeSplitValue($objWriter, 'PositionTop', 'short', '0');
$this->writeSplitValue($objWriter, 'PositionBottom', 'short', (string) ($row - 1));
$this->writeSplitValue($objWriter, 'ActiveSplitRange', 'short', '3');
}
} }