From 4724c8f7e96ccfcf6d20360ead93dda81ee3b978 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Thu, 4 Aug 2022 14:05:18 +0200 Subject: [PATCH] Initial work on the ARRAYTOTEXT() Excel Function --- CHANGELOG.md | 1 + .../Calculation/Calculation.php | 4 +- .../Calculation/TextData/Text.php | 44 +++++++++++++++++++ .../Functions/TextData/ArrayToTextTest.php | 24 ++++++++++ .../data/Calculation/TextData/ARRAYTOTEXT.php | 26 +++++++++++ 5 files changed, 97 insertions(+), 2 deletions(-) create mode 100644 tests/PhpSpreadsheetTests/Calculation/Functions/TextData/ArrayToTextTest.php create mode 100644 tests/data/Calculation/TextData/ARRAYTOTEXT.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 017e31ed..38c1b6b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org). ### Added - Implementation of the new `TEXTBEFORE()`, `TEXTAFTER()` and `TEXTSPLIT()` Excel Functions +- Implementation of the `ARRAYTOTEXT()` Excel Function ### Changed diff --git a/src/PhpSpreadsheet/Calculation/Calculation.php b/src/PhpSpreadsheet/Calculation/Calculation.php index 13f38f66..cf93a694 100644 --- a/src/PhpSpreadsheet/Calculation/Calculation.php +++ b/src/PhpSpreadsheet/Calculation/Calculation.php @@ -304,8 +304,8 @@ class Calculation ], 'ARRAYTOTEXT' => [ 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '?', + 'functionCall' => [TextData\Text::class, 'fromArray'], + 'argumentCount' => '1,2', ], 'ASC' => [ 'category' => Category::CATEGORY_TEXT_AND_DATA, diff --git a/src/PhpSpreadsheet/Calculation/TextData/Text.php b/src/PhpSpreadsheet/Calculation/TextData/Text.php index bd533f20..83810422 100644 --- a/src/PhpSpreadsheet/Calculation/TextData/Text.php +++ b/src/PhpSpreadsheet/Calculation/TextData/Text.php @@ -3,6 +3,7 @@ namespace PhpOffice\PhpSpreadsheet\Calculation\TextData; use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Functions; class Text @@ -207,4 +208,47 @@ class Text { return ($matchMode === true) ? 'miu' : 'mu'; } + + public static function fromArray(array $array, int $format = 0): string + { + $result = []; + foreach ($array as $row) { + $cells = []; + foreach ($row as $cellValue) { + $value = ($format === 1) ? self::formatValueMode1($cellValue) : self::formatValueMode0($cellValue); + $cells[] = $value; + } + $result[] = implode(($format === 1) ? ',' : ', ', $cells); + } + + $result = implode(($format === 1) ? ';' : ', ', $result); + + return ($format === 1) ? '{' . $result . '}' : $result; + } + + /** + * @param mixed $cellValue + */ + private static function formatValueMode0($cellValue): string + { + if (is_bool($cellValue)) { + return ($cellValue) ? Calculation::$localeBoolean['TRUE'] : Calculation::$localeBoolean['FALSE']; + } + + return (string) $cellValue; + } + + /** + * @param mixed $cellValue + */ + private static function formatValueMode1($cellValue): string + { + if (is_string($cellValue) && Functions::isError($cellValue) === false) { + return Calculation::FORMULA_STRING_QUOTE . $cellValue . Calculation::FORMULA_STRING_QUOTE; + } elseif (is_bool($cellValue)) { + return ($cellValue) ? Calculation::$localeBoolean['TRUE'] : Calculation::$localeBoolean['FALSE']; + } + + return (string) $cellValue; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/ArrayToTextTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/ArrayToTextTest.php new file mode 100644 index 00000000..81fa5a53 --- /dev/null +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/ArrayToTextTest.php @@ -0,0 +1,24 @@ +getSheet(); + $worksheet->fromArray($testData, null, 'A1', true); + $worksheet->getCell('H1')->setValue("=ARRAYTOTEXT(A1:C5, {$mode})"); + + $result = $worksheet->getCell('H1')->getCalculatedValue(); + self::assertSame($expectedResult, $result); + } + + public function providerARRAYTOTEXT(): array + { + return require 'tests/data/Calculation/TextData/ARRAYTOTEXT.php'; + } +} diff --git a/tests/data/Calculation/TextData/ARRAYTOTEXT.php b/tests/data/Calculation/TextData/ARRAYTOTEXT.php new file mode 100644 index 00000000..4bef2823 --- /dev/null +++ b/tests/data/Calculation/TextData/ARRAYTOTEXT.php @@ -0,0 +1,26 @@ +