diff --git a/src/PhpSpreadsheet/Reader/Xlsx.php b/src/PhpSpreadsheet/Reader/Xlsx.php
index c8b2de2a9..2daa2dc07 100644
--- a/src/PhpSpreadsheet/Reader/Xlsx.php
+++ b/src/PhpSpreadsheet/Reader/Xlsx.php
@@ -891,9 +891,16 @@ class Xlsx extends BaseReader
} else {
// Formula
$this->castToFormula($c, $r, $cellDataType, $value, $calculatedValue, 'castToString');
- if (isset($c->f['t'])) {
- $attributes = $c->f['t'];
- $docSheet->getCell($r)->setFormulaAttributes(['t' => (string) $attributes]);
+ $formulaAttributes = [];
+ $attributes = $c->f->attributes();
+ if (isset($attributes['t'])) {
+ $formulaAttributes['t'] = (string) $attributes['t'];
+ }
+ if (isset($attributes['ref'])) {
+ $formulaAttributes['ref'] = (string) $attributes['ref'];
+ }
+ if (!empty($formulaAttributes)) {
+ $docSheet->getCell($r)->setFormulaAttributes($formulaAttributes);
}
}
diff --git a/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php b/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php
index 301d988ab..1b149c833 100644
--- a/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php
+++ b/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php
@@ -1401,8 +1401,8 @@ class Worksheet extends WriterPart
$calculatedValue = (int) $calculatedValue;
}
- $attributes = $cell->getFormulaAttributes();
- $ref = $cell->getCoordinate();
+ $attributes = $cell->getFormulaAttributes() ?? [];
+ $ref = array_key_exists('ref', $attributes) ? $attributes['ref'] : $cell->getCoordinate();
if (is_array($calculatedValue)) {
$attributes['t'] = 'array';
$rows = max(1, count($calculatedValue));
@@ -1424,6 +1424,17 @@ class Worksheet extends WriterPart
$objWriter->writeAttribute('ca', '1');
$objWriter->text(FunctionPrefix::addFunctionPrefixStripEquals($cellValue));
$objWriter->endElement();
+ $result = $calculatedValue;
+ while (is_array($result)) {
+ $result = array_shift($result);
+ }
+ if (
+ is_scalar($result)
+ && $this->getParentWriter()->getOffice2003Compatibility() === false
+ && $this->getParentWriter()->getPreCalculateFormulas()
+ ) {
+ $objWriter->writeElement('v', (string) $result);
+ }
} else {
$objWriter->writeElement('f', FunctionPrefix::addFunctionPrefixStripEquals($cellValue));
self::writeElementIf(
diff --git a/tests/PhpSpreadsheetTests/Writer/Xlsx/ArrayFunctionsTest.php b/tests/PhpSpreadsheetTests/Writer/Xlsx/ArrayFunctionsTest.php
index 39cc72ff7..fc26beb54 100644
--- a/tests/PhpSpreadsheetTests/Writer/Xlsx/ArrayFunctionsTest.php
+++ b/tests/PhpSpreadsheetTests/Writer/Xlsx/ArrayFunctionsTest.php
@@ -120,8 +120,44 @@ class ArrayFunctionsTest extends TestCase
if ($data === false) {
self::fail('Unable to read file');
} else {
- self::assertStringContainsString('_xlfn.UNIQUE(A1:A19)', $data, '15 results for UNIQUE');
- self::assertStringContainsString('_xlfn._xlws.SORT(A1:A19)', $data, '19 results for SORT');
+ self::assertStringContainsString('_xlfn.UNIQUE(A1:A19)41', $data, '15 results for UNIQUE');
+ self::assertStringContainsString('_xlfn._xlws.SORT(A1:A19)26', $data, '19 results for SORT');
+ }
+ }
+
+ public function testUnimplementedArrayOutput(): void
+ {
+ //Calculation::setArrayReturnType(Calculation::RETURN_ARRAY_AS_ARRAY); // not required for this test
+ $reader = new XlsxReader();
+ $spreadsheet = $reader->load('tests/data/Reader/XLSX/atsign.choosecols.xlsx');
+ $writer = new XlsxWriter($spreadsheet);
+ $this->outputFile = File::temporaryFilename();
+ $writer->save($this->outputFile);
+ $spreadsheet->disconnectWorksheets();
+
+ $reader = new XlsxReader();
+ $spreadsheet2 = $reader->load($this->outputFile);
+ $sheet2 = $spreadsheet2->getActiveSheet();
+ self::assertSame('=_xlfn.CHOOSECOLS(A1:C5,3,1)', $sheet2->getCell('F1')->getValue());
+ $expectedFG = [
+ ['11', '1'],
+ ['12', '2'],
+ ['13', '3'],
+ ['14', '4'],
+ ['15', '5'],
+ ];
+ $actualFG = $sheet2->rangeToArray('F1:G5');
+ self::assertSame($expectedFG, $actualFG);
+ $spreadsheet2->disconnectWorksheets();
+
+ $file = 'zip://';
+ $file .= $this->outputFile;
+ $file .= '#xl/worksheets/sheet1.xml';
+ $data = file_get_contents($file);
+ if ($data === false) {
+ self::fail('Unable to read file');
+ } else {
+ self::assertStringContainsString('_xlfn.CHOOSECOLS(A1:C5,3,1)11', $data);
}
}
}
diff --git a/tests/data/Reader/XLSX/atsign.choosecols.xlsx b/tests/data/Reader/XLSX/atsign.choosecols.xlsx
new file mode 100644
index 000000000..45ea6ca2a
Binary files /dev/null and b/tests/data/Reader/XLSX/atsign.choosecols.xlsx differ