Skip to content

Commit 6c1a2e5

Browse files
authored
Merge branch 'master' into issue1515minor
2 parents ed677fe + c196847 commit 6c1a2e5

34 files changed

+564
-90
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org).
1010
### Added
1111

1212
- Xlsx Reader Optionally Ignore Rows With No Cells. [Issue #3982](https://github.com/PHPOffice/PhpSpreadsheet/issues/3982) [PR #4035](https://github.com/PHPOffice/PhpSpreadsheet/pull/4035)
13+
- Means to change style without affecting current cell/sheet. [PR #4073](https://github.com/PHPOffice/PhpSpreadsheet/pull/4073)
1314
- Option for CSV output file to have varying numbers of columns for each row. [Issue #1415](https://github.com/PHPOffice/PhpSpreadsheet/issues/1415) [PR #4076](https://github.com/PHPOffice/PhpSpreadsheet/pull/4076)
1415

1516
### Changed
@@ -34,11 +35,17 @@ and this project adheres to [Semantic Versioning](https://semver.org).
3435
- Mpdf and Tcpdf Borders on Merged Cells. [Issue #3557](https://github.com/PHPOffice/PhpSpreadsheet/issues/3557) [PR #4047](https://github.com/PHPOffice/PhpSpreadsheet/pull/4047)
3536
- Xls Conditional Format Improvements. [PR #4030](https://github.com/PHPOffice/PhpSpreadsheet/pull/4030) [PR #4033](https://github.com/PHPOffice/PhpSpreadsheet/pull/4033)
3637
- Conditional Range Unions and Intersections [Issue #4039](https://github.com/PHPOffice/PhpSpreadsheet/issues/4039) [PR #4042](https://github.com/PHPOffice/PhpSpreadsheet/pull/4042)
38+
- Ods comments with newlines. [Issue #4081](https://github.com/PHPOffice/PhpSpreadsheet/issues/4081) [PR #4086](https://github.com/PHPOffice/PhpSpreadsheet/pull/4086)
39+
- Propagate errors in Text functions. [Issue #2581](https://github.com/PHPOffice/PhpSpreadsheet/issues/2581) [PR #4080](https://github.com/PHPOffice/PhpSpreadsheet/pull/4080)
3740
- Csv Reader allow use of html mimetype. [Issue #4036](https://github.com/PHPOffice/PhpSpreadsheet/issues/4036) [PR #4040](https://github.com/PHPOffice/PhpSpreadsheet/pull/4040)
3841
- Problem rendering line chart with missing plot label. [PR #4074](https://github.com/PHPOffice/PhpSpreadsheet/pull/4074)
3942
- More RTL in Xlsx/Html Comments [Issue #4004](https://github.com/PHPOffice/PhpSpreadsheet/issues/4004) [PR #4065](https://github.com/PHPOffice/PhpSpreadsheet/pull/4065)
4043
- Empty String in sharedStrings. [Issue #4063](https://github.com/PHPOffice/PhpSpreadsheet/issues/4063) [PR #4064](https://github.com/PHPOffice/PhpSpreadsheet/pull/4064)
4144
- Html Writer Minor Fixes. [PR #4089](https://github.com/PHPOffice/PhpSpreadsheet/pull/4089)
45+
- Changes to INDEX function. [Issue #64](https://github.com/PHPOffice/PhpSpreadsheet/issues/64) [PR #4088](https://github.com/PHPOffice/PhpSpreadsheet/pull/4088)
46+
- Ods Reader and Whitespace Text Nodes. [Issue #804](https://github.com/PHPOffice/PhpSpreadsheet/issues/804) [PR #4087](https://github.com/PHPOffice/PhpSpreadsheet/pull/4087)
47+
- Ods Xml Reader and Whitespace Text Nodes. [Issue #804](https://github.com/PHPOffice/PhpSpreadsheet/issues/804) [PR #4087](https://github.com/PHPOffice/PhpSpreadsheet/pull/4087)
48+
- Treat invalid formulas as strings. [Issue #1310](https://github.com/PHPOffice/PhpSpreadsheet/issues/1310) [PR #4073](https://github.com/PHPOffice/PhpSpreadsheet/pull/4073)
4249

4350
## 2024-05-11 - 2.1.0
4451

docs/index.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ allow you to read and write various spreadsheet file formats such as Excel and L
2020
|CSV |||
2121
|PDF (using either the TCPDF, Dompdf or mPDF libraries, which need to be installed separately)| ||
2222

23+
Note - reading or writing certain aspects of a spreadsheet may not be supported in all formats. For more details, please consult
24+
[Features Cross-reference](./references/features-cross-reference.md).
25+
2326
# Getting started
2427

2528
## Software requirements

docs/references/features-cross-reference.md

Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
<td style="text-align: center; color: green;">✔</td>
2929
<td style="text-align: center; color: green;">✔</td>
3030
<td style="text-align: center; color: orange;">●</td>
31-
<td style="text-align: center; color: orange;">●</td>
31+
<td style="text-align: center; color: orange;">● <a href="#footnote6"><sup>6</sup></a></td>
3232
<td style="text-align: center; color: green;">✔</td>
3333
<td style="text-align: center;">N/A</td>
3434
<td style="text-align: center;">N/A</td>
@@ -389,7 +389,7 @@
389389
</tr>
390390
<tr>
391391
<td style="padding-left: 0.5em;"><strong>Conditional Formatting</strong></td>
392-
<td style="text-align: center; color: orange;"></td>
392+
<td style="text-align: center; color: green;"></td>
393393
<td style="text-align: center; color: green;">✔</td>
394394
<td style="text-align: center; color: red;">✖</td>
395395
<td style="text-align: center; color: red;">✖</td>
@@ -414,7 +414,7 @@
414414
<td style="text-align: center; color: green;">✔</td>
415415
<td style="text-align: center; color: green;">✔</td>
416416
<td style="text-align: center; color: green;">✔</td>
417-
<td style="text-align: center; color: red;"></td>
417+
<td style="text-align: center; color: green;"></td>
418418
<td style="text-align: center; color: green;">✔</td>
419419
<td style="text-align: center;">N/A</td>
420420
<td style="text-align: center;">N/A</td>
@@ -495,14 +495,14 @@
495495
<td style="text-align: center; color: green;">✔</td>
496496
<td style="text-align: center;">N/A</td>
497497
<td style="text-align: center; color: orange;">●</td>
498-
<td style="text-align: center; color: orange;">●</td>
498+
<td style="text-align: center; color: orange;">● <a href="#footnote7"><sup>7</sup></a></td>
499499
</tr>
500500
<tr>
501501
<td style="padding-left: 1em;">Number Format Mask</td>
502502
<td style="text-align: center; color: green;">✔</td>
503503
<td style="text-align: center; color: green;">✔</td>
504504
<td style="text-align: center; color: green;">✔</td>
505-
<td style="text-align: center; color: green;"></td>
505+
<td style="text-align: center; color: orange;"></td>
506506
<td style="text-align: center; color: green;">✔</td>
507507
<td style="text-align: center;">N/A</td>
508508
<td style="text-align: center; color: green;">✔</td>
@@ -517,7 +517,7 @@
517517
<td style="text-align: center; color: green;">✔</td>
518518
<td style="text-align: center;">N/A</td>
519519
<td style="text-align: center; color: red;">✖</td>
520-
<td style="text-align: center; color: orange;">●</td>
520+
<td style="text-align: center; color: orange;">● <a href="#footnote7"><sup>7</sup></a></td>
521521
</tr>
522522
<tr>
523523
<td style="padding-left: 2em;">Horizontal</td>
@@ -583,7 +583,7 @@
583583
<td style="text-align: center; color: green;">✔</td>
584584
<td style="text-align: center;">N/A</td>
585585
<td style="text-align: center; color: green;">✔</td>
586-
<td style="text-align: center; color: green;"></td>
586+
<td style="text-align: center; color: orange;">● <a href="#footnote7"><sup>7</sup></a></td>
587587
</tr>
588588
<tr>
589589
<td style="padding-left: 2em;">Patterned</td>
@@ -605,7 +605,7 @@
605605
<td style="text-align: center; color: green;">✔</td>
606606
<td style="text-align: center;">N/A</td>
607607
<td style="text-align: center; color: green;">✔</td>
608-
<td style="text-align: center; color: green;"></td>
608+
<td style="text-align: center; color: orange;">● <a href="#footnote7"><sup>7</sup></a></td>
609609
</tr>
610610
<tr>
611611
<td style="padding-left: 2em;">Font Face</td>
@@ -704,7 +704,7 @@
704704
<td style="text-align: center; color: green;">✔</td>
705705
<td style="text-align: center;">N/A</td>
706706
<td style="text-align: center; color: orange;">●</td>
707-
<td style="text-align: center; color: green;"></td>
707+
<td style="text-align: center; color: orange;">● <a href="#footnote7"><sup>7</sup></a></td>
708708
</tr>
709709
<tr>
710710
<td style="padding-left: 2em;">Line Style</td>
@@ -797,13 +797,13 @@
797797
<tr>
798798
<td style="padding-left: 2em;">Alignment</td>
799799
<td style="text-align: center; color: red;">✖ <a href="#footnote3"><sup>3</sup></a></td>
800-
<td style="text-align: center; color: red;"></td>
800+
<td style="text-align: center; color: green;"></td>
801801
<td style="text-align: center; color: red;">✖</td>
802802
<td style="text-align: center; color: red;">✖</td>
803803
<td style="text-align: center; color: red;">✖</td>
804804
<td style="text-align: center;">N/A</td>
805805
<td style="text-align: center; color: red;">✖</td>
806-
<td style="text-align: center; color: red;"></td>
806+
<td style="text-align: center; color: green;"></td>
807807
</tr>
808808
<tr>
809809
<td style="padding-left: 2em;">Background Image</td>
@@ -929,7 +929,7 @@
929929
<tr>
930930
<td style="padding-left: 0.5em;"><a href="#setGetMacro"><strong>Macros</strong></a></td>
931931
<td style="text-align: center; color: red;">✖</td>
932-
<td style="text-align: center; color: green;"></td>
932+
<td style="text-align: center; color: orange;">● <a href="#footnote5"><sup>5</sup</td>
933933
<td style="text-align: center; color: red;">✖</td>
934934
<td style="text-align: center; color: red;">✖</td>
935935
<td style="text-align: center; color: red;">✖</td>
@@ -940,7 +940,7 @@
940940
<tr>
941941
<td style="padding-left: 0.5em;"><strong>Form Controls</strong></td>
942942
<td style="text-align: center; color: red;">✖</td>
943-
<td style="text-align: center; color: red;"></td>
943+
<td style="text-align: center; color: orange;">● <a href="#footnote4"><sup>4</sup</td>
944944
<td style="text-align: center; color: red;">✖</td>
945945
<td style="text-align: center; color: red;">✖</td>
946946
<td style="text-align: center; color: red;">✖</td>
@@ -1001,6 +1001,10 @@
10011001
1. <span id="footnote1">Only text contents</span>
10021002
2. <span id="footnote2">Only BIFF8 files support Rich Text. Prior to that, comments could only be plain text</span>
10031003
3. <span id="footnote3">Only BIFF8 files support alignment and rotation. Prior to that, comments could only be unformatted text</span>
1004+
4. <span id="footnote4">Xlsx forms and controls can be read and written but not otherwise manipulated</span>
1005+
5. <span id="footnote5">Xlsx macros can be read and written; their values can be retrieved and changed, but only in a binary form which is unlikely to be useful</span>
1006+
6. <span id="footnote6">There is very limited support for reading styles from an Ods spreadsheet. Writing styles has better support, although Number Format is incomplete.</span>
1007+
7. <span id="footnote7">In most cases, Html reader processes only inline styles; styles provided by Css classes may be ignored.</span>
10041008

10051009
## Writers
10061010

@@ -1184,7 +1188,7 @@
11841188
<td style="padding-left: 1em;">Row Height/Column Width</td>
11851189
<td style="text-align: center; color: green;">✔</td>
11861190
<td style="text-align: center; color: green;">✔</td>
1187-
<td style="text-align: center; color: red;"></td>
1191+
<td style="text-align: center; color: green;"></td>
11881192
<td style="text-align: center;">N/A</td>
11891193
<td style="text-align: center; color: green;">✔</td>
11901194
<td style="text-align: center; color: green;">✔</td>
@@ -1256,7 +1260,7 @@
12561260
<td style="padding-left: 1em;">Number Format Mask</td>
12571261
<td style="text-align: center; color: green;">✔</td>
12581262
<td style="text-align: center; color: green;">✔</td>
1259-
<td style="text-align: center; color: green;"></td>
1263+
<td style="text-align: center; color: orange;"></td>
12601264
<td style="text-align: center;">N/A</td>
12611265
<td style="text-align: center; color: green;">✔</td>
12621266
<td style="text-align: center; color: green;">✔</td>
@@ -1472,10 +1476,10 @@
14721476
<td style="padding-left: 0.5em;"><strong>Merged Cells</strong></td>
14731477
<td style="text-align: center; color: green;">✔</td>
14741478
<td style="text-align: center; color: green;">✔</td>
1475-
<td style="text-align: center; color: red;"></td>
1479+
<td style="text-align: center; color: green;"></td>
14761480
<td style="text-align: center;">N/A</td>
14771481
<td style="text-align: center; color: green;">✔</td>
1478-
<td style="text-align: center; color: red;"></td>
1482+
<td style="text-align: center; color: green;"></td>
14791483
</tr>
14801484
<tr>
14811485
<td style="padding-left: 0.5em;"><a href="#setGetComment"><strong>Cell Comments</strong></a></td>
@@ -1498,10 +1502,10 @@
14981502
<tr>
14991503
<td style="padding-left: 1em;">Alignment</td>
15001504
<td style="text-align: center; color: red;">✖</td>
1501-
<td style="text-align: center; color: red;"></td>
1505+
<td style="text-align: center; color: green;"></td>
15021506
<td style="text-align: center; color: red;">✖</td>
15031507
<td style="text-align: center;">N/A</td>
1504-
<td style="text-align: center; color: red;"></td>
1508+
<td style="text-align: center; color: green;"></td>
15051509
<td style="text-align: center;">N/A</td>
15061510
</tr>
15071511
<tr>
@@ -1606,7 +1610,7 @@
16061610
<tr>
16071611
<td style="padding-left: 0.5em;"><a href="#setGetMacro"><strong>Macros</strong></a></td>
16081612
<td style="text-align: center; color: red;">✖</td>
1609-
<td style="text-align: center; color: green;"></td>
1613+
<td style="text-align: center; color: orange;">● <a href="#footnote5"><sup>5</sup</td>
16101614
<td style="text-align: center; color: red;">✖</td>
16111615
<td style="text-align: center;">N/A</td>
16121616
<td style="text-align: center; color: red;">✖</td>
@@ -1615,7 +1619,7 @@
16151619
<tr>
16161620
<td style="padding-left: 0.5em;"><strong>Form Controls</strong></td>
16171621
<td style="text-align: center; color: red;">✖</td>
1618-
<td style="text-align: center; color: red;"></td>
1622+
<td style="text-align: center; color: orange;">● <a href="#footnote4"><sup>4</sup</td>
16191623
<td style="text-align: center; color: red;">✖</td>
16201624
<td style="text-align: center;">N/A</td>
16211625
<td style="text-align: center; color: red;">✖</td>
@@ -1803,8 +1807,8 @@
18031807
</tr>
18041808
<tr>
18051809
<td id="setGetMacro"><strong>Macros</strong></td>
1806-
<td>$spreadsheet->getMacrosCode();</td>
1807-
<td>$spreadsheet->setMacrosCode();</td>
1810+
<td>$spreadsheet->getMacrosCode();<a href="#footnote5"><sup>5</sup></td>
1811+
<td>$spreadsheet->setMacrosCode();<a href="#footnote5"><sup>5</sup></td>
18081812
</tr>
18091813
<tr>
18101814
<td id="setGetSecurity"><strong>Security</strong></td>

src/PhpSpreadsheet/Calculation/Calculation.php

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4065,7 +4065,7 @@ private function internalParseFormula(string $formula, ?Cell $cell = null): bool
40654065
$opCharacter = $formula[$index]; // Get the first character of the value at the current index position
40664066

40674067
// Check for two-character operators (e.g. >=, <=, <>)
4068-
if ((isset(self::$comparisonOperators[$opCharacter])) && (strlen($formula) > $index) && (isset(self::$comparisonOperators[$formula[$index + 1]]))) {
4068+
if ((isset(self::$comparisonOperators[$opCharacter])) && (strlen($formula) > $index) && isset($formula[$index + 1], self::$comparisonOperators[$formula[$index + 1]])) {
40694069
$opCharacter .= $formula[++$index];
40704070
}
40714071
// Find out if we're currently at the beginning of a number, variable, cell/row/column reference,
@@ -4792,13 +4792,20 @@ private function processTokenStack(mixed $tokens, ?string $cellID = null, ?Cell
47924792

47934793
for ($row = 0; $row < $rows; ++$row) {
47944794
for ($column = 0; $column < $columns; ++$column) {
4795-
$operand1[$row][$column]
4796-
= Shared\StringHelper::substring(
4797-
self::boolToString($operand1[$row][$column])
4798-
. self::boolToString($operand2[$row][$column]),
4799-
0,
4800-
DataType::MAX_STRING_LENGTH
4801-
);
4795+
$op1x = self::boolToString($operand1[$row][$column]);
4796+
$op2x = self::boolToString($operand2[$row][$column]);
4797+
if (Information\ErrorValue::isError($op1x)) {
4798+
// no need to do anything
4799+
} elseif (Information\ErrorValue::isError($op2x)) {
4800+
$operand1[$row][$column] = $op2x;
4801+
} else {
4802+
$operand1[$row][$column]
4803+
= Shared\StringHelper::substring(
4804+
$op1x . $op2x,
4805+
0,
4806+
DataType::MAX_STRING_LENGTH
4807+
);
4808+
}
48024809
}
48034810
}
48044811
$result = $operand1;
@@ -4808,7 +4815,13 @@ private function processTokenStack(mixed $tokens, ?string $cellID = null, ?Cell
48084815
// using the concatenation operator
48094816
// with literals that fits in 32K,
48104817
// so I don't think we can overflow here.
4811-
$result = self::FORMULA_STRING_QUOTE . str_replace('""', self::FORMULA_STRING_QUOTE, self::unwrapResult($operand1) . self::unwrapResult($operand2)) . self::FORMULA_STRING_QUOTE;
4818+
if (Information\ErrorValue::isError($operand1)) {
4819+
$result = $operand1;
4820+
} elseif (Information\ErrorValue::isError($operand2)) {
4821+
$result = $operand2;
4822+
} else {
4823+
$result = self::FORMULA_STRING_QUOTE . str_replace('""', self::FORMULA_STRING_QUOTE, self::unwrapResult($operand1) . self::unwrapResult($operand2)) . self::FORMULA_STRING_QUOTE;
4824+
}
48124825
}
48134826
$this->debugLog->writeDebugLog('Evaluation Result is %s', $this->showTypeDetails($result));
48144827
$stack->push('Value', $result);

src/PhpSpreadsheet/Calculation/Functions.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ class Functions
2626
const RETURNDATE_PHP_DATETIME_OBJECT = 'O';
2727
const RETURNDATE_EXCEL = 'E';
2828

29+
public const NOT_YET_IMPLEMENTED = '#Not Yet Implemented';
30+
2931
/**
3032
* Compatibility mode to use for error checking and responses.
3133
*/
@@ -123,7 +125,7 @@ public static function getReturnDateType(): string
123125
*/
124126
public static function DUMMY(): string
125127
{
126-
return '#Not Yet Implemented';
128+
return self::NOT_YET_IMPLEMENTED;
127129
}
128130

129131
public static function isMatrixValue(mixed $idx): bool

src/PhpSpreadsheet/Calculation/Information/ErrorValue.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace PhpOffice\PhpSpreadsheet\Calculation\Information;
44

55
use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
6+
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
67

78
class ErrorValue
89
{
@@ -35,7 +36,7 @@ public static function isErr(mixed $value = ''): array|bool
3536
* @return array|bool If an array of numbers is passed as an argument, then the returned result will also be an array
3637
* with the same dimensions
3738
*/
38-
public static function isError(mixed $value = ''): array|bool
39+
public static function isError(mixed $value = '', bool $tryNotImplemented = false): array|bool
3940
{
4041
if (is_array($value)) {
4142
return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $value);
@@ -44,6 +45,9 @@ public static function isError(mixed $value = ''): array|bool
4445
if (!is_string($value)) {
4546
return false;
4647
}
48+
if ($tryNotImplemented && $value === Functions::NOT_YET_IMPLEMENTED) {
49+
return true;
50+
}
4751

4852
return in_array($value, ExcelError::ERROR_CODES, true);
4953
}

0 commit comments

Comments
 (0)