Skip to content

Commit d5cdc29

Browse files
authored
Merge pull request #4864 from williamdes/fix/no-spurious-t-attribute-when-pre-calc-off
Don't infer cell t attribute from formula source when pre-calc is off
2 parents c0e3284 + 5eb433e commit d5cdc29

2 files changed

Lines changed: 15 additions & 3 deletions

File tree

src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1576,7 +1576,13 @@ private function writeCellFormula(XMLWriter $objWriter, string $cellValue, Cell
15761576
{
15771577
$attributes = $cell->getFormulaAttributes() ?? [];
15781578
$coordinate = $cell->getCoordinate();
1579-
$calculatedValue = $this->getParentWriter()->getPreCalculateFormulas() ? $cell->getCalculatedValue() : $cellValue;
1579+
$preCalc = $this->getParentWriter()->getPreCalculateFormulas();
1580+
// When pre-calc is off we have no calculated value to infer the cell type from. The
1581+
// previous fall-back of $cellValue (the formula source) made every formula cell write
1582+
// t="str" because the source is always a string — misleading for formulas that resolve
1583+
// to numbers/booleans. Leave $calculatedValue/$calculatedValueString null so the
1584+
// type-inference branches below are skipped and no t attribute is written.
1585+
$calculatedValue = $preCalc ? $cell->getCalculatedValue() : null;
15801586
if ($calculatedValue === ExcelError::SPILL()) {
15811587
$objWriter->writeAttribute('t', 'e');
15821588
//$objWriter->writeAttribute('cm', '1'); // already added
@@ -1592,7 +1598,10 @@ private function writeCellFormula(XMLWriter $objWriter, string $cellValue, Cell
15921598

15931599
return;
15941600
}
1595-
$calculatedValueString = $this->getParentWriter()->getPreCalculateFormulas() ? $cell->getCalculatedValueString() : $cellValue;
1601+
// Empty string (not null) so str_starts_with($calculatedValueString, '#') below stays
1602+
// type-correct when pre-calc is off; the surrounding writeElementIf condition guards
1603+
// against actually emitting <v> when there is no calculated value.
1604+
$calculatedValueString = $preCalc ? $cell->getCalculatedValueString() : '';
15961605
$result = $calculatedValue;
15971606
while (is_array($result)) {
15981607
$result = array_shift($result);

tests/PhpSpreadsheetTests/Writer/PreCalcTest.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,10 @@ private function verifyXlsx(?bool $preCalc, string $type): void
108108
$data = self::readFile($file);
109109
// confirm that file contains B2 pre-calculated or not as appropriate
110110
if ($preCalc === false) {
111-
self::assertStringContainsString('<c r="B2" t="str"><f>3+A3</f></c>', $data);
111+
// No t="str" when pre-calc is off: with no calculated value to inspect, the
112+
// writer can no longer infer the result type from the formula source string
113+
// (which is always a string). Readers compute on open per fullCalcOnLoad.
114+
self::assertStringContainsString('<c r="B2"><f>3+A3</f></c>', $data);
112115
} else {
113116
self::assertStringContainsString('<c r="B2"><f>3+A3</f><v>14</v></c>', $data);
114117
}

0 commit comments

Comments
 (0)