Skip to content

Commit 9caa827

Browse files
authored
Merge pull request #2753 from PHPOffice/Issue-2346_Column-Dimensions-for-Ods-Writer
Ods Writer support for setting column width/row height
2 parents de173d4 + 7a2f5c4 commit 9caa827

File tree

7 files changed

+105
-19
lines changed

7 files changed

+105
-19
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
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 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)
1213
- 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.
1314
- Implementation of the FILTER(), SORT(), SORTBY() and UNIQUE() Lookup/Reference (array) functions.
1415
- Implementation of the ISREF() Information function.

phpstan-baseline.neon

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4675,11 +4675,6 @@ parameters:
46754675
count: 1
46764676
path: src/PhpSpreadsheet/Writer/Ods/Content.php
46774677

4678-
-
4679-
message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, int given\\.$#"
4680-
count: 4
4681-
path: src/PhpSpreadsheet/Writer/Ods/Content.php
4682-
46834678
-
46844679
message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, int\\<2, max\\> given\\.$#"
46854680
count: 3

src/PhpSpreadsheet/Writer/Ods/Cell/Style.php

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,20 @@
22

33
namespace PhpOffice\PhpSpreadsheet\Writer\Ods\Cell;
44

5+
use PhpOffice\PhpSpreadsheet\Helper\Dimension;
56
use PhpOffice\PhpSpreadsheet\Shared\XMLWriter;
67
use PhpOffice\PhpSpreadsheet\Style\Alignment;
78
use PhpOffice\PhpSpreadsheet\Style\Fill;
89
use PhpOffice\PhpSpreadsheet\Style\Font;
910
use PhpOffice\PhpSpreadsheet\Style\Style as CellStyle;
11+
use PhpOffice\PhpSpreadsheet\Worksheet\ColumnDimension;
12+
use PhpOffice\PhpSpreadsheet\Worksheet\RowDimension;
1013

1114
class Style
1215
{
1316
public const CELL_STYLE_PREFIX = 'ce';
17+
public const COLUMN_STYLE_PREFIX = 'co';
18+
public const ROW_STYLE_PREFIX = 'ro';
1419

1520
private $writer;
1621

@@ -159,6 +164,63 @@ protected function writeTextProperties(CellStyle $style): void
159164
$this->writer->endElement(); // Close style:text-properties
160165
}
161166

167+
protected function writeColumnProperties(ColumnDimension $columnDimension): void
168+
{
169+
$this->writer->startElement('style:table-column-properties');
170+
$this->writer->writeAttribute(
171+
'style:column-width',
172+
round($columnDimension->getWidth(Dimension::UOM_CENTIMETERS), 3) . 'cm'
173+
);
174+
$this->writer->writeAttribute('fo:break-before', 'auto');
175+
176+
// End
177+
$this->writer->endElement(); // Close style:table-column-properties
178+
}
179+
180+
public function writeColumnStyles(ColumnDimension $columnDimension, int $sheetId): void
181+
{
182+
$this->writer->startElement('style:style');
183+
$this->writer->writeAttribute('style:family', 'table-column');
184+
$this->writer->writeAttribute(
185+
'style:name',
186+
sprintf('%s_%d_%d', self::COLUMN_STYLE_PREFIX, $sheetId, $columnDimension->getColumnNumeric())
187+
);
188+
189+
$this->writeColumnProperties($columnDimension);
190+
191+
// End
192+
$this->writer->endElement(); // Close style:style
193+
}
194+
195+
protected function writeRowProperties(RowDimension $rowDimension): void
196+
{
197+
$this->writer->startElement('style:table-row-properties');
198+
$this->writer->writeAttribute(
199+
'style:row-height',
200+
round($rowDimension->getRowHeight(Dimension::UOM_CENTIMETERS), 3) . 'cm'
201+
);
202+
$this->writer->writeAttribute('style:use-optimal-row-height', 'true');
203+
$this->writer->writeAttribute('fo:break-before', 'auto');
204+
205+
// End
206+
$this->writer->endElement(); // Close style:table-row-properties
207+
}
208+
209+
public function writeRowStyles(RowDimension $rowDimension, int $sheetId): void
210+
{
211+
$this->writer->startElement('style:style');
212+
$this->writer->writeAttribute('style:family', 'table-row');
213+
$this->writer->writeAttribute(
214+
'style:name',
215+
sprintf('%s_%d_%d', self::ROW_STYLE_PREFIX, $sheetId, $rowDimension->getRowIndex())
216+
);
217+
218+
$this->writeRowProperties($rowDimension);
219+
220+
// End
221+
$this->writer->endElement(); // Close style:style
222+
}
223+
162224
public function write(CellStyle $style): void
163225
{
164226
$this->writer->startElement('style:style');

src/PhpSpreadsheet/Writer/Ods/Content.php

Lines changed: 41 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -119,22 +119,29 @@ private function writeSheets(XMLWriter $objWriter): void
119119
{
120120
$spreadsheet = $this->getParentWriter()->getSpreadsheet(); /** @var Spreadsheet $spreadsheet */
121121
$sheetCount = $spreadsheet->getSheetCount();
122-
for ($i = 0; $i < $sheetCount; ++$i) {
122+
for ($sheetIndex = 0; $sheetIndex < $sheetCount; ++$sheetIndex) {
123123
$objWriter->startElement('table:table');
124-
$objWriter->writeAttribute('table:name', $spreadsheet->getSheet($i)->getTitle());
124+
$objWriter->writeAttribute('table:name', $spreadsheet->getSheet($sheetIndex)->getTitle());
125125
$objWriter->writeElement('office:forms');
126-
$objWriter->startElement('table:table-column');
127-
$objWriter->writeAttribute('table:number-columns-repeated', self::NUMBER_COLS_REPEATED_MAX);
128-
$objWriter->endElement();
129-
$this->writeRows($objWriter, $spreadsheet->getSheet($i));
126+
foreach ($spreadsheet->getSheet($sheetIndex)->getColumnDimensions() as $columnDimension) {
127+
$objWriter->startElement('table:table-column');
128+
$objWriter->writeAttribute(
129+
'table:style-name',
130+
sprintf('%s_%d_%d', Style::COLUMN_STYLE_PREFIX, $sheetIndex, $columnDimension->getColumnNumeric())
131+
);
132+
$objWriter->writeAttribute('table:default-cell-style-name', 'ce0');
133+
// $objWriter->writeAttribute('table:number-columns-repeated', self::NUMBER_COLS_REPEATED_MAX);
134+
$objWriter->endElement();
135+
}
136+
$this->writeRows($objWriter, $spreadsheet->getSheet($sheetIndex), $sheetIndex);
130137
$objWriter->endElement();
131138
}
132139
}
133140

134141
/**
135142
* Write rows of the specified sheet.
136143
*/
137-
private function writeRows(XMLWriter $objWriter, Worksheet $sheet): void
144+
private function writeRows(XMLWriter $objWriter, Worksheet $sheet, int $sheetIndex): void
138145
{
139146
$numberRowsRepeated = self::NUMBER_ROWS_REPEATED_MAX;
140147
$span_row = 0;
@@ -148,8 +155,14 @@ private function writeRows(XMLWriter $objWriter, Worksheet $sheet): void
148155
if ($span_row > 1) {
149156
$objWriter->writeAttribute('table:number-rows-repeated', $span_row);
150157
}
158+
if ($sheet->getRowDimension($row->getRowIndex())->getRowHeight() > 0) {
159+
$objWriter->writeAttribute(
160+
'table:style_name',
161+
sprintf('%s_%d_%d', Style::ROW_STYLE_PREFIX, $sheetIndex, $row->getRowIndex())
162+
);
163+
}
151164
$objWriter->startElement('table:table-cell');
152-
$objWriter->writeAttribute('table:number-columns-repeated', self::NUMBER_COLS_REPEATED_MAX);
165+
$objWriter->writeAttribute('table:number-columns-repeated', (string) self::NUMBER_COLS_REPEATED_MAX);
153166
$objWriter->endElement();
154167
$objWriter->endElement();
155168
$span_row = 0;
@@ -275,6 +288,24 @@ private function writeCellSpan(XMLWriter $objWriter, $curColumn, $prevColumn): v
275288
private function writeXfStyles(XMLWriter $writer, Spreadsheet $spreadsheet): void
276289
{
277290
$styleWriter = new Style($writer);
291+
292+
$sheetCount = $spreadsheet->getSheetCount();
293+
for ($i = 0; $i < $sheetCount; ++$i) {
294+
$worksheet = $spreadsheet->getSheet($i);
295+
$worksheet->calculateColumnWidths();
296+
foreach ($worksheet->getColumnDimensions() as $columnDimension) {
297+
$styleWriter->writeColumnStyles($columnDimension, $i);
298+
}
299+
}
300+
for ($i = 0; $i < $sheetCount; ++$i) {
301+
$worksheet = $spreadsheet->getSheet($i);
302+
foreach ($worksheet->getRowDimensions() as $rowDimension) {
303+
if ($rowDimension->getRowHeight() > 0.0) {
304+
$styleWriter->writeRowStyles($rowDimension, $i);
305+
}
306+
}
307+
}
308+
278309
foreach ($spreadsheet->getCellXfCollection() as $style) {
279310
$styleWriter->write($style);
280311
}
@@ -296,7 +327,7 @@ private function writeCellMerge(XMLWriter $objWriter, Cell $cell): void
296327
$columnSpan = Coordinate::columnIndexFromString($end[0]) - Coordinate::columnIndexFromString($start[0]) + 1;
297328
$rowSpan = ((int) $end[1]) - ((int) $start[1]) + 1;
298329

299-
$objWriter->writeAttribute('table:number-columns-spanned', $columnSpan);
300-
$objWriter->writeAttribute('table:number-rows-spanned', $rowSpan);
330+
$objWriter->writeAttribute('table:number-columns-spanned', (string) $columnSpan);
331+
$objWriter->writeAttribute('table:number-rows-spanned', (string) $rowSpan);
301332
}
302333
}

tests/PhpSpreadsheetTests/Writer/PreCalcTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ private static function verifyA2(Calculation $calculation, string $title, ?bool
6464
}
6565
}
6666

67-
private const AUTOSIZE_TYPES = ['Xlsx', 'Xls', 'Html'];
67+
private const AUTOSIZE_TYPES = ['Xlsx', 'Xls', 'Html', 'Ods'];
6868

6969
private static function verifyA3B2(Calculation $calculation, string $title, ?bool $preCalc, string $type): void
7070
{

tests/data/Writer/Ods/content-empty.xml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
<table:calculation-settings />
1515
<table:table table:name="Worksheet">
1616
<office:forms />
17-
<table:table-column table:number-columns-repeated="1024" />
1817
<table:table-row>
1918
<table:table-cell table:style-name="ce0" />
2019
<table:table-cell table:number-columns-repeated="1023" />

tests/data/Writer/Ods/content-with-data.xml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,6 @@
6464
<table:calculation-settings/>
6565
<table:table table:name="Worksheet">
6666
<office:forms/>
67-
<table:table-column table:number-columns-repeated="1024"/>
6867
<table:table-row>
6968
<table:table-cell office:value="1" office:value-type="float" table:style-name="ce2">
7069
<text:p>1</text:p>
@@ -110,7 +109,6 @@
110109
</table:table>
111110
<table:table table:name="New Worksheet">
112111
<office:forms/>
113-
<table:table-column table:number-columns-repeated="1024"/>
114112
<table:table-row>
115113
<table:table-cell office:value="2" office:value-type="float" table:style-name="ce0">
116114
<text:p>2</text:p>

0 commit comments

Comments
 (0)