Merge pull request #83 from box/wrap_text_on_multiline_strings
Set wrap text style when multiline string encountered
This commit is contained in:
commit
353d4e86a5
@ -13,6 +13,9 @@ class XLSX implements EscaperInterface
|
||||
/** @var string[] Control characters to be escaped */
|
||||
protected $controlCharactersEscapingMap;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->controlCharactersEscapingMap = $this->getControlCharactersEscapingMap();
|
||||
|
@ -71,6 +71,51 @@ class StyleHelper
|
||||
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.
|
||||
* @return string
|
||||
|
@ -44,11 +44,6 @@ class Workbook
|
||||
/** @var Worksheet The worksheet where data will be written to */
|
||||
protected $currentWorksheet;
|
||||
|
||||
protected $styles = [];
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @param string $tempFolder
|
||||
* @param bool $shouldUseInlineStrings
|
||||
@ -192,13 +187,15 @@ class Workbook
|
||||
if ($this->shouldCreateNewSheetsAutomatically) {
|
||||
$currentWorksheet = $this->addNewSheetAndMakeItCurrent();
|
||||
|
||||
$registeredStyle = $this->styleHelper->registerStyle($style);
|
||||
$updatedStyle = $this->styleHelper->applyExtraStylesIfNeeded($style, $dataRow);
|
||||
$registeredStyle = $this->styleHelper->registerStyle($updatedStyle);
|
||||
$currentWorksheet->addRow($dataRow, $registeredStyle);
|
||||
} else {
|
||||
// otherwise, do nothing as the data won't be read anyways
|
||||
}
|
||||
} else {
|
||||
$registeredStyle = $this->styleHelper->registerStyle($style);
|
||||
$updatedStyle = $this->styleHelper->applyExtraStylesIfNeeded($style, $dataRow);
|
||||
$registeredStyle = $this->styleHelper->registerStyle($updatedStyle);
|
||||
$currentWorksheet->addRow($dataRow, $registeredStyle);
|
||||
}
|
||||
}
|
||||
|
@ -56,4 +56,34 @@ class StyleHelperTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertEquals(1, $registeredStyle1->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'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 string $fileName
|
||||
|
Loading…
x
Reference in New Issue
Block a user