diff --git a/CHANGELOG.md b/CHANGELOG.md index ce4abdc2e3..483fe65d66 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org). ### Added +- Support Justify Last Line. [Issue #4374](https://github.com/PHPOffice/PhpSpreadsheet/issues/4374) [PR #4373](https://github.com/PHPOffice/PhpSpreadsheet/pull/4373) - Allow Spreadsheet clone. [PR #437-](https://github.com/PHPOffice/PhpSpreadsheet/pull/4370) ### Removed diff --git a/docs/topics/recipes.md b/docs/topics/recipes.md index e2d9f58628..bdc86b9823 100644 --- a/docs/topics/recipes.md +++ b/docs/topics/recipes.md @@ -1188,15 +1188,16 @@ quotePrefix | setQuotePrefix() **\PhpOffice\PhpSpreadsheet\Style\Alignment** -Array key | Maps to property -------------|------------------- -horizontal | setHorizontal() -indent | setIndent() -readOrder | setReadOrder() -shrinkToFit | setShrinkToFit() -textRotation| setTextRotation() -vertical | setVertical() -wrapText | setWrapText() +Array key | Maps to property +----------------|------------------- +horizontal | setHorizontal() +justifyLastLine | setJustifyLastLine() +indent | setIndent() +readOrder | setReadOrder() +shrinkToFit | setShrinkToFit() +textRotation | setTextRotation() +vertical | setVertical() +wrapText | setWrapText() **\PhpOffice\PhpSpreadsheet\Style\Border** diff --git a/src/PhpSpreadsheet/Reader/Xlsx/Styles.php b/src/PhpSpreadsheet/Reader/Xlsx/Styles.php index b02f3d3ffb..4b1a7d36c5 100644 --- a/src/PhpSpreadsheet/Reader/Xlsx/Styles.php +++ b/src/PhpSpreadsheet/Reader/Xlsx/Styles.php @@ -265,6 +265,12 @@ public function readAlignmentStyle(Alignment $alignment, SimpleXMLElement $align if ($horizontal !== '') { $alignment->setHorizontal($horizontal); } + $justifyLastLine = (string) $this->getAttribute($alignmentXml, 'justifyLastLine'); + if ($justifyLastLine !== '') { + $alignment->setJustifyLastLine( + self::boolean($justifyLastLine) + ); + } $vertical = (string) $this->getAttribute($alignmentXml, 'vertical'); if ($vertical !== '') { $alignment->setVertical($vertical); diff --git a/src/PhpSpreadsheet/Style/Alignment.php b/src/PhpSpreadsheet/Style/Alignment.php index 3aed77c697..a50229930d 100644 --- a/src/PhpSpreadsheet/Style/Alignment.php +++ b/src/PhpSpreadsheet/Style/Alignment.php @@ -97,6 +97,11 @@ class Alignment extends Supervisor */ protected ?string $horizontal = self::HORIZONTAL_GENERAL; + /** + * Justify Last Line alignment. + */ + protected ?bool $justifyLastLine = null; + /** * Vertical alignment. */ @@ -196,6 +201,9 @@ public function applyFromArray(array $styleArray): static if (isset($styleArray['horizontal'])) { $this->setHorizontal($styleArray['horizontal']); } + if (isset($styleArray['justifyLastLine'])) { + $this->setJustifyLastLine($styleArray['justifyLastLine']); + } if (isset($styleArray['vertical'])) { $this->setVertical($styleArray['vertical']); } @@ -255,6 +263,35 @@ public function setHorizontal(string $horizontalAlignment): static return $this; } + /** + * Get Justify Last Line. + */ + public function getJustifyLastLine(): ?bool + { + if ($this->isSupervisor) { + return $this->getSharedComponent()->getJustifyLastLine(); + } + + return $this->justifyLastLine; + } + + /** + * Set Justify Last Line. + * + * @return $this + */ + public function setJustifyLastLine(bool $justifyLastLine): static + { + if ($this->isSupervisor) { + $styleArray = $this->getStyleArray(['justifyLastLine' => $justifyLastLine]); + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); + } else { + $this->justifyLastLine = $justifyLastLine; + } + + return $this; + } + /** * Get Vertical. */ @@ -475,6 +512,7 @@ public function getHashCode(): string return md5( $this->horizontal + . (($this->justifyLastLine === null) ? 'null' : ($this->justifyLastLine ? 't' : 'f')) . $this->vertical . $this->textRotation . ($this->wrapText ? 't' : 'f') @@ -489,6 +527,7 @@ protected function exportArray1(): array { $exportedArray = []; $this->exportArray2($exportedArray, 'horizontal', $this->getHorizontal()); + $this->exportArray2($exportedArray, 'justifyLastLine', $this->getJustifyLastLine()); $this->exportArray2($exportedArray, 'indent', $this->getIndent()); $this->exportArray2($exportedArray, 'readOrder', $this->getReadOrder()); $this->exportArray2($exportedArray, 'shrinkToFit', $this->getShrinkToFit()); diff --git a/src/PhpSpreadsheet/Writer/Xlsx/Style.php b/src/PhpSpreadsheet/Writer/Xlsx/Style.php index 37c6c31276..8b09dd66ca 100644 --- a/src/PhpSpreadsheet/Writer/Xlsx/Style.php +++ b/src/PhpSpreadsheet/Writer/Xlsx/Style.php @@ -457,6 +457,10 @@ private function writeCellStyleXf(XMLWriter $objWriter, \PhpOffice\PhpSpreadshee if ($vertical !== '') { $objWriter->writeAttribute('vertical', $vertical); } + $justifyLastLine = $style->getAlignment()->getJustifyLastLine(); + if (is_bool($justifyLastLine)) { + $objWriter->writeAttribute('justifyLastLine', (string) (int) $justifyLastLine); + } if ($style->getAlignment()->getTextRotation() >= 0) { $textRotation = $style->getAlignment()->getTextRotation(); diff --git a/tests/PhpSpreadsheetTests/Reader/Xlsx/AlignmentTest.php b/tests/PhpSpreadsheetTests/Reader/Xlsx/AlignmentTest.php new file mode 100644 index 0000000000..bccb99b4a6 --- /dev/null +++ b/tests/PhpSpreadsheetTests/Reader/Xlsx/AlignmentTest.php @@ -0,0 +1,65 @@ +spreadsheet !== null) { + $this->spreadsheet->disconnectWorksheets(); + $this->spreadsheet = null; + } + if ($this->reloadedSpreadsheet !== null) { + $this->reloadedSpreadsheet->disconnectWorksheets(); + $this->reloadedSpreadsheet = null; + } + } + + public function testJustifyLastLine(): void + { + $this->spreadsheet = new Spreadsheet(); + $sheet = $this->spreadsheet->getActiveSheet(); + $sheet->setCellValue('A1', 'ABC'); + $sheet->setCellValue('A2', 'DEF'); + $sheet->setCellValue('A3', 'GHI'); + $sheet->getStyle('A1') + ->getAlignment() + ->setHorizontal(Alignment::HORIZONTAL_DISTRIBUTED) + ->setJustifyLastLine(true); + $sheet->getStyle('A2') + ->getAlignment() + ->setHorizontal(Alignment::HORIZONTAL_DISTRIBUTED) + ->setJustifyLastLine(false); + $sheet->getStyle('A3') + ->getAlignment() + ->setHorizontal(Alignment::HORIZONTAL_DISTRIBUTED); + $this->reloadedSpreadsheet = $this->writeAndReload($this->spreadsheet, 'Xlsx'); + $rsheet = $this->reloadedSpreadsheet->getActiveSheet(); + self::assertTrue( + $rsheet->getStyle('A1') + ->getAlignment() + ->getJustifyLastLine() + ); + self::assertFalse( + $rsheet->getStyle('A2') + ->getAlignment() + ->getJustifyLastLine() + ); + self::assertNull( + $rsheet->getStyle('A3') + ->getAlignment() + ->getJustifyLastLine() + ); + } +} diff --git a/tests/PhpSpreadsheetTests/Style/AlignmentTest.php b/tests/PhpSpreadsheetTests/Style/AlignmentTest.php index 32957d90fa..3a5cecb078 100644 --- a/tests/PhpSpreadsheetTests/Style/AlignmentTest.php +++ b/tests/PhpSpreadsheetTests/Style/AlignmentTest.php @@ -84,6 +84,17 @@ public function testHorizontal(): void self::assertEquals(0, $cell3->getStyle()->getAlignment()->getIndent()); } + public function testJustifyLastLine(): void + { + $this->spreadsheet = new Spreadsheet(); + $sheet = $this->spreadsheet->getActiveSheet(); + $cell1 = $sheet->getCell('A1'); + $cell1->setValue('ABC'); + $cell1->getStyle()->getAlignment()->setHorizontal(Alignment::HORIZONTAL_DISTRIBUTED); + $cell1->getStyle()->getAlignment()->setJustifyLastLine(true); + self::assertTrue($cell1->getStyle()->getAlignment()->getJustifyLastLine()); + } + public function testReadOrder(): void { $this->spreadsheet = new Spreadsheet(); diff --git a/tests/PhpSpreadsheetTests/Writer/Xlsx/Issue3443Test.php b/tests/PhpSpreadsheetTests/Writer/Xlsx/Issue3443Test.php index 8b658bbf0b..54d55ba4be 100644 --- a/tests/PhpSpreadsheetTests/Writer/Xlsx/Issue3443Test.php +++ b/tests/PhpSpreadsheetTests/Writer/Xlsx/Issue3443Test.php @@ -37,6 +37,7 @@ public function testNonDefaultAlign(): void $rsheet = $reloadedSpreadsheet->getActiveSheet(); $expected1 = [ 'horizontal' => 'center', + 'justifyLastLine' => null, 'indent' => 0, 'readOrder' => 0, 'shrinkToFit' => false, @@ -78,6 +79,7 @@ public function testDefaultAlign(): void $rsheet = $reloadedSpreadsheet->getActiveSheet(); $expected1 = [ 'horizontal' => 'general', + 'justifyLastLine' => null, 'indent' => 0, 'readOrder' => 0, 'shrinkToFit' => false,