Commit Graph

697 Commits

Author SHA1 Message Date
oleibman 684c677937 Document NumberFormat Wizard Dependency on Intl Extension
Intl is only a "suggested" extension. A lot of the NumberFormat Wizard code depends on it. That's insufficient reason to make it required, but the suggestion text now mentions this dependency explicitly. Also clean up the Wizard documentation to reflect some changes since PhpSpreadsheet 1.28.
2025-09-17 23:04:31 -07:00
oleibman fff2373b39 Merge branch 'master' into issue4584 2025-09-16 23:48:50 -07:00
oleibman 31d1cd7e17 Minor Tweaks 2025-09-14 01:20:24 -07:00
oleibman 9df8ceb5c0 Minor Improvements to Reader/Writer Coverage 2025-09-14 00:18:08 -07:00
oleibman dc25bc1ac4 Coverage Tweaks 2025-09-12 00:41:14 -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 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 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 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 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
issa a3588b2c22 Add test for unsupported icon sets 2025-08-09 07:23:18 +09:00
issa 0327b49060 Added Conditional Formatting: IconSet for Xlsx (#4560) 2025-08-07 08:59:11 +09:00
oleibman b489fb3a17 Merge branch 'master' into issue4539 2025-07-21 21:23:15 -07:00
oleibman 2735c40179 StyleMerger Use Copy Of baseStyle
Using baseStyle directly can lead to the by-reference problems associated with Cell and Style.
2025-07-17 07:45:55 -07:00
oleibman a15091737f Html Writer Conditional Formatting Inline Css
Fix #4539. Conditional Formatting was recently added to Html Writer. It works fine when not using inline Css. However, when using inline Css, the code inadvertently added 2 different `style` attributes (one for the unconditional style and one for the conditional style) to the same cell. This is not valid html, and results in losing the conditional styling. This PR combines the two `style` attributes into one, which will now come after the `class`, `colspan`, and `rowspan` attributes.

Aside from the new tests, this PR changes an unusually large number of existing tests. While this might normally be considered a red flag, it is not a problem here. All of the changes involve merely changing the order of attributes within html tags; none of them affect how the generated html would appear in a browser.
2025-07-15 22:22:34 -07:00
oleibman 9708d72ee1 Ods Reader Process Nested table-row
Fix #4528. Fix #2507. Ods Reader expects `table:table-row` to descend directly from `table:table`. But it turns out that it can be nested under `table:table-header-rows`, `table:table-rows`, or `table:table-row-group`. Similar considerations apply to `table:table-column`. Ods Reader is changed to process the nesting tags, and therefore the nested tags underneath them. This is a major change, but it doesn't seem to have broken any existing tests or samples.

No attempt is made to add any of the nesting tags in Ods Writer.

It should be noted that 4528 has an additional problem, which has been reported as issue #4530. It is not fixed by this PR.
2025-07-08 12:52:55 -07:00
oleibman f3c3aba618 TOCOL and TOROW
TOCOL and TOROW were introduced to Excel in 2024, and will now be supported by PhpSpreadsheet. The documentation says that, under certain circumstances, "blanks" will be ignored. This seems demonstrably wrong. In the right circumstance, Excel will ignore nulls, not blanks. Further, when it decides to not ignore the nulls, it changes them to 0, which also seems insufficiently documented. PhpSpreadsheet will behave as Excel does.

I discovered some minor problems and some missing test conditions for the TRANSPOSE function while testing these. Those are now fixed.
2025-05-28 23:15:06 -07:00
oleibman cadeb88d4b Xlsx Reader Do Not Process Printer Settings for Dataonly
Fix #4477. Xlsx Spreadsheet could be loaded and saved normally, but, when the load specified Dataonly, the output file was corrupt. Reader is changed to not process Printer Settings when Dataonly is in effect.
2025-05-21 19:15:20 -07:00
oleibman e6aacf72b0 Merge pull request #4466 from oleibman/issue407b
Ods Handling of Ceiling and Floor
2025-05-15 01:22:53 +00:00
oleibman 01e97405f8 Tweaks for Gnumeric and Xls 2025-05-12 11:05:39 -07:00
oleibman 3a6009d49e Recalibrate for Significance=0
Very peculiar implementation in Excel. PhpSpreadsheet will match it:
- FLOOR(8,0) is #DIV/0. This already matched, and is the only result I understand.
- CEILING(8,0) is 0 (already matched)
- FLOOR.MATH(8,0) is 0 (changed to match)
- FLOOR.PRECISE(8,0) is 0 (changed to match)
- CEILING.MATH(8,0) is 0 (already matched)
- CEILING.PRECISE(8,0) is 0 (already matched)
2025-05-11 00:27:34 -07:00
oleibman 39511e03b5 Ods Handling of Ceiling and Floor
Fix #407, which went stale over 7 years ago, and is now reopened. Ods handling of CEILING and FLOOR functions is, apparently by design, subject to interoperability problems with Excel. See [FLOOR](https://wiki.documentfoundation.org/Documentation/Calc_Functions/FLOOR) and [CEILING](https://wiki.documentfoundation.org/Documentation/Calc_Functions/CEILING). Ods implements its own `CEILING.XCL` and `FLOOR.XCL` functions for interoperability purposes. PhpSpreadsheet will implement those, and `CEILING.ODS` and `FLOOR.ODS` psuedo-functions as well; none of these four will be listed in the official Functions documentation.

In all of the descriptions below, FLOOR follows CEILING exactly.

Ods writes its functions to Xml as follows:
- CEILING.XCL becomes COM.MICROSOFT.CEILING
- CEILING.MATH becomes COM.MICROSOFT.CEILING.MATH
- CEILING.PRECISE becomes COM.MICROSOFT.CEILING.PRECISE
- CEILING remains unchanged

PhpSpreadsheet Ods Writer will do the same, plus:
- CEILING.ODS becomes CEILING

PhpSpreadsheet Ods Reader will act as follows:
- CEILING (not preceded by 'COM.MICROSOFT.') becomes CEILING.ODS
- COM.MICROSOFT.CEILING.MATH becomes CEILING.MATH
- COM.MICROSOFT.CEILING.PRECISE becomes CEILING.PRECISE
- COM.MICROSOFT.CEILING becomes CEILING

PhpSpreadsheet Xlsx Writer will act as follows:
- CEILING.ODS becomes CEILING.MATH
- CEILING.XCL becomes CEILING

PhpSpreadsheet Xls Writer will recognize only the CEILING and FLOOR functions.

Note that the only difference between Ods CEILING and CEILING.MATH is that CEILING will return an error if the number and significance operands have opposite signs. PhpSpreadsheet implements this as `#VALUE!`.
2025-05-10 21:40:28 -07:00
oleibman 0245f6ba22 Removing Columns/Rows Containing Merged Cells
Fix #282, which went stale over 7 years ago, and is now reopened. This is certainly related to issue #4379. If merged cells are in the midst of deleted rows/columns, the merge may continue to exist after the deletion, leading to various problems including spreadsheet corruption. The problem is not with either Reader or Writer.

This PR will automatically unmerge all merged cells whose first cell is in the delete range before performing the deletion. This will address the corruption problem. Something more sophisticated may be required, so I won't merge this PR for a while to give me a chance to think about it some more.
2025-05-09 20:58:06 -07:00
oleibman 5c94de34a9 More Phpstan Level 10 Prep - Readers
Also upgrade Phpstan.
2025-05-03 21:18:55 -07:00
oleibman d8ad4b03d7 Merge pull request #4449 from oleibman/issue4448
XML Reader Recognize Indents
2025-04-23 05:45:32 +00:00
oleibman de9fdc3855 XML Reader Recognize Indents
Fix #4448
2025-04-20 16:10:50 -07:00
oleibman 19555d6d96 Phpstan 10 and IterableValue Prep Part 2
There will probably be dozens, if not hundreds, of these before I'm ready to commit.
2025-04-18 23:27:29 -07:00
oleibman 5ce46da559 Merge branch 'master' into issue4435 2025-04-05 17:29:22 -07:00
oleibman 5b799dbbed Ods Reader No Datatype for Null Value
Issue #4435 was initially described incorrectly. While investigating the original description, I came upon this problem. Ods Reader is trying to set some cells to null without supplying a valid DataType to setValueExplicit, causing that method to throw an exception. Reader is changed to no longer call that method when value is null and DataType is null-string.
2025-04-03 19:55:33 -07:00
oleibman 5dee5a7bbb Merge pull request #4420 from oleibman/stan2lv905
Phpstan Level 9 - Part 5 of Many
2025-03-28 05:42:51 +00:00
oleibman 2213139d96 Merge branch 'master' into issue4416 2025-03-27 00:01:29 -07:00
oleibman 6b61da0017 Column Widths Not Preserved When Using Read Filter
Fix #4416. A peculiar problem indeed. PhpSpreadsheet has been considering a column to be filtered if any cell in the column is filtered and does not preserve the column width if that is the case. It should consider the column not filtered if any cell in the column is not filtered, and consider it filtered only if there are no cells to which that applies. At least, that's how I think it should work, and this change doesn't break any existing tests, and solves this issue.
2025-03-24 20:18:51 -07:00
oleibman bc315a3edc A Win For Scrutinizer!
It flagged a statement as dead code. It was correct - there was a typo in the variable name. But no tests had failed. The explanation was, of course, that this particular path was not adequately tested.

PhpSpreadsheet extends Excel (dating back to PHPExcel) by allowing the ordinal form of days in the DATE function, implemented as "take the numeric portion if the field is a string consisting of a numeric portion followed by some alphabetics". Whether or not this is a good idea, it would be a breaking change to eliminate it, so that's not going to happen. However, the same logic has been applied to month, and I don't see a use case for that, so I'm eliminating it - any non-numeric string used as the month parameter will now result in a VALUE error. It also turns out that Excel accepts null, false, and true for the month, and PhpSpreadsheet will now do likewise.
2025-03-23 12:33:01 -07:00
oleibman 71b243539a Ignore Fractional Part of Drawing Shadow Alpha
Fix #4415. We store the rarely-used property Drawing/Shadow/Alpha as an integer representing the percentage. Excel also stores it as an integer, but multiplies it by 1,000, so we divide by 1,000 when we read this value. This can, and in the case of the issue at hand does, leave a fractional portion. Php has deprecated passing a float with a fractional portion to an int argument, so the reporter saw a deprecation message. This is easily fixed.
2025-03-20 20:11:11 -07:00
oleibman 3ef8ec4b1a Merge pull request #4393 from oleibman/formularange
Add FormulaRange to IgnoredErrors Possibilities
2025-03-07 03:44:16 +00:00
oleibman 190af743f8 Add FormulaRange to IgnoredErrors Possibilities
When I implemented IgnoredErrors (PR #3508), I dealt only with those that I understood well enough to come up with an example. I finally found an example for FormulaRange in the wild, so this PR adds it. Still unsupported are `calculatedColumn`, `emptyCellReferece`, `listDataValidation`, and `unlockedFormula`.
2025-03-03 20:16:12 -08:00
oleibman a67a981d5e BIN2DEC, OCT2DEC, HEX2DEC Return Numbers Rather than Strings
Fix #4383.
2025-03-02 01:16:14 -08:00
oleibman a1f90b76e4 Add A Test 2025-02-26 18:52:31 -08:00
oleibman ea490a1d87 Remove Unwanted Tests 2025-02-26 00:58:57 -08:00
oleibman fcc781d3d7 Merge branch 'master' into php82-str-split-function-return 2025-02-25 22:33:31 -08:00
oleibman 01539876b1 Merge branch 'master' into issue4375 2025-02-23 12:28:17 -08:00
oleibman d813d7efcb Merge pull request #4360 from oleibman/issue4536
Xlsx Reader Defined Name on Sheet with Apostrophe in Title
2025-02-21 01:32:02 +00:00
oleibman 2b7e6f50a2 Ignore ignoredErrors when Not Applicable
Fix #4375. Do not set ignoredErrors when using readDataOnly, not when the cell to which it applies doesn't exist.
2025-02-19 19:15:01 -08:00
oleibman 94117dd7e6 Merge branch 'master' into visibility 2025-02-18 21:15:21 -08:00
oleibman ae6c92b006 More Tests 2025-02-17 22:45:05 -08:00
oleibman 8930e634a1 Add Some Tests 2025-02-17 17:58:17 -08:00
oleibman 9b07be9a0f Add sheetState to ListWorksheetInfo Data
Fix #4345. Add a new item to the output array. Although the output is changed, this does not seem like a breaking change to me.
2025-02-14 23:40:50 -08:00
oleibman a9749332d7 Merge branch 'master' into datetext 2025-02-09 20:31:23 -08:00
oleibman 04c0a793ee Fix TEXT and TIMEVALUE Functions Master Branch
Fix #4249. Technically speaking, only the 1.29 branch needs fixing, and only for TEXT. It was fixed for the other branches by PR #3898. However, in adding test cases for the fix, it became apparent that PhpSpreadsheet's parsing in TIMEVALUE (which is called from TEXT in the original issue) did not really match Excel's. There are probably still edge cases where it doesn't, but, in the absence of a spec for how it operates, this will do for now.

We do not usually backport fixes from the master branch. Because this is more of a forward port from the earlier branch, there is an equivalent PR for each active branch.
2025-02-09 20:27:27 -08:00