mirror of
https://github.com/PHPOffice/PhpSpreadsheet.git
synced 2026-08-30 12:07:56 +00:00
cf709f3d3f
Fix #4809. This initial work for this PR was done by @xxltomcat-ux in PR #4812. That PR needed some work, and was accidentally closed in a manner that caused all its work to be lost. As compared with that version, this version corrects a write bug when Ods output is added to 27_Images_Xlsx, adds limited support for Read, and adds some tests (more are probably needed). What follows here is the original description from the closed PR. # Summary Currently, the ODS writer in PhpSpreadsheet does not support exporting images. Images (Drawing or MemoryDrawing objects) are completely ignored in ODS exports, though they work correctly for XLSX. This issue proposes and provides a full implementation to add support for image/drawing export in ODS, bringing feature parity with the XLSX writer. # Problem - ODS exports silently drop images and worksheet graphics - This is a required feature for interoperability with LibreOffice/OpenOffice users # Key Implementation: - Update: Writer/Ods.php to collect/package images into the export ZIP - Update: Writer/Ods/Content.php to integrate images into content.xml and table cells - New: Writer/Ods/Drawing.php to manage extraction & XML for worksheet images (Drawing & MemoryDrawing) - Update: Writer/Ods/MetaInf.php to list all Pictures/ images in the manifest - Update: Reader/Ods.php to read drawing-related Xml and add those which meet certain criteria to spreadsheet. # Features - Exports all worksheet images (Drawing, MemoryDrawing) - Embeds images in Pictures/ directory inside ODS - Writes <draw:frame> and <draw:image> elements linked to cell positions - Updates META-INF/manifest.xml with all images - Handles cell/row mapping & coordinates - Supports PNG, JPEG, GIF, BMP
88 KiB
88 KiB
Features cross reference
- ✔ Supported
- ● Partially supported
- ✖ Not supported
- N/A Cannot be supported
Readers
| Readers | |||||||||
|---|---|---|---|---|---|---|---|---|---|
| XLS | XLSX | Excel2003XML | Ods | Gnumeric | CSV | SYLK | HTML | ||
| Reader Options | ✔ | ✔ | ● | ● | ✔ | N/A | N/A | ✔ | |
| Read Charts | ✖ | ✔ | ✖ | ✖ | ✖ | N/A | N/A | ✖ | |
| Read Data Only (no formatting) | ✔ | ✔ | ✖ | ✔ | ✔ | N/A | N/A | ✔ | |
| Read Only Specified Worksheets | ✔ | ✔ | ✔ | ✔ | ✔ | N/A | N/A | ✔ | |
| Read Only Specified Cells | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✖ | ✔ | |
| Read External Images | ✖ | ✔ 9 | ✖ | ✖ | ✖ | N/A | N/A | ✔ 9 | |
| Document Properties | ● | ✔ | ✔ | ✔ | ✔ | N/A | N/A | ✔ | |
| Standard Properties | ✔ | ✔ | ✔ | ✔ | ✔ | N/A | N/A | ✔ | |
| Creator | ✔ | ✔ | ✔ | ✔ | ✔ | N/A | N/A | ✔ | |
| Creation Date/Time | ✔ | ✔ | ✔ | ✔ | ✔ | N/A | N/A | ✔ | |
| Modifier | ✔ | ✔ | ✔ | N/A | N/A | N/A | N/A | ✔ | |
| Modified Date/Time | ✔ | ✔ | ✔ | ✔ | N/A | N/A | N/A | ✔ | |
| Title | ✔ | ✔ | ✔ | ✔ | ✔ | N/A | N/A | ✔ | |
| Description | ✔ | ✔ | ✔ | ✔ | ✔ | N/A | N/A | ✔ | |
| Subject | ✔ | ✔ | ✔ | ✔ | ✔ | N/A | N/A | ✔ | |
| Keywords | ✔ | ✔ | ✔ | ✔ | ✔ | N/A | N/A | ✔ | |
| Extended Properties | ✔ | ✔ | ✔ | N/A | ✔ | N/A | N/A | ✔ | |
| Category | ✔ | ✔ | ✔ | N/A | ✔ | N/A | N/A | ✔ | |
| Company | ✔ | ✔ | ✔ | N/A | ✔ | N/A | N/A | ✔ | |
| Manager | ✔ | ✔ | ✔ | N/A | ✔ | N/A | N/A | ✔ | |
| User-Defined (Custom) Properties | ✖ | ✔ | ✔ | ✔ | N/A | N/A | N/A | ✔ | |
| Text Properties | ✖ | ✔ | ✔ | ✔ | N/A | N/A | N/A | ✔ | |
| Number Properties | ✖ | ✔ | ✔ | ✔ | N/A | N/A | N/A | ✔ | |
| Date Properties | ✖ | ✔ | ✔ | ✔ | N/A | N/A | N/A | ✔ | |
| Yes/No (Boolean) Properties | ✖ | ✔ | ✔ | ✔ | N/A | N/A | N/A | ✔ | |
| Cell Data Types | |||||||||
| Empty/NULL | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | |
| Boolean | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | |
| Integer | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | |
| Floating Point | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | |
| String | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | |
| Error | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | |
| Formula | ✔ | ✔ | ✔ | ✔ | ✔ | ✖ | ✔ | ✖ | |
| Array Formula | ✖ | ✔ | ✔ | ✔ | ✔ | N/A | ✖ | N/A | |
| Rich Text | ✔ | ✔ | ✔ | ✔ | ✔ | ✖ | ✖ | ✖ | |
| Image Above Cell | ✔ | ✔ | ✖ | ✔ | ✖ | N/A | N/A | ✔ | |
| Image In Cell | ✖ | ✔ | ✖ | ✖ | ✖ | N/A | N/A | ✖ | |
| Conditional Formatting | ✔ | ✔ | ✖ | ✖ | ✖ | N/A | N/A | ✖ | |
| Rows and Column Properties | ✔ | ✔ | ✔ | ✖ | ✔ | N/A | N/A | ✔ | |
| Row Height/Column Width | ✔ | ✔ | ✔ | ✔ | ✔ | N/A | N/A | ✔ | |
| Hidden | ✔ | ✔ | ✔ | ✖ | ✔ | N/A | N/A | ✔ | |
| Worksheet Properties | ● | ✔ | ● | ● | ✖ | N/A | N/A | ● | |
| Frozen Panes | ✔ | ✔ | ✔ | ✖ | ✖ | N/A | N/A | N/A | |
| Hidden Worksheets | ✔ | ✔ | ✖ | ✔ | ✖ | N/A | N/A | ● | |
| Coloured Tabs | ✖ | ✔ | ✖ | ✖ | ✖ | N/A | N/A | N/A | |
| Drawing hyperlink | ✖ | ✔ | ✖ | ✖ | ✖ | N/A | N/A | ✔ | |
| Cell Formatting | ✔ | ✔ | ● | ✖ | ✔ | N/A | ● | ● 7 | |
| Number Format Mask | ✔ | ✔ | ✔ | ● 6 | ✔ | N/A | ✔ | ✔ | |
| Alignment | ✔ | ✔ | ✔ | ✔ | ✔ | N/A | ✖ | ● 7 | |
| Horizontal | ✔ | ✔ | ✔ | ✔ | ✔ | N/A | ✖ | ✔ | |
| Vertical | ✔ | ✔ | ✔ | ✔ | ✔ | N/A | ✖ | ✔ | |
| Wrapping | ✔ | ✔ | ✔ | ✔ | ✔ | N/A | ✖ | ● | |
| Shrink-to-Fit | ✔ | ✔ | ✔ | ✔ | ✔ | N/A | ✖ | ● | |
| Indent | ✔ | ✔ | ✖ | ✔ | ✔ | N/A | ✖ | ✔ | |
| Background Colour | ✔ | ✔ | ✔ | ✔ | ✔ | N/A | ✔ | ● 7 | |
| Patterned | ✔ | ✔ | ✔ | N/A | ✔ | N/A | ✔ | ✖ | |
| Font Attributes | ✔ | ✔ | ✔ | ● | ✔ | N/A | ✔ | ● 7 | |
| Font Face | ✔ | ✔ | ✔ | ✔ | ✔ | N/A | ✔ | ✔ | |
| Font Size | ✔ | ✔ | ✔ | ✔ | ✔ | N/A | ✔ | ✔ | |
| Bold | ✔ | ✔ | ✔ | ✔ | ✔ | N/A | ✔ | ✔ | |
| Italic | ✔ | ✔ | ✔ | ✔ | ✔ | N/A | ✔ | ✔ | |
| Strikethrough | ✔ | ✔ | ✔ | ✔ | ✔ | N/A | ✔ | ✔ | |
| Underline | ✔ | ✔ | ✔ | ✔ | ✔ | N/A | ✔ | ✔ | |
| Superscript | ✔ | ✔ | ✔ | ✖ | ✔ | N/A | ✔ | ✔ | |
| Subscript | ✔ | ✔ | ✔ | ✖ | ✔ | N/A | ✔ | ✔ | |
| Borders | ✔ | ✔ | ✔ | ✔ | ✔ | N/A | ● | ● 7 | |
| Line Style | ✔ | ✔ | ✔ | ✔ | ✔ | N/A | ✔ | ✔ | |
| Position | ✔ | ✔ | ✔ | ✔ | ✔ | N/A | ✔ | ✔ | |
| Diagonal | ✔ | ✔ | ✔ | ✔ | ✔ | N/A | ✖ | ✖ | |
| Hyperlinks | ✔ | ✔ | ✔ | ✔ | ✔ | ✖ | ✖ | ✔ | |
| http | ✔ | ✔ | ✔ | ✔ | ✔ | N/A | ✖ | ✔ | |
| Merged Cells | ✔ | ✔ | ✔ | ✔ | ✔ | N/A | ✖ | ✔ | |
| Cell Comments | ● | ● | ● | ● | ● | N/A | ● | ● | |
| Rich Text | ✖ 2 | ✔ | ✖ | ✖ | ● | N/A | N/A | ✖ | |
| Alignment | ✖ 3 | ✔ | ✖ | ✖ | ✖ | N/A | ✖ | ✔ | |
| Background Image | ✖ | ✔ | ✖ | ✖ | ✖ | N/A | ✖ | ✖ | |
| Cell Validation | ✔ | ✔ | ✖ | ✖ | ✖ | N/A | N/A | N/A | |
| AutoFilters | ● | ● | ● | ● | ● | N/A | N/A | N/A | |
| AutoFilter Expressions | ✔ | ✔ | ✔ | ✔ | ✔ | N/A | N/A | N/A | |
| Filter | ✔ | ✔ | ✔ | ✔ | ✔ | N/A | N/A | N/A | |
| Custom Filter | ✔ | ✔ | ✔ | ✔ | ✔ | N/A | N/A | N/A | |
| Date Filter | ✔ | ✔ | ✔ | ✔ | ✔ | N/A | N/A | N/A | |
| Dynamic Filter | ✔ | ✔ | ✔ | ✔ | ✔ | N/A | N/A | N/A | |
| Colour Filter | ✖ | ✖ | ✖ | ✖ | ✖ | N/A | N/A | N/A | |
| Icon Filter | ✖ | ✖ | ✖ | ✖ | ✖ | N/A | N/A | N/A | |
| Top 10 Filter | ✖ | ✔ | ✖ | ✖ | ✖ | N/A | N/A | N/A | |
| Macros | ✖ | ● 5 | ✖ | ✖ | ✖ | ✖ | ✖ | ✖ | |
| Form Controls | ✖ | ● 4 | ✖ | ✖ | ✖ | ✖ | ✖ | ✖ | |
| Security | ● | ● | ✖ | ✖ | ✖ | ✖ | ✖ | ✖ | |
| Protection (prevent editing) | ✔ | ✔ | ✖ | ✖ | ✖ | ✖ | ✖ | ✖ | |
| Encryption (prevent viewing) | ✖ | ✖ | ✖ | ✖ | ✖ | ✖ | ✖ | ✖ | |
| XLS | XLSX | Excel2003XML | Ods | Gnumeric | CSV | SYLK | HTML | ||
| Readers | |||||||||
- Only text contents
- Only BIFF8 files support Rich Text. Prior to that, comments could only be plain text
- Only BIFF8 files support alignment and rotation. Prior to that, comments could only be unformatted text
- Xlsx forms and controls can be read and written but not otherwise manipulated
- Xlsx macros can be read and written; their values can be retrieved and changed, but only in a binary form which is unlikely to be useful
- There is very limited support for reading styles from an Ods spreadsheet before release 5.5.0. Writing styles has much better support. Starting with release 5.5.0, Number Format Writer supports many common styles, and users may extend support to additional styles; Reader support for Number Formats is improved but still imperfect; for other styles, it is much improved.
- In most cases, Html reader processes only inline styles; styles provided by Css classes may be ignored.
- Code must opt in to array output.
- Use with caution - allowing external images may can subject the caller to security exploits. Starting with release 4.5.0 (also earlier releases 3.9.3, 2.3.10, 2.1.11, and 1.29.12), code can allow or not external images. In those starting releases, and in earlier releases which do not offer an option, default is to allow it. In release 5+ (and earlier supported versions 1.30+, 2.1.12+, 2.4+, and 3.10+), the default is to not allow it.
Writers
| Writers | |||||||
|---|---|---|---|---|---|---|---|
| XLS | XLSX | Ods | CSV | HTML | |||
| Document Properties | |||||||
| Standard Properties | |||||||
| Creator | ✔ | ✔ | ✔ | N/A | ✔ | ✔ | |
| Creation Date/Time | ✔ | ✔ | ✔ | N/A | ✔ | ✖ | |
| Modifier | ✔ | ✔ | ✖ | N/A | ✔ | ✖ | |
| Modified Date/Time | ✔ | ✔ | ✖ | N/A | ✔ | ✖ | |
| Title | ✔ | ✔ | ✔ | N/A | ✔ | ✔ | |
| Description | ✔ | ✔ | ✔ | N/A | ✔ | ✖ | |
| Subject | ✔ | ✔ | ✔ | N/A | ✔ | ✔ | |
| Keywords | ✔ | ✔ | ✔ | N/A | ✔ | ✔ | |
| Extended Properties | |||||||
| Category | ✔ | ✔ | ✖ | N/A | ✔ | ✖ | |
| Company | ✖ | ✔ | ✖ | N/A | ✔ | ✖ | |
| Manager | ✖ | ✔ | ✖ | N/A | ✔ | ✖ | |
| User-Defined (Custom) Properties | ✖ | ✔ | ✔ | N/A | ✔ | N/A | |
| Rich Text | ✔ | ✔ | ✖ | N/A | ✔ | ✔ | |
| Image Above Cell | ✔ | ✔ | ✔ | N/A | ✔ | ✔ | |
| Image In Cell | ✖ | ✔ | ✖ | N/A | ✖ | ✖ | |
| Conditional Formatting | ✔ | ✔ | ✖ | ✖ | ✔ | ✔ | |
| Array Formula8 | ✖ | ✔ | ✔ | ✔ | ✔ | ✔ | |
| Rows and Column Properties | |||||||
| Row Height/Column Width | ✔ | ✔ | ✔ | N/A | ✔ | ✔ | |
| Hidden | ✔ | ✔ | ✖ | N/A | ✔ | ✔ | |
| Worksheet Properties | |||||||
| Frozen Panes | ● | ✔ | ✖ | N/A | ✔ | ✖ | |
| Hidden Worksheets | ● | ✔ | ✖ | N/A | ✔ | ✖ | |
| Coloured Tabs | ✖ | ✔ | ✖ | N/A | ✖ | ✖ | |
| Drawing hyperlink | ✖ | ✔ | ✖ | N/A | ✖ | ✖ | |
| Cell Formatting | |||||||
| Number Format Mask | ✔ | ✔ | ✔6 | N/A | ✔ | ✔ | |
| Alignment | ✔ | ✔ | ✔ | N/A | ✔ | ✔ | |
| Horizontal | ✔ | ✔ | ✔ | N/A | ✔ | ✔ | |
| Vertical | ✔ | ✔ | ✔ | N/A | ✔ | ✔ | |
| Wrapping | ✔ | ✔ | ✔ | N/A | ✔ | ✔ | |
| Shrink-to-Fit | ✔ | ✔ | ✔ | N/A | ✔ | ✔ | |
| Indent | ✔ | ✔ | ✔ | N/A | ✔ | ✔ | |
| Background Colour | ✔ | ✔ | ✔ | N/A | ✔ | ✔ | |
| Patterned | ✔ | ✔ | N/A | N/A | ✖ | ✖ | |
| Font Attributes | |||||||
| Font Face | ✔ | ✔ | ✔ | N/A | ✔ | ✔ | |
| Font Size | ✔ | ✔ | ✔ | N/A | ✔ | ✔ | |
| Bold | ✔ | ✔ | ✔ | N/A | ✔ | ✔ | |
| Italic | ✔ | ✔ | ✔ | N/A | ✔ | ✔ | |
| Strikethrough | ✔ | ✔ | ✔ | N/A | ✔ | ✔ | |
| Underline | ✔ | ✔ | ✔ | N/A | ✔ | ✔ | |
| Superscript | ✔ | ✔ | ✔ | N/A | ✔ | ✔ | |
| Subscript | ✔ | ✔ | ✔ | N/A | ✔ | ✔ | |
| Borders | |||||||
| Line Style | ✔ | ✔ | ✔ | N/A | ✔ | ✔ | |
| Position | ✔ | ✔ | ✔ | N/A | ✔ | ✔ | |
| Diagonal | ✔ | ✔ | ✔ | N/A | ✖ | ✖ | |
| Hyperlinks | ✔ | ✔ | ✖ | N/A | ✔ | ✖ | |
| http | ✔ | ✔ | ✖ | N/A | ✔ | ✖ | |
| Merged Cells | ✔ | ✔ | ✔ | N/A | ✔ | ✔ | |
| Cell Comments | ✖ | ● | ● | N/A | ● 1 | N/A | |
| Rich Text | ✖ | ✔ | ✖ | N/A | ✖ | N/A | |
| Alignment | ✖ | ✔ | ✖ | N/A | ✔ | N/A | |
| Background Image | ✖ | ✔ | ✖ | ✖ | ✖ | ✖ | |
| Cell Validation | ✔ | ✔ | ✖ | N/A | N/A | N/A | |
| AutoFilters | |||||||
| AutoFilter Expressions | ✔ | ✔ | ✔ | N/A | N/A | N/A | |
| Filter | ✔ | ✔ | ✔ | N/A | N/A | N/A | |
| Custom Filter | ✔ | ✔ | ✔ | N/A | N/A | N/A | |
| DateGroup Filter | ✔ | ✔ | ✔ | N/A | N/A | N/A | |
| Dynamic Filter | ✔ | ✔ | ✔ | N/A | N/A | N/A | |
| Colour Filter | ✖ | ✖ | ✖ | N/A | N/A | N/A | |
| Icon Filter | ✖ | ✖ | ✖ | N/A | N/A | N/A | |
| Top 10 Filter | ✖ | ✔ | ✖ | N/A | N/A | N/A | |
| Macros | ✖ | ● 5 | ✖ | N/A | ✖ | ✖ | |
| Form Controls | ✖ | ● 4 | ✖ | N/A | ✖ | ✖ | |
| Security | |||||||
| Protection (prevent editing) | ✔ | ✔ | ✖ | N/A | ✖ | ✖ | |
| Encryption (prevent viewing) | ✖ | ✖ | ✖ | N/A | ✖ | ✖ | |
| XLS | XLSX | Ods | CSV | HTML | |||
| Writers | |||||||
Setters and Getters
| Methods | ||
|---|---|---|
| Getters | Setters | |
| Reader Options | ||
| Read Data Only (no formatting) | $reader->getReadDataOnly() | $reader->setReadDataOnly() |
| Read Only Specified Worksheets | $reader->getLoadSheetsOnly() | $reader->setLoadSheetsOnly() $reader->setLoadAllSheets() |
| Read Only Specified Cells | $reader->getReadFilter() | $reader->setReadFilter() |
| Document Properties | ||
| Standard Properties | ||
| Creator | $spreadsheet->getProperties()->getCreator() | $spreadsheet->getProperties()->setCreator() |
| Creation Date/Time | $spreadsheet->getProperties()->getCreated() | $spreadsheet->getProperties()->setCreated() |
| Modifier | $spreadsheet->getProperties()->getLastModifiedBy() | $spreadsheet->getProperties()->setLastModifiedBy() |
| Modified Date/Time | $spreadsheet->getProperties()->getModified() | $spreadsheet->getProperties()->setModified() |
| Title | $spreadsheet->getProperties()->getTitle() | $spreadsheet->getProperties()->setTitle() |
| Description | $spreadsheet->getProperties()->getDescription() | $spreadsheet->getProperties()->setDescription() |
| Subject | $spreadsheet->getProperties()->getSubject() | $spreadsheet->getProperties()->setSubject() |
| Keywords | $spreadsheet->getProperties()->getKeywords() | $spreadsheet->getProperties()->setKeywords() |
| Extended Properties | ||
| Category | $spreadsheet->getProperties()->getCategory() | $spreadsheet->getProperties()->setCategory() |
| Company | $spreadsheet->getProperties()->getCompany() | $spreadsheet->getProperties()->setCompany() |
| Manager | $spreadsheet->getProperties()->getManager() | $spreadsheet->getProperties()->setManager() |
| User-Defined (Custom) Properties | $spreadsheet->getProperties()->getCustomProperties() $spreadsheet->getProperties()->isCustomPropertySet() $spreadsheet->getProperties()->getCustomPropertyValue() $spreadsheet->getProperties()->getCustomPropertyType() |
$spreadsheet->getProperties()->setCustomProperty() |
| Drawing hyperlink | $drawing->getHyperlink()->getUrl() | $drawing->setHyperlink()->setUrl($url) |
| Hyperlinks | $cell->getHyperlink()->getUrl($url) | $cell->getHyperlink()->setUrl($url) |
| Cell Comments | ||
| Background Image | $comment->getBackgroundImage() | $comment->setBackgroundImage() |
| Cell Validation | $cell->getDataValidation() | $cell->setDataValidation() |
| AutoFilters | $sheet->getAutoFilter() | $sheet->setAutoFilter() |
| Macros | $spreadsheet->getMacrosCode();5 | $spreadsheet->setMacrosCode();5 |
| Security | ||
| Protection (prevent editing) | $sheet->getProtection() | $sheet->getProtection()->setSheet(true) |
| Getters | Setters | |
| Methods | ||