Ods Writer support for setting column width/row height (including Autosizing)

This commit is contained in:
MarkBaker 2022-04-16 19:34:41 +02:00
parent de173d4705
commit 7a2f5c4ccc
7 changed files with 105 additions and 19 deletions

View File

@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org).
### Added
- 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.
- Implementation of the FILTER(), SORT(), SORTBY() and UNIQUE() Lookup/Reference (array) functions.
- Implementation of the ISREF() Information function.

View File

@ -4675,11 +4675,6 @@ parameters:
count: 1
path: src/PhpSpreadsheet/Writer/Ods/Content.php
-
message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, int given\\.$#"
count: 4
path: src/PhpSpreadsheet/Writer/Ods/Content.php
-
message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, int\\<2, max\\> given\\.$#"
count: 3

View File

@ -2,15 +2,20 @@
namespace PhpOffice\PhpSpreadsheet\Writer\Ods\Cell;
use PhpOffice\PhpSpreadsheet\Helper\Dimension;
use PhpOffice\PhpSpreadsheet\Shared\XMLWriter;
use PhpOffice\PhpSpreadsheet\Style\Alignment;
use PhpOffice\PhpSpreadsheet\Style\Fill;
use PhpOffice\PhpSpreadsheet\Style\Font;
use PhpOffice\PhpSpreadsheet\Style\Style as CellStyle;
use PhpOffice\PhpSpreadsheet\Worksheet\ColumnDimension;
use PhpOffice\PhpSpreadsheet\Worksheet\RowDimension;
class Style
{
public const CELL_STYLE_PREFIX = 'ce';
public const COLUMN_STYLE_PREFIX = 'co';
public const ROW_STYLE_PREFIX = 'ro';
private $writer;
@ -159,6 +164,63 @@ class Style
$this->writer->endElement(); // Close style:text-properties
}
protected function writeColumnProperties(ColumnDimension $columnDimension): void
{
$this->writer->startElement('style:table-column-properties');
$this->writer->writeAttribute(
'style:column-width',
round($columnDimension->getWidth(Dimension::UOM_CENTIMETERS), 3) . 'cm'
);
$this->writer->writeAttribute('fo:break-before', 'auto');
// End
$this->writer->endElement(); // Close style:table-column-properties
}
public function writeColumnStyles(ColumnDimension $columnDimension, int $sheetId): void
{
$this->writer->startElement('style:style');
$this->writer->writeAttribute('style:family', 'table-column');
$this->writer->writeAttribute(
'style:name',
sprintf('%s_%d_%d', self::COLUMN_STYLE_PREFIX, $sheetId, $columnDimension->getColumnNumeric())
);
$this->writeColumnProperties($columnDimension);
// End
$this->writer->endElement(); // Close style:style
}
protected function writeRowProperties(RowDimension $rowDimension): void
{
$this->writer->startElement('style:table-row-properties');
$this->writer->writeAttribute(
'style:row-height',
round($rowDimension->getRowHeight(Dimension::UOM_CENTIMETERS), 3) . 'cm'
);
$this->writer->writeAttribute('style:use-optimal-row-height', 'true');
$this->writer->writeAttribute('fo:break-before', 'auto');
// End
$this->writer->endElement(); // Close style:table-row-properties
}
public function writeRowStyles(RowDimension $rowDimension, int $sheetId): void
{
$this->writer->startElement('style:style');
$this->writer->writeAttribute('style:family', 'table-row');
$this->writer->writeAttribute(
'style:name',
sprintf('%s_%d_%d', self::ROW_STYLE_PREFIX, $sheetId, $rowDimension->getRowIndex())
);
$this->writeRowProperties($rowDimension);
// End
$this->writer->endElement(); // Close style:style
}
public function write(CellStyle $style): void
{
$this->writer->startElement('style:style');

View File

@ -119,14 +119,21 @@ class Content extends WriterPart
{
$spreadsheet = $this->getParentWriter()->getSpreadsheet(); /** @var Spreadsheet $spreadsheet */
$sheetCount = $spreadsheet->getSheetCount();
for ($i = 0; $i < $sheetCount; ++$i) {
for ($sheetIndex = 0; $sheetIndex < $sheetCount; ++$sheetIndex) {
$objWriter->startElement('table:table');
$objWriter->writeAttribute('table:name', $spreadsheet->getSheet($i)->getTitle());
$objWriter->writeAttribute('table:name', $spreadsheet->getSheet($sheetIndex)->getTitle());
$objWriter->writeElement('office:forms');
$objWriter->startElement('table:table-column');
$objWriter->writeAttribute('table:number-columns-repeated', self::NUMBER_COLS_REPEATED_MAX);
$objWriter->endElement();
$this->writeRows($objWriter, $spreadsheet->getSheet($i));
foreach ($spreadsheet->getSheet($sheetIndex)->getColumnDimensions() as $columnDimension) {
$objWriter->startElement('table:table-column');
$objWriter->writeAttribute(
'table:style-name',
sprintf('%s_%d_%d', Style::COLUMN_STYLE_PREFIX, $sheetIndex, $columnDimension->getColumnNumeric())
);
$objWriter->writeAttribute('table:default-cell-style-name', 'ce0');
// $objWriter->writeAttribute('table:number-columns-repeated', self::NUMBER_COLS_REPEATED_MAX);
$objWriter->endElement();
}
$this->writeRows($objWriter, $spreadsheet->getSheet($sheetIndex), $sheetIndex);
$objWriter->endElement();
}
}
@ -134,7 +141,7 @@ class Content extends WriterPart
/**
* Write rows of the specified sheet.
*/
private function writeRows(XMLWriter $objWriter, Worksheet $sheet): void
private function writeRows(XMLWriter $objWriter, Worksheet $sheet, int $sheetIndex): void
{
$numberRowsRepeated = self::NUMBER_ROWS_REPEATED_MAX;
$span_row = 0;
@ -148,8 +155,14 @@ class Content extends WriterPart
if ($span_row > 1) {
$objWriter->writeAttribute('table:number-rows-repeated', $span_row);
}
if ($sheet->getRowDimension($row->getRowIndex())->getRowHeight() > 0) {
$objWriter->writeAttribute(
'table:style_name',
sprintf('%s_%d_%d', Style::ROW_STYLE_PREFIX, $sheetIndex, $row->getRowIndex())
);
}
$objWriter->startElement('table:table-cell');
$objWriter->writeAttribute('table:number-columns-repeated', self::NUMBER_COLS_REPEATED_MAX);
$objWriter->writeAttribute('table:number-columns-repeated', (string) self::NUMBER_COLS_REPEATED_MAX);
$objWriter->endElement();
$objWriter->endElement();
$span_row = 0;
@ -275,6 +288,24 @@ class Content extends WriterPart
private function writeXfStyles(XMLWriter $writer, Spreadsheet $spreadsheet): void
{
$styleWriter = new Style($writer);
$sheetCount = $spreadsheet->getSheetCount();
for ($i = 0; $i < $sheetCount; ++$i) {
$worksheet = $spreadsheet->getSheet($i);
$worksheet->calculateColumnWidths();
foreach ($worksheet->getColumnDimensions() as $columnDimension) {
$styleWriter->writeColumnStyles($columnDimension, $i);
}
}
for ($i = 0; $i < $sheetCount; ++$i) {
$worksheet = $spreadsheet->getSheet($i);
foreach ($worksheet->getRowDimensions() as $rowDimension) {
if ($rowDimension->getRowHeight() > 0.0) {
$styleWriter->writeRowStyles($rowDimension, $i);
}
}
}
foreach ($spreadsheet->getCellXfCollection() as $style) {
$styleWriter->write($style);
}
@ -296,7 +327,7 @@ class Content extends WriterPart
$columnSpan = Coordinate::columnIndexFromString($end[0]) - Coordinate::columnIndexFromString($start[0]) + 1;
$rowSpan = ((int) $end[1]) - ((int) $start[1]) + 1;
$objWriter->writeAttribute('table:number-columns-spanned', $columnSpan);
$objWriter->writeAttribute('table:number-rows-spanned', $rowSpan);
$objWriter->writeAttribute('table:number-columns-spanned', (string) $columnSpan);
$objWriter->writeAttribute('table:number-rows-spanned', (string) $rowSpan);
}
}

View File

@ -64,7 +64,7 @@ class PreCalcTest extends AbstractFunctional
}
}
private const AUTOSIZE_TYPES = ['Xlsx', 'Xls', 'Html'];
private const AUTOSIZE_TYPES = ['Xlsx', 'Xls', 'Html', 'Ods'];
private static function verifyA3B2(Calculation $calculation, string $title, ?bool $preCalc, string $type): void
{

View File

@ -14,7 +14,6 @@
<table:calculation-settings />
<table:table table:name="Worksheet">
<office:forms />
<table:table-column table:number-columns-repeated="1024" />
<table:table-row>
<table:table-cell table:style-name="ce0" />
<table:table-cell table:number-columns-repeated="1023" />

View File

@ -64,7 +64,6 @@
<table:calculation-settings/>
<table:table table:name="Worksheet">
<office:forms/>
<table:table-column table:number-columns-repeated="1024"/>
<table:table-row>
<table:table-cell office:value="1" office:value-type="float" table:style-name="ce2">
<text:p>1</text:p>
@ -110,7 +109,6 @@
</table:table>
<table:table table:name="New Worksheet">
<office:forms/>
<table:table-column table:number-columns-repeated="1024"/>
<table:table-row>
<table:table-cell office:value="2" office:value-type="float" table:style-name="ce0">
<text:p>2</text:p>