Commit Graph

1734 Commits

Author SHA1 Message Date
oleibman 77eaac2e79 Merge branch 'master' into wakeup 2025-09-11 21:21:49 -07:00
oleibman c07675a59c Merge pull request #4641 from oleibman/issue4638
Proper Output for BASE Function
2025-09-12 03:29:16 +00:00
oleibman 9b28b9e9c1 Merge pull request #4644 from oleibman/phpstan2123
Upgrade Phpstan
2025-09-12 03:08:23 +00:00
oleibman 4b8f4e8d66 Upgrade Phpstan
A lot of changes since its last update, including one that I requested.
2025-09-11 20:02:57 -07:00
oleibman 43754a130e Bug in Uncovered Code in XMLWriter
Add test, fix bug.
2025-09-10 08:19:57 -07:00
oleibman f19a73fdd6 Proper Output for BASE Function
Fix #4638. Microsoft does not document BASE as being introduced in Excel 2010 or later, but apparently it was.
2025-09-10 07:34:50 -07:00
oleibman 00191100ba Deprecate Worksheet::getHashInt and Spreadsheet::getId
Php8.5 *may* deprecate the use of `__wakeup` (it is planned, but not yet implemented, and it is convtroversial). We use it only twice. In the first instance, it just throws an exception to prevent a security exploit. This can be trivially replaced with `__unserialize`.

The other instance is merely to initialize a Worksheet instance variable. Converting this use to `__unserialize` is *not* trivial (one of the reasons for the controversy). However, I see no useful purpose for that variable. Since it has no use, there is no real need for `__wakeup`, so we will just remove the routine altogether, and deprecate the variable's getter (there is no setter).

A similar instance variable in Spreadsheet also serves no useful purpose, so we will deprecate its getter as well (again no setter).
2025-09-10 00:27:22 -07:00
oleibman 3ace47ad4d Merge branch 'master' into issue4629 2025-09-07 00:37:14 -07:00
oleibman 5082b35709 Conditional Formatting in extLst
Fix #4629. Excel Xml can specify Conditional Formatting in 2 ways - either using a `conditionalFormatting` tag as a child of `worksheet`, or in a slightly different manner as a child of `worksheet->extLst`. Although these are both handled by PhpSpreadsheet, the former is lost if there exists a latter whose cell range (`sqref`) matches it. This PR merges the former with the latter in that circumstance, preserving both.

The issue also notes that `font` and `stopIfTrue` are not handled correctly. Support for those was missing in the `extlst` handling, and is now added with this PR.
2025-09-05 11:13:09 -07:00
oleibman b7d48e687d More Minor Tweaks 2025-09-05 10:28:48 -07:00
oleibman eec235765c Merge branch 'master' into calccov 2025-09-05 00:46:28 -07:00
oleibman 2059d3b241 A Tiny Amount of Coverage 2025-09-04 23:43:40 -07:00
oleibman a88993dcc8 More Accurate Handling of Countries in validLocaleLanguages
This is a theoretical problem. Building FalseTrueArray only looks at languages, not countries. The only example we have is `pt` vs `pt_br`, and since True and False have the same translation for both locales, there is no problem. This PR will help it from becoming a problem in future if a new language/country combo is added.
2025-09-01 18:37:48 -07:00
oleibman 2803d96129 Cover Important Path in StringHelper 2025-09-01 07:45:27 -07:00
oleibman 3dfd3afff8 One More Test 2025-09-01 01:03:23 -07:00
oleibman f375d9a69b Minor Improvements to Calculation Coverage 2025-09-01 00:28:46 -07:00
oleibman 53d926d569 Additional Tests 2025-08-29 01:00:06 -07:00
oleibman 2fd3ac5552 Option to Create Blank Sheet If LoadSheetsOnly Doesn't Find Any
In PhpSpreadsheet Release 1, if the LoadSheetsOnly option was specified, and no sheets matched, a new blank sheet was created. This behavior changed in PhpSpreadsheet Release 2, so that an exception wound up being thrown instead. Although the Release 2 approach seems more sensible to me, it was actually collateral damage from a different change, and was not an intentional result.

