Commit Graph

173 Commits

Author SHA1 Message Date
oleibman ef440dd714 Merge commit from fork 2026-11-01 01:23:38 -07:00
oleibman a845ef2427 Merge commit from fork 2026-10-31 17:03:50 -07:00
Progi1984 9d09ae0c31 Support for Windows Metafiles images (WMF, EMF and EMF+) 2026-10-16 07:02:20 +02:00
oleibman b3511404e0 Merge pull request #5043 from oleibman/realpath
File::realpath should not issue file_exists
2026-10-08 06:59:14 +00:00
oleibman 5b5b12647e File::realpath should not issue file_exists
Fix #5042. `Shared\File::realpath` is used to normalize file name references in a zip file. It can be used for non-zip file names as well, but zip members is its primary use, and `file_exists` does not work with zip file members. Such usage leads to the issue to which this PR is linked, and there have been other instances in past. In particular, issue #3553 was addressed by editing it out a leading slash in such references; it is not needed, and neither Excel nor PhpSpreadsheet generate one, but it's legal. The fix for 3553 addressed only loading a spreadsheet; but `listWorksheetInfo` and `listWorksheetNames` are subject to the same problem, which is this issue.

The normalization that `realpath` does is already built into `File::realpath` using a well-documented algorithm. So neither `filepath` nor `file_exists` is needed there, and they are removed. There are other problems with the current implementation. It looks only for Unix, not Windows, file separators. And a very peculiar problem arises when the zip entry name matches a file path in the current working directory. These problems all go away with this PR.

It is very likely that some manipulation of the zip entry names can be removed entirely from `Reader\Xlsx`. I may look into this in future, but I'm not going looking for trouble now. The fix for 3553 remains in place, even though no changes are made to match it in `listWorksheet...`, so, chances are the 3553 change could be dropped. As I say, maybe some day.
2026-10-04 16:16:38 -07:00
Jonathan Goode 4c8b52d09d Add reader support for Box and Whisker charts 2026-09-25 20:24:49 +01:00
oleibman 89f455c133 Merge commit from fork
* Security Patch

* Minor Improvement to `unentity`

* More Unentity Tweaks
2026-09-15 19:03:30 -07:00
^^ b624d78289 Add sanitized Agile encryption fixture 2026-08-25 19:09:31 +08:00
saifulislamferoz 0f318f0aa6 Add read-only object model for Xlsx pivot tables
Introduces a first-class, read-only representation of pivot tables that
already exist in a loaded Xlsx file (issue #4534). Previously pivot tables
were completely inaccessible from the object model.

New model classes under Worksheet\PivotTable:
- PivotTable: name, location, source cache definition and field layout,
  with axis helpers (getRowFields/getColumnFields/getPageFields/getDataFields).
- PivotCacheDefinition: cache id, source worksheet/range and cache field names.
- PivotField: field index, name, axis placement, and data-field aggregation.

Reader\Xlsx\PivotTableReader parses a pivotTableDefinition part and its
associated pivotCacheDefinition part into that model. The main Xlsx reader
discovers pivot parts via worksheet relationships and wires them up (skipped
under setReadDataOnly). Worksheet gains getPivotTableCollection(),
getPivotTables(), addPivotTable(), getPivotTableByName(), getPivotTableNames()
and removePivotTableCollection().

This is inspection-only: it does not create, modify, recalculate or render
pivot tables, and does not change what the writer emits. A minimal pivot-table
fixture and functional tests cover reading name, location, cache source,
fields and axis placement, plus the read-data-only path.
2026-08-03 11:51:43 +06:00
saifulislamferoz 041c85060f Improve sparkline test coverage and harden reader
Add tests for previously-uncovered SparklineGroup setters (axis types,
manual limits, additional display options and colours) and a hand-crafted
Xlsx fixture exercising the reader's edge cases (non-sparkline ext, group
without sparklines, sparkline with empty sqref, missing colour elements).

