Fixes #135 Added border support for ODS and XLSX files. Updated README.
This commit is contained in:
parent
1891c0b053
commit
e30bc37448
29
README.md
29
README.md
@ -125,7 +125,7 @@ The writer always generate CSV files encoded in UTF-8, with a BOM.
|
|||||||
|
|
||||||
#### Row styling
|
#### Row styling
|
||||||
|
|
||||||
It is possible to apply some formatting options to a row. Spout supports fonts as well as alignment styles.
|
It is possible to apply some formatting options to a row. Spout supports fonts, borders as well as alignment styles.
|
||||||
|
|
||||||
```php
|
```php
|
||||||
use Box\Spout\Common\Type;
|
use Box\Spout\Common\Type;
|
||||||
@ -150,6 +150,33 @@ $writer->addRowsWithStyle($multipleRows, $style); // style will be applied to al
|
|||||||
$writer->close();
|
$writer->close();
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Adding borders to a row requires a ```Border``` object.
|
||||||
|
|
||||||
|
```php
|
||||||
|
use Box\Spout\Common\Type;
|
||||||
|
use Box\Spout\Writer\Style\Border;
|
||||||
|
use Box\Spout\Writer\Style\BorderBuilder;
|
||||||
|
use Box\Spout\Writer\Style\Color;
|
||||||
|
use Box\Spout\Writer\Style\StyleBuilder;
|
||||||
|
use Box\Spout\Writer\WriterFactory;
|
||||||
|
|
||||||
|
$border = (new BorderBuilder())
|
||||||
|
->setBorderBottom(Color::GREEN, Border::WIDTH_THIN, Border::STYLE_DASHED)
|
||||||
|
->build();
|
||||||
|
|
||||||
|
$style = (new StyleBuilder())
|
||||||
|
->setBorder($border)
|
||||||
|
->build();
|
||||||
|
|
||||||
|
$writer = WriterFactory::create(Type::ODS);
|
||||||
|
$writer->openToFile(__DIR__ . '/borders.xlsx');
|
||||||
|
|
||||||
|
$writer->addRowWithStyle(['Border Bottom Green Thin Dashed'], $style)
|
||||||
|
|
||||||
|
$writer->close();
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
Unfortunately, Spout does not support all the possible formatting options yet. But you can find the most important ones:
|
Unfortunately, Spout does not support all the possible formatting options yet. But you can find the most important ones:
|
||||||
|
|
||||||
Category | Property | API
|
Category | Property | API
|
||||||
|
16
src/Spout/Writer/Exception/Border/InvalidNameException.php
Normal file
16
src/Spout/Writer/Exception/Border/InvalidNameException.php
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Box\Spout\Writer\Exception\Border;
|
||||||
|
|
||||||
|
use Box\Spout\Writer\Exception\WriterException;
|
||||||
|
use Box\Spout\Writer\Style\BorderPart;
|
||||||
|
|
||||||
|
class InvalidNameException extends WriterException
|
||||||
|
{
|
||||||
|
public function __construct($name)
|
||||||
|
{
|
||||||
|
$msg = '%s is not a valid name identifier for a border. Valid identifiers are: %s.';
|
||||||
|
|
||||||
|
parent::__construct(sprintf($msg, $name, implode(',', BorderPart::getAllowedNames())));
|
||||||
|
}
|
||||||
|
}
|
16
src/Spout/Writer/Exception/Border/InvalidStyleException.php
Normal file
16
src/Spout/Writer/Exception/Border/InvalidStyleException.php
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Box\Spout\Writer\Exception\Border;
|
||||||
|
|
||||||
|
use Box\Spout\Writer\Exception\WriterException;
|
||||||
|
use Box\Spout\Writer\Style\BorderPart;
|
||||||
|
|
||||||
|
class InvalidStyleException extends WriterException
|
||||||
|
{
|
||||||
|
public function __construct($name)
|
||||||
|
{
|
||||||
|
$msg = '%s is not a valid style identifier for a border. Valid identifiers are: %s.';
|
||||||
|
|
||||||
|
parent::__construct(sprintf($msg, $name, implode(',', BorderPart::getAllowedStyles())));
|
||||||
|
}
|
||||||
|
}
|
16
src/Spout/Writer/Exception/Border/InvalidWidthException.php
Normal file
16
src/Spout/Writer/Exception/Border/InvalidWidthException.php
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Box\Spout\Writer\Exception\Border;
|
||||||
|
|
||||||
|
use Box\Spout\Writer\Exception\WriterException;
|
||||||
|
use Box\Spout\Writer\Style\BorderPart;
|
||||||
|
|
||||||
|
class InvalidWidthException extends WriterException
|
||||||
|
{
|
||||||
|
public function __construct($name)
|
||||||
|
{
|
||||||
|
$msg = '%s is not a valid width identifier for a border. Valid identifiers are: %s.';
|
||||||
|
|
||||||
|
parent::__construct(sprintf($msg, $name, implode(',', BorderPart::getAllowedWidths())));
|
||||||
|
}
|
||||||
|
}
|
68
src/Spout/Writer/ODS/Helper/BorderHelper.php
Normal file
68
src/Spout/Writer/ODS/Helper/BorderHelper.php
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Box\Spout\Writer\ODS\Helper;
|
||||||
|
|
||||||
|
use Box\Spout\Writer\Style\BorderPart;
|
||||||
|
use Box\Spout\Writer\Style\Border;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class BorderHelper
|
||||||
|
*
|
||||||
|
* The fo:border, fo:border-top, fo:border-bottom, fo:border-left and fo:border-right attributes
|
||||||
|
* specify border properties
|
||||||
|
* http://docs.oasis-open.org/office/v1.2/os/OpenDocument-v1.2-os-part1.html#__RefHeading__1419780_253892949
|
||||||
|
*
|
||||||
|
* Example table-cell-properties
|
||||||
|
*
|
||||||
|
* <style:table-cell-properties
|
||||||
|
* fo:border-bottom="0.74pt solid #ffc000" style:diagonal-bl-tr="none"
|
||||||
|
* style:diagonal-tl-br="none" fo:border-left="none" fo:border-right="none"
|
||||||
|
* style:rotation-align="none" fo:border-top="none"/>
|
||||||
|
*/
|
||||||
|
class BorderHelper
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Width mappings
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected static $widthMap = [
|
||||||
|
Border::WIDTH_THIN => '0.75pt',
|
||||||
|
Border::WIDTH_MEDIUM => '1.75pt',
|
||||||
|
Border::WIDTH_THICK => '2.5pt',
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Style mapping
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected static $styleMap = [
|
||||||
|
Border::STYLE_SOLID => 'solid',
|
||||||
|
Border::STYLE_DASHED => 'dashed',
|
||||||
|
Border::STYLE_DOTTED => 'dotted',
|
||||||
|
Border::STYLE_DOUBLE => 'double',
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param BorderPart $borderPart
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function serializeBorderPart(BorderPart $borderPart)
|
||||||
|
{
|
||||||
|
$definition = 'fo:border-%s="%s"';
|
||||||
|
|
||||||
|
if ($borderPart->getStyle() === Border::STYLE_NONE) {
|
||||||
|
$borderPartDefinition = sprintf($definition, $borderPart->getName(), 'none');
|
||||||
|
} else {
|
||||||
|
$attributes = [
|
||||||
|
self::$widthMap[$borderPart->getWidth()],
|
||||||
|
self::$styleMap[$borderPart->getStyle()],
|
||||||
|
'#' . $borderPart->getColor(),
|
||||||
|
];
|
||||||
|
$borderPartDefinition = sprintf($definition, $borderPart->getName(), implode(' ', $attributes));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $borderPartDefinition;
|
||||||
|
}
|
||||||
|
}
|
@ -3,6 +3,7 @@
|
|||||||
namespace Box\Spout\Writer\ODS\Helper;
|
namespace Box\Spout\Writer\ODS\Helper;
|
||||||
|
|
||||||
use Box\Spout\Writer\Common\Helper\AbstractStyleHelper;
|
use Box\Spout\Writer\Common\Helper\AbstractStyleHelper;
|
||||||
|
use Box\Spout\Writer\Style\BorderPart;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class StyleHelper
|
* Class StyleHelper
|
||||||
@ -256,9 +257,16 @@ EOD;
|
|||||||
$content .= '<style:table-cell-properties fo:wrap-option="wrap" style:vertical-align="automatic"/>';
|
$content .= '<style:table-cell-properties fo:wrap-option="wrap" style:vertical-align="automatic"/>';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($style->shouldApplyBorder()) {
|
||||||
|
$borderProperty = '<style:table-cell-properties %s />';
|
||||||
|
$borders = array_map(function (BorderPart $borderPart) {
|
||||||
|
return BorderHelper::serializeBorderPart($borderPart);
|
||||||
|
}, $style->getBorder()->getParts());
|
||||||
|
$content .= sprintf($borderProperty, implode(' ', $borders));
|
||||||
|
}
|
||||||
|
|
||||||
$content .= '</style:style>';
|
$content .= '</style:style>';
|
||||||
|
|
||||||
return $content;
|
return $content;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
67
src/Spout/Writer/Style/Border.php
Normal file
67
src/Spout/Writer/Style/Border.php
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Box\Spout\Writer\Style;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Border
|
||||||
|
*/
|
||||||
|
class Border
|
||||||
|
{
|
||||||
|
const LEFT = 'left';
|
||||||
|
const RIGHT = 'right';
|
||||||
|
const TOP = 'top';
|
||||||
|
const BOTTOM = 'bottom';
|
||||||
|
|
||||||
|
const STYLE_NONE = 'none';
|
||||||
|
const STYLE_SOLID = 'solid';
|
||||||
|
const STYLE_DASHED = 'dashed';
|
||||||
|
const STYLE_DOTTED = 'dotted';
|
||||||
|
const STYLE_DOUBLE = 'double';
|
||||||
|
|
||||||
|
const WIDTH_THIN = 'thin';
|
||||||
|
const WIDTH_MEDIUM = 'medium';
|
||||||
|
const WIDTH_THICK = 'thick';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array A list of BorderPart objects for this border.
|
||||||
|
*/
|
||||||
|
protected $parts = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array|void $borderParts
|
||||||
|
*/
|
||||||
|
public function __construct(array $borderParts = [])
|
||||||
|
{
|
||||||
|
$this->setParts($borderParts);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getParts()
|
||||||
|
{
|
||||||
|
return $this->parts;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set BorderParts
|
||||||
|
* @param array $parts
|
||||||
|
*/
|
||||||
|
public function setParts($parts)
|
||||||
|
{
|
||||||
|
unset($this->parts);
|
||||||
|
foreach ($parts as $part) {
|
||||||
|
$this->addPart($part);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param BorderPart $borderPart
|
||||||
|
* @return self
|
||||||
|
*/
|
||||||
|
public function addPart(BorderPart $borderPart)
|
||||||
|
{
|
||||||
|
$this->parts[$borderPart->getName()] = $borderPart;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
}
|
75
src/Spout/Writer/Style/BorderBuilder.php
Normal file
75
src/Spout/Writer/Style/BorderBuilder.php
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Box\Spout\Writer\Style;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class BorderBuilder
|
||||||
|
*/
|
||||||
|
class BorderBuilder
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var Border
|
||||||
|
*/
|
||||||
|
protected $border;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->border = new Border();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string|void $color Border A RGB color code
|
||||||
|
* @param string|void $width Border width @see BorderPart::allowedWidths
|
||||||
|
* @param string|void $style Border style @see BorderPart::allowedStyles
|
||||||
|
* @return BorderBuilder
|
||||||
|
*/
|
||||||
|
public function setBorderTop($color = Color::BLACK, $width = Border::WIDTH_MEDIUM, $style = Border::STYLE_SOLID)
|
||||||
|
{
|
||||||
|
$this->border->addPart(new BorderPart(Border::TOP, $color, $width, $style));
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string|void $color Border A RGB color code
|
||||||
|
* @param string|void $width Border width @see BorderPart::allowedWidths
|
||||||
|
* @param string|void $style Border style @see BorderPart::allowedStyles
|
||||||
|
* @return BorderBuilder
|
||||||
|
*/
|
||||||
|
public function setBorderRight($color = Color::BLACK, $width = Border::WIDTH_MEDIUM, $style = Border::STYLE_SOLID)
|
||||||
|
{
|
||||||
|
$this->border->addPart(new BorderPart(Border::RIGHT, $color, $width, $style));
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string|void $color Border A RGB color code
|
||||||
|
* @param string|void $width Border width @see BorderPart::allowedWidths
|
||||||
|
* @param string|void $style Border style @see BorderPart::allowedStyles
|
||||||
|
* @return BorderBuilder
|
||||||
|
*/
|
||||||
|
public function setBorderBottom($color = Color::BLACK, $width = Border::WIDTH_MEDIUM, $style = Border::STYLE_SOLID)
|
||||||
|
{
|
||||||
|
$this->border->addPart(new BorderPart(Border::BOTTOM, $color, $width, $style));
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string|void $color Border A RGB color code
|
||||||
|
* @param string|void $width Border width @see BorderPart::allowedWidths
|
||||||
|
* @param string|void $style Border style @see BorderPart::allowedStyles
|
||||||
|
* @return BorderBuilder
|
||||||
|
*/
|
||||||
|
public function setBorderLeft($color = Color::BLACK, $width = Border::WIDTH_MEDIUM, $style = Border::STYLE_SOLID)
|
||||||
|
{
|
||||||
|
$this->border->addPart(new BorderPart(Border::LEFT, $color, $width, $style));
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Border
|
||||||
|
*/
|
||||||
|
public function build()
|
||||||
|
{
|
||||||
|
return $this->border;
|
||||||
|
}
|
||||||
|
}
|
184
src/Spout/Writer/Style/BorderPart.php
Normal file
184
src/Spout/Writer/Style/BorderPart.php
Normal file
@ -0,0 +1,184 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Box\Spout\Writer\Style;
|
||||||
|
|
||||||
|
use Box\Spout\Writer\Exception\Border\InvalidNameException;
|
||||||
|
use Box\Spout\Writer\Exception\Border\InvalidStyleException;
|
||||||
|
use Box\Spout\Writer\Exception\Border\InvalidWidthException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class BorderPart
|
||||||
|
*/
|
||||||
|
class BorderPart
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var string The style of this border part.
|
||||||
|
*/
|
||||||
|
protected $style;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string The name of this border part.
|
||||||
|
*/
|
||||||
|
protected $name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string The color of this border part.
|
||||||
|
*/
|
||||||
|
protected $color;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string The width of this border part.
|
||||||
|
*/
|
||||||
|
protected $width;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array Allowed style constants for parts.
|
||||||
|
*/
|
||||||
|
protected static $allowedStyles = [
|
||||||
|
'none',
|
||||||
|
'solid',
|
||||||
|
'dashed',
|
||||||
|
'dotted',
|
||||||
|
'double'
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array Allowed names constants for border parts.
|
||||||
|
*/
|
||||||
|
protected static $allowedNames = [
|
||||||
|
'left',
|
||||||
|
'right',
|
||||||
|
'top',
|
||||||
|
'bottom',
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array Allowed width constants for border parts.
|
||||||
|
*/
|
||||||
|
protected static $allowedWidths = [
|
||||||
|
'thin',
|
||||||
|
'medium',
|
||||||
|
'thick',
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $name @see BorderPart::$allowedNames
|
||||||
|
* @param string $color A RGB color code
|
||||||
|
* @param string $width @see BorderPart::$allowedWidths
|
||||||
|
* @param string $style @see BorderPart::$allowedStyles
|
||||||
|
* @throws InvalidNameException
|
||||||
|
* @throws InvalidStyleException
|
||||||
|
* @throws InvalidWidthException
|
||||||
|
*/
|
||||||
|
public function __construct($name, $color = Color::BLACK, $width = Border::WIDTH_MEDIUM, $style = Border::STYLE_SOLID)
|
||||||
|
{
|
||||||
|
$this->setName($name);
|
||||||
|
$this->setColor($color);
|
||||||
|
$this->setWidth($width);
|
||||||
|
$this->setStyle($style);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getName()
|
||||||
|
{
|
||||||
|
return $this->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $name The name of the border part @see BorderPart::$allowedNames
|
||||||
|
* @throws InvalidNameException
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function setName($name)
|
||||||
|
{
|
||||||
|
if (!in_array($name, self::$allowedNames)) {
|
||||||
|
throw new InvalidNameException($name);
|
||||||
|
}
|
||||||
|
$this->name = $name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getStyle()
|
||||||
|
{
|
||||||
|
return $this->style;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $style The style of the border part @see BorderPart::$allowedStyles
|
||||||
|
* @throws InvalidStyleException
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function setStyle($style)
|
||||||
|
{
|
||||||
|
if (!in_array($style, self::$allowedStyles)) {
|
||||||
|
throw new InvalidStyleException($style);
|
||||||
|
}
|
||||||
|
$this->style = $style;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getColor()
|
||||||
|
{
|
||||||
|
return $this->color;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $color The color of the border part @see Color::rgb()
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function setColor($color)
|
||||||
|
{
|
||||||
|
$this->color = $color;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getWidth()
|
||||||
|
{
|
||||||
|
return $this->width;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $width The width of the border part @see BorderPart::$allowedWidths
|
||||||
|
* @throws InvalidWidthException
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function setWidth($width)
|
||||||
|
{
|
||||||
|
if (!in_array($width, self::$allowedWidths)) {
|
||||||
|
throw new InvalidWidthException($width);
|
||||||
|
}
|
||||||
|
$this->width = $width;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function getAllowedStyles()
|
||||||
|
{
|
||||||
|
return self::$allowedStyles;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function getAllowedNames()
|
||||||
|
{
|
||||||
|
return self::$allowedNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function getAllowedWidths()
|
||||||
|
{
|
||||||
|
return self::$allowedWidths;
|
||||||
|
}
|
||||||
|
}
|
@ -61,6 +61,16 @@ class Style
|
|||||||
/** @var bool Whether the wrap text property was set */
|
/** @var bool Whether the wrap text property was set */
|
||||||
protected $hasSetWrapText = false;
|
protected $hasSetWrapText = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Border
|
||||||
|
*/
|
||||||
|
protected $border = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var bool Whether border properties should be applied
|
||||||
|
*/
|
||||||
|
protected $shouldApplyBorder = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return int|null
|
* @return int|null
|
||||||
*/
|
*/
|
||||||
@ -79,6 +89,32 @@ class Style
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Border
|
||||||
|
*/
|
||||||
|
public function getBorder()
|
||||||
|
{
|
||||||
|
return $this->border;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Border $border
|
||||||
|
*/
|
||||||
|
public function setBorder(Border $border)
|
||||||
|
{
|
||||||
|
$this->shouldApplyBorder = true;
|
||||||
|
$this->border = $border;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public function shouldApplyBorder()
|
||||||
|
{
|
||||||
|
return $this->shouldApplyBorder;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
@ -302,6 +338,9 @@ class Style
|
|||||||
if (!$this->hasSetWrapText && $baseStyle->shouldWrapText()) {
|
if (!$this->hasSetWrapText && $baseStyle->shouldWrapText()) {
|
||||||
$mergedStyle->setShouldWrapText();
|
$mergedStyle->setShouldWrapText();
|
||||||
}
|
}
|
||||||
|
if (!$this->getBorder() && $baseStyle->shouldApplyBorder()) {
|
||||||
|
$mergedStyle->setBorder($baseStyle->getBorder());
|
||||||
|
}
|
||||||
|
|
||||||
return $mergedStyle;
|
return $mergedStyle;
|
||||||
}
|
}
|
||||||
|
@ -121,6 +121,18 @@ class StyleBuilder
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a border
|
||||||
|
*
|
||||||
|
* @param Border $border
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function setBorder(Border $border)
|
||||||
|
{
|
||||||
|
$this->style->setBorder($border);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the configured style. The style is cached and can be reused.
|
* Returns the configured style. The style is cached and can be reused.
|
||||||
*
|
*
|
||||||
|
68
src/Spout/Writer/XLSX/Helper/BorderHelper.php
Normal file
68
src/Spout/Writer/XLSX/Helper/BorderHelper.php
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Box\Spout\Writer\XLSX\Helper;
|
||||||
|
|
||||||
|
use Box\Spout\Writer\Style\Border;
|
||||||
|
use Box\Spout\Writer\Style\BorderPart;
|
||||||
|
|
||||||
|
class BorderHelper
|
||||||
|
{
|
||||||
|
public static $xlsxStyleMap = [
|
||||||
|
Border::STYLE_SOLID => [
|
||||||
|
Border::WIDTH_THIN => 'thin',
|
||||||
|
Border::WIDTH_MEDIUM => 'medium',
|
||||||
|
Border::WIDTH_THICK => 'thick'
|
||||||
|
],
|
||||||
|
Border::STYLE_DOTTED => [
|
||||||
|
Border::WIDTH_THIN => 'dotted',
|
||||||
|
Border::WIDTH_MEDIUM => 'dotted',
|
||||||
|
Border::WIDTH_THICK => 'dotted',
|
||||||
|
],
|
||||||
|
Border::STYLE_DASHED => [
|
||||||
|
Border::WIDTH_THIN => 'dashed',
|
||||||
|
Border::WIDTH_MEDIUM => 'mediumDashed',
|
||||||
|
Border::WIDTH_THICK => 'mediumDashed',
|
||||||
|
],
|
||||||
|
Border::STYLE_DOUBLE => [
|
||||||
|
Border::WIDTH_THIN => 'double',
|
||||||
|
Border::WIDTH_MEDIUM => 'double',
|
||||||
|
Border::WIDTH_THICK => 'double',
|
||||||
|
],
|
||||||
|
Border::STYLE_NONE => [
|
||||||
|
Border::WIDTH_THIN => 'none',
|
||||||
|
Border::WIDTH_MEDIUM => 'none',
|
||||||
|
Border::WIDTH_THICK => 'none',
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param BorderPart $borderPart
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function serializeBorderPart(BorderPart $borderPart)
|
||||||
|
{
|
||||||
|
$borderStyle = self::getBorderStyle($borderPart);
|
||||||
|
|
||||||
|
$colorEl = $borderPart->getColor() ? sprintf('<color rgb="%s"/>', $borderPart->getColor()) : '';
|
||||||
|
$partEl = sprintf(
|
||||||
|
'<%s style="%s">%s</%s>',
|
||||||
|
$borderPart->getName(),
|
||||||
|
$borderStyle,
|
||||||
|
$colorEl,
|
||||||
|
$borderPart->getName()
|
||||||
|
);
|
||||||
|
|
||||||
|
return $partEl . PHP_EOL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the style definition from the style map
|
||||||
|
*
|
||||||
|
* @param BorderPart $borderPart
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected static function getBorderStyle(BorderPart $borderPart)
|
||||||
|
{
|
||||||
|
return self::$xlsxStyleMap[$borderPart->getStyle()][$borderPart->getWidth()];
|
||||||
|
}
|
||||||
|
}
|
@ -100,17 +100,29 @@ EOD;
|
|||||||
*/
|
*/
|
||||||
protected function getBordersSectionContent()
|
protected function getBordersSectionContent()
|
||||||
{
|
{
|
||||||
return <<<EOD
|
$registeredStyles = $this->getRegisteredStyles();
|
||||||
<borders count="1">
|
$registeredStylesCount = count($registeredStyles);
|
||||||
<border>
|
|
||||||
<left/>
|
$content = '<borders count="' . $registeredStylesCount . '">';
|
||||||
<right/>
|
|
||||||
<top/>
|
/** @var \Box\Spout\Writer\Style\Style $style */
|
||||||
<bottom/>
|
foreach ($registeredStyles as $style) {
|
||||||
<diagonal/>
|
$border = $style->getBorder();
|
||||||
</border>
|
if ($border) {
|
||||||
</borders>
|
$content .= '<border>';
|
||||||
EOD;
|
foreach ($border->getParts() as $part) {
|
||||||
|
/** @var $part \Box\Spout\Writer\Style\BorderPart */
|
||||||
|
$content .= BorderHelper::serializeBorderPart($part);
|
||||||
|
}
|
||||||
|
$content .= '</border>';
|
||||||
|
} else {
|
||||||
|
$content .= '<border><left/><right/><top/><bottom/><diagonal/></border>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$content .= '</borders>';
|
||||||
|
|
||||||
|
return $content;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -139,12 +151,16 @@ EOD;
|
|||||||
$content = '<cellXfs count="' . count($registeredStyles) . '">';
|
$content = '<cellXfs count="' . count($registeredStyles) . '">';
|
||||||
|
|
||||||
foreach ($registeredStyles as $style) {
|
foreach ($registeredStyles as $style) {
|
||||||
$content .= '<xf numFmtId="0" fontId="' . $style->getId() . '" fillId="0" borderId="0" xfId="0"';
|
$content .= '<xf numFmtId="0" fontId="' . $style->getId() . '" fillId="0" borderId="' . $style->getId() . '" xfId="0"';
|
||||||
|
|
||||||
if ($style->shouldApplyFont()) {
|
if ($style->shouldApplyFont()) {
|
||||||
$content .= ' applyFont="1"';
|
$content .= ' applyFont="1"';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($style->shouldApplyBorder()) {
|
||||||
|
$content .= ' applyBorder="1"';
|
||||||
|
}
|
||||||
|
|
||||||
if ($style->shouldWrapText()) {
|
if ($style->shouldWrapText()) {
|
||||||
$content .= ' applyAlignment="1">';
|
$content .= ' applyAlignment="1">';
|
||||||
$content .= '<alignment wrapText="1"/>';
|
$content .= '<alignment wrapText="1"/>';
|
||||||
|
@ -5,6 +5,9 @@ namespace Box\Spout\Writer\ODS;
|
|||||||
use Box\Spout\Common\Type;
|
use Box\Spout\Common\Type;
|
||||||
use Box\Spout\Reader\Wrapper\XMLReader;
|
use Box\Spout\Reader\Wrapper\XMLReader;
|
||||||
use Box\Spout\TestUsingResource;
|
use Box\Spout\TestUsingResource;
|
||||||
|
use Box\Spout\Writer\ODS\Helper\BorderHelper;
|
||||||
|
use Box\Spout\Writer\Style\Border;
|
||||||
|
use Box\Spout\Writer\Style\BorderBuilder;
|
||||||
use Box\Spout\Writer\Style\Color;
|
use Box\Spout\Writer\Style\Color;
|
||||||
use Box\Spout\Writer\Style\Style;
|
use Box\Spout\Writer\Style\Style;
|
||||||
use Box\Spout\Writer\Style\StyleBuilder;
|
use Box\Spout\Writer\Style\StyleBuilder;
|
||||||
@ -208,7 +211,7 @@ class WriterWithStyleTest extends \PHPUnit_Framework_TestCase
|
|||||||
];
|
];
|
||||||
$style = (new StyleBuilder())->setShouldWrapText()->build();
|
$style = (new StyleBuilder())->setShouldWrapText()->build();
|
||||||
|
|
||||||
$this->writeToODSFile($dataRows, $fileName,$style);
|
$this->writeToODSFile($dataRows, $fileName, $style);
|
||||||
|
|
||||||
$styleElements = $this->getCellStyleElementsFromContentXmlFile($fileName);
|
$styleElements = $this->getCellStyleElementsFromContentXmlFile($fileName);
|
||||||
$this->assertEquals(2, count($styleElements), 'There should be 2 styles (default and custom)');
|
$this->assertEquals(2, count($styleElements), 'There should be 2 styles (default and custom)');
|
||||||
@ -236,6 +239,72 @@ class WriterWithStyleTest extends \PHPUnit_Framework_TestCase
|
|||||||
$this->assertFirstChildHasAttributeEquals('wrap', $customStyleElement, 'table-cell-properties', 'fo:wrap-option');
|
$this->assertFirstChildHasAttributeEquals('wrap', $customStyleElement, 'table-cell-properties', 'fo:wrap-option');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testBorders()
|
||||||
|
{
|
||||||
|
$fileName = 'test_borders.ods';
|
||||||
|
|
||||||
|
$dataRows = [
|
||||||
|
['row-with-border-bottom-green-thick-solid'],
|
||||||
|
['row-without-border'],
|
||||||
|
['row-with-border-top-red-thin-dashed'],
|
||||||
|
];
|
||||||
|
|
||||||
|
$borderBottomGreenThickSolid = (new BorderBuilder())
|
||||||
|
->setBorderBottom(Color::GREEN, Border::WIDTH_THICK, Border::STYLE_SOLID)->build();
|
||||||
|
|
||||||
|
|
||||||
|
$borderTopRedThinDashed = (new BorderBuilder())
|
||||||
|
->setBorderTop(Color::RED, Border::WIDTH_THIN, Border::STYLE_DASHED)->build();
|
||||||
|
|
||||||
|
$styles = [
|
||||||
|
(new StyleBuilder())->setBorder($borderBottomGreenThickSolid)->build(),
|
||||||
|
(new StyleBuilder())->build(),
|
||||||
|
(new StyleBuilder())->setBorder($borderTopRedThinDashed)->build(),
|
||||||
|
];
|
||||||
|
|
||||||
|
$this->writeToODSFileWithMultipleStyles($dataRows, $fileName, $styles);
|
||||||
|
|
||||||
|
$styleElements = $this->getCellStyleElementsFromContentXmlFile($fileName);
|
||||||
|
|
||||||
|
$this->assertEquals(3, count($styleElements), 'There should be 3 styles)');
|
||||||
|
|
||||||
|
// Use reflection for protected members here
|
||||||
|
$widthMap = \ReflectionHelper::getStaticValue('Box\Spout\Writer\ODS\Helper\BorderHelper', 'widthMap');
|
||||||
|
$styleMap = \ReflectionHelper::getStaticValue('Box\Spout\Writer\ODS\Helper\BorderHelper', 'styleMap');
|
||||||
|
|
||||||
|
$expectedFirst = sprintf(
|
||||||
|
'%s %s #%s',
|
||||||
|
$widthMap[Border::WIDTH_THICK],
|
||||||
|
$styleMap[Border::STYLE_SOLID],
|
||||||
|
Color::GREEN
|
||||||
|
);
|
||||||
|
|
||||||
|
$actualFirst = $styleElements[1]
|
||||||
|
->getElementsByTagName('table-cell-properties')
|
||||||
|
->item(0)
|
||||||
|
->getAttribute('fo:border-bottom');
|
||||||
|
|
||||||
|
$this->assertEquals($expectedFirst, $actualFirst);
|
||||||
|
|
||||||
|
$expectedThird = sprintf(
|
||||||
|
'%s %s #%s',
|
||||||
|
$widthMap[Border::WIDTH_THIN],
|
||||||
|
$styleMap[Border::STYLE_DASHED],
|
||||||
|
Color::RED
|
||||||
|
);
|
||||||
|
|
||||||
|
$actualThird = $styleElements[2]
|
||||||
|
->getElementsByTagName('table-cell-properties')
|
||||||
|
->item(0)
|
||||||
|
->getAttribute('fo:border-top');
|
||||||
|
|
||||||
|
$this->assertEquals($expectedThird, $actualThird);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array $allRows
|
* @param array $allRows
|
||||||
* @param string $fileName
|
* @param string $fileName
|
||||||
|
110
tests/Spout/Writer/Style/BorderTest.php
Normal file
110
tests/Spout/Writer/Style/BorderTest.php
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Box\Spout\Writer\Style;
|
||||||
|
|
||||||
|
class BorderTest extends \PHPUnit_Framework_TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testValidInstance()
|
||||||
|
{
|
||||||
|
$noConstructorParams = new Border();
|
||||||
|
$withConstructorParams = new Border([
|
||||||
|
new BorderPart(Border::LEFT)
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException \Box\Spout\Writer\Exception\Border\InvalidNameException
|
||||||
|
*/
|
||||||
|
public function testInvalidBorderPart()
|
||||||
|
{
|
||||||
|
$invalidBorderPart = new BorderPart('invalid');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException \Box\Spout\Writer\Exception\Border\InvalidStyleException
|
||||||
|
*/
|
||||||
|
public function testInvalidBorderPartStyle()
|
||||||
|
{
|
||||||
|
$invalidBorderPartStyle = new BorderPart(Border::LEFT, Color::BLACK, Border::WIDTH_THIN, 'invalid');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException \Box\Spout\Writer\Exception\Border\InvalidWidthException
|
||||||
|
*/
|
||||||
|
public function testInvalidBorderPartWidth()
|
||||||
|
{
|
||||||
|
$invalidBorderPartStyle = new BorderPart(Border::LEFT, Color::BLACK, 'invalid', Border::STYLE_DASHED);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testNotMoreThanFourPartsPossible()
|
||||||
|
{
|
||||||
|
$border = new Border();
|
||||||
|
$border
|
||||||
|
->addPart(new BorderPart(Border::LEFT))
|
||||||
|
->addPart(new BorderPart(Border::RIGHT))
|
||||||
|
->addPart(new BorderPart(Border::TOP))
|
||||||
|
->addPart(new BorderPart(Border::BOTTOM))
|
||||||
|
->addPart(new BorderPart(Border::LEFT));
|
||||||
|
|
||||||
|
$this->assertEquals(4, count($border->getParts()), 'There should never be more than 4 border parts');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testSetParts()
|
||||||
|
{
|
||||||
|
$border = new Border();
|
||||||
|
$border->setParts([
|
||||||
|
new BorderPart(Border::LEFT)
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->assertEquals(1, count($border->getParts()), 'It should be possible to set the border parts');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testBorderBuilderFluent()
|
||||||
|
{
|
||||||
|
$border = (new BorderBuilder())
|
||||||
|
->setBorderBottom()
|
||||||
|
->setBorderTop()
|
||||||
|
->setBorderLeft()
|
||||||
|
->setBorderRight()
|
||||||
|
->build();
|
||||||
|
$this->assertEquals(4, count($border->getParts()), 'The border builder exposes a fluent interface');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* :D :S
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testAnyCombinationOfAllowedBorderPartsParams()
|
||||||
|
{
|
||||||
|
$color = Color::BLACK;
|
||||||
|
foreach (BorderPart::getAllowedNames() as $allowedName) {
|
||||||
|
foreach (BorderPart::getAllowedStyles() as $allowedStyle) {
|
||||||
|
foreach (BorderPart::getAllowedWidths() as $allowedWidth) {
|
||||||
|
$borderPart = new BorderPart($allowedName, $color, $allowedWidth, $allowedStyle);
|
||||||
|
$border = new Border();
|
||||||
|
$border->addPart($borderPart);
|
||||||
|
$this->assertEquals(1, count($border->getParts()));
|
||||||
|
|
||||||
|
/** @var $part BorderPart */
|
||||||
|
$part = $border->getParts()[$allowedName];
|
||||||
|
|
||||||
|
$this->assertEquals($allowedStyle, $part->getStyle());
|
||||||
|
$this->assertEquals($allowedWidth, $part->getWidth());
|
||||||
|
$this->assertEquals($color, $part->getColor());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -129,4 +129,32 @@ class StyleTest extends \PHPUnit_Framework_TestCase
|
|||||||
|
|
||||||
$this->assertTrue($currentStyle->serialize() === $mergedStyle->serialize());
|
$this->assertTrue($currentStyle->serialize() === $mergedStyle->serialize());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testStyleBuilderShouldApplyBorders()
|
||||||
|
{
|
||||||
|
$border = (new BorderBuilder())
|
||||||
|
->setBorderBottom()
|
||||||
|
->build();
|
||||||
|
$style = (new StyleBuilder())->setBorder($border)->build();
|
||||||
|
$this->assertTrue($style->shouldApplyBorder());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testStyleBuilderShouldMergeBorders()
|
||||||
|
{
|
||||||
|
$border = (new BorderBuilder())->setBorderBottom(Color::RED, Border::WIDTH_THIN, Border::STYLE_DASHED)->build();
|
||||||
|
|
||||||
|
$baseStyle = (new StyleBuilder())->setBorder($border)->build();
|
||||||
|
$currentStyle = (new StyleBuilder())->build();
|
||||||
|
$mergedStyle = $currentStyle->mergeWith($baseStyle);
|
||||||
|
|
||||||
|
$this->assertEquals(null, $currentStyle->getBorder(), 'Current style has no border');
|
||||||
|
$this->assertInstanceOf('Box\Spout\Writer\Style\Border', $baseStyle->getBorder(), 'Base style has a border');
|
||||||
|
$this->assertInstanceOf('Box\Spout\Writer\Style\Border', $mergedStyle->getBorder(), 'Merged style has a border');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,8 @@ namespace Box\Spout\Writer\XLSX;
|
|||||||
use Box\Spout\Common\Type;
|
use Box\Spout\Common\Type;
|
||||||
use Box\Spout\Reader\Wrapper\XMLReader;
|
use Box\Spout\Reader\Wrapper\XMLReader;
|
||||||
use Box\Spout\TestUsingResource;
|
use Box\Spout\TestUsingResource;
|
||||||
|
use Box\Spout\Writer\Style\Border;
|
||||||
|
use Box\Spout\Writer\Style\BorderBuilder;
|
||||||
use Box\Spout\Writer\Style\Color;
|
use Box\Spout\Writer\Style\Color;
|
||||||
use Box\Spout\Writer\Style\Style;
|
use Box\Spout\Writer\Style\Style;
|
||||||
use Box\Spout\Writer\Style\StyleBuilder;
|
use Box\Spout\Writer\Style\StyleBuilder;
|
||||||
@ -205,7 +207,7 @@ class WriterWithStyleTest extends \PHPUnit_Framework_TestCase
|
|||||||
];
|
];
|
||||||
$style = (new StyleBuilder())->setShouldWrapText()->build();
|
$style = (new StyleBuilder())->setShouldWrapText()->build();
|
||||||
|
|
||||||
$this->writeToXLSXFile($dataRows, $fileName,$style);
|
$this->writeToXLSXFile($dataRows, $fileName, $style);
|
||||||
|
|
||||||
$cellXfsDomElement = $this->getXmlSectionFromStylesXmlFile($fileName, 'cellXfs');
|
$cellXfsDomElement = $this->getXmlSectionFromStylesXmlFile($fileName, 'cellXfs');
|
||||||
$xfElement = $cellXfsDomElement->getElementsByTagName('xf')->item(1);
|
$xfElement = $cellXfsDomElement->getElementsByTagName('xf')->item(1);
|
||||||
@ -232,6 +234,40 @@ class WriterWithStyleTest extends \PHPUnit_Framework_TestCase
|
|||||||
$this->assertFirstChildHasAttributeEquals('1', $xfElement, 'alignment', 'wrapText');
|
$this->assertFirstChildHasAttributeEquals('1', $xfElement, 'alignment', 'wrapText');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testBorders()
|
||||||
|
{
|
||||||
|
$fileName = 'test_borders.xlsx';
|
||||||
|
|
||||||
|
$dataRows = [
|
||||||
|
['row-with-border-bottom-green-thick-solid'],
|
||||||
|
['row-without-border'],
|
||||||
|
['row-with-border-top-red-thin-dashed'],
|
||||||
|
];
|
||||||
|
|
||||||
|
$borderBottomGreenThickSolid = (new BorderBuilder())
|
||||||
|
->setBorderBottom(Color::GREEN, Border::WIDTH_THICK, Border::STYLE_SOLID)->build();
|
||||||
|
|
||||||
|
|
||||||
|
$borderTopRedThinDashed = (new BorderBuilder())
|
||||||
|
->setBorderTop(Color::RED, Border::WIDTH_THIN, Border::STYLE_DASHED)->build();
|
||||||
|
|
||||||
|
$styles = [
|
||||||
|
(new StyleBuilder())->setBorder($borderBottomGreenThickSolid)->build(),
|
||||||
|
(new StyleBuilder())->build(),
|
||||||
|
(new StyleBuilder())->setBorder($borderTopRedThinDashed)->build(),
|
||||||
|
];
|
||||||
|
|
||||||
|
$this->writeToXLSXFileWithMultipleStyles($dataRows, $fileName, $styles);
|
||||||
|
$borderElements = $this->getXmlSectionFromStylesXmlFile($fileName, 'borders');
|
||||||
|
$this->assertEquals(3, $borderElements->getAttribute('count'), '3 borders present');
|
||||||
|
|
||||||
|
$styleXfsElements = $this->getXmlSectionFromStylesXmlFile($fileName, 'cellXfs');
|
||||||
|
$this->assertEquals(3, $styleXfsElements->getAttribute('count'), '3 cell xfs present');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array $allRows
|
* @param array $allRows
|
||||||
* @param string $fileName
|
* @param string $fileName
|
||||||
|
Loading…
x
Reference in New Issue
Block a user