Skip to content

Commit

Permalink
Xlsx Reader Shared Formula with Boolean Results
Browse files Browse the repository at this point in the history
A solution, at least in part, for issue PHPOffice#4280. Xlsx Reader is not handling shared formulae correctly. As a result, some cells are treated as if they contain boolean values rather than formulae.
  • Loading branch information
oleibman committed Dec 17, 2024
1 parent eccbcce commit cf5bf08
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 6 deletions.
14 changes: 8 additions & 6 deletions src/PhpSpreadsheet/Reader/Xlsx.php
Original file line number Diff line number Diff line change
Expand Up @@ -854,6 +854,8 @@ protected function loadSpreadsheetFromFile(string $filename): Spreadsheet
}

// Read cell!
$useFormula = isset($c->f)
&& ((string) $c->f !== '' || (isset($c->f->attributes()['t']) && strtolower((string) $c->f->attributes()['t']) === 'shared'));
switch ($cellDataType) {
case DataType::TYPE_STRING:
if ((string) $c->v != '') {
Expand All @@ -868,7 +870,7 @@ protected function loadSpreadsheetFromFile(string $filename): Spreadsheet

break;
case DataType::TYPE_BOOL:
if (!isset($c->f) || ((string) $c->f) === '') {
if (!$useFormula) {
if (isset($c->v)) {
$value = self::castToBoolean($c);
} else {
Expand All @@ -883,16 +885,16 @@ protected function loadSpreadsheetFromFile(string $filename): Spreadsheet

break;
case DataType::TYPE_STRING2:
if (isset($c->f)) {
if ($useFormula) {
$this->castToFormula($c, $r, $cellDataType, $value, $calculatedValue, 'castToString');
self::storeFormulaAttributes($c->f, $docSheet, $r);
} else {
$value = self::castToString($c);
$value = self::castToString($c);
}

break;
case DataType::TYPE_INLINE:
if (isset($c->f)) {
if ($useFormula) {
$this->castToFormula($c, $r, $cellDataType, $value, $calculatedValue, 'castToError');
self::storeFormulaAttributes($c->f, $docSheet, $r);
} else {
Expand All @@ -901,7 +903,7 @@ protected function loadSpreadsheetFromFile(string $filename): Spreadsheet

break;
case DataType::TYPE_ERROR:
if (!isset($c->f)) {
if (!$useFormula) {
$value = self::castToError($c);
} else {
// Formula
Expand All @@ -916,7 +918,7 @@ protected function loadSpreadsheetFromFile(string $filename): Spreadsheet

break;
default:
if (!isset($c->f)) {
if (!$useFormula) {
$value = self::castToString($c);
if (is_numeric($value)) {
$value += 0;
Expand Down
37 changes: 37 additions & 0 deletions tests/PhpSpreadsheetTests/Reader/Xlsx/SharedFormulaeTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

declare(strict_types=1);

namespace PhpOffice\PhpSpreadsheetTests\Reader\Xlsx;

use PhpOffice\PhpSpreadsheet\IOFactory;
use PHPUnit\Framework\TestCase;

class SharedFormulaeTest extends TestCase
{
public function testSharedFormulae(): void
{
// Boolean functions were not handled correctly.
$filename = 'tests/data/Reader/XLSX/sharedformulae.xlsx';
$reader = IOFactory::createReader('Xlsx');
$spreadsheet = $reader->load($filename);
$sheet = $spreadsheet->getActiveSheet();
$expected = [
[1, '=A1+1', '=A1>3', '="x"&A1'],
[2, '=A2+1', '=A2>3', '="x"&A2'],
[3, '=A3+1', '=A3>3', '="x"&A3'],
[4, '=A4+1', '=A4>3', '="x"&A4'],
[5, '=A5+1', '=A5>3', '="x"&A5'],
];
self::assertSame($expected, $sheet->toArray(null, false, false));
$expected = [
[1, 2, false, 'x1'],
[2, 3, false, 'x2'],
[3, 4, false, 'x3'],
[4, 5, true, 'x4'],
[5, 6, true, 'x5'],
];
self::assertSame($expected, $sheet->toArray(null, true, false));
$spreadsheet->disconnectWorksheets();
}
}
Binary file added tests/data/Reader/XLSX/sharedformulae.xlsx
Binary file not shown.

0 comments on commit cf5bf08

Please sign in to comment.