Cell alignment
This PR adds support for cell alignment for XLSX and ODS files.
You can now align the content of the cells this way:
```
use Box\Spout\Common\Entity\Style\CellAlignment;
use Box\Spout\Writer\Common\Creator\Style\StyleBuilder;
$style = (new StyleBuilder())
->setCellAlignment(CellAlignment::RIGHT)
->build();
...
```
Possible cell alignments are: LEFT, RIGHT, CENTER and JUSTIFY.
This commit is contained in:
1 parent
0a0b1f7196
commit
9f4c094fa0
12 files changed
+246
-46
No files matched your search
@@ -3,7 +3,9 @@
|
||||
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\Style;
|
||||
use Box\Spout\Common\Exception\InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* Class StyleBuilder
|
||||
@@ -122,6 +124,25 @@ class StyleBuilder
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the cell alignment.
|
||||
*
|
||||
* @param string $cellAlignment The cell alignment
|
||||
*
|
||||
* @throws InvalidArgumentException If the given cell alignment is not valid
|
||||
* @return StyleBuilder
|
||||
*/
|
||||
public function setCellAlignment($cellAlignment)
|
||||
{
|
||||
if (!CellAlignment::isValid($cellAlignment)) {
|
||||
throw new InvalidArgumentException('Invalid cell alignment value');
|
||||
}
|
||||
|
||||
$this->style->setCellAlignment($cellAlignment);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a border
|
||||
*
|
||||
|
||||
@@ -85,6 +85,9 @@ class StyleMerger
|
||||
if (!$style->hasSetWrapText() && $baseStyle->shouldWrapText()) {
|
||||
$styleToUpdate->setShouldWrapText();
|
||||
}
|
||||
if (!$style->hasSetCellAlignment() && $baseStyle->shouldApplyCellAlignment()) {
|
||||
$styleToUpdate->setCellAlignment($baseStyle->getCellAlignment());
|
||||
}
|
||||
if (!$style->getBorder() && $baseStyle->shouldApplyBorder()) {
|
||||
$styleToUpdate->setBorder($baseStyle->getBorder());
|
||||
}
|
||||
|
||||
@@ -3,6 +3,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\Writer\Common\Entity\Worksheet;
|
||||
use Box\Spout\Writer\ODS\Helper\BorderHelper;
|
||||
|
||||
@@ -199,6 +200,7 @@ EOD;
|
||||
$content = '<style:style style:data-style-name="N0" style:family="table-cell" style:name="ce' . $styleIndex . '" style:parent-style-name="Default">';
|
||||
|
||||
$content .= $this->getTextPropertiesSectionContent($style);
|
||||
$content .= $this->getParagraphPropertiesSectionContent($style);
|
||||
$content .= $this->getTableCellPropertiesSectionContent($style);
|
||||
|
||||
$content .= '</style:style>';
|
||||
@@ -214,26 +216,26 @@ EOD;
|
||||
*/
|
||||
private function getTextPropertiesSectionContent($style)
|
||||
{
|
||||
$content = '';
|
||||
|
||||
if ($style->shouldApplyFont()) {
|
||||
$content .= $this->getFontSectionContent($style);
|
||||
if (!$style->shouldApplyFont()) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return $content;
|
||||
return '<style:text-properties '
|
||||
. $this->getFontSectionContent($style)
|
||||
. '/>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the contents of the "<style:text-properties>" section, inside "<style:style>" section
|
||||
* Returns the contents of the fonts definition section, inside "<style:text-properties>" section
|
||||
*
|
||||
* @param \Box\Spout\Common\Entity\Style\Style $style
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getFontSectionContent($style)
|
||||
{
|
||||
$defaultStyle = $this->getDefaultStyle();
|
||||
|
||||
$content = '<style:text-properties';
|
||||
$content = '';
|
||||
|
||||
$fontColor = $style->getFontColor();
|
||||
if ($fontColor !== $defaultStyle->getFontColor()) {
|
||||
@@ -263,11 +265,60 @@ EOD;
|
||||
$content .= ' style:text-line-through-style="solid"';
|
||||
}
|
||||
|
||||
$content .= '/>';
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the contents of the "<style:paragraph-properties>" section, inside "<style:style>" section
|
||||
*
|
||||
* @param \Box\Spout\Common\Entity\Style\Style $style
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getParagraphPropertiesSectionContent($style)
|
||||
{
|
||||
if (!$style->shouldApplyCellAlignment()) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return '<style:paragraph-properties '
|
||||
. $this->getCellAlignmentSectionContent($style)
|
||||
. '/>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the contents of the cell alignment definition for the "<style:paragraph-properties>" section
|
||||
*
|
||||
* @param \Box\Spout\Common\Entity\Style\Style $style
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getCellAlignmentSectionContent($style)
|
||||
{
|
||||
return sprintf(
|
||||
' fo:text-align="%s" ',
|
||||
$this->transformCellAlignment($style->getCellAlignment())
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Even though "left" and "right" alignments are part of the spec, and interpreted
|
||||
* respectively as "start" and "end", using the recommended values increase compatibility
|
||||
* with software that will read the created ODS file.
|
||||
*
|
||||
* @param string $cellAlignment
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function transformCellAlignment($cellAlignment)
|
||||
{
|
||||
switch ($cellAlignment) {
|
||||
case CellAlignment::LEFT: return 'start';
|
||||
case CellAlignment::RIGHT: return 'end';
|
||||
default: return $cellAlignment;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the contents of the "<style:table-cell-properties>" section, inside "<style:style>" section
|
||||
*
|
||||
@@ -276,7 +327,7 @@ EOD;
|
||||
*/
|
||||
private function getTableCellPropertiesSectionContent($style)
|
||||
{
|
||||
$content = '';
|
||||
$content = '<style:table-cell-properties ';
|
||||
|
||||
if ($style->shouldWrapText()) {
|
||||
$content .= $this->getWrapTextXMLContent();
|
||||
@@ -290,6 +341,8 @@ EOD;
|
||||
$content .= $this->getBackgroundColorXMLContent($style);
|
||||
}
|
||||
|
||||
$content .= '/>';
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
@@ -300,7 +353,7 @@ EOD;
|
||||
*/
|
||||
private function getWrapTextXMLContent()
|
||||
{
|
||||
return '<style:table-cell-properties fo:wrap-option="wrap" style:vertical-align="automatic"/>';
|
||||
return ' fo:wrap-option="wrap" style:vertical-align="automatic" ';
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -311,13 +364,11 @@ EOD;
|
||||
*/
|
||||
private function getBorderXMLContent($style)
|
||||
{
|
||||
$borderProperty = '<style:table-cell-properties %s />';
|
||||
|
||||
$borders = array_map(function (BorderPart $borderPart) {
|
||||
return BorderHelper::serializeBorderPart($borderPart);
|
||||
}, $style->getBorder()->getParts());
|
||||
|
||||
return sprintf($borderProperty, implode(' ', $borders));
|
||||
return sprintf(' %s ', implode(' ', $borders));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -328,9 +379,6 @@ EOD;
|
||||
*/
|
||||
private function getBackgroundColorXMLContent($style)
|
||||
{
|
||||
return sprintf(
|
||||
'<style:table-cell-properties fo:background-color="#%s"/>',
|
||||
$style->getBackgroundColor()
|
||||
);
|
||||
return sprintf(' fo:background-color="#%s" ', $style->getBackgroundColor());
|
||||
}
|
||||
}
|
||||
@@ -249,9 +249,16 @@ EOD;
|
||||
|
||||
$content .= sprintf(' applyBorder="%d"', $style->shouldApplyBorder() ? 1 : 0);
|
||||
|
||||
if ($style->shouldWrapText()) {
|
||||
if ($style->shouldApplyCellAlignment() || $style->shouldWrapText()) {
|
||||
$content .= ' applyAlignment="1">';
|
||||
$content .= '<alignment wrapText="1"/>';
|
||||
$content .= '<alignment';
|
||||
if ($style->shouldApplyCellAlignment()) {
|
||||
$content .= sprintf(' horizontal="%s"', $style->getCellAlignment());
|
||||
}
|
||||
if ($style->shouldWrapText()) {
|
||||
$content .= ' wrapText="1"';
|
||||
}
|
||||
$content .= '/>';
|
||||
$content .= '</xf>';
|
||||
} else {
|
||||
$content .= '/>';
|
||||
|
||||
Reference in new issue
Block a user