Skip to content

Commit

Permalink
upd: save formulas with values
Browse files Browse the repository at this point in the history
  • Loading branch information
aVadim483 committed Apr 12, 2024
1 parent 86e2695 commit 22eb55d
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 6 deletions.
18 changes: 18 additions & 0 deletions docs/03-writing.md
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,24 @@ $sheet1->writeRow([120, 560]);
$sheet1->writeRow([130, 117]);
```

**Important!** The library cannot pre-calculate values of formulas. It save formulas as is, without pre-calculation.
But when the saved file is opened in Excel, Excel recalculates all cells with formulas and show results.
There's only one way to save pre-calculations: you do those calculations in your code and save them along with the formula
```php
$a1 = 10;
$b1 = 30;
$a2 = 50;
$b2 = 70;
$sheet->writeRow([$a1, $b1]);
$sheet->writeRow([$a2, $b2]);

// formula and pre-calculated result
$a3 = ['=A1+A2', $a1 + $a2];
$b3 = ['=B1+B2', $b1 + $b2];
$sheet->writeRow([$a3, $b3]);
```


### Hyperlinks
You can insert URLs as active hyperlinks

Expand Down
6 changes: 4 additions & 2 deletions src/FastExcelWriter/Sheet.php
Original file line number Diff line number Diff line change
Expand Up @@ -2311,7 +2311,10 @@ protected function _setCellData($cellAddress, $value, $styles = null, ?bool $mer
}

if ($value !== null) {
if (!is_scalar($value)) {
if (is_array($value) && !empty($value[0]) && is_string($value[0]) && ($value[0][0] === '=') && count($value) === 2) {
// it's a formula & value ['=A1+B2', 123]
}
elseif (!is_scalar($value)) {
$addr = Excel::cellAddress($colIdx + 1, $rowIdx + 1);
Exception::throwNew('Value for cell %s must be scalar', $addr);
}
Expand Down Expand Up @@ -2377,7 +2380,6 @@ public function setFormula($cellAddress, $value, array $styles = null): Sheet
$value = '=' . $value;
}

///-- $styles = $styles ? Style::normalize($styles) : null;
$this->_setCellData($cellAddress, $value, $styles, true);

return $this;
Expand Down
16 changes: 12 additions & 4 deletions src/FastExcelWriter/Writer/Writer.php
Original file line number Diff line number Diff line change
Expand Up @@ -1200,14 +1200,22 @@ public function _writeCell(FileWriter $file, int $rowNumber, int $colNumber, $va
if (is_array($value) && isset($value['shared_index'])) {
$file->write('<c r="' . $cellName . '" s="' . $cellStyleIdx . '" t="s"><v>' . $value['shared_index'] . '</v></c>');
}
elseif (!is_scalar($value) || $value === '') { //objects, array, empty; null is not scalar
$file->write('<c r="' . $cellName . '" s="' . $cellStyleIdx . '"/>');
}
elseif (is_string($value) && $value[0] === '=') {
elseif ($value && is_string($value) && $value[0] === '=') {
// formula
$value = $this->_convertFormula($value, [$rowNumber, $colNumber]);
$file->write('<c r="' . $cellName . '" s="' . $cellStyleIdx . '"><f>' . self::xmlSpecialChars($value) . '</f></c>');
}
elseif (is_array($value) && !empty($value[0]) && $value[0][0] === '=' && isset($value[1])) {
// formula & value
$formula = $this->_convertFormula($value[0], [$rowNumber, $colNumber]);
$file->write('<c r="' . $cellName . '" s="' . $cellStyleIdx . '">');
$file->write('<f>' . self::xmlSpecialChars($formula) . '</f>');
$file->write('<v>' . self::xmlSpecialChars($value[1]) . '</v>');
$file->write('</c>');
}
elseif (!is_scalar($value) || $value === '') { //objects, array, empty; null is not scalar
$file->write('<c r="' . $cellName . '" s="' . $cellStyleIdx . '"/>');
}
elseif ($numFormatType === 'n_shared_string') {
$file->write('<c r="' . $cellName . '" s="' . $cellStyleIdx . '" t="s"><v>' . $value . '</v></c>');
}
Expand Down
5 changes: 5 additions & 0 deletions tests/FastExcelWriterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -536,6 +536,7 @@ public function testExcelWriter4()
$data = [
[2, 2, '=RC[-1]+RC[-2]', 2],
[3, 3, '=RC[-1]+RC[-2]', 3],
[4, 4, ['=RC[-1]+RC[-2]', 8], 4], // formula & value
];
$area = $sheet->beginArea('b2');
$area->moveTo('c3');
Expand All @@ -549,6 +550,10 @@ public function testExcelWriter4()

$this->assertEquals([1, 1, '=D3+C3', '1'], $this->getValues(['c3', 'd3', 'e3', 'f3']));

// formula & value
$this->assertEquals(8, $this->cells[6]['E']['v']);
$this->assertEquals('=D6+C6', $this->cells[6]['E']['f']);

$style = $this->getStyle('c3', true);
$this->assertEquals('21', $style['font-size']);
$this->assertEquals('Century', $style['font-name']);
Expand Down

0 comments on commit 22eb55d

Please sign in to comment.