Commit Graph

1164 Commits

Author SHA1 Message Date
Mark Baker 5ebb1c9943 Merge branch 'master' into Worksheet-toArray_Ignore-Hidden-Rows-Columns-Option 2023-04-01 22:22:23 +02:00
oleibman d6180ad113 Font Themes (#3486)
* Font Themes

It isn't a feature of Excel that I've made any use of, but PR #3476 added better Theme support for colors, and it is relatively easy to add Theme support for Fonts on top of that.

Excel assigns two theme fonts to its spreadsheets, one for Headings (major), and one for Body (minor). If the body theme is Calibri, when you choose a font for a cell in Excel, you can choose 'Calibri (Body)' from the Theme Fonts section at the top of the Font dropdown, or 'Calibri' from the 'All Fonts' section. If you choose the former, the cell will be automatically restyled if you change the Theme Fonts (via Page Layout, Themes, Fonts). The relationship to the theme fonts is recorded in the XML via a `scheme` tag (descending from `font`) whose `val` attribute can be either `major` or `minor`. Accordingly, this PR, in addition to defining the Theme Font properties, adds a `scheme` property, with getter and setter, to Style/Font.

The main benefit of this PR is that you can now load and save a spreadsheet preserving the connections to the Theme Fonts, without having to take any additional action.

A secondary benefit arises from the following difference. Empty cells in Excel will use the spreadsheet's default font name when they are filled in; but, in Google Sheets, they will use the Theme Minor Font name. By setting the `scheme` property in the default style, the resulting spreadsheet will behave the same in both Excel and Google.

I will note that Excel's font themes specify a Latin font, an East Asian font, a Complex Scripts font, and a set of font substitutions for various languages. PhpSpreadsheet will preserve all of these, and allow them to be changed. However, although it is easy to imagine how the non-Latin options might work, I have not yet been able to come up with an example where Excel uses any of them. In particular, if I use a theme font which does not support language X, and I use Language X in a cell bound to the theme, Excel will use a substitution font which does support it, but the font which it uses does not seem to be chosen from the alternatives supplied in the theme.

* Scrutinizer

The sun rises in the east, and Scrutinizer issues more false positives.
2023-03-31 17:12:37 -07:00
Mark Baker b48232c616 Merge branch 'master' into Xlsx-Reader_Windows-Folder-Separator-in-Zip 2023-03-31 12:56:02 +02:00
MarkBaker 41fd431acc Allow CellRange and CellAddress objects for the range argument in the rangeToArray() method. 2023-03-30 22:03:25 +02:00
MarkBaker e5ed056b81 Provide an Ignore/Return Hidden rows/columns option to the toArray() methods 2023-03-30 18:18:46 +02:00
oleibman 0e6866d6f0 Font/Effects/Theme Support for Chart Data Labels and Axis (#3476)
* Font and Effects Support for Chart Data Labels and Axis

Addresses some remaining issues with 32readwriteLineChart5 (see issue #1797). Font size is covered. So are effects, although the results are a bit odd. For the new spreadsheet 32readwriteLineChart6, the Axis labels have a yellow-ish glow, but reading and writing the spreadsheet in PhpSpreadsheet gives them a purple-ish glow. Nevertheless, the new test shows that the output file uses schemeClr accent4, as does the input file. So the effect is handled correctly, but it seems there is likely to be a difference between theme colors (Writer/Xlsx/Theme appears to write hard-coded color schemes, and, in any case, Reader/Xlsx does not appear to handle schemeClr). Fixing that will be a great deal more difficult, with a large chance of regression, and will need to happen in a separate PR (one that I am not currently investigating, but I will open a new issue). Effects using srgbClr (and probably sysclr) should be okay.

* Better Theme Support

When reading Xlsx, the theme colors will now also be used for writing. This means that a file can be loaded and saved and its chart colors will now be preserved. If the spreadsheet is created new, Excel 2007-2010 colors are used. The writer is currently hard-coded to use them, so this avoids making this a breaking change. The theme colors can be explicitly changed if desired, and Excel 2013+ colors can be introduced very easily.
```php
$spreadsheet->getTheme()
    ->setThemeColorName(Theme::COLOR_SCHEME_2013_PLUS_NAME);
```
Likewise, if the old behavior of changing to the 2007-2010 scheme rather than using the input values is desired, that is easy to achieve after the load has taken place.
```php
$spreadsheet->getTheme()
    ->setThemeColorName(Theme::COLOR_SCHEME_2007_2010_NAME);
```
The new Theme class introduced by this change can easily be extended to include Fonts and Effects. Unlike Colors, I am unsure what the practical effects of changing those to, say, the 2013+ defaults would be.

* Scrutinizer

Use an alias in a use statement.

* Update Change Log

Due to potential behavior change.
2023-03-26 03:19:34 -07:00
oleibman cd9f1659fe WIP Handle REF Error as Part of Range (#3467)
Fix #3453. User sets a valid formula (e.g. `=SUM(Sheet2!B1:Sheet2!B3)`), and then does something to invalidate the formula (e.g. delete Sheet2). Excel changes the formula to `SUM(#REF!:#REF!)` when the spreadsheet is saved; apparently someone thought this was a good idea. But PhpSpreadsheet (a) used to throw an Exception when it evaluated the formula, and (b) now gives a result of `0` when evaluating the formula. Neither is ideal. It would be better to propagate the `#REF!` error.

It is likely that more tests are needed, which is why I will keep this in draft status for a bit.
2023-03-25 07:03:52 -07:00
Mark Baker 0016de81a4 Merge branch 'master' into NumberFormat-Wizard-Duration 2023-03-25 02:39:35 +01:00
MarkBaker 235f11b438 Unit tests for both linux and windows directory separators in zip files 2023-03-24 23:14:11 +01:00
MarkBaker 6f60191b61 Add defaults for Date and Time NumberFormat Wizards 2023-03-23 21:53:30 +01:00
MarkBaker 0c0fa705db Duration NumberFormat Wizard 2023-03-23 16:29:24 +01:00
oleibman dafd78b462 Support Border for Charts (#3462)
* Support Border for Charts

All chart linestyles will be supported for Chart Border. Also add fill color for Chart. Also 'nofill' for Axis (allows suppressing of vertical axis line). These are demonstrated in sample 32_readwriteChartLine5, and a new unit test member is added. This addresses some vague problems added to issue #1797 over 8 months after it was closed; there is still at least one problem, much more complicated than the 2 being addressed in this PR.

* Handle Legend Borders in Same Way as Chart Borders

Consistency is good, and the implementation of Chart Borders offers more possibilities than the implementation of Legend Borders had. Since Legend Borders hasn't made it to a release yet, there is no need for deprecations.
2023-03-19 18:32:33 -07:00
MarkBaker a085835eb5 Fix for Issue 3439 - Getting a style for a CellAddress instance fails if the worksheet is set in the CellAddress instance 2023-03-19 17:33:00 +01:00
oleibman 011f9cd1a4 Xlsx Writer Honor Alignment in Default Font (#3459)
* Xlsx Writer Honor Alignment in Default Font

Fix #3443. A mysterious implementation by Excel. The style tags have an attribute applyAlignment, which nominally says whether or not the style should use its own Alignment. Except ... Excel ignores that attribute and uses the alignment tag if it is supplied ... and, another mystery, uses not the default style for the spreadsheet if not supplied, but rather uses the default alignment style for all spreadsheets even if the spreadsheet's default style uses a non-default alignment. I am changing Xlsx Writer to generate alignment tag unless the alignment matches both the default alignment for the spreadsheet and the default alignment for all spreadsheets (which I expect to happen most of the time).

* Improve Performance

Also don't change horizontal/vertical on Xlsx Read if they aren't explicitly set.
2023-03-18 11:50:12 -07:00
Mark Baker c3ac0cff71 Merge branch 'master' into NumberFormat-Wizards_Non-breaking-space 2023-03-18 17:25:56 +01:00
MarkBaker b906d10111 Use NBSP in Accounting Wizard, and as an option for Date/Time Wizards 2023-03-18 17:05:40 +01:00
anhoder b4e4e2085b Fix incorrect font color read from xlsx (#3465)
Place the read font color after setting the styles
2023-03-18 09:04:31 -07:00
Pouria Seyfi 603d093df7 Specify data type in html tags using attributes (#3445)
* Specify data type in html tags using attributes #3444

* Set data types using attributes in flushCell function and add some unit tests

* Check TYPE_INLINE in flushCell and some changes in test cases
2023-03-18 08:37:39 -07:00
Mark Baker cea9c4dce7 Merge branch 'master' into NumberFormat-Wizards-Date-Time-Duration 2023-03-17 13:26:47 +01:00
MarkBaker e58d51fdb9 Issue 3461 - Establish boundary for function prefix regexp to prevent NETWORKDAYS being picked up by DAYS 2023-03-17 08:13:22 +01:00
MarkBaker ec60f5896b Escape single characters in Date, Time and DateTime NumberFormat Wizards 2023-03-16 13:06:03 +01:00
MarkBaker 7a0c18f3e7 Refinements to Date, Time and DateTime NumberFormat Wizards 2023-03-16 10:53:01 +01:00
MarkBaker ca05f69b4a Initial work on Date, Time and DateTime NumberFormat Wizards 2023-03-16 02:25:10 +01:00
Mark Baker c196625cb1 Merge branch 'master' into UnitTests_Refactoring-Database-and-DateTime 2023-03-14 11:15:49 +01:00
MarkBaker fe31c2004f Extended unit tests for Engineering functions 2023-03-14 06:53:45 +01:00
MarkBaker 36e9e864e6 Additional edge-case tests 2023-03-14 06:53:45 +01:00
oleibman ff625d784d More Coverage In Unit Tests (#3447)
* More Coverage In Unit Tests

Minimal source code changes.

* Scrutinizer

One legitimate complaint and one from out of left field.

* Scrutinizer Lunacy

If this doesn't stop its complaint, I give up.

* Scrutinizer - Whatever

Try again.

* Glutton For Punishment

Try again.
2023-03-13 05:25:42 -07:00
oleibman a3489b5d89 Minor Changes to 3 Tests/Samples (#3451)
No source changes. Act on some items that have come up in recent discussions.
- Sample 33_Chart_create_line creates a stacked line chart. According to @MarkBaker, the stacking is done on the wrong variable, and, even were that not the case, stacking is unusual for line charts. Since this is our primary sample showing how to create a line chart, remove the stacking. Another sample, with a more appropriate choice of chart (33_Chart_create_bar_stacked), still shows how to create a stacked chart.
- The test for reading a styled cell from Html is flawed. It sets a date format for a string date/time, but the format is applied only to numeric data, so the format, although set correctly, is ineffective. Keep the test, but add some explanation in the assertion, and add some new more effective tests, also with explanations in the assertions.
- Wrong namespace used for Writer/Xlsx/ConditionalFillTest.
2023-03-12 00:22:20 -08:00
MarkBaker 9c2deb125f Scrutinizer really sucks!!!
Stop a few of scrutinizers complaints about 100% valid use of PHP variadics.
Hopefully, this issue will cease to be an issue when we can specify mixed datatype for variadic arguments in the tests
2023-03-10 04:43:11 +01:00
MarkBaker a91dd60a98 Refactor unit tests to ensure that assertions are in the actual test, and not in an abstract class; and that setup/teardown are in the test and not an abstract. This means that assertions and setup/teardown are always in the file when reviewing PRs.
Also enforce more rigorous Excel Function implementation by testing the underlying implementation, call via the Calc Engine, and execution from in a worksheet.
Separate out unhappy path (exception) checks into a separate test, so that a single test isn't made overcomplex checking for every potentiality.

Scrutinizer may dislike variadics, for variable number of arguments of mixed type; but tough. It's 100% valid PHP, accepted by phpstan, and makes life a lot easier.

Initial work here covers all the database and datetime unit tests for Excel function implementations.
2023-03-10 04:15:12 +01:00
oleibman 20348642ed More Display Options for Chart Axis and Legend (#3434)
* Allow Color and Effects on Data Points on Chart Axis

Fix #3414. There had been no way to do this. It is now supported via a new AxisText class, which derives from Properties, and has FillColor and effects (glow/shadow/softEdges) properties. The code changes in chart sample 33_Chart_create_scatter2 illustrate usage.

* Minor Performance Improvement

May also get rid of Scrutinizer complaint.

* Eliminate New Spacing Patch

No need for it.

* Add Legend Formatting to Change

Much in common with Data Point formatting.
2023-03-09 10:15:24 -08:00
oleibman 73f880ff19 Correct Xlsx Parsing of quotePrefix="0" (#3438)
* Correct Xlsx Parsing of quotePrefix="0"

Fix #3435. Mis-parsed attribute is not normally generated by Excel or PhpSpreadsheet, but some 3rd-party software (correctly) generates it.

* Update Issue3435Test.php
2023-03-07 07:51:20 -08:00
MarkBaker 9006d2a3f4 Fix for Issue #3436 - Result from Excel's EDATE() and EOMONTH() should always be rounded to 0 decimal 2023-03-06 17:22:30 +01:00
oleibman bb54c89cde Xlsx Column Autosize Approximate for CJK (#3416)
Fix #3405. Autosize is definitely not working well with CJK characters (column is not wide enough). User reports a workaround using `mb_strwidth` to calculate and set the column width. PhpSpreadsheet uses `mb_strlen` for width calculations. Change it to use mb_strwidth instead. For non-CJK strings, the results will be identical (and there are already unit tests on such strings which assert the expected results, and these tests did not need to change). For CJK strings, the results will be wider. The string I'm using to test comes from the issue. It currently results in a column width of 30.564. When I open the resulting sheet in Excel and auto-fit the column width, the width winds up as 43.00. So, as long as the computed width exceeds 43.00, the spreadsheet will show the full cell. With the new calculation, the computed width is 55.2722, satisfying our condition. This is wider than expected, but that is generally true for this type of computation. For example, for 'abcdefghijklmnopqrstuvwxyz', the computed width (before and after this change) is 31.7065, but Excel auto-fit actually uses 24.73.

Disappointingly, "exact width calculation" does not solve this problem. It does seem to do a little better than "approximate" for non-CJK, but its CJK calculation is not wide enough. This might or might not indicate a bug in Php function `imagegetttfbbox`; I do not know enough about it to report a bug. Anyhow, since we're dependent on that result, there is no equivalent in this case for swapping mb_strlen out for mb_strwidth.
2023-03-04 07:37:52 -08:00
oleibman 66221bfcb2 TEXT Function Ignores Time in DateTimeStamp (#3411)
Fix #3409. Calculate both the date and time portions when a date/time format is supplied for the TEXT function.
2023-03-01 19:57:49 -08:00
oleibman bef3a0066b Misplaced Xml Writing Chart Label FillColor (#3404)
* Misplaced Xml Writing Chart Label FillColor

Fix #3397. Move code to correct location.

* Update Issue3397Test.php

No need for spacing patch - just fix it now.

* Minor Fix

See discussion at bottom of PR #2856.
2023-03-01 19:19:41 -08:00
MarkBaker c71aedeb56 Modify Date/Time check in the NumberFormatter so that masks with a decimal/fractional time aren't misinterpreted as number masks, while still ensuring that durations are interpreted as date/time masks, and locale currency masks are still treated as numbers
A date/time with a decimal time shouldn't have a digit placeholder __before__ the decimal point, only after
2023-02-28 12:34:00 +01:00
MarkBaker 0ebbb3297d Allow use of # and 0 digit placeholders in fraction masks 2023-02-25 12:48:53 +01:00
oleibman 324e19035f Xls Reader Conditional Styles (#3400)
The code currently allocates the style object as a non-conditional style, leading to corruption when the spreadsheet is written out.

That being said, Font Color is the only Conditional Formatting I have gotten to work for Xls for read or write. Use of other styles will essentially continue to be ignored, but will at least no longer result in corrupt spreadsheets.
2023-02-24 18:11:38 -08:00
MarkBaker 6409af4dcc When a Worksheet has an AutoFilter, make allowance for Center Alignment in the filter heading when calculating AutoFit column widths. 2023-02-24 21:24:46 +01:00
oleibman ab420f4499 Coerce Bool to Int for Mathematical Operators on Arrays (#3392)
* Coerce Bool to Int for Unary Operation on Arrays

Fix #3389. It seems some functionality was left behind when JAMA was eliminated (PR #3260). In particular, it is apparently a known trick to use double negation on boolean values as arguments to functions like SUMPRODUCT.

* Fix 3396

Treat booleans in arrays as int for mathematical operators as well.

* Edge Case

When array operand was neither numeric nor boolean, PhpSpreadsheet had always been evaluating the operand as #NUM!. It will now propagate an error string like #DIV/0!, and treat non-error strings as #VALUE!, consistent with Excel.
2023-02-23 23:11:22 -08:00
oleibman 6925b7f621 Conditional Formatting Improvements for Xlsx (#3372)
* WIP Conditional Formatting Improvements for Xlsx

Fix #3370. Conditional styles are always generated with 5 borders (right, left, top, bottom, diagonal) even though the border style is none in each case. For the spreadsheet in question, top and bottom were inappropriate and interfered with the desired formatting. A new border style, BORDER_OMIT is added which will cause the Xlsx Writer to not generate that style. All conditional borders will be initialized with that value. Any border included in the Xml will, of course, change it to the specified type.

Fix #3202. User wants a condition to use "No format set" as you can in Excel. A new boolean property `$noFormatSet`, along with setter and getter, is added to Style/Conditional. It is initialized to false. User can call setter to change it. More importantly for the issue in question, if the Xlsx Reader encounters a `cfRule` tag which does not have a `dxfId` attribute (i.e. no style is associated with the rule), it will set noFormatSet to true. Similarly, the Xlsx writer will not generate a `dfxId` tag when noFormatSet is true.

This change is applicable only to Xlsx. Html, Csv, and Ods do not have support for Conditional Formatting. Limited support was added to Xls with PR #2696 in April 2022 and PR #2702 about a month later. However, with the current release code, Xls equivalents of the two new test spreadsheets in this PR are too complicated to be handled correctly by PhpSpreadsheet - loading and then saving them as Xls results in Excel complaining of corruption, and the results don't meet expectations. Since I have no idea how BIFF works, and since the problems with those spreadsheets are not caused by this PR, I am not planning to address those problems at this time.

* Update Documentation, Write Alignment and Font Less Often

It doesn't cause any particular harm except for small increases in file size and run time, but Alignment tags are written even when (a) all its attributes are null for Conditional Formatting, and (b) when the xml specifically indicates that Alignment should not be applied. Similarly, Font is written even when all its attributes are null for Conditional Formatting.

There are some errors in the Conditional Formatting documentation. Specifying a solid fill color in a Conditional Style requires the use of endColor, not StartColor. The discussion of Order of Evaluating is not entirely accurate. I have changed it to what I believe is an accurate explanation of how Excel works; and also added a mention that other spreadsheet programs might not work the same way, adding a couple of illustrations of the difference. The description of the multiple conditions did not quite match the diagram. 'Stop if true' was a blank paragraph; it is now described, and the new 'No format set' option is described in that paragraph since (I think) it would be used most often in conjunction with 'Stop if true'.

* Xlsx Writer Allow StartColor for Conditional Solid Fill

To set a solid fill in a non-conditional style, you set StartColor (xml will use that value as fgColor and a default value as bgColor). If you instead set EndColor (xml will use that value as bgColor and a default value as fgColor), the styling will not work as expected.

However, for conditional styles, if you set StartColor (xml will use that value as fgColor and not specify bgColor), the styling will not work as expected. If you instead set EndColor (xml will use that value as bgColor and not specify fgColor), the styling will work as expected.

Together, this means that you need to use different methods for non-conditional style fill than for conditional style fill. This isn't a big problem, but it is a bit weird. This PR changes Xlsx Writer so that if (a) fill is olid and (b) startColor is specified and (c) endColor is null, the xml will be written as bgColor without specifying fgColor. This means that you can set StartColor for both conditional and non-conditional and get the expected styling. You may, of course, continue to specify EndColor instead for conditional.

* Fix Some (Not Many) Xls Problems

I will open an issue for the (pre-existing) remainder.
2023-02-23 22:28:22 -08:00
oleibman 378beac8f2 Xls Writer Parser Handle Boolean Literals as Function Arguments (#3391)
Fix #3369. The parser had failed to account for `TRUE` and `FALSE` when supplied as arguments to a function.

I had hoped to be able to do something about its inability to handle defined names as well. I failed. I think another section might need to be added to the Writer output which specifies the defined names. I haven't yet located any suitable documentation.
2023-02-23 10:54:54 -08:00
MarkBaker f468e78b66 Improved handling for ? placeholder in Number Format Masks 2023-02-22 12:55:21 +01:00
MarkBaker e812b49bb6 Additional unit tests for scaling values in Number Format Masks 2023-02-21 13:20:23 +01:00
MarkBaker 5cf4e2cca1 Fix handling for a # symbol in quotes inside a number format mask 2023-02-21 03:17:08 +01:00
oleibman ac1172810e Another Xls Coverage Change (#3385)
I hadn't noticed some minor corruption in a file. It is fixed. Xls now supports BAHTTEXT as _xlfn.BAHTTEXT, not as an index to a list of built-in functions, so it is no longer suitable for this test and is removed from the spreadsheet. TRANSPOSE changes, e.g. A1:B2 to {1,2;3,4}, and the Xls Writer Parser has trouble with that, so its test is also removed from the test spreadsheet.
2023-02-20 12:15:22 -08:00
MarkBaker 207d029c26 Allow use of an explicit 0 for a decimals value when using Currency and Accounting Number Format Wizards with a locale, to indicate whole currency units only, no minor units 2023-02-20 18:34:59 +01:00
oleibman 33eefe7c9d Resolve Phpstan Messages - FINALE - Shared/OLE (#3364)
* Resolve Phpstan Messages - FINALE - Shared/OLE

Reduce number of Phpstan messages by addressing their issues. This is the last of a series of related tickets to achieve that end. Only a handful of messages will be left in Phpstan baseline after this change is merged.

Shared/Ole.php and Shared/Ole/ChainedBlockStream.php were completely uncovered in the test suite. So I wrote some tests and found they didn't work at all. There were 2 problems. The first was that ChainedBlockStream checks for a mode of `r`, but Ole invokes it with mode `rb`. ChainedBlockStream will now just check the first character of the mode.

The second was a more interesting problem. Ole was reading "an *unsigned* long". However, what it should have been reading was "a 32-bit *signed* long". The irony of this mismatch is that, once the mode problem was corrected, 32-bit Php handled Ole and ChainedBlockStream correctly, but 64-bit Php did not. The code is corrected to work properly for both 32- and 64-bit.

* Scrutinizer

2 dead assignments - sufficient to just make calls which are expected to fail.
2023-02-20 06:40:02 -08:00
oleibman 28fb962cdb Complete Functions Coverage for Xls (except GETPIVOTDATA) (#3383)
Finish the work started in PR #3371 and PR #3340.
2023-02-20 06:07:12 -08:00