Harden Reader/Xlsx/Sparklines against malformed input: guard the
sparklineGroup and sparkline iterations against a null children set so an
empty <x14:sparklineGroups> or <x14:sparklines> element no longer emits a
PHP warning.
2026-07-28 06:40:12 +06:00
oleibman 1876d6062f Permit Ignoring 'Misleading Format' Tag
Building on PR #3508 and PR #4393, which allowed ignoring 5 different cell 'errors'. Adding this new one should have been dead easy, but MS, in its own inscrutable way, decided to complicate this by making the xml attribute require its very own namespace, unlike any of its relatives.

There are supposed to be several ways to activate this tag. One is to enter a date in cell A1, then in cell B1 enter the formula `=A1`, and set B1's numeric format to `General`.
2026-06-16 19:45:13 -07:00
oleibman 9019a9c9da Merge commit from fork 2026-04-18 23:43:10 -07:00
oleibman 162fd2ce5b Add Unit Test 2026-03-27 22:54:55 -07:00
oleibman ff03307cce Merge pull request #4801 from IndrekHaav/css-size
Add support for image CSS size in millimetres
2026-02-11 03:51:37 +00:00
Indrek Haav eafca4a3a8 Add unit tests 2026-02-07 00:23:56 +02:00
oleibman c9b01653e7 Coverage Tweak 2026-01-31 00:40:47 -08:00
oleibman 50a7552f12 Option to Whitelist External Images
Loading external images from a spreadsheet can subject the caller to security exploits. For those who think they need something between not loading any external images (the default and our strong recommendation) or loading them all unconditionally (the current alternative), a callback can now be provided to indicate whether a specific image is okay to load. We continue to urge caution in using this option.
2026-01-30 22:43:21 -08:00
Thomas Lallement 059a75880e Merge branch 'master' into drawing-in-cell 2026-01-06 09:38:09 +01:00
oleibman 60a04419cc Rowspan in Html
Fix #1319, which went stale in 2020, and is now reopened. Rowspan is not showing up when saving some spreadsheets as Html. There is some logic concerning property `isSpannedRow` which indicates that this is deliberate, but I have no idea what purpose it serves. It leads directly to this issue, and also adversely affects (in a minor way) some samples (e.g. 17a_Html), where merged cells maintain their text but lose their top and bottom padding. After discarding this logic, the reported problem goes away, the samples look better, and no tests fail. So, whatever its purpose, it wasn't tested for. This PR permanently removes the property, and adds a little additional bulletproofing. A minor accommodation is needed for Tcpdf in one place.

This PR probably deletes more lines from Html Writer than it adds. It would not surprise me if this is one of those unusual cases where Coveralls reports a decrease in coverage despite the fact that all the new code is covered.
2026-01-01 16:34:56 -08:00
Thomas Lallement 35074f377b Finalize XLSX In-Cell Drawing Writer 2025-12-31 13:07:21 +01:00
Thomas Lallement 67f57394ac Merge branch 'PHPOffice:master' into patch-1 2025-12-31 12:04:31 +01:00
oleibman 84747121a1 Changes to WEBSERVICE
This PR started because the documentation on how to configure an Http client was out of date. However, as I investigated further, I found problems. GuzzleHttp, a client mentioned in the documentation, for example - it probably works fine when executed from a browser, but it does not work for `https:` requests from the Windows command line. See https://github.com/guzzle/guzzle/issues/2601, where a user notes that Guzzle's own program to demonstrate how to use it doesn't work, a result that I can confirm is still true. A linked explanation says that the solution is to explicitly specify a path to a CA bundle. For starters, this is impractical from our perspective. One possible solution is to change a php.ini option which is not needed for any other purpose, and which probably needs to change frequently - a burden on users who follow that route. An alternative solution is to use a method `request` to specify the path to the certificate store; this also will need to change from time to time, and, worse, the only method defined in ClientInterface is `sendRequest`, so using this solution isn't client-agnostic, which is a stated goal of https://github.com/PHPOffice/PhpSpreadsheet/commit/7cb4884b96174eb611621635e6fb603ef54178f7. Additionally, it is not clear why an external interface is needed rather than a call to file_get_contents, used elsewhere in PhpSpreadsheet, and not requiring a path to a certificate store.