The difference in behavior is causing a problem for Laravel-Excel. In particular, a PR which would move their supported PhpSpreadsheet release from 1 to 5, is delayed because this change in behavior breaks part of their test suite. See https://github.com/SpartnerNL/Laravel-Excel/pull/4302. We would very much like them to get off release 1. I volunteered to add a compatibility option to the Readers which would emulate the release 1 behavior. The result is this PR.

Usage:
```php
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xlsx();
$reader->setLoadSheetsOnly([list of sheet names]);
if (method_exists($reader, 'setCreateBlankSheetIfNoneRead')) {
    $reader->setCreateBlankSheetIfNoneRead(true);
}
```
In addition to Xlsx Reader, the method is available for Xls, Ods, Xml, and Gnumeric.
2025-08-28 13:44:32 -07:00
oleibman f8f78a7ed3 String Increments and Php8.5
Fix #4600. String incrementation through the `++` operator is deprecated in Php 8.5. Because we make use of that operator to iterate through columns, we are particularly hard hit by that change - unaddressed, it causes over 2,000 errors in our test suite! It is, fortunately, not as difficult as I feared to correct. Replacing the `++` operator with a call to new method `StringHelper::stringIncrement` in 79 statements scattered over 31 source modules (in src, samples, test, and infra) eliminates all the messages in the test suite. It is possible that others are lurking, but I don't know a systematic way of determining if there are others. We'll stick with this for now, and deal with any others as they show up.

This PR will be applied to the master, release390, and release222 branches. It will not be applied to the release210 or release1291 branches, which will now accept security changes only.
2025-08-27 18:18:40 -07:00
oleibman b99dc608a0 Merge pull request #4598 from oleibman/issue2912
Better Handling of Print Area After Column/Row Removal
2025-08-26 16:15:58 +00:00
oleibman 31502b05d5 Merge branch 'master' into maxwidth 2025-08-26 07:36:50 -07:00
oleibman 5e02e282c7 Better Handling of Print Area After Column/Row Removal
Fix #2912, another oldie (3+ years). Removal of rows or columns which include part of the print area is not recalculating the print area correctly. This PR will correct that problem, but only if the print area consists of a single range. I think that is by far the most common use case. If there is a demonstrated need to handle multiple ranges, I will respond to a new issue.
2025-08-24 09:05:12 -07:00
oleibman e31c9246ed Merge pull request #4582 from oleibman/setaccessible
Remove Reflection::setAccessible From Tests
2025-08-18 06:43:32 +00:00
oleibman 029d79c3fc Remove Reflection::setAccessible From Tests
Method has no effect starting with Php 8.1.0, and will be deprecated in 8.5. Remove it from our test suite.
2025-08-17 23:21:17 -07:00
oleibman 06fef872be Maximum Column Width
PR #455 was submitted by @Aketos in 2018. It added no unit tests, so it was not merged, and it eventually went stale. Without the tests, I'm not sure exactly what the user had in mind. But my investigation indicates the following:
- for Xls files, if the column width in the file specifies a value greater than 255, Excel will choose its own width when it opens the file.
- for Xlsx files:
    - Excel does not allow you to set a column width > 255, neither by dragging the column boundary, nor by right-clicking and setting a value, nor by auto-fitting the column width.
    - Nevertheless, if the XML specifies a column width > 255, Excel will honor that value in the displayed spreadsheet, and even write it out if the file is saved.


I have taken a different approach than the original PR, which changed `Worksheet::calculateColumnWidths`. Instead, this PR adds an option to the Xlsx Writer to either restrict column widths to 255 or not. The default is "not" in order to avoid a breaking change. For emulating Excel's behavior, in the unusual situation where it might matter, the user might consider using the non-default option.

