Skip to content

Commit 25e3e45

Browse files
authored
Added support for the ARABIC excel function (#1343)
Updated changelog Updated docprops Fixed stylci
1 parent 14d807c commit 25e3e45

File tree

6 files changed

+133
-0
lines changed

6 files changed

+133
-0
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org).
77

88
## [Unreleased]
99

10+
- Added support for the ARABIC function
1011
- Conditionals - Extend Support for (NOT)CONTAINSBLANKS [#1278](https://github.com/PHPOffice/PhpSpreadsheet/pull/1278)
1112
- Handle Error in Formula Processing Better for Xls [#1267](https://github.com/PHPOffice/PhpSpreadsheet/pull/1267)
1213
- Handle ConditionalStyle NumberFormat When Reading Xlsx File [#1296](https://github.com/PHPOffice/PhpSpreadsheet/pull/1296)

src/PhpSpreadsheet/Calculation/Calculation.php

+5
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,11 @@ class Calculation
263263
'functionCall' => [Logical::class, 'logicalAnd'],
264264
'argumentCount' => '1+',
265265
],
266+
'ARABIC' => [
267+
'category' => Category::CATEGORY_MATH_AND_TRIG,
268+
'functionCall' => [MathTrig::class, 'ARABIC'],
269+
'argumentCount' => '1',
270+
],
266271
'AREAS' => [
267272
'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE,
268273
'functionCall' => [Functions::class, 'DUMMY'],

src/PhpSpreadsheet/Calculation/MathTrig.php

+58
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,64 @@ private static function romanCut($num, $n)
3838
return ($num - ($num % $n)) / $n;
3939
}
4040

41+
/**
42+
* ARABIC.
43+
*
44+
* Converts a Roman numeral to an Arabic numeral.
45+
*
46+
* Excel Function:
47+
* ARABIC(text)
48+
*
49+
* @category Mathematical and Trigonometric Functions
50+
*
51+
* @param string $roman
52+
*
53+
* @return int|string the arabic numberal contrived from the roman numeral
54+
*/
55+
public static function ARABIC($roman)
56+
{
57+
// An empty string should return 0
58+
$roman = substr(trim(strtoupper((string) Functions::flattenSingleValue($roman))), 0, 255);
59+
if ($roman === '') {
60+
return 0;
61+
}
62+
63+
// Convert the roman numeral to an arabic number
64+
$lookup = [
65+
'M' => 1000, 'CM' => 900,
66+
'D' => 500, 'CD' => 400,
67+
'C' => 100, 'XC' => 90,
68+
'L' => 50, 'XL' => 40,
69+
'X' => 10, 'IX' => 9,
70+
'V' => 5, 'IV' => 4, 'I' => 1,
71+
];
72+
73+
$negativeNumber = $roman[0] === '-';
74+
if ($negativeNumber) {
75+
$roman = substr($roman, 1);
76+
}
77+
78+
$arabic = 0;
79+
for ($i = 0; $i < strlen($roman); ++$i) {
80+
if (!isset($lookup[$roman[$i]])) {
81+
return Functions::VALUE(); // Invalid character detected
82+
}
83+
84+
if ($i < (strlen($roman) - 1) && isset($lookup[substr($roman, $i, 2)])) {
85+
$arabic += $lookup[substr($roman, $i, 2)]; // Detected a match on the next 2 characters
86+
++$i;
87+
} else {
88+
$arabic += $lookup[$roman[$i]]; // Detected a match on one character only
89+
}
90+
}
91+
92+
if ($negativeNumber) {
93+
$arabic *= -1; // The number should be negative
94+
}
95+
96+
return $arabic;
97+
}
98+
4199
/**
42100
* ATAN2.
43101
*

src/PhpSpreadsheet/Calculation/functionlist.txt

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ ADDRESS
99
AMORDEGRC
1010
AMORLINC
1111
AND
12+
ARABIC
1213
AREAS
1314
ASC
1415
ASIN
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
4+
5+
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
6+
use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
7+
use PHPUnit\Framework\TestCase;
8+
9+
class ArabicTest extends TestCase
10+
{
11+
public function setUp()
12+
{
13+
Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
14+
}
15+
16+
/**
17+
* @dataProvider providerARABIC
18+
*
19+
* @param mixed $expectedResult
20+
* @param string $romanNumeral
21+
*/
22+
public function testARABIC($expectedResult, $romanNumeral)
23+
{
24+
$result = MathTrig::ARABIC($romanNumeral);
25+
$this->assertEquals($expectedResult, $result);
26+
}
27+
28+
public function providerARABIC()
29+
{
30+
return require 'data/Calculation/MathTrig/ARABIC.php';
31+
}
32+
}
+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
return [
4+
[
5+
0,
6+
' ',
7+
],
8+
[
9+
49,
10+
'XLIX',
11+
],
12+
[
13+
50,
14+
'L',
15+
],
16+
[
17+
2012,
18+
'MMXII',
19+
],
20+
[
21+
999,
22+
'CMXCIX',
23+
],
24+
[
25+
499,
26+
'CDXCIX',
27+
],
28+
[
29+
2018,
30+
'MMXVIII',
31+
],
32+
[
33+
-2018,
34+
'-MMXVIII',
35+
],
36+
];

0 commit comments

Comments
 (0)