I also believe that automatically evaluating WEBSERVICE for any arbitrary argument is not a good idea. I am adding a domain whitelist which the user must populate. For domains not in the whitelist, the calculation will revert to `oldCalculatedValue`, which is good enough for pass-through purposes, which probably encompasses most cases. That is how Excel behaves by default - it disables WEBSERVICE calls when it opens a spreadsheet which contains them. For cases where the user adds a new WEBSERVICE call, there is a choice of whitelisting the domain, or getting the result in some other way and using `setCalculatedValue` to store it.

Finally, when a WEBSERVICE call *is* evaluated, it will now accept a cell-address argument rather than just a literal string as is now the case.
2025-12-19 10:12:50 -08:00
oleibman 1daaad2576 Xlsx Reader ListWorksheetInfo Honor readEmptyCells
Fix #3255, another oldie (3+ years). Allow the ability to only count rows and columns with data. To avoid a breaking change, keep present logic unless Reader `readEmptyCells` attribute is set to its non-default value, i.e. `false`. This adds very little overhead, and gives a result that I think many users would prefer.
2025-12-13 20:14:11 -08:00
oleibman 65c0477e88 Edge Case 2025-12-01 22:35:43 -08:00
oleibman 98ca50e9fe Handle Surrogates If Read
It is probably very anal of me to do this. Excel does it. I can't see it happening in the wild.
2025-12-01 16:57:42 -08:00
oleibman 0a96e52457 Additional Test 2025-11-27 23:43:31 -08:00
oleibman 0faea6c1c1 Slightly Better Support for Escaped Characters in Xlsx Reader/Writer
See [Discussion 4724](https://github.com/PHPOffice/PhpSpreadsheet/discussions/4724)

PhpSpreadsheet converts all control characters (x00-x1f) in strings to and from a form which Excel recognizes (e.g. `x1c` becomes `_x001C_` when writing, and vice versa when reading). There have historically been 3 exceptions which go unconverted - tab (x09), line feed (new line) (x0a), and carriage return (x0d). PR #4536 removed those exceptions, but that caused some problems; these were fixed by PR #4619, but the exceptions were restored.

The referenced discussion deals with a spreadsheet with a cell containing `_x000D_`, carriage return. Although the writer no longer converts to that string on output, the reader should be able to handle it on input. In fact, the reader ought to handle any string of the form "underscore x 4-hex-digits underscore", whether or not it represents a control character.

And there's an interesting edge case. If a user enters into a cell the string `A_x0030_B`, it needs to be handled as-is. Excel handles this by writing it out as `A_x005F_x0030_B`, i.e. substituting `_x005F_` for the first underscore, so that the reader sees `_x005F_` (converting it to underscore) followed by `x0030_B` (no leading underscore, so no conversion). PhpSpreadsheet could probably handle this by converting all underscores on write, but I am trying to emulate Excel and do it only when needed.
2025-11-27 10:35:06 -08:00
oleibman db1aba6554 Better Sample File 2025-10-09 08:19:12 -07:00
Emeka Oziri 8fcde62db6 Xlsx: register x and o namespaces for VML shapes; add test for #4505
Fixes SimpleXMLElement::xpath(): Undefined namespace prefix when reading VML comments/shapes by registering x: (Excel) and o: (Office) namespaces alongside v:.

Includes:
- tests/PhpSpreadsheetTests/Reader/Xlsx/Issue4505Test.php
- tests/data/Reader/XLSX/issue.4505.xlsx

Refs: https://github.com/PHPOffice/PhpSpreadsheet/issues/4505
2025-10-03 23:37:56 +01:00
Thomas Lallement 9920935fdb Support Read Image in Cell 2025-09-27 18:12:37 +02:00
oleibman fff2373b39 Merge branch 'master' into issue4584 2025-09-16 23:48:50 -07:00
oleibman dc25bc1ac4 Coverage Tweaks 2025-09-12 00:41: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 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 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 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 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 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 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 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 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 01539876b1 Merge branch 'master' into issue4375 2025-02-23 12:28:17 -08: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 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 8d7500b1e2 Merge branch 'master' into issue4312 2025-01-21 19:58:05 -08:00
oleibman 41ca105c88 Handle Overlapping Ranges
Fix #4318. Also make getConditionalStyles more useful, by adding a non-default parameter so that all rules pertaining to a single-cell coordinate can be returned, and in priority order. By default, just the first matching rule will be returned.
2025-01-14 20:57:55 -08:00