This PR also restricts column dimension width to 255 when saving an Xls file.
2025-08-17 20:29:47 -07:00
oleibman 3174773a81 Merge pull request #4580 from oleibman/issue1457
splitRange and ProtectedRange
2025-08-17 04:12:03 +00:00
oleibman efa0c0fa73 Merge pull request #4577 from oleibman/issue1203
Copy Cell Adjusting Formula
2025-08-17 03:55:42 +00:00
oleibman 08f2f1bfd8 Merge pull request #4579 from oleibman/issue1637
Handle Google-only Formulas Exported from Google Sheets
2025-08-17 03:43:32 +00:00
oleibman 653645c50b Merge pull request #4574 from issakujitsuk/icon-set
Add Conditional Formatting with IconSet
2025-08-17 03:01:08 +00:00
oleibman 14a989a7e3 Handle Missing Defined Names Better
The original issue leading to this PR was fixed by correctly treating a token in Calculator as a function rather than a defined name. However, it *should* have worked even when treating it as a defined name. There was a problem because Calculator was raising an exception for a missing defined name rather than returning `#NAME?`. It is now changed to return the error.

That change initially had some adverse affects for functions ROW, ROWS, COLUMN, and COLUMNS. Those are fixed to handle the change correctly. As a bonus, a test for each which had been commented out, because it didn't work, is now uncommented and works correctly. One test for ISFORMULA and one for ISREF were also changed - the old expected result did not reflect Excel's behavior and the new one does.

Sheet title and Defined Name matching used `strtoupper` to achieve case-insensitive compares. This handles only ASCII characters. They are changed to use a conversion routine which handles non-ASCII UTF-8 character sets.
2025-08-12 09:21:26 -07:00
oleibman 05fa51581c splitRange and ProtectedRange
Fix #1457, which had gone stale but is now re-opened. The `Coordinate::splitRange` method expects a string of cell ranges, but it is a bit limited. Excel sometimes uses comma for union and space for intersection, and sometimes vice versa. `splitRange` uses comma for union, and doesn't do anything with spaces. This PR adds a new method `Coordinate::allRanges` which handles both union and intersection, and adds a parameter to indicate whether comma means union or intersection (with space meaning the other). Also, since the issue specifically mentioned this as a problem for `ProtectedRange`, an `allRanges` method is added to that class.
2025-08-10 15:05:51 -07:00
oleibman f51ec365c5 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.
2025-08-10 14:45:05 -07:00
oleibman 1e6668fe58 Copy Cell Adjusting Formula
Fix #1203. The issue actually complains about the documentation, but I think it wants documented functionality that doesn't yet exist. This PR adds a method for copying a formula from one cell to another, adjusting cell references in the formula as Excel would. For a non-formula, it copies the value without making any adjustments.
2025-08-10 13:45:03 -07:00
issa a0f9706855 Add Conditional Formatting tests for IconSet in Xlsx writer 2025-08-09 08:06:19 +09:00
issa a3588b2c22 Add test for unsupported icon sets 2025-08-09 07:23:18 +09:00
oleibman 0c8db6e7d2 Merge branch 'master' into issue1324 2025-08-07 20:33:00 -07:00
oleibman a4ee68bf1e Merge branch 'master' into issue484 2025-08-06 22:26:24 -07:00
oleibman fa2c32996a Merge branch 'master' into issue4588 2025-08-06 21:57:24 -07:00
oleibman 7689037b60 Additional Floating Point Precision Changes
Fix #1324, which went stale many years ago, and is now re-opened. It can be considered a follow-on to PR #4479 which was installed in May. The user complains of a *very* small loss of precision. This can be corrected by using `StringHelper::convertToString` in lieu of a simple cast from float to string in two places. `Style\NumberFormat\Formatter` is quite straightforward. `Writer\Csv` is a bit more complicated. If you put a float with more than 15 digits precision in a Csv, on opening it Excel will give a pop-up, saying something inaccurate like "We've corrected this for you - is that okay?" Better to avoid that by making sure to avoid too much precision when writing to Csv.
2025-08-06 17:53:04 -07:00
issa 0327b49060 Added Conditional Formatting: IconSet for Xlsx (#4560) 2025-08-07 08:59:11 +09:00
oleibman c4cd1b3410 Merge branch 'master' into issue4557date 2025-08-05 23:52:31 -07:00
oleibman 9c083e271d Header/Footer Images Expand "Location"
Fix #484. Fix #1318. Both went stale a long time ago. The images can currently specify their location as Left, Center, or Right. However, they also need to specify their type - first page, even pages, or odd pages (which is what is used when neither of the others is applicable). This is accomplished by adding 18 new constants to `Worksheet\HeaderFooter`, any of which can be specified as the second argument to `HeaderFooter::addImage`. Somewhat surprisingly, no changes are required to Xlsx Writer or Reader.

Xls Reader and Writer support header/footer, but do not support using images in them. No other readers nor writers support header/footer.
2025-08-04 18:15:19 -07:00
oleibman 79fca7601c Clean Up Some Engineering Tests
This came to light while cleaning up ComplexAssert. Many tests are calling `_calculateFormulaValue` rather than `calculateFormula`, and, as a result, have to be trimmed before asserting. This PR changes those calls, and does a bit more to simplify the tests. There are a lot of other non-Engineering tests which call `_calculateFormulaValue`, but none of those need to manipulate the result after the test.

This PR changes only tests, no source code.
2025-08-03 13:48:45 -07:00
oleibman f65b0a2d10 Merge pull request #4570 from oleibman/complextests
Redo ComplexAssert
2025-08-03 15:56:42 +00:00
oleibman e78bca9668 Merge pull request #4556 from oleibman/xmlspace
Xlsx Writer Eliminate xml:space From Non-Text Nodes
2025-08-03 15:46:51 +00:00
oleibman 3dcdbcac3e Redo ComplexAssert
Its use is already causes an issue with Phpstan. It uses interfaces marked as internal by Phpunit, and it will not work with Phpunit 12. It is more complicated than needed. This PR corrects all these problems. It also corrects a handful of other problems that will show up with Phpunit 12. Only tests are changed - no source code.
2025-08-03 08:25:05 -07:00
oleibman 6d8fc67512 Merge branch 'master' into deprecations 2025-08-02 19:07:45 -07:00
oleibman 20ac2f1940 Merge pull request #4527 from oleibman/issue4522
Minor Breaking Change to DefaultValueBinder
2025-08-03 01:48:03 +00:00
oleibman ac4befd2f7 Merge commit from fork 2025-08-02 18:06:29 -07:00
oleibman 150b3849a8 Create Uninitialized Cell If Used in Calculation
Fix #4558. Fix #4530. 4558 deals with a problem with COUNTA. Excel does not count empty cells, but it does count literal nulls (usually empty parameters) in the argument list. PhpSpreadsheet has till now not created empty cells during calculation, and so winds up treating them as literals. It is changed to create the cell when appropriate.

4530 has a similar problem. When INDIRECT winds up evaluating an uninitialized cell, it treats it as a null literal, leading to incorrect results. It is now changed to create the missing cell.

A number of functions, almost all of them Financial, have a related problem. They test for a null literal when initializing some of their parameters, but they should be testing for null literal or cell containing null. They are changed to do the right thing.

SUMIF and related functions are slightly affected by this change, and are changed so that they are no longer affected.

New tests have been added. Only one existing test had to change. MergeBehaviorTest for `[12, '=5+1', '=A1/A2']`, where cell A2 was uninitialized formerly returned one row, but now returns a second all-null row because A2, by virtue of being used in a calculation, now winds up defined. I do not consider this a significant difference.
2025-07-31 23:58:05 -07:00