Set wrap text style when multiline string encountered
Fixes #10 If a cell contains a multiline string, "wrap text" style option should automatically be set.
This commit is contained in:
parent
1c8934790d
commit
c8ddcf5441
@ -13,6 +13,9 @@ class XLSX implements EscaperInterface
|
|||||||
/** @var string[] Control characters to be escaped */
|
/** @var string[] Control characters to be escaped */
|
||||||
protected $controlCharactersEscapingMap;
|
protected $controlCharactersEscapingMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->controlCharactersEscapingMap = $this->getControlCharactersEscapingMap();
|
$this->controlCharactersEscapingMap = $this->getControlCharactersEscapingMap();
|
||||||
|
@ -71,6 +71,51 @@ class StyleHelper
|
|||||||
return $this->styleIdToStyleMappingTable[$styleId];
|
return $this->styleIdToStyleMappingTable[$styleId];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply additional styles if the given row needs it.
|
||||||
|
* Typically, set "wrap text" if a cell contains a new line.
|
||||||
|
*
|
||||||
|
* @param \Box\Spout\Writer\Style\Style $style The original style
|
||||||
|
* @param array $dataRow The row the style will be applied to
|
||||||
|
* @return \Box\Spout\Writer\Style\Style The updated style
|
||||||
|
*/
|
||||||
|
public function applyExtraStylesIfNeeded($style, $dataRow)
|
||||||
|
{
|
||||||
|
$updatedStyle = $this->applyWrapTextIfCellContainsNewLine($style, $dataRow);
|
||||||
|
|
||||||
|
return $updatedStyle;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the "wrap text" option if a cell of the given row contains a new line.
|
||||||
|
*
|
||||||
|
* @NOTE: There is a bug on the Mac version of Excel (2011 and below) where new lines
|
||||||
|
* are ignored even when the "wrap text" option is set. This only occurs with
|
||||||
|
* inline strings (shared strings do work fine).
|
||||||
|
* A workaround would be to encode "\n" as "_x000D_" but it does not work
|
||||||
|
* on the Windows version of Excel...
|
||||||
|
*
|
||||||
|
* @param \Box\Spout\Writer\Style\Style $style The original style
|
||||||
|
* @param array $dataRow The row the style will be applied to
|
||||||
|
* @return \Box\Spout\Writer\Style\Style The eventually updated style
|
||||||
|
*/
|
||||||
|
protected function applyWrapTextIfCellContainsNewLine($style, $dataRow)
|
||||||
|
{
|
||||||
|
// if the "wrap text" option is already set, no-op
|
||||||
|
if ($style->shouldWrapText()) {
|
||||||
|
return $style;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($dataRow as $cell) {
|
||||||
|
if (is_string($cell) && strpos($cell, "\n") !== false) {
|
||||||
|
$style->setShouldWrapText();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $style;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the content of the "styles.xml" file, given a list of styles.
|
* Returns the content of the "styles.xml" file, given a list of styles.
|
||||||
* @return string
|
* @return string
|
||||||
|
@ -44,11 +44,6 @@ class Workbook
|
|||||||
/** @var Worksheet The worksheet where data will be written to */
|
/** @var Worksheet The worksheet where data will be written to */
|
||||||
protected $currentWorksheet;
|
protected $currentWorksheet;
|
||||||
|
|
||||||
protected $styles = [];
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $tempFolder
|
* @param string $tempFolder
|
||||||
* @param bool $shouldUseInlineStrings
|
* @param bool $shouldUseInlineStrings
|
||||||
@ -192,13 +187,15 @@ class Workbook
|
|||||||
if ($this->shouldCreateNewSheetsAutomatically) {
|
if ($this->shouldCreateNewSheetsAutomatically) {
|
||||||
$currentWorksheet = $this->addNewSheetAndMakeItCurrent();
|
$currentWorksheet = $this->addNewSheetAndMakeItCurrent();
|
||||||
|
|
||||||
$registeredStyle = $this->styleHelper->registerStyle($style);
|
$updatedStyle = $this->styleHelper->applyExtraStylesIfNeeded($style, $dataRow);
|
||||||
|
$registeredStyle = $this->styleHelper->registerStyle($updatedStyle);
|
||||||
$currentWorksheet->addRow($dataRow, $registeredStyle);
|
$currentWorksheet->addRow($dataRow, $registeredStyle);
|
||||||
} else {
|
} else {
|
||||||
// otherwise, do nothing as the data won't be read anyways
|
// otherwise, do nothing as the data won't be read anyways
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$registeredStyle = $this->styleHelper->registerStyle($style);
|
$updatedStyle = $this->styleHelper->applyExtraStylesIfNeeded($style, $dataRow);
|
||||||
|
$registeredStyle = $this->styleHelper->registerStyle($updatedStyle);
|
||||||
$currentWorksheet->addRow($dataRow, $registeredStyle);
|
$currentWorksheet->addRow($dataRow, $registeredStyle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -56,4 +56,34 @@ class StyleHelperTest extends \PHPUnit_Framework_TestCase
|
|||||||
$this->assertEquals(1, $registeredStyle1->getId());
|
$this->assertEquals(1, $registeredStyle1->getId());
|
||||||
$this->assertEquals(1, $registeredStyle2->getId());
|
$this->assertEquals(1, $registeredStyle2->getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testApplyExtraStylesIfNeededShouldApplyWrapTextIfCellContainsNewLine()
|
||||||
|
{
|
||||||
|
$style = clone $this->defaultStyle;
|
||||||
|
$styleHelper = new StyleHelper($this->defaultStyle);
|
||||||
|
|
||||||
|
$this->assertFalse($style->shouldWrapText());
|
||||||
|
|
||||||
|
$updatedStyle = $styleHelper->applyExtraStylesIfNeeded($style, [12, 'single line', "multi\nlines", null]);
|
||||||
|
|
||||||
|
$this->assertTrue($updatedStyle->shouldWrapText());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testApplyExtraStylesIfNeededShouldDoNothingIfWrapTextAlreadyApplied()
|
||||||
|
{
|
||||||
|
$style = (new StyleBuilder())->setShouldWrapText()->build();
|
||||||
|
$styleHelper = new StyleHelper($this->defaultStyle);
|
||||||
|
|
||||||
|
$this->assertTrue($style->shouldWrapText());
|
||||||
|
|
||||||
|
$updatedStyle = $styleHelper->applyExtraStylesIfNeeded($style, ["multi\nlines"]);
|
||||||
|
|
||||||
|
$this->assertTrue($updatedStyle->shouldWrapText());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -206,6 +206,25 @@ class WriterWithStyleTest extends \PHPUnit_Framework_TestCase
|
|||||||
$this->assertEquals('1', $cellDomElements[1]->getAttribute('s'));
|
$this->assertEquals('1', $cellDomElements[1]->getAttribute('s'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testAddRowWithStyleShouldApplyWrapTextIfCellContainsNewLine()
|
||||||
|
{
|
||||||
|
$fileName = 'test_add_row_with_style_should_apply_wrap_text_if_new_lines.xlsx';
|
||||||
|
$dataRows = [
|
||||||
|
["xlsx--11\nxlsx--11"],
|
||||||
|
['xlsx--21'],
|
||||||
|
];
|
||||||
|
|
||||||
|
$this->writeToXLSXFile($dataRows, $fileName, $this->defaultStyle);
|
||||||
|
|
||||||
|
$cellXfsDomElement = $this->getXmlSectionFromStylesXmlFile($fileName, 'cellXfs');
|
||||||
|
$xfElement = $cellXfsDomElement->getElementsByTagName('xf')->item(1);
|
||||||
|
$this->assertEquals(1, $xfElement->getAttribute('applyAlignment'));
|
||||||
|
$this->assertFirstChildHasAttributeEquals('1', $xfElement, 'alignment', 'wrapText');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array $allRows
|
* @param array $allRows
|
||||||
* @param string $fileName
|
* @param string $fileName
|
||||||
|
Loading…
x
Reference in New Issue
Block a user