diff --git a/README.md b/README.md
index a2054be..821c3b7 100644
--- a/README.md
+++ b/README.md
@@ -125,7 +125,7 @@ The writer always generate CSV files encoded in UTF-8, with a BOM.
#### 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
use Box\Spout\Common\Type;
@@ -150,6 +150,33 @@ $writer->addRowsWithStyle($multipleRows, $style); // style will be applied to al
$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:
Category | Property | API
diff --git a/src/Spout/Writer/Exception/Border/InvalidNameException.php b/src/Spout/Writer/Exception/Border/InvalidNameException.php
new file mode 100644
index 0000000..13ac06c
--- /dev/null
+++ b/src/Spout/Writer/Exception/Border/InvalidNameException.php
@@ -0,0 +1,16 @@
+
+ */
+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;
+ }
+}
diff --git a/src/Spout/Writer/ODS/Helper/StyleHelper.php b/src/Spout/Writer/ODS/Helper/StyleHelper.php
index f8b0c4d..7dfb828 100644
--- a/src/Spout/Writer/ODS/Helper/StyleHelper.php
+++ b/src/Spout/Writer/ODS/Helper/StyleHelper.php
@@ -3,6 +3,7 @@
namespace Box\Spout\Writer\ODS\Helper;
use Box\Spout\Writer\Common\Helper\AbstractStyleHelper;
+use Box\Spout\Writer\Style\BorderPart;
/**
* Class StyleHelper
@@ -256,9 +257,16 @@ EOD;
$content .= '';
}
+ if ($style->shouldApplyBorder()) {
+ $borderProperty = '';
+ $borders = array_map(function (BorderPart $borderPart) {
+ return BorderHelper::serializeBorderPart($borderPart);
+ }, $style->getBorder()->getParts());
+ $content .= sprintf($borderProperty, implode(' ', $borders));
+ }
+
$content .= '';
return $content;
}
-
}
diff --git a/src/Spout/Writer/Style/Border.php b/src/Spout/Writer/Style/Border.php
new file mode 100644
index 0000000..b68ec80
--- /dev/null
+++ b/src/Spout/Writer/Style/Border.php
@@ -0,0 +1,67 @@
+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;
+ }
+}
diff --git a/src/Spout/Writer/Style/BorderBuilder.php b/src/Spout/Writer/Style/BorderBuilder.php
new file mode 100644
index 0000000..c0b8aea
--- /dev/null
+++ b/src/Spout/Writer/Style/BorderBuilder.php
@@ -0,0 +1,75 @@
+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;
+ }
+}
diff --git a/src/Spout/Writer/Style/BorderPart.php b/src/Spout/Writer/Style/BorderPart.php
new file mode 100644
index 0000000..9ade797
--- /dev/null
+++ b/src/Spout/Writer/Style/BorderPart.php
@@ -0,0 +1,184 @@
+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;
+ }
+}
diff --git a/src/Spout/Writer/Style/Style.php b/src/Spout/Writer/Style/Style.php
index 91e9475..b595b3a 100644
--- a/src/Spout/Writer/Style/Style.php
+++ b/src/Spout/Writer/Style/Style.php
@@ -61,6 +61,16 @@ class Style
/** @var bool Whether the wrap text property was set */
protected $hasSetWrapText = false;
+ /**
+ * @var Border
+ */
+ protected $border = null;
+
+ /**
+ * @var bool Whether border properties should be applied
+ */
+ protected $shouldApplyBorder = false;
+
/**
* @return int|null
*/
@@ -79,6 +89,32 @@ class Style
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
*/
@@ -302,6 +338,9 @@ class Style
if (!$this->hasSetWrapText && $baseStyle->shouldWrapText()) {
$mergedStyle->setShouldWrapText();
}
+ if (!$this->getBorder() && $baseStyle->shouldApplyBorder()) {
+ $mergedStyle->setBorder($baseStyle->getBorder());
+ }
return $mergedStyle;
}
diff --git a/src/Spout/Writer/Style/StyleBuilder.php b/src/Spout/Writer/Style/StyleBuilder.php
index 4619f43..6d6239c 100644
--- a/src/Spout/Writer/Style/StyleBuilder.php
+++ b/src/Spout/Writer/Style/StyleBuilder.php
@@ -121,6 +121,18 @@ class StyleBuilder
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.
*
diff --git a/src/Spout/Writer/XLSX/Helper/BorderHelper.php b/src/Spout/Writer/XLSX/Helper/BorderHelper.php
new file mode 100644
index 0000000..ad63aea
--- /dev/null
+++ b/src/Spout/Writer/XLSX/Helper/BorderHelper.php
@@ -0,0 +1,68 @@
+ [
+ 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('', $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()];
+ }
+}
diff --git a/src/Spout/Writer/XLSX/Helper/StyleHelper.php b/src/Spout/Writer/XLSX/Helper/StyleHelper.php
index f3da2b5..3c2b3d1 100644
--- a/src/Spout/Writer/XLSX/Helper/StyleHelper.php
+++ b/src/Spout/Writer/XLSX/Helper/StyleHelper.php
@@ -100,17 +100,29 @@ EOD;
*/
protected function getBordersSectionContent()
{
- return <<
-
-
-
-
-
-
-
-
-EOD;
+ $registeredStyles = $this->getRegisteredStyles();
+ $registeredStylesCount = count($registeredStyles);
+
+ $content = '';
+
+ /** @var \Box\Spout\Writer\Style\Style $style */
+ foreach ($registeredStyles as $style) {
+ $border = $style->getBorder();
+ if ($border) {
+ $content .= '';
+ foreach ($border->getParts() as $part) {
+ /** @var $part \Box\Spout\Writer\Style\BorderPart */
+ $content .= BorderHelper::serializeBorderPart($part);
+ }
+ $content .= '';
+ } else {
+ $content .= '';
+ }
+ }
+
+ $content .= '';
+
+ return $content;
}
/**
@@ -139,12 +151,16 @@ EOD;
$content = '';
foreach ($registeredStyles as $style) {
- $content .= 'getId() . '" fillId="0" borderId="' . $style->getId() . '" xfId="0"';
if ($style->shouldApplyFont()) {
$content .= ' applyFont="1"';
}
+ if ($style->shouldApplyBorder()) {
+ $content .= ' applyBorder="1"';
+ }
+
if ($style->shouldWrapText()) {
$content .= ' applyAlignment="1">';
$content .= '';
diff --git a/tests/Spout/Writer/ODS/WriterWithStyleTest.php b/tests/Spout/Writer/ODS/WriterWithStyleTest.php
index 9888bfc..7a7c190 100644
--- a/tests/Spout/Writer/ODS/WriterWithStyleTest.php
+++ b/tests/Spout/Writer/ODS/WriterWithStyleTest.php
@@ -5,6 +5,9 @@ namespace Box\Spout\Writer\ODS;
use Box\Spout\Common\Type;
use Box\Spout\Reader\Wrapper\XMLReader;
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\Style;
use Box\Spout\Writer\Style\StyleBuilder;
@@ -208,7 +211,7 @@ class WriterWithStyleTest extends \PHPUnit_Framework_TestCase
];
$style = (new StyleBuilder())->setShouldWrapText()->build();
- $this->writeToODSFile($dataRows, $fileName,$style);
+ $this->writeToODSFile($dataRows, $fileName, $style);
$styleElements = $this->getCellStyleElementsFromContentXmlFile($fileName);
$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');
}
+ /**
+ * @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 string $fileName
diff --git a/tests/Spout/Writer/Style/BorderTest.php b/tests/Spout/Writer/Style/BorderTest.php
new file mode 100644
index 0000000..181d8cf
--- /dev/null
+++ b/tests/Spout/Writer/Style/BorderTest.php
@@ -0,0 +1,110 @@
+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());
+ }
+ }
+ }
+ }
+}
diff --git a/tests/Spout/Writer/Style/StyleTest.php b/tests/Spout/Writer/Style/StyleTest.php
index fb93e9b..7d3ec36 100644
--- a/tests/Spout/Writer/Style/StyleTest.php
+++ b/tests/Spout/Writer/Style/StyleTest.php
@@ -129,4 +129,32 @@ class StyleTest extends \PHPUnit_Framework_TestCase
$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');
+ }
}
diff --git a/tests/Spout/Writer/XLSX/WriterWithStyleTest.php b/tests/Spout/Writer/XLSX/WriterWithStyleTest.php
index d43b566..df34a33 100644
--- a/tests/Spout/Writer/XLSX/WriterWithStyleTest.php
+++ b/tests/Spout/Writer/XLSX/WriterWithStyleTest.php
@@ -5,6 +5,8 @@ namespace Box\Spout\Writer\XLSX;
use Box\Spout\Common\Type;
use Box\Spout\Reader\Wrapper\XMLReader;
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\Style;
use Box\Spout\Writer\Style\StyleBuilder;
@@ -205,7 +207,7 @@ class WriterWithStyleTest extends \PHPUnit_Framework_TestCase
];
$style = (new StyleBuilder())->setShouldWrapText()->build();
- $this->writeToXLSXFile($dataRows, $fileName,$style);
+ $this->writeToXLSXFile($dataRows, $fileName, $style);
$cellXfsDomElement = $this->getXmlSectionFromStylesXmlFile($fileName, 'cellXfs');
$xfElement = $cellXfsDomElement->getElementsByTagName('xf')->item(1);
@@ -232,6 +234,40 @@ class WriterWithStyleTest extends \PHPUnit_Framework_TestCase
$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 string $fileName