Merge 887d6ef0339aaa04fc15691e3890f8234ccfb8c2 into 84596668410bea89d21aa9867b91e1550e359329
This commit is contained in:
commit
bc54327cf4
@ -117,7 +117,7 @@ $reader->setShouldPreserveEmptyRows(true);
|
||||
For fonts and alignments, {{ site.spout_html }} does not support all the possible formatting options yet. But you can find the most important ones:
|
||||
|
||||
| Category | Property | API
|
||||
|:---------------------|:---------------|:--------------------------------------
|
||||
|:---------------------|:------------------------|:--------------------------------------
|
||||
| Font | Bold | `StyleBuilder::setFontBold()`
|
||||
| | Italic | `StyleBuilder::setFontItalic()`
|
||||
| | Underline | `StyleBuilder::setFontUnderline()`
|
||||
@ -126,6 +126,7 @@ For fonts and alignments, {{ site.spout_html }} does not support all the possibl
|
||||
| | Font size | `StyleBuilder::setFontSize(14)`
|
||||
| | Font color | `StyleBuilder::setFontColor(Color::BLUE)`<br>`StyleBuilder::setFontColor(Color::rgb(0, 128, 255))`
|
||||
| Alignment | Cell alignment | `StyleBuilder::setCellAlignment(CellAlignment::CENTER)`
|
||||
| | Cell vertical alignment | `StyleBuilder::setCellVerticalAlignment(CellVerticalAlignment::CENTER)`
|
||||
| | Wrap text | `StyleBuilder::setShouldWrapText(true)`
|
||||
| Format _(XLSX only)_ | Number format | `StyleBuilder::setFormat('0.000')`
|
||||
| | Date format | `StyleBuilder::setFormat('m/d/yy h:mm')`
|
||||
@ -150,6 +151,7 @@ $style = (new StyleBuilder())
|
||||
->setFontColor(Color::BLUE)
|
||||
->setShouldWrapText()
|
||||
->setCellAlignment(CellAlignment::RIGHT)
|
||||
->setCellVerticalAlignment(CellVerticalAlignment::BOTTOM)
|
||||
->setBackgroundColor(Color::YELLOW)
|
||||
->build();
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
namespace Box\Spout\Common\Entity\Style;
|
||||
|
||||
/**
|
||||
* Class Alignment
|
||||
* Class CellAlignment
|
||||
* This class provides constants to work with text alignment.
|
||||
*/
|
||||
abstract class CellAlignment
|
||||
|
38
src/Spout/Common/Entity/Style/CellVerticalAlignment.php
Normal file
38
src/Spout/Common/Entity/Style/CellVerticalAlignment.php
Normal file
@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace Box\Spout\Common\Entity\Style;
|
||||
|
||||
/**
|
||||
* Class CellVerticalAlignment
|
||||
* This class provides constants to work with text vertical alignment.
|
||||
*/
|
||||
abstract class CellVerticalAlignment
|
||||
{
|
||||
public const AUTO = 'auto';
|
||||
public const BASELINE = 'baseline';
|
||||
public const BOTTOM = 'bottom';
|
||||
public const CENTER = 'center';
|
||||
public const DISTRIBUTED = 'distributed';
|
||||
public const JUSTIFY = 'justify';
|
||||
public const TOP = 'top';
|
||||
|
||||
private static $VALID_ALIGNMENTS = [
|
||||
self::AUTO => 1,
|
||||
self::BASELINE => 1,
|
||||
self::BOTTOM => 1,
|
||||
self::CENTER => 1,
|
||||
self::DISTRIBUTED => 1,
|
||||
self::JUSTIFY => 1,
|
||||
self::TOP => 1,
|
||||
];
|
||||
|
||||
/**
|
||||
* @param string $cellVerticalAlignment
|
||||
*
|
||||
* @return bool Whether the given cell vertical alignment is valid
|
||||
*/
|
||||
public static function isValid($cellVerticalAlignment)
|
||||
{
|
||||
return isset(self::$VALID_ALIGNMENTS[$cellVerticalAlignment]);
|
||||
}
|
||||
}
|
@ -61,6 +61,13 @@ class Style
|
||||
/** @var bool Whether the cell alignment property was set */
|
||||
private $hasSetCellAlignment = false;
|
||||
|
||||
/** @var bool Whether specific cell vertical alignment should be applied */
|
||||
private $shouldApplyCellVerticalAlignment = false;
|
||||
/** @var string Cell vertical alignment */
|
||||
private $cellVerticalAlignment;
|
||||
/** @var bool Whether the cell vertical alignment property was set */
|
||||
private $hasSetCellVerticalAlignment = false;
|
||||
|
||||
/** @var bool Whether the text should wrap in the cell (useful for long or multi-lines text) */
|
||||
private $shouldWrapText = false;
|
||||
/** @var bool Whether the wrap text property was set */
|
||||
@ -354,6 +361,14 @@ class Style
|
||||
return $this->cellAlignment;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getCellVerticalAlignment()
|
||||
{
|
||||
return $this->cellVerticalAlignment;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $cellAlignment The cell alignment
|
||||
*
|
||||
@ -369,6 +384,21 @@ class Style
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $cellVerticalAlignment The cell vertical alignment
|
||||
*
|
||||
* @return Style
|
||||
*/
|
||||
public function setCellVerticalAlignment($cellVerticalAlignment)
|
||||
{
|
||||
$this->cellVerticalAlignment = $cellVerticalAlignment;
|
||||
$this->hasSetCellVerticalAlignment = true;
|
||||
$this->shouldApplyCellVerticalAlignment = true;
|
||||
$this->isEmpty = false;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
@ -377,6 +407,14 @@ class Style
|
||||
return $this->hasSetCellAlignment;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function hasSetCellVerticalAlignment()
|
||||
{
|
||||
return $this->hasSetCellVerticalAlignment;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool Whether specific cell alignment should be applied
|
||||
*/
|
||||
@ -385,6 +423,14 @@ class Style
|
||||
return $this->shouldApplyCellAlignment;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool Whether specific cell alignment should be applied
|
||||
*/
|
||||
public function shouldApplyCellVerticalAlignment()
|
||||
{
|
||||
return $this->shouldApplyCellVerticalAlignment;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
|
@ -4,6 +4,7 @@ namespace Box\Spout\Writer\Common\Creator\Style;
|
||||
|
||||
use Box\Spout\Common\Entity\Style\Border;
|
||||
use Box\Spout\Common\Entity\Style\CellAlignment;
|
||||
use Box\Spout\Common\Entity\Style\CellVerticalAlignment;
|
||||
use Box\Spout\Common\Entity\Style\Style;
|
||||
use Box\Spout\Common\Exception\InvalidArgumentException;
|
||||
|
||||
@ -143,6 +144,25 @@ class StyleBuilder
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the cell vertical alignment.
|
||||
*
|
||||
* @param string $cellVerticalAlignment The cell vertical alignment
|
||||
*
|
||||
* @throws InvalidArgumentException If the given cell vertical alignment is not valid
|
||||
* @return StyleBuilder
|
||||
*/
|
||||
public function setCellVerticalAlignment($cellVerticalAlignment)
|
||||
{
|
||||
if (!CellVerticalAlignment::isValid($cellVerticalAlignment)) {
|
||||
throw new InvalidArgumentException('Invalid cell vertical alignment value');
|
||||
}
|
||||
|
||||
$this->style->setCellVerticalAlignment($cellVerticalAlignment);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a border
|
||||
*
|
||||
|
@ -82,12 +82,15 @@ class StyleMerger
|
||||
*/
|
||||
private function mergeCellProperties(Style $styleToUpdate, Style $style, Style $baseStyle)
|
||||
{
|
||||
if (!$style->hasSetWrapText() && $baseStyle->shouldWrapText()) {
|
||||
$styleToUpdate->setShouldWrapText();
|
||||
if (!$style->hasSetWrapText() && $baseStyle->hasSetWrapText()) {
|
||||
$styleToUpdate->setShouldWrapText($baseStyle->shouldWrapText());
|
||||
}
|
||||
if (!$style->hasSetCellAlignment() && $baseStyle->shouldApplyCellAlignment()) {
|
||||
$styleToUpdate->setCellAlignment($baseStyle->getCellAlignment());
|
||||
}
|
||||
if (!$style->hasSetCellVerticalAlignment() && $baseStyle->shouldApplyCellVerticalAlignment()) {
|
||||
$styleToUpdate->setCellVerticalAlignment($baseStyle->getCellVerticalAlignment());
|
||||
}
|
||||
if ($style->getBorder() === null && $baseStyle->shouldApplyBorder()) {
|
||||
$styleToUpdate->setBorder($baseStyle->getBorder());
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ namespace Box\Spout\Writer\ODS\Manager\Style;
|
||||
|
||||
use Box\Spout\Common\Entity\Style\BorderPart;
|
||||
use Box\Spout\Common\Entity\Style\CellAlignment;
|
||||
use Box\Spout\Common\Entity\Style\CellVerticalAlignment;
|
||||
use Box\Spout\Writer\Common\Entity\Worksheet;
|
||||
use Box\Spout\Writer\ODS\Helper\BorderHelper;
|
||||
|
||||
@ -277,12 +278,13 @@ EOD;
|
||||
*/
|
||||
private function getParagraphPropertiesSectionContent($style)
|
||||
{
|
||||
if (!$style->shouldApplyCellAlignment()) {
|
||||
if (!$style->shouldApplyCellAlignment() && !$style->shouldApplyCellVerticalAlignment()) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return '<style:paragraph-properties '
|
||||
. $this->getCellAlignmentSectionContent($style)
|
||||
. $this->getCellVerticalAlignmentSectionContent($style)
|
||||
. '/>';
|
||||
}
|
||||
|
||||
@ -301,6 +303,21 @@ EOD;
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the contents of the cell vertical alignment definition for the "<style:paragraph-properties>" section
|
||||
*
|
||||
* @param \Box\Spout\Common\Entity\Style\Style $style
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getCellVerticalAlignmentSectionContent($style)
|
||||
{
|
||||
return \sprintf(
|
||||
' fo:vertical-align="%s" ',
|
||||
$this->transformCellVerticalAlignment($style->getCellVerticalAlignment())
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Even though "left" and "right" alignments are part of the spec, and interpreted
|
||||
* respectively as "start" and "end", using the recommended values increase compatibility
|
||||
@ -319,6 +336,21 @@ EOD;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Spec uses 'middle' rather than 'center'
|
||||
* http://docs.oasis-open.org/office/v1.2/os/OpenDocument-v1.2-os-part1.html#__RefHeading__1420236_253892949
|
||||
*
|
||||
* @param string $cellAlignment
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function transformCellVerticalAlignment($cellVerticalAlignment)
|
||||
{
|
||||
return ($cellVerticalAlignment === CellVerticalAlignment::CENTER)
|
||||
? 'middle'
|
||||
: $cellVerticalAlignment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the contents of the "<style:table-cell-properties>" section, inside "<style:style>" section
|
||||
*
|
||||
@ -329,8 +361,8 @@ EOD;
|
||||
{
|
||||
$content = '<style:table-cell-properties ';
|
||||
|
||||
if ($style->shouldWrapText()) {
|
||||
$content .= $this->getWrapTextXMLContent();
|
||||
if ($style->hasSetWrapText()) {
|
||||
$content .= $this->getWrapTextXMLContent($style->shouldWrapText());
|
||||
}
|
||||
|
||||
if ($style->shouldApplyBorder()) {
|
||||
@ -349,11 +381,12 @@ EOD;
|
||||
/**
|
||||
* Returns the contents of the wrap text definition for the "<style:table-cell-properties>" section
|
||||
*
|
||||
* @param boolean $shouldWrapText
|
||||
* @return string
|
||||
*/
|
||||
private function getWrapTextXMLContent()
|
||||
private function getWrapTextXMLContent($shouldWrapText)
|
||||
{
|
||||
return ' fo:wrap-option="wrap" style:vertical-align="automatic" ';
|
||||
return ' fo:wrap-option="' . ($shouldWrapText ? '' : 'no-') . 'wrap" style:vertical-align="automatic" ';
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -250,14 +250,17 @@ EOD;
|
||||
|
||||
$content .= \sprintf(' applyBorder="%d"', $style->shouldApplyBorder() ? 1 : 0);
|
||||
|
||||
if ($style->shouldApplyCellAlignment() || $style->shouldWrapText()) {
|
||||
if ($style->shouldApplyCellAlignment() || $style->shouldApplyCellVerticalAlignment() || $style->hasSetWrapText()) {
|
||||
$content .= ' applyAlignment="1">';
|
||||
$content .= '<alignment';
|
||||
if ($style->shouldApplyCellAlignment()) {
|
||||
$content .= \sprintf(' horizontal="%s"', $style->getCellAlignment());
|
||||
}
|
||||
if ($style->shouldWrapText()) {
|
||||
$content .= ' wrapText="1"';
|
||||
if ($style->shouldApplyCellVerticalAlignment()) {
|
||||
$content .= \sprintf(' vertical="%s"', $style->getCellVerticalAlignment());
|
||||
}
|
||||
if ($style->hasSetWrapText()) {
|
||||
$content .= ' wrapText="' . ($style->shouldWrapText() ? '1' : '0') . '"';
|
||||
}
|
||||
$content .= '/>';
|
||||
$content .= '</xf>';
|
||||
|
@ -4,6 +4,7 @@ namespace Box\Spout\Writer\Common\Creator\Style;
|
||||
|
||||
use Box\Spout\Common\Entity\Style\Border;
|
||||
use Box\Spout\Common\Entity\Style\CellAlignment;
|
||||
use Box\Spout\Common\Entity\Style\CellVerticalAlignment;
|
||||
use Box\Spout\Common\Entity\Style\Color;
|
||||
use Box\Spout\Common\Exception\InvalidArgumentException;
|
||||
use Box\Spout\Writer\Common\Manager\Style\StyleMerger;
|
||||
@ -53,6 +54,15 @@ class StyleBuilderTest extends TestCase
|
||||
$this->assertTrue($style->shouldApplyCellAlignment());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function testStyleBuilderShouldApplyCellVerticalAlignment()
|
||||
{
|
||||
$style = (new StyleBuilder())->setCellVerticalAlignment(CellVerticalAlignment::CENTER)->build();
|
||||
$this->assertTrue($style->shouldApplyCellVerticalAlignment());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
@ -61,4 +71,13 @@ class StyleBuilderTest extends TestCase
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
(new StyleBuilder())->setCellAlignment('invalid_cell_alignment')->build();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function testStyleBuilderShouldThrowOnInvalidCellVerticalAlignment()
|
||||
{
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
(new StyleBuilder())->setCellVerticalAlignment('invalid_cell_alignment')->build();
|
||||
}
|
||||
}
|
||||
|
@ -188,6 +188,27 @@ class WriterWithStyleTest extends TestCase
|
||||
$this->assertFirstChildHasAttributeEquals('wrap', $customStyleElement, 'table-cell-properties', 'fo:wrap-option');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function testAddRowShouldAddNegatedWrapTextAlignmentInfoInStylesXmlFileIfSpecified()
|
||||
{
|
||||
$fileName = 'test_add_row_should_add_negated_wrap_text_alignment.ods';
|
||||
|
||||
$style = (new StyleBuilder())->setShouldWrapText(false)->build();
|
||||
$dataRows = $this->createStyledRowsFromValues([
|
||||
['ods--11', 'ods--12'],
|
||||
], $style);
|
||||
|
||||
$this->writeToODSFile($dataRows, $fileName);
|
||||
|
||||
$styleElements = $this->getCellStyleElementsFromContentXmlFile($fileName);
|
||||
$this->assertCount(2, $styleElements, 'There should be 2 styles (default and custom)');
|
||||
|
||||
$customStyleElement = $styleElements[1];
|
||||
$this->assertFirstChildHasAttributeEquals('no-wrap', $customStyleElement, 'table-cell-properties', 'fo:wrap-option');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
|
@ -271,6 +271,26 @@ class WriterWithStyleTest extends TestCase
|
||||
$this->assertFirstChildHasAttributeEquals('1', $xfElement, 'alignment', 'wrapText');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function testAddRowShouldAddNegatedWrapTextAlignmentInfoInStylesXmlFileIfSpecified()
|
||||
{
|
||||
$fileName = 'test_add_row_should_add_negated_wrap_text_alignment.xlsx';
|
||||
|
||||
$style = (new StyleBuilder())->setShouldWrapText(false)->build();
|
||||
$dataRows = $this->createStyledRowsFromValues([
|
||||
['xlsx--11', 'xlsx--12'],
|
||||
], $style);
|
||||
|
||||
$this->writeToXLSXFile($dataRows, $fileName);
|
||||
|
||||
$cellXfsDomElement = $this->getXmlSectionFromStylesXmlFile($fileName, 'cellXfs');
|
||||
$xfElement = $cellXfsDomElement->getElementsByTagName('xf')->item(1);
|
||||
$this->assertEquals(1, $xfElement->getAttribute('applyAlignment'));
|
||||
$this->assertFirstChildHasAttributeEquals('0', $xfElement, 'alignment', 'wrapText');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user