update xlsx writer
This commit is contained in:
parent
ab973cab34
commit
7f26167be8
@ -64,14 +64,21 @@ class Cell
|
|||||||
*/
|
*/
|
||||||
protected $style;
|
protected $style;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The cell formula
|
||||||
|
* @var string|null
|
||||||
|
*/
|
||||||
|
protected $formula;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $value mixed
|
* @param $value mixed
|
||||||
* @param Style|null $style
|
* @param Style|null $style
|
||||||
*/
|
*/
|
||||||
public function __construct($value, Style $style = null)
|
public function __construct($value, ?Style $style = null, $formula = null)
|
||||||
{
|
{
|
||||||
$this->setValue($value);
|
$this->setValue($value);
|
||||||
$this->setStyle($style);
|
$this->setStyle($style);
|
||||||
|
$this->setFormula($formula);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -131,6 +138,22 @@ class Cell
|
|||||||
$this->type = $type;
|
$this->type = $type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string|null
|
||||||
|
*/
|
||||||
|
public function getFormula()
|
||||||
|
{
|
||||||
|
return $this->formula;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string|null $formula
|
||||||
|
*/
|
||||||
|
public function setFormula(?string $formula)
|
||||||
|
{
|
||||||
|
$this->formula = $formula;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the current value type
|
* Get the current value type
|
||||||
*
|
*
|
||||||
|
@ -211,18 +211,21 @@ EOD;
|
|||||||
$columnLetters = CellHelper::getColumnLettersFromColumnIndex($columnIndexZeroBased);
|
$columnLetters = CellHelper::getColumnLettersFromColumnIndex($columnIndexZeroBased);
|
||||||
$cellXML = '<c r="' . $columnLetters . $rowIndexOneBased . '"';
|
$cellXML = '<c r="' . $columnLetters . $rowIndexOneBased . '"';
|
||||||
$cellXML .= ' s="' . $styleId . '"';
|
$cellXML .= ' s="' . $styleId . '"';
|
||||||
|
$cellFormulaXMLFragment = $this->getCellFormulaXMLFragment($cell);
|
||||||
|
|
||||||
if ($cell->isString()) {
|
if ($cell->isString()) {
|
||||||
$cellXML .= $this->getCellXMLFragmentForNonEmptyString($cell->getValue());
|
$cellXML .= $this->getCellXMLFragmentForNonEmptyString($cell);
|
||||||
} elseif ($cell->isBoolean()) {
|
} elseif ($cell->isBoolean()) {
|
||||||
$cellXML .= ' t="b"><v>' . (int) ($cell->getValue()) . '</v></c>';
|
$cellXML .= ' t="b">' . $cellFormulaXMLFragment . '<v>' . (int) ($cell->getValue()) . '</v></c>';
|
||||||
} elseif ($cell->isNumeric()) {
|
} elseif ($cell->isNumeric()) {
|
||||||
$cellXML .= '><v>' . $cell->getValue() . '</v></c>';
|
$cellXML .= '>' . $cellFormulaXMLFragment . '<v>' . $cell->getValue() . '</v></c>';
|
||||||
} elseif ($cell->isError() && is_string($cell->getValueEvenIfError())) {
|
} elseif ($cell->isError() && is_string($cell->getValueEvenIfError())) {
|
||||||
// only writes the error value if it's a string
|
// only writes the error value if it's a string
|
||||||
$cellXML .= ' t="e"><v>' . $cell->getValueEvenIfError() . '</v></c>';
|
$cellXML .= ' t="e"><v>' . $cell->getValueEvenIfError() . '</v></c>';
|
||||||
} elseif ($cell->isEmpty()) {
|
} elseif ($cell->isEmpty()) {
|
||||||
if ($this->styleManager->shouldApplyStyleOnEmptyCell($styleId)) {
|
if ($cellFormulaXMLFragment) {
|
||||||
|
$cellXML .= '>' . $cellFormulaXMLFragment . '<v></v></c>';
|
||||||
|
} else if ($this->styleManager->shouldApplyStyleOnEmptyCell($styleId)) {
|
||||||
$cellXML .= '/>';
|
$cellXML .= '/>';
|
||||||
} else {
|
} else {
|
||||||
// don't write empty cells that do no need styling
|
// don't write empty cells that do no need styling
|
||||||
@ -237,19 +240,37 @@ EOD;
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the XML fragment for a cell containing a non empty string
|
* Returns the XML fragment for a cell formula
|
||||||
*
|
*
|
||||||
* @param string $cellValue The cell value
|
* @param string $cellValue The cell value
|
||||||
* @throws InvalidArgumentException If the string exceeds the maximum number of characters allowed per cell
|
* @throws InvalidArgumentException If the string exceeds the maximum number of characters allowed per cell
|
||||||
* @return string The XML fragment representing the cell
|
* @return string The XML fragment representing the cell
|
||||||
*/
|
*/
|
||||||
private function getCellXMLFragmentForNonEmptyString($cellValue)
|
private function getCellFormulaXMLFragment($cell)
|
||||||
{
|
{
|
||||||
|
$cellFormula = $cell->getFormula();
|
||||||
|
return $cellFormula ? '<f>' . $cellFormula . '</f>' : '';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the XML fragment for a cell containing a non empty string
|
||||||
|
*
|
||||||
|
* @param Cell $cell cell
|
||||||
|
* @throws InvalidArgumentException If the string exceeds the maximum number of characters allowed per cell
|
||||||
|
* @return string The XML fragment representing the cell
|
||||||
|
*/
|
||||||
|
private function getCellXMLFragmentForNonEmptyString($cell)
|
||||||
|
{
|
||||||
|
$cellValue = $cell->getValue();
|
||||||
|
$cellFormulaXMLFragment = $this->getCellFormulaXMLFragment($cell);
|
||||||
|
|
||||||
if ($this->stringHelper->getStringLength($cellValue) > self::MAX_CHARACTERS_PER_CELL) {
|
if ($this->stringHelper->getStringLength($cellValue) > self::MAX_CHARACTERS_PER_CELL) {
|
||||||
throw new InvalidArgumentException('Trying to add a value that exceeds the maximum number of characters allowed in a cell (32,767)');
|
throw new InvalidArgumentException('Trying to add a value that exceeds the maximum number of characters allowed in a cell (32,767)');
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->shouldUseInlineStrings) {
|
if ($cellFormulaXMLFragment) {
|
||||||
|
$cellXMLFragment = ' t="str">' . $cellFormulaXMLFragment . '<v>' . $cellValue . '</v></c>';
|
||||||
|
} else if ($this->shouldUseInlineStrings) {
|
||||||
$cellXMLFragment = ' t="inlineStr"><is><t>' . $this->stringsEscaper->escape($cellValue) . '</t></is></c>';
|
$cellXMLFragment = ' t="inlineStr"><is><t>' . $this->stringsEscaper->escape($cellValue) . '</t></is></c>';
|
||||||
} else {
|
} else {
|
||||||
$sharedStringId = $this->sharedStringsManager->writeString($cellValue);
|
$sharedStringId = $this->sharedStringsManager->writeString($cellValue);
|
||||||
|
@ -189,6 +189,33 @@ class WriterTest extends TestCase
|
|||||||
$this->assertEquals($sheets[1], $writer->getCurrentSheet(), 'The current sheet should be the second one.');
|
$this->assertEquals($sheets[1], $writer->getCurrentSheet(), 'The current sheet should be the second one.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testCellFormula()
|
||||||
|
{
|
||||||
|
$fileName = 'test_cell_formula.xlsx';
|
||||||
|
|
||||||
|
$rowsAsArray = [
|
||||||
|
[[1], [3], ['Github link', 'HYPERLINK("https://github.com/","Github link")']],
|
||||||
|
[[0, 'A1+B1'], [-2, 'A1-B1'], ['Google link', 'HYPERLINK("https://google.com/","Google link")'], ['test']],
|
||||||
|
];
|
||||||
|
$rows = array_map(function($rowAsArray) {
|
||||||
|
return WriterEntityFactory::createRow((array_map(function($cellAsArray) {
|
||||||
|
return new Cell($cellAsArray[0] ?? "", null, $cellAsArray[1] ?? "");
|
||||||
|
}, $rowAsArray)));
|
||||||
|
}, $rowsAsArray);
|
||||||
|
|
||||||
|
$this->writeToXLSXFile($rows, $fileName);
|
||||||
|
|
||||||
|
foreach ($rows as $row) {
|
||||||
|
foreach ($row->getCells() as $cell) {
|
||||||
|
$this->assertInlineDataWasWrittenToSheet($fileName, 1, $cell->getValue());
|
||||||
|
$this->assertInlineDataWasWrittenToSheet($fileName, 1, $cell->getFormula());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user