Added
- Ods Writer writes each table as a named database range, with its header row, so that LibreOffice tags the header cells of an exported PDF as
/TH; Ods Reader reads a named database range back as a table (the anonymous range LibreOffice keeps for the filter of a sheet stays that sheet's autofilter), and an autofilter now lands on the sheet its range names. Issue #5022 PR #5023 - Support for Box and Whisker charts in Xlsx reader and writer. Issue #3493
- Support for Windows Metafiles images (WMF, EMF and EMF+), using the
phpoffice/wmflibrary: Xlsx Writer stores them as is, Ods, Xls, Html and Pdf Writers and comment backgrounds use a PNG rendering; Xlsx and Ods Writers can switch withsetConvertMetafilesToPng()(new inBaseWriter), andMemoryDrawing::fromString()/fromStream()accept them. New methodsDrawing::isMetafile()andDrawing::getMetafileType(), and new helperShared\Metafile. Document\Properties::setLanguage(): the language of a spreadsheet as a BCP 47 tag, written and read asdc:languagein Xlsx and Ods; the Ods writer also gives it to the default cell style, where LibreOffice keeps a spreadsheet's language, as LibreOffice writes it (the Western, Asian or complex slot by script, andstyle:rfc-language-tagfor a tag with more than a language and a country), and the Ods reader reads it from there when there is nodc:language. Html writes and reads it as thelangof thehtmlelement. Issue #5040 PR #5041- Xlsx Writer and Reader:
Chart::setDescription()is the alternative text of a chart, written asdescrof the chart's frame and read back, and the frame takes the chart's name; LibreOffice exports it as/Altof the chart in a tagged PDF. Issue #5038 PR #5039 BaseDrawing::setDecorative()marks an image as decorative. Xlsx writes and reads it as Excel and LibreOffice do (adec:decorativein the image'scNvPr), Ods as LibreOffice does (loext:decorativein the frame's graphic style, which the writer now defines; the reader also takes ODF 1.4'sdraw:decorative); LibreOffice then leaves the image out of a tagged PDF as an artifact. Html writes and reads it as an emptyalt. Issue #5036 PR #5037- Xlsx Writer and Reader: the description of a header/footer image is its alternative text,
alton the VML shape as Excel writes it. Issue #5056 PR #5057
Changed
- Update infrastructure for running samples in browser. PR #5061 PR #5068
phpoffice/wmfis a new required dependency, used to render Windows Metafiles images.- The exception thrown for an unsupported comment background image now lists WMF and EMF among the supported types (
Drawing::UNSUPPORTED_IMAGE_TYPE_MESSAGE). - Some Windows environments are added to CI unit tests. PR #5053
Deprecated
- Deprecate
_calculateFormulaValueforcalculateFormulaValue. PR #4992 - Tcpdf V6 is now officially deprecated. We will continue to support it for now, but are considering dropping support with the next major PhpSpreadsheet release.
Fixed
- Xls Writer: a color matching a built-in palette entry above the custom range (e.g.
333333) no longer makes the palette look full, so later custom colors are no longer written as black. Issue #5065 PR #5066 - Xlsx Reader and AgileEncryption parser reject a DOCTYPE or entity declaration in encrypted workbook metadata before parsing. PR #5072
RIGHT()returns all of the text when the number of characters requested is greater than its length. PR #5044- Comparison operators order values of different types as Excel does (numbers < text < FALSE < TRUE), so
=""<75is FALSE. PR #5004 - A "TRUE" or "FALSE" criterion matches logical values in COUNTIF, SUMIF, the database functions and the others sharing their criteria, as Excel does. PR #5006
- OLE Writer now validates directory names, orders and colors sibling trees correctly, writes conformant CLSIDs and timestamps, and initializes unused directory-entry pointers to NOSTREAM. PR #5033
- MIN and MAX return #VALUE! for non-numeric text typed as an argument, and count logical values and numeric text typed as an argument, as Excel (and SUM) do. PR #5005
VALUE()no longer treats product-like text such as5V 2.1A - EU Wall Adaptoras a date serial. Issue #4996 PR #4997- Minor Xml Reader Improvements. PR #4989
- Rename and change visibility of 2 Xls Writer properties. PR #4995
- Documentation infrastructure tweaks. PR #4994 PR #4999
- Ods Writer writes a right-to-left sheet as
style:writing-mode="rl-tb", and Ods Reader reads it back; the direction was lost both ways. Issue #5015 PR #5016 - Ods Writer writes a link to another sheet as
#Sheet.A1, as ODF and LibreOffice do, and Ods Reader reads that form back assheet://Sheet!A1, so a Xlsx saved from it no longer gets a broken location. Issue #5011 PR #5012 - Ods Writer and Reader: the description of an image is written as
svg:descand read back, so that LibreOffice exports it as the alternative text of the figure. Issue #5009 PR #5010 - Ods Writer and Csv Writer (with
preferHyperlinkToLabel) no longer add an empty hyperlink to every cell they write, which made a later Xlsx save throw "Invalid parameters passed." Issue #5007 PR #5008 PR #5021 - Ods Writer keeps the hyperlink of a number, boolean or formula cell, and Ods Reader reads it back; only text cells had one. Issue #5013 PR #5014
- Don't iterate cell ranges on non-existent sheets. Issue #5032 PR #5035
- Xls Writer normalizes color strings to upper case and picks the next custom palette index from the highest index in use, so a color can no longer overwrite the palette slot of an earlier color (e.g. a font rendering in a fill color). Issue #5019 PR #5020
- Ods Reader reads the hyperlink LibreOffice keeps in the style of a number, boolean, date or formula cell (
style:hyperlinkinstyle:table-cell-properties), as it writes a link from a Xlsx file. Issue #5017 PR #5018 removeColumn()no longer throws "Invalid column index 0" when it removes column A and every column up to the highest data column, e.g.removeColumn('A')on an empty sheet. Issue #5049 PR #5050removeColumn()andremoveRow()take the removed columns/rows out of data validation ranges: a validation that lies only on them is deleted, and a range that ends on them shrinks, instead of covering the column/row that slides into their place. Issue #5047 PR #5048- Minor cleanup in Ods Reader to fix test which was not working in Windows. PR #5052
- A fraction number format writes an integer as a fraction when the format has no integer part, so 1 is
1/1with0/0, and when the last numerator placeholder is 0, so 1 is1 0/1with0 0/0, as Excel does. Issue #3625 PR #5060 - Removing or inserting a column that shifts the header row of a table no longer throws
Worksheet no longer exists. Issue #5058 PR #5059 - Branch pruning no longer throws "internal error" for an IF nested in the condition of another IF inside a pruned branch. Issue #3755 Issue #3790 PR #5055
- Xls Writer no longer loses EMF and WMF images (they are written as PNG); the resulting file could not be read back (
Call to a member function getBlipType() on null). Issue #274 - Xls Reader reads EMF and WMF pictures (as PNG
MemoryDrawing); they were ignored. Issue #274 - Xlsx Writer declares WMF and EMF images as
image/x-wmfandimage/x-emfinstead ofapplication/octet-stream, and Ods Writer does the same in its manifest when it stores them as is. - Html and Pdf Writers display WMF and EMF images (as PNG) instead of an empty image.
- Ods Writer no longer writes the formula text as the cell value when formulas are not pre-calculated. Issue #5045 PR #5046
- Xlsx Writer and Reader keep the custom formula of a table totals row (
Column::setTotalsRowFormula()), written astotalsRowFormulawithtotalsRowFunction="custom"; before it was dropped. The totals row label, function (asSUBTOTAL) or formula of a column also sets its totals row cell when that cell is empty, so it no longer has to be set by hand. Issue #5063 PR #5064 - Avoid some breaks caused by new versions of libxml. PR #5054
getDataValidation()anddataValidationExists()no longer throw "Cell coordinate string can not be a range of cells" for a range once a validation on a range exists; a range gets the validation set on exactly that range, or a new one. Issue #5073 PR #5074- Text formats containing
@treat a backslash as an escape character, as Excel does, so@\XdisplaysTestasTestXinstead ofTest\X; backslashes in the text itself are kept. Issue #5069 PR #5071