Skip to content

Commit f51ec36

Browse files
committed
Handle Google-only Formulas Exported from Google Sheets
Fix #1637, which went stale but is now re-opened. When Google Sheets exports a document to Xlsx or Ods, it replaces Google-only formulas with something that Excel or LibreOffice can handle. In the test case accompanying this PR, cell C1 on Google Sheets contains `=flatten(A1:A5,B1:B5)`. On export, C1:C10 (the actual result is a 10*1 array) are changed to `=IFERROR(__xludf.DUMMYFUNCTION("flatten(A1:A5, B1:B5)"),1.0)`, where `1.0` is replaced by the calculated value for each cell in question. The issue reports an Internal Error when evaluating such a formula. I am unable to duplicate that. However, PhpSpreadsheet evaluates the cell as a `#NAME?` error rather than the correct value (1.0 for cell C1). The reason is that `__xludf.DUMMYFUNCTION` does not match the regexp for formulas, but does match the regexp for defined names. Not finding such a defined name results in the Name error. Altering the formula regexp to recognize `__xludf.` is easy, and solves the problem.
1 parent f65b0a2 commit f51ec36

File tree

3 files changed

+27
-1
lines changed

3 files changed

+27
-1
lines changed

src/PhpSpreadsheet/Calculation/Calculation.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ class Calculation extends CalculationLocale
3535
// Opening bracket
3636
const CALCULATION_REGEXP_OPENBRACE = '\(';
3737
// Function (allow for the old @ symbol that could be used to prefix a function, but we'll ignore it)
38-
const CALCULATION_REGEXP_FUNCTION = '@?(?:_xlfn\.)?(?:_xlws\.)?([\p{L}][\p{L}\p{N}\.]*)[\s]*\(';
38+
const CALCULATION_REGEXP_FUNCTION = '@?(?:_xlfn\.)?(?:_xlws\.)?((?:__xludf\.)?[\p{L}][\p{L}\p{N}\.]*)[\s]*\(';
3939
// Cell reference (cell or range of cells, with or without a sheet reference)
4040
const CALCULATION_REGEXP_CELLREF = '((([^\s,!&%^\/\*\+<>=:`-]*)|(\'(?:[^\']|\'[^!])+?\')|(\"(?:[^\"]|\"[^!])+?\"))!)?\$?\b([a-z]{1,3})\$?(\d{1,7})(?![\w.])';
4141
// Used only to detect spill operator #
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpOffice\PhpSpreadsheetTests\Reader\Xlsx;
6+
7+
use PhpOffice\PhpSpreadsheet\Reader\Xlsx;
8+
use PHPUnit\Framework\TestCase;
9+
10+
class Issue1637Test extends TestCase
11+
{
12+
private static string $testbook = 'tests/data/Reader/XLSX/issue.1637.xlsx';
13+
14+
public function testXludf(): void
15+
{
16+
$reader = new Xlsx();
17+
$spreadsheet = $reader->load(self::$testbook);
18+
$sheet = $spreadsheet->getActiveSheet();
19+
self::assertSame(
20+
'=IFERROR(__xludf.DUMMYFUNCTION("flatten(A1:A5, B1:B5)"),1.0)',
21+
$sheet->getCell('C1')->getValue()
22+
);
23+
self::assertSame(1.0, $sheet->getCell('C1')->getCalculatedValue());
24+
$spreadsheet->disconnectWorksheets();
25+
}
26+
}
4.8 KB
Binary file not shown.

0 commit comments

Comments
 (0)