Skip to content

Commit b03e10b

Browse files
authored
Merge pull request #4264 from oleibman/odsrepeat
Ods Writer Eliminate Padding at End of Row
2 parents 61272f0 + 3dfec28 commit b03e10b

File tree

6 files changed

+69
-54
lines changed

6 files changed

+69
-54
lines changed

src/PhpSpreadsheet/Writer/Ods/Content.php

Lines changed: 21 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,6 @@
2020
*/
2121
class Content extends WriterPart
2222
{
23-
const NUMBER_COLS_REPEATED_MAX = 1024;
24-
const NUMBER_ROWS_REPEATED_MAX = 1048576;
25-
2623
private Formula $formulaConvertor;
2724

2825
/**
@@ -142,7 +139,6 @@ private function writeSheets(XMLWriter $objWriter): void
142139
sprintf('%s_%d_%d', Style::COLUMN_STYLE_PREFIX, $sheetIndex, $columnDimension->getColumnNumeric())
143140
);
144141
$objWriter->writeAttribute('table:default-cell-style-name', 'ce0');
145-
// $objWriter->writeAttribute('table:number-columns-repeated', self::NUMBER_COLS_REPEATED_MAX);
146142
$objWriter->endElement();
147143
}
148144
$this->writeRows($objWriter, $spreadsheet->getSheet($sheetIndex), $sheetIndex);
@@ -155,34 +151,33 @@ private function writeSheets(XMLWriter $objWriter): void
155151
*/
156152
private function writeRows(XMLWriter $objWriter, Worksheet $sheet, int $sheetIndex): void
157153
{
158-
$numberRowsRepeated = self::NUMBER_ROWS_REPEATED_MAX;
159-
$span_row = 0;
154+
$spanRow = 0;
160155
$rows = $sheet->getRowIterator();
161156
foreach ($rows as $row) {
162-
$cellIterator = $row->getCellIterator();
163-
--$numberRowsRepeated;
164-
if ($cellIterator->valid()) {
165-
$objWriter->startElement('table:table-row');
166-
if ($span_row) {
167-
if ($span_row > 1) {
168-
$objWriter->writeAttribute('table:number-rows-repeated', (string) $span_row);
169-
}
170-
$objWriter->startElement('table:table-cell');
171-
$objWriter->writeAttribute('table:number-columns-repeated', (string) self::NUMBER_COLS_REPEATED_MAX);
157+
$cellIterator = $row->getCellIterator(iterateOnlyExistingCells: true);
158+
$cellIterator->rewind();
159+
$rowStyleExists = $sheet->rowDimensionExists($row->getRowIndex()) && $sheet->getRowDimension($row->getRowIndex())->getRowHeight() > 0;
160+
if ($cellIterator->valid() || $rowStyleExists) {
161+
if ($spanRow) {
162+
$objWriter->startElement('table:table-row');
163+
$objWriter->writeAttribute(
164+
'table:number-rows-repeated',
165+
(string) $spanRow
166+
);
172167
$objWriter->endElement();
173-
$span_row = 0;
174-
} else {
175-
if ($sheet->rowDimensionExists($row->getRowIndex()) && $sheet->getRowDimension($row->getRowIndex())->getRowHeight() > 0) {
176-
$objWriter->writeAttribute(
177-
'table:style-name',
178-
sprintf('%s_%d_%d', Style::ROW_STYLE_PREFIX, $sheetIndex, $row->getRowIndex())
179-
);
180-
}
181-
$this->writeCells($objWriter, $cellIterator);
168+
$spanRow = 0;
169+
}
170+
$objWriter->startElement('table:table-row');
171+
if ($rowStyleExists) {
172+
$objWriter->writeAttribute(
173+
'table:style-name',
174+
sprintf('%s_%d_%d', Style::ROW_STYLE_PREFIX, $sheetIndex, $row->getRowIndex())
175+
);
182176
}
177+
$this->writeCells($objWriter, $cellIterator);
183178
$objWriter->endElement();
184179
} else {
185-
++$span_row;
180+
++$spanRow;
186181
}
187182
}
188183
}
@@ -192,7 +187,6 @@ private function writeRows(XMLWriter $objWriter, Worksheet $sheet, int $sheetInd
192187
*/
193188
private function writeCells(XMLWriter $objWriter, RowCellIterator $cells): void
194189
{
195-
$numberColsRepeated = self::NUMBER_COLS_REPEATED_MAX;
196190
$prevColumn = -1;
197191
foreach ($cells as $cell) {
198192
/** @var Cell $cell */
@@ -293,17 +287,6 @@ private function writeCells(XMLWriter $objWriter, RowCellIterator $cells): void
293287
$objWriter->endElement();
294288
$prevColumn = $column;
295289
}
296-
297-
$numberColsRepeated = $numberColsRepeated - $prevColumn - 1;
298-
if ($numberColsRepeated > 0) {
299-
if ($numberColsRepeated > 1) {
300-
$objWriter->startElement('table:table-cell');
301-
$objWriter->writeAttribute('table:number-columns-repeated', (string) $numberColsRepeated);
302-
$objWriter->endElement();
303-
} else {
304-
$objWriter->writeElement('table:table-cell');
305-
}
306-
}
307290
}
308291

309292
/**
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpOffice\PhpSpreadsheetTests\Reader\Ods;
6+
7+
use PhpOffice\PhpSpreadsheet\Spreadsheet;
8+
use PhpOffice\PhpSpreadsheetTests\Functional\AbstractFunctional;
9+
10+
class RepeatEmptyCellsAndRowsTest extends AbstractFunctional
11+
{
12+
public function testSaveAndLoadHyperlinks(): void
13+
{
14+
$spreadsheetOld = new Spreadsheet();
15+
$oldSheet = $spreadsheetOld->getActiveSheet();
16+
$oldSheet->setCellValue('C1', 'xx');
17+
$oldSheet->setCellValue('G1', 'aa');
18+
$oldSheet->setCellValue('BB1', 'bb');
19+
$oldSheet->setCellValue('A6', 'aaa');
20+
$oldSheet->setCellValue('B7', 'bbb');
21+
$oldSheet->getRowDimension(10)->setRowHeight(12);
22+
$oldSheet->setCellValue('A12', 'this is A12');
23+
$style = $oldSheet->getStyle('B14:D14');
24+
$style->getFont()->setBold(true);
25+
$oldSheet->getCell('E15')->setValue('X');
26+
$oldSheet->mergeCells('E15:G16');
27+
$oldSheet->getCell('J15')->setValue('j15');
28+
$oldSheet->getCell('J16')->setValue('j16');
29+
$oldSheet->getCell('A19')->setValue('lastrow');
30+
$spreadsheet = $this->writeAndReload($spreadsheetOld, 'Ods');
31+
$spreadsheetOld->disconnectWorksheets();
32+
33+
$sheet = $spreadsheet->getActiveSheet();
34+
self::assertSame('xx', $sheet->getCell('C1')->getValue());
35+
self::assertSame('aa', $sheet->getCell('G1')->getValue());
36+
self::assertSame('bb', $sheet->getCell('BB1')->getValue());
37+
self::assertSame('aaa', $sheet->getCell('A6')->getValue());
38+
self::assertSame('bbb', $sheet->getCell('B7')->getValue());
39+
self::assertSame('this is A12', $sheet->getCell('A12')->getValue());
40+
// Read styles, including row height, not yet implemented for ODS
41+
self::assertSame('j15', $sheet->getCell('J15')->getValue());
42+
self::assertSame('j16', $sheet->getCell('J16')->getValue());
43+
self::assertSame(['E15:G16' => 'E15:G16'], $sheet->getMergeCells());
44+
self::assertSame('lastrow', $sheet->getCell('A19')->getValue());
45+
46+
$spreadsheet->disconnectWorksheets();
47+
}
48+
}

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

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
<table:table-cell table:style-name="ce0" table:number-matrix-columns-spanned="1" table:number-matrix-rows-spanned="2" table:formula="of:=UNIQUE([.A1:.A3])" office:value-type="float" office:value="1">
2424
<text:p>1</text:p>
2525
</table:table-cell>
26-
<table:table-cell table:number-columns-repeated="1022"/>
2726
</table:table-row>
2827
<table:table-row>
2928
<table:table-cell table:style-name="ce0" office:value-type="float" office:value="1">
@@ -32,14 +31,11 @@
3231
<table:table-cell table:style-name="ce0" office:value-type="float" office:value="3">
3332
<text:p>3</text:p>
3433
</table:table-cell>
35-
<table:table-cell table:number-columns-repeated="1022"/>
3634
</table:table-row>
3735
<table:table-row>
3836
<table:table-cell table:style-name="ce0" office:value-type="float" office:value="3">
3937
<text:p>3</text:p>
4038
</table:table-cell>
41-
<table:table-cell table:style-name="ce0"/>
42-
<table:table-cell table:number-columns-repeated="1022"/>
4339
</table:table-row>
4440
</table:table>
4541
<table:named-expressions/>

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

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,6 @@
1616
<table:calculation-settings />
1717
<table:table table:name="Worksheet" table:style-name="ta1">
1818
<office:forms />
19-
<table:table-row>
20-
<table:table-cell table:style-name="ce0" />
21-
<table:table-cell table:number-columns-repeated="1023" />
22-
</table:table-row>
2319
</table:table>
2420
<table:named-expressions />
2521
</office:spreadsheet>

tests/data/Writer/Ods/content-hidden-worksheet.xml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
<table:table-cell office:value="1" office:value-type="float" table:style-name="ce0">
2424
<text:p>1</text:p>
2525
</table:table-cell>
26-
<table:table-cell table:number-columns-repeated="1023"/>
2726
</table:table-row>
2827
</table:table>
2928
<table:table table:name="New Worksheet" table:style-name="ta2">
@@ -32,7 +31,6 @@
3231
<table:table-cell office:value="2" office:value-type="float" table:style-name="ce0">
3332
<text:p>2</text:p>
3433
</table:table-cell>
35-
<table:table-cell table:number-columns-repeated="1023" />
3634
</table:table-row>
3735
</table:table>
3836
<table:named-expressions />

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

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,6 @@
8181
<table:table-cell office:value-type="string" table:style-name="ce0">
8282
<text:p>Lorem ipsum</text:p>
8383
</table:table-cell>
84-
<table:table-cell table:number-columns-repeated="1017"/>
8584
</table:table-row>
8685
<table:table-row>
8786
<table:table-cell office:boolean-value="true" office:value-type="boolean" table:style-name="ce0">
@@ -96,10 +95,6 @@
9695
<table:table-cell office:value="42798.572060185" office:value-type="float" table:style-name="ce1">
9796
<text:p>42798.572060185</text:p>
9897
</table:table-cell>
99-
<table:table-cell table:style-name="ce0"/>
100-
<table:table-cell table:style-name="ce0"/>
101-
<table:table-cell table:style-name="ce0"/>
102-
<table:table-cell table:number-columns-repeated="1017"/>
10398
</table:table-row>
10499
</table:table>
105100
<table:table table:name="New Worksheet" table:style-name="ta2">
@@ -108,7 +103,6 @@
108103
<table:table-cell office:value="2" office:value-type="float" table:style-name="ce0">
109104
<text:p>2</text:p>
110105
</table:table-cell>
111-
<table:table-cell table:number-columns-repeated="1023"/>
112106
</table:table-row>
113107
</table:table>
114108
<table:named-expressions/>

0 commit comments

Comments
 (0)