From 9920935fdb11523f06474d6fcb31dd12a67db9bf Mon Sep 17 00:00:00 2001 From: Thomas Lallement Date: Fri, 26 Sep 2025 19:14:03 +0200 Subject: [PATCH 1/8] Support Read Image in Cell --- src/PhpSpreadsheet/Reader/Xlsx.php | 35 ++++++++++++++++ .../Reader/Xlsx/DrawingInCell.php | 38 ++++++++++++++++++ tests/data/Reader/XLSX/drawing_in_cell.xlsx | Bin 0 -> 24096 bytes 3 files changed, 73 insertions(+) create mode 100644 tests/PhpSpreadsheetTests/Reader/Xlsx/DrawingInCell.php create mode 100644 tests/data/Reader/XLSX/drawing_in_cell.xlsx diff --git a/src/PhpSpreadsheet/Reader/Xlsx.php b/src/PhpSpreadsheet/Reader/Xlsx.php index f8a0b11324..9b3bac4374 100644 --- a/src/PhpSpreadsheet/Reader/Xlsx.php +++ b/src/PhpSpreadsheet/Reader/Xlsx.php @@ -784,6 +784,19 @@ protected function loadSpreadsheetFromFile(string $filename): Spreadsheet $charts = $chartDetails = []; + // Add richData (contains relation of in-cell images) + $richData = []; + $relationsFileName = $dir . '/richData/_rels/richValueRel.xml.rels'; + if ($zip->locateName($relationsFileName)) { + $relsWorksheet = $this->loadZip($relationsFileName, Namespaces::RELATIONSHIPS); + foreach ($relsWorksheet->Relationship as $elex) { + $ele = self::getAttributes($elex); + if ($ele['Type'] == Namespaces::IMAGE) { + $richData['image'][(string) $ele['Id']] = (string) $ele['Target']; + } + } + } + $sheetCreated = false; if ($xmlWorkbookNS->sheets) { foreach ($xmlWorkbookNS->sheets->sheet as $eleSheet) { @@ -940,6 +953,28 @@ protected function loadSpreadsheetFromFile(string $filename): Spreadsheet break; case DataType::TYPE_ERROR: + if (isset($cAttr->vm, $richData['image']['rId' . $cAttr->vm]) && !$useFormula) { + $imagePath = $dir . '/' . str_replace('../', '', $richData['image']['rId' . $cAttr->vm]); + $objDrawing = new \PhpOffice\PhpSpreadsheet\Worksheet\Drawing(); + $objDrawing->setPath( + 'zip://' . File::realpath($filename) . '#' . $imagePath, + false, + $zip + ); + + $objDrawing->setCoordinates($r); + $objDrawing->setOffsetX(0); + $objDrawing->setOffsetY(0); + $objDrawing->setResizeProportional(false); + $objDrawing->setWorksheet($docSheet); + + $value = $objDrawing; + $cellDataType = DataType::TYPE_NULL; + $c->t = DataType::TYPE_NULL; + + break; + } + if (!$useFormula) { $value = self::castToError($c); } else { diff --git a/tests/PhpSpreadsheetTests/Reader/Xlsx/DrawingInCell.php b/tests/PhpSpreadsheetTests/Reader/Xlsx/DrawingInCell.php new file mode 100644 index 0000000000..478ab05377 --- /dev/null +++ b/tests/PhpSpreadsheetTests/Reader/Xlsx/DrawingInCell.php @@ -0,0 +1,38 @@ +load($file); + + $reloadedSpreadsheet = $this->writeAndReload($spreadsheet, 'Xlsx'); + $spreadsheet->disconnectWorksheets(); + $sheet = $reloadedSpreadsheet->getActiveSheet(); + $drawings = $sheet->getDrawingCollection(); + self::assertCount(1, $drawings); + if ($drawings[0] === null) { + self::fail('Unexpected null drawing'); + } else { + self::assertSame(IMAGETYPE_PNG, $drawings[0]->getType()); + self::assertSame('B2', $drawings[0]->getCoordinates()); + self::assertSame(0, $drawings[0]->getOffsetX()); + self::assertSame(0, $drawings[0]->getOffsetY()); + self::assertSame(296, $drawings[0]->getWidth()); + self::assertSame(154, $drawings[0]->getHeight()); + self::assertSame(296, $drawings[0]->getImageWidth()); + self::assertSame(154, $drawings[0]->getImageHeight()); + } + + $reloadedSpreadsheet->disconnectWorksheets(); + } +} diff --git a/tests/data/Reader/XLSX/drawing_in_cell.xlsx b/tests/data/Reader/XLSX/drawing_in_cell.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..7ba1881fa12d709d63a13d4f1f3afb77512c8ec9 GIT binary patch literal 24096 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 Date: Sat, 27 Sep 2025 19:53:45 +0200 Subject: [PATCH 2/8] Fix the Unit Test --- .../{DrawingInCell.php => DrawingInCellTest.php} | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) rename tests/PhpSpreadsheetTests/Reader/Xlsx/{DrawingInCell.php => DrawingInCellTest.php} (78%) diff --git a/tests/PhpSpreadsheetTests/Reader/Xlsx/DrawingInCell.php b/tests/PhpSpreadsheetTests/Reader/Xlsx/DrawingInCellTest.php similarity index 78% rename from tests/PhpSpreadsheetTests/Reader/Xlsx/DrawingInCell.php rename to tests/PhpSpreadsheetTests/Reader/Xlsx/DrawingInCellTest.php index 478ab05377..79beb08325 100644 --- a/tests/PhpSpreadsheetTests/Reader/Xlsx/DrawingInCell.php +++ b/tests/PhpSpreadsheetTests/Reader/Xlsx/DrawingInCellTest.php @@ -5,21 +5,19 @@ namespace PhpOffice\PhpSpreadsheetTests\Reader\Xlsx; use PhpOffice\PhpSpreadsheet\Reader\Xlsx; -use PhpOffice\PhpSpreadsheetTests\Functional\AbstractFunctional; +use PHPUnit\Framework\TestCase; -class DrawingInCell extends AbstractFunctional +class DrawingInCellTest extends TestCase { public function testPictureInCell(): void { $file = 'tests/data/Reader/XLSX/drawing_in_cell.xlsx'; $reader = new Xlsx(); $spreadsheet = $reader->load($file); - - $reloadedSpreadsheet = $this->writeAndReload($spreadsheet, 'Xlsx'); - $spreadsheet->disconnectWorksheets(); - $sheet = $reloadedSpreadsheet->getActiveSheet(); + $sheet = $spreadsheet->getActiveSheet(); $drawings = $sheet->getDrawingCollection(); self::assertCount(1, $drawings); + if ($drawings[0] === null) { self::fail('Unexpected null drawing'); } else { @@ -33,6 +31,6 @@ public function testPictureInCell(): void self::assertSame(154, $drawings[0]->getImageHeight()); } - $reloadedSpreadsheet->disconnectWorksheets(); + $spreadsheet->disconnectWorksheets(); } } From 4ccf9c044dafefbe19e9eedb29ebc22c6e2ff77b Mon Sep 17 00:00:00 2001 From: Thomas Lallement Date: Wed, 1 Oct 2025 00:54:49 +0200 Subject: [PATCH 3/8] WIP - Write in-cell drawing --- src/PhpSpreadsheet/Cell/Cell.php | 7 + src/PhpSpreadsheet/Cell/DataType.php | 1 + src/PhpSpreadsheet/Reader/Xlsx.php | 5 +- src/PhpSpreadsheet/Worksheet/BaseDrawing.php | 14 ++ src/PhpSpreadsheet/Writer/Xlsx.php | 9 + src/PhpSpreadsheet/Writer/Xlsx/Drawing.php | 7 +- .../Writer/Xlsx/RichDataDrawing.php | 192 ++++++++++++++++++ src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php | 11 + .../Reader/Xlsx/DrawingInCellTest.php | 4 + 9 files changed, 245 insertions(+), 5 deletions(-) create mode 100644 src/PhpSpreadsheet/Writer/Xlsx/RichDataDrawing.php diff --git a/src/PhpSpreadsheet/Cell/Cell.php b/src/PhpSpreadsheet/Cell/Cell.php index e9fbabb415..4699671e43 100644 --- a/src/PhpSpreadsheet/Cell/Cell.php +++ b/src/PhpSpreadsheet/Cell/Cell.php @@ -15,6 +15,7 @@ use PhpOffice\PhpSpreadsheet\Style\NumberFormat; use PhpOffice\PhpSpreadsheet\Style\Protection; use PhpOffice\PhpSpreadsheet\Style\Style; +use PhpOffice\PhpSpreadsheet\Worksheet\BaseDrawing; use PhpOffice\PhpSpreadsheet\Worksheet\Table; use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; use Stringable; @@ -307,6 +308,12 @@ public function setValueExplicit(mixed $value, string $dataType = DataType::TYPE $this->value = SharedDate::convertIsoDate($value); $dataType = DataType::TYPE_NUMERIC; + break; + case DataType::TYPE_DRAWING_IN_CELL: + if ($value instanceof BaseDrawing) { + $this->value = $value; + } + break; case DataType::TYPE_ERROR: $this->value = DataType::checkErrorCode($value); diff --git a/src/PhpSpreadsheet/Cell/DataType.php b/src/PhpSpreadsheet/Cell/DataType.php index 774a57b23f..71cde4aca2 100644 --- a/src/PhpSpreadsheet/Cell/DataType.php +++ b/src/PhpSpreadsheet/Cell/DataType.php @@ -17,6 +17,7 @@ class DataType const TYPE_INLINE = 'inlineStr'; const TYPE_ERROR = 'e'; const TYPE_ISO_DATE = 'd'; + const TYPE_DRAWING_IN_CELL = 'drawingCell'; /** * List of error codes. diff --git a/src/PhpSpreadsheet/Reader/Xlsx.php b/src/PhpSpreadsheet/Reader/Xlsx.php index 9b3bac4374..24dd7ec986 100644 --- a/src/PhpSpreadsheet/Reader/Xlsx.php +++ b/src/PhpSpreadsheet/Reader/Xlsx.php @@ -967,10 +967,11 @@ protected function loadSpreadsheetFromFile(string $filename): Spreadsheet $objDrawing->setOffsetY(0); $objDrawing->setResizeProportional(false); $objDrawing->setWorksheet($docSheet); + $objDrawing->setInCell(true); $value = $objDrawing; - $cellDataType = DataType::TYPE_NULL; - $c->t = DataType::TYPE_NULL; + $cellDataType = DataType::TYPE_DRAWING_IN_CELL; + $c->t = DataType::TYPE_ERROR; break; } diff --git a/src/PhpSpreadsheet/Worksheet/BaseDrawing.php b/src/PhpSpreadsheet/Worksheet/BaseDrawing.php index faa836c545..2c87fa2be5 100644 --- a/src/PhpSpreadsheet/Worksheet/BaseDrawing.php +++ b/src/PhpSpreadsheet/Worksheet/BaseDrawing.php @@ -137,6 +137,8 @@ class BaseDrawing implements IComparable */ protected ?int $opacity = null; + protected bool $inCell = false; + /** * Create a new BaseDrawing. */ @@ -572,4 +574,16 @@ public function getOpacity(): ?int { return $this->opacity; } + + public function setInCell(bool $inCell): self + { + $this->inCell = $inCell; + + return $this; + } + + public function isInCell(): ?bool + { + return $this->inCell; + } } diff --git a/src/PhpSpreadsheet/Writer/Xlsx.php b/src/PhpSpreadsheet/Writer/Xlsx.php index a38c930e42..45cb147be0 100644 --- a/src/PhpSpreadsheet/Writer/Xlsx.php +++ b/src/PhpSpreadsheet/Writer/Xlsx.php @@ -24,6 +24,7 @@ use PhpOffice\PhpSpreadsheet\Writer\Xlsx\Rels; use PhpOffice\PhpSpreadsheet\Writer\Xlsx\RelsRibbon; use PhpOffice\PhpSpreadsheet\Writer\Xlsx\RelsVBA; +use PhpOffice\PhpSpreadsheet\Writer\Xlsx\RichDataDrawing; use PhpOffice\PhpSpreadsheet\Writer\Xlsx\StringTable; use PhpOffice\PhpSpreadsheet\Writer\Xlsx\Style; use PhpOffice\PhpSpreadsheet\Writer\Xlsx\Table; @@ -463,6 +464,14 @@ public function save($filename, int $flags = 0): void $zipContent['xl/drawings/drawing' . ($i + 1) . '.xml'] = ''; } + $richDataDrawing = new RichDataDrawing(); + $richDataFiles = $richDataDrawing->generateFiles($this->spreadSheet->getSheet($i)); + + // Add all Rich Data files to ZIP + foreach ($richDataFiles as $path => $content) { + $zipContent[$path] = $content; + } + // Add comment relationship parts /** @var mixed[][] */ $legacyTemp = $unparsedLoadedData['sheets'] ?? []; diff --git a/src/PhpSpreadsheet/Writer/Xlsx/Drawing.php b/src/PhpSpreadsheet/Writer/Xlsx/Drawing.php index 887b436ea9..05601171e1 100644 --- a/src/PhpSpreadsheet/Writer/Xlsx/Drawing.php +++ b/src/PhpSpreadsheet/Writer/Xlsx/Drawing.php @@ -48,10 +48,11 @@ public function writeDrawings(\PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $wor $pRelationId = $i; $hlinkClickId = $pDrawing->getHyperlink() === null ? null : ++$i; - $this->writeDrawing($objWriter, $pDrawing, $pRelationId, $hlinkClickId); - + if (!$pDrawing->isInCell()) { + $this->writeDrawing($objWriter, $pDrawing, $pRelationId, $hlinkClickId); + ++$i; + } $iterator->next(); - ++$i; } if ($includeCharts) { diff --git a/src/PhpSpreadsheet/Writer/Xlsx/RichDataDrawing.php b/src/PhpSpreadsheet/Writer/Xlsx/RichDataDrawing.php new file mode 100644 index 0000000000..cec24f5881 --- /dev/null +++ b/src/PhpSpreadsheet/Writer/Xlsx/RichDataDrawing.php @@ -0,0 +1,192 @@ + [path => XML content] + */ + public function generateFiles(Worksheet $worksheet): array + { + $iterator = $worksheet->getDrawingCollection()->getIterator(); + while ($iterator->valid()) { + /** @var BaseDrawing $pDrawing */ + $pDrawing = $iterator->current(); + if ($pDrawing->isInCell()) { + $this->drawings[] = $pDrawing; + } + $iterator->next(); + } + + if (count($this->drawings) === 0) { + return []; + } + + return [ + 'xl/richData/rdrichvalue.xml' => $this->writeRdrichvalueXML(), + 'xl/richData/rdrichvaluestructure.xml' => $this->writeRdrichvaluestructureXML(), + 'xl/richData/rdRichValueTypes.xml' => $this->writeRdRichValueTypesXML(), + 'xl/richData/richValueRel.xml' => $this->writeRichValueRelXML(), + 'xl/richData/_rels/richValueRel.xml.rels' => $this->writeRichValueRelRelsXML(), + ]; + } + + private function writeRdrichvalueXML(): string + { + $xml = new XMLWriter(XMLWriter::STORAGE_MEMORY); + $xml->startDocument('1.0', 'UTF-8', 'yes'); + $xml->startElement('rvData'); + $xml->writeAttribute('xmlns', 'http://schemas.microsoft.com/office/spreadsheetml/2017/richdata'); + $xml->writeAttribute('count', (string) count($this->drawings)); + + foreach ($this->drawings as $index => $drawing) { + if (!$drawing->isInCell()) { + continue; + } + $xml->startElement('rv'); + $xml->writeAttribute('s', (string) $index); + + // Sample values; adapt to your needs + $xml->writeElement('v', '0'); + $xml->writeElement('v', '5'); + + $xml->endElement(); // rv + } + + $xml->endElement(); // rvData + + return $xml->getData(); + } + + private function writeRdrichvaluestructureXML(): string + { + $xml = new XMLWriter(XMLWriter::STORAGE_MEMORY); + $xml->startDocument('1.0', 'UTF-8', 'yes'); + $xml->startElement('rvStructures'); + $xml->writeAttribute('xmlns', 'http://schemas.microsoft.com/office/spreadsheetml/2017/richdata'); + $xml->writeAttribute('count', (string) count($this->drawings)); + + foreach ($this->drawings as $drawing) { + if (!$drawing->isInCell()) { + continue; + } + + $xml->startElement('s'); + $xml->writeAttribute('t', '_localImage'); + + $xml->startElement('k'); + $xml->writeAttribute('n', '_rvRel:LocalImageIdentifier'); + $xml->writeAttribute('t', 'i'); + $xml->endElement(); + + $xml->startElement('k'); + $xml->writeAttribute('n', 'CalcOrigin'); + $xml->writeAttribute('t', 'i'); + $xml->endElement(); + + $xml->endElement(); // s + } + + $xml->endElement(); // rvStructures + + return $xml->getData(); + } + + private function writeRdRichValueTypesXML(): string + { + $xml = new XMLWriter(XMLWriter::STORAGE_MEMORY); + $xml->startDocument('1.0', 'UTF-8', 'yes'); + $xml->startElement('rvTypesInfo'); + $xml->writeAttribute('xmlns', 'http://schemas.microsoft.com/office/spreadsheetml/2017/richdata2'); + $xml->writeAttribute('xmlns:mc', 'http://schemas.openxmlformats.org/markup-compatibility/2006'); + $xml->writeAttribute('mc:Ignorable', 'x'); + $xml->writeAttribute('xmlns:x', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main'); + + $xml->startElement('global'); + $xml->startElement('keyFlags'); + + $keys = [ + '_Self', '_DisplayString', '_Flags', '_Format', + '_SubLabel', '_Attribution', '_Icon', '_Display', + '_CanonicalPropertyNames', '_ClassificationId', + ]; + + foreach ($keys as $key) { + $xml->startElement('key'); + $xml->writeAttribute('name', $key); + + $xml->startElement('flag'); + $xml->writeAttribute('name', 'ExcludeFromCalcComparison'); + $xml->writeAttribute('value', '1'); + if ($key === '_Self') { + $xml->startElement('flag'); + $xml->writeAttribute('name', 'ExcludeFromFile'); + $xml->writeAttribute('value', '1'); + $xml->endElement(); + } + $xml->endElement(); // flag + $xml->endElement(); // key + } + + $xml->endElement(); // keyFlags + $xml->endElement(); // global + $xml->endElement(); // rvTypesInfo + + return $xml->getData(); + } + + private function writeRichValueRelXML(): string + { + $xml = new XMLWriter(XMLWriter::STORAGE_MEMORY); + $xml->startDocument('1.0', 'UTF-8', 'yes'); + $xml->startElement('richValueRels'); + $xml->writeAttribute('xmlns', 'http://schemas.microsoft.com/office/spreadsheetml/2022/richvaluerel'); + $xml->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'); + + foreach ($this->drawings as $index => $drawing) { + if (!$drawing->isInCell()) { + continue; + } + $xml->startElement('rel'); + $xml->writeAttribute('r:id', 'rId' . ($index + 1)); + $xml->endElement(); + } + + $xml->endElement(); // richValueRels + + return $xml->getData(); + } + + private function writeRichValueRelRelsXML(): string + { + $xml = new XMLWriter(XMLWriter::STORAGE_MEMORY); + $xml->startDocument('1.0', 'UTF-8', 'yes'); + $xml->startElement('Relationships'); + $xml->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships'); + + foreach ($this->drawings as $index => $drawing) { + if (!$drawing->isInCell()) { + continue; + } + $xml->startElement('Relationship'); + $xml->writeAttribute('Id', 'rId' . ($index + 1)); + $xml->writeAttribute('Type', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image'); + $xml->writeAttribute('Target', '../media/' . $drawing->getIndexedFilename()); + $xml->endElement(); + } + + $xml->endElement(); // Relationships + + return $xml->getData(); + } +} diff --git a/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php b/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php index 5e445f6819..2eb38c05d2 100644 --- a/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php +++ b/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php @@ -1557,6 +1557,13 @@ private function writeCellError(XMLWriter $objWriter, string $mappedType, string $objWriter->writeElement('v', $cellIsFormula ? $formulaerr : $cellValue); } + private function writeCellDrawing(XMLWriter $objWriter): void + { + $objWriter->writeAttribute('t', 'e'); + $objWriter->writeAttribute('vm', '1'); + $objWriter->writeElement('v', '#VALUE!'); + } + private function writeCellFormula(XMLWriter $objWriter, string $cellValue, Cell $cell): void { $attributes = $cell->getFormulaAttributes() ?? []; @@ -1737,6 +1744,10 @@ private function writeCell(XMLWriter $objWriter, PhpspreadsheetWorksheet $worksh case 'b': // Boolean $this->writeCellBoolean($objWriter, $mappedType, (bool) $cellValue); + break; + case 'drawingcell': // DrawingInCell + $this->writeCellDrawing($objWriter); + break; case 'e': // Error $this->writeCellError($objWriter, $mappedType, $cellValueString); diff --git a/tests/PhpSpreadsheetTests/Reader/Xlsx/DrawingInCellTest.php b/tests/PhpSpreadsheetTests/Reader/Xlsx/DrawingInCellTest.php index 79beb08325..3a43a959d6 100644 --- a/tests/PhpSpreadsheetTests/Reader/Xlsx/DrawingInCellTest.php +++ b/tests/PhpSpreadsheetTests/Reader/Xlsx/DrawingInCellTest.php @@ -4,6 +4,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Reader\Xlsx; +use PhpOffice\PhpSpreadsheet\IOFactory; use PhpOffice\PhpSpreadsheet\Reader\Xlsx; use PHPUnit\Framework\TestCase; @@ -31,6 +32,9 @@ public function testPictureInCell(): void self::assertSame(154, $drawings[0]->getImageHeight()); } + $writer = IOFactory::createWriter($spreadsheet, 'Xlsx'); + $writer->save('tests/data/Reader/XLSX/drawing_in_cell-written.xlsx'); + $spreadsheet->disconnectWorksheets(); } } From f4141428faaa2ce26f0811b340dbd40b1f2bad84 Mon Sep 17 00:00:00 2001 From: Thomas Lallement Date: Sat, 4 Oct 2025 01:15:44 +0200 Subject: [PATCH 4/8] Finalize XLSX In-Cell Drawing Writer --- src/PhpSpreadsheet/Reader/Xlsx.php | 2 +- src/PhpSpreadsheet/Reader/Xlsx/Namespaces.php | 8 + src/PhpSpreadsheet/Spreadsheet.php | 15 ++ src/PhpSpreadsheet/Worksheet/BaseDrawing.php | 23 ++- src/PhpSpreadsheet/Worksheet/Worksheet.php | 28 ++- src/PhpSpreadsheet/Writer/Xlsx.php | 23 ++- .../Writer/Xlsx/ContentTypes.php | 8 + src/PhpSpreadsheet/Writer/Xlsx/Drawing.php | 13 +- src/PhpSpreadsheet/Writer/Xlsx/Metadata.php | 162 +++++++++++------- src/PhpSpreadsheet/Writer/Xlsx/Rels.php | 8 + .../Writer/Xlsx/RichDataDrawing.php | 91 +++++----- src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php | 10 +- .../Reader/Xlsx/DrawingInCellTest.php | 27 ++- .../Writer/Xlsx/DrawingInCellTest.php | 64 +++++++ tests/data/Reader/XLSX/drawing_in_cell.xlsx | Bin 24096 -> 70102 bytes tests/data/Writer/XLSX/drawing_in_cell.xlsx | Bin 0 -> 70102 bytes 16 files changed, 345 insertions(+), 137 deletions(-) create mode 100644 tests/PhpSpreadsheetTests/Writer/Xlsx/DrawingInCellTest.php create mode 100644 tests/data/Writer/XLSX/drawing_in_cell.xlsx diff --git a/src/PhpSpreadsheet/Reader/Xlsx.php b/src/PhpSpreadsheet/Reader/Xlsx.php index 24dd7ec986..208c44b7dd 100644 --- a/src/PhpSpreadsheet/Reader/Xlsx.php +++ b/src/PhpSpreadsheet/Reader/Xlsx.php @@ -966,8 +966,8 @@ protected function loadSpreadsheetFromFile(string $filename): Spreadsheet $objDrawing->setOffsetX(0); $objDrawing->setOffsetY(0); $objDrawing->setResizeProportional(false); - $objDrawing->setWorksheet($docSheet); $objDrawing->setInCell(true); + $objDrawing->setWorksheet($docSheet); $value = $objDrawing; $cellDataType = DataType::TYPE_DRAWING_IN_CELL; diff --git a/src/PhpSpreadsheet/Reader/Xlsx/Namespaces.php b/src/PhpSpreadsheet/Reader/Xlsx/Namespaces.php index 7356cd8829..a6181eb225 100644 --- a/src/PhpSpreadsheet/Reader/Xlsx/Namespaces.php +++ b/src/PhpSpreadsheet/Reader/Xlsx/Namespaces.php @@ -121,4 +121,12 @@ class Namespaces const DYNAMIC_ARRAY = 'http://schemas.microsoft.com/office/spreadsheetml/2017/dynamicarray'; const DYNAMIC_ARRAY_RICHDATA = 'http://schemas.microsoft.com/office/spreadsheetml/2017/richdata'; + + const RELATIONSHIPS_RICH_VALUE_TYPES = 'http://schemas.microsoft.com/office/2017/06/relationships/rdRichValueTypes'; + + const RELATIONSHIPS_RICH_VALUE_STRUCTURE = 'http://schemas.microsoft.com/office/2017/06/relationships/rdRichValueStructure'; + + const RELATIONSHIPS_RICH_VALUE = 'http://schemas.microsoft.com/office/2017/06/relationships/rdRichValue'; + + const RELATIONSHIPS_RICH_VALUE_REL = 'http://schemas.microsoft.com/office/2022/10/relationships/richValueRel'; } diff --git a/src/PhpSpreadsheet/Spreadsheet.php b/src/PhpSpreadsheet/Spreadsheet.php index 5681e4aaa0..aa97e97403 100644 --- a/src/PhpSpreadsheet/Spreadsheet.php +++ b/src/PhpSpreadsheet/Spreadsheet.php @@ -412,6 +412,21 @@ public function hasRibbonBinObjects(): bool return $this->ribbonBinObjects !== null; } + /** + * This workbook have in cell images + */ + public function hasInCellDrawings(): bool + { + $sheetCount = $this->getSheetCount(); + for ($i = 0; $i < $sheetCount; ++$i) { + if ($this->getSheet($i)->getInCellDrawingCollection()->count() > 0) { + return true; + } + } + + return false; + } + /** * Check if a sheet with a specified code name already exists. * diff --git a/src/PhpSpreadsheet/Worksheet/BaseDrawing.php b/src/PhpSpreadsheet/Worksheet/BaseDrawing.php index 2c87fa2be5..2fd81366fe 100644 --- a/src/PhpSpreadsheet/Worksheet/BaseDrawing.php +++ b/src/PhpSpreadsheet/Worksheet/BaseDrawing.php @@ -139,6 +139,8 @@ class BaseDrawing implements IComparable protected bool $inCell = false; + protected int $index = 0; + /** * Create a new BaseDrawing. */ @@ -205,8 +207,13 @@ public function setWorksheet(?Worksheet $worksheet = null, bool $overrideOld = f if (!($this instanceof Drawing && $this->getPath() === '')) { $this->worksheet->getCell($this->coordinates); } - $this->worksheet->getDrawingCollection() - ->append($this); + if ($this->inCell) { + $this->worksheet->getInCellDrawingCollection() + ->append($this); + } else { + $this->worksheet->getDrawingCollection() + ->append($this); + } } } else { if ($overrideOld) { @@ -586,4 +593,16 @@ public function isInCell(): ?bool { return $this->inCell; } + + public function setIndex(int $index): self + { + $this->index = $index; + + return $this; + } + + public function getIndex(): int + { + return $this->index; + } } diff --git a/src/PhpSpreadsheet/Worksheet/Worksheet.php b/src/PhpSpreadsheet/Worksheet/Worksheet.php index 64c4ec23a1..7b37e0d07e 100644 --- a/src/PhpSpreadsheet/Worksheet/Worksheet.php +++ b/src/PhpSpreadsheet/Worksheet/Worksheet.php @@ -108,6 +108,13 @@ class Worksheet */ private ArrayObject $drawingCollection; + /** + * Collection of drawings. + * + * @var ArrayObject + */ + private ArrayObject $inCellDrawingCollection; + /** * Collection of Chart objects. * @@ -334,6 +341,8 @@ public function __construct(?Spreadsheet $parent = null, string $title = 'Worksh $this->sheetView = new SheetView(); // Drawing collection $this->drawingCollection = new ArrayObject(); + // In Cell Drawing collection + $this->inCellDrawingCollection = new ArrayObject(); // Chart collection $this->chartCollection = new ArrayObject(); // Protection @@ -371,7 +380,7 @@ public function __destruct() ?->clearCalculationCacheForWorksheet($this->title); $this->disconnectCells(); - unset($this->rowDimensions, $this->columnDimensions, $this->tableCollection, $this->drawingCollection, $this->chartCollection, $this->autoFilter); + unset($this->rowDimensions, $this->columnDimensions, $this->tableCollection, $this->drawingCollection, $this->inCellDrawingCollection, $this->chartCollection, $this->autoFilter); } /** @@ -519,6 +528,16 @@ public function getDrawingCollection(): ArrayObject return $this->drawingCollection; } + /** + * Get collection of drawings. + * + * @return ArrayObject + */ + public function getInCellDrawingCollection(): ArrayObject + { + return $this->inCellDrawingCollection; + } + /** * Get collection of charts. * @@ -3730,6 +3749,13 @@ public function __clone() $newDrawing = clone $item; $newDrawing->setWorksheet($this); } + } elseif ($key === 'inCellDrawingCollection') { + $currentCollection = $this->inCellDrawingCollection; + $this->inCellDrawingCollection = new ArrayObject(); + foreach ($currentCollection as $item) { + $newDrawing = clone $item; + $newDrawing->setWorksheet($this); + } } elseif ($key === 'tableCollection') { $currentCollection = $this->tableCollection; $this->tableCollection = new ArrayObject(); diff --git a/src/PhpSpreadsheet/Writer/Xlsx.php b/src/PhpSpreadsheet/Writer/Xlsx.php index 45cb147be0..53cad20b4a 100644 --- a/src/PhpSpreadsheet/Writer/Xlsx.php +++ b/src/PhpSpreadsheet/Writer/Xlsx.php @@ -330,9 +330,22 @@ public function save($filename, int $flags = 0): void /** @var string[] */ $zipContent = []; + $richDataCount = 0; + + if ($this->spreadSheet->hasInCellDrawings()) { + $richDataDrawing = new RichDataDrawing(); + $richDataFiles = $richDataDrawing->generateFiles($this->spreadSheet); + $richDataCount = count($richDataFiles); + + // Add all Rich Data files to ZIP + foreach ($richDataFiles as $path => $content) { + $zipContent[$path] = $content; + } + } + // Add [Content_Types].xml to ZIP file $zipContent['[Content_Types].xml'] = $this->getWriterPartContentTypes()->writeContentTypes($this->spreadSheet, $this->includeCharts); - $metadataData = (new Xlsx\Metadata($this))->writeMetadata(); + $metadataData = (new Xlsx\Metadata($this))->writeMetadata($richDataCount); if ($metadataData !== '') { $zipContent['xl/metadata.xml'] = $metadataData; } @@ -464,14 +477,6 @@ public function save($filename, int $flags = 0): void $zipContent['xl/drawings/drawing' . ($i + 1) . '.xml'] = ''; } - $richDataDrawing = new RichDataDrawing(); - $richDataFiles = $richDataDrawing->generateFiles($this->spreadSheet->getSheet($i)); - - // Add all Rich Data files to ZIP - foreach ($richDataFiles as $path => $content) { - $zipContent[$path] = $content; - } - // Add comment relationship parts /** @var mixed[][] */ $legacyTemp = $unparsedLoadedData['sheets'] ?? []; diff --git a/src/PhpSpreadsheet/Writer/Xlsx/ContentTypes.php b/src/PhpSpreadsheet/Writer/Xlsx/ContentTypes.php index 16c7bb978a..cdc10f7ffb 100644 --- a/src/PhpSpreadsheet/Writer/Xlsx/ContentTypes.php +++ b/src/PhpSpreadsheet/Writer/Xlsx/ContentTypes.php @@ -156,6 +156,14 @@ public function writeContentTypes(Spreadsheet $spreadsheet, bool $includeCharts $this->writeDefaultContentType($objWriter, $extension, $mimeType); } } + + if ($spreadsheet->hasInCellDrawings()) { + $this->writeOverrideContentType($objWriter, '/xl/richData/richValueRel.xml', 'application/vnd.ms-excel.richvaluerel+xml'); + $this->writeOverrideContentType($objWriter, '/xl/richData/rdrichvalue.xml', 'application/vnd.ms-excel.rdrichvalue+xml'); + $this->writeOverrideContentType($objWriter, '/xl/richData/rdrichvaluestructure.xml', 'application/vnd.ms-excel.rdrichvaluestructure+xml'); + $this->writeOverrideContentType($objWriter, '/xl/richData/rdRichValueTypes.xml', 'application/vnd.ms-excel.rdrichvaluetypes+xml'); + } + if ($spreadsheet->hasRibbonBinObjects()) { // Some additional objects in the ribbon ? // we need to write "Extension" but not already write for media content diff --git a/src/PhpSpreadsheet/Writer/Xlsx/Drawing.php b/src/PhpSpreadsheet/Writer/Xlsx/Drawing.php index 05601171e1..1abaa65edd 100644 --- a/src/PhpSpreadsheet/Writer/Xlsx/Drawing.php +++ b/src/PhpSpreadsheet/Writer/Xlsx/Drawing.php @@ -48,11 +48,10 @@ public function writeDrawings(\PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $wor $pRelationId = $i; $hlinkClickId = $pDrawing->getHyperlink() === null ? null : ++$i; - if (!$pDrawing->isInCell()) { - $this->writeDrawing($objWriter, $pDrawing, $pRelationId, $hlinkClickId); - ++$i; - } + $this->writeDrawing($objWriter, $pDrawing, $pRelationId, $hlinkClickId); + $iterator->next(); + ++$i; } if ($includeCharts) { @@ -563,6 +562,12 @@ public function allDrawings(Spreadsheet $spreadsheet): array while ($iterator->valid()) { $aDrawings[] = $iterator->current(); + $iterator->next(); + } + $iterator = $spreadsheet->getSheet($i)->getInCellDrawingCollection()->getIterator(); + while ($iterator->valid()) { + $aDrawings[] = $iterator->current(); + $iterator->next(); } } diff --git a/src/PhpSpreadsheet/Writer/Xlsx/Metadata.php b/src/PhpSpreadsheet/Writer/Xlsx/Metadata.php index 00c15f0003..360f4e37cb 100644 --- a/src/PhpSpreadsheet/Writer/Xlsx/Metadata.php +++ b/src/PhpSpreadsheet/Writer/Xlsx/Metadata.php @@ -10,9 +10,11 @@ class Metadata extends WriterPart /** * Write content types to XML format. * + * @param int $richDataCount + * * @return string XML Output */ - public function writeMetadata(): string + public function writeMetadata(int $richDataCount = 0): string { if (!$this->getParentWriter()->useDynamicArrays()) { return ''; @@ -32,29 +34,40 @@ public function writeMetadata(): string $objWriter->startElement('metadata'); $objWriter->writeAttribute('xmlns', Namespaces::MAIN); $objWriter->writeAttribute('xmlns:xlrd', Namespaces::DYNAMIC_ARRAY_RICHDATA); - $objWriter->writeAttribute('xmlns:xda', Namespaces::DYNAMIC_ARRAY); - $objWriter->startElement('metadataTypes'); - $objWriter->writeAttribute('count', '2'); + if ($richDataCount > 0) { + $objWriter->startElement('metadataTypes'); + $objWriter->writeAttribute('count', '1'); + $this->writeMetadataType($objWriter, 'XLRICHVALUE', false); + $objWriter->endElement(); // metadataTypes - $objWriter->startElement('metadataType'); - $objWriter->writeAttribute('name', 'XLDAPR'); - $objWriter->writeAttribute('minSupportedVersion', '120000'); - $objWriter->writeAttribute('copy', '1'); - $objWriter->writeAttribute('pasteAll', '1'); - $objWriter->writeAttribute('pasteValues', '1'); - $objWriter->writeAttribute('merge', '1'); - $objWriter->writeAttribute('splitFirst', '1'); - $objWriter->writeAttribute('rowColShift', '1'); - $objWriter->writeAttribute('clearFormats', '1'); - $objWriter->writeAttribute('clearComments', '1'); - $objWriter->writeAttribute('assign', '1'); - $objWriter->writeAttribute('coerce', '1'); - $objWriter->writeAttribute('cellMeta', '1'); - $objWriter->endElement(); // metadataType XLDAPR + $this->writeFutureMetadataXLRICHVALUE($objWriter, $richDataCount); + $this->writeValueMetadata($objWriter, $richDataCount); + } else { + $objWriter->writeAttribute('xmlns:xda', Namespaces::DYNAMIC_ARRAY); + + $objWriter->startElement('metadataTypes'); + $objWriter->writeAttribute('count', '2'); + $this->writeMetadataType($objWriter, 'XLDAPR'); + $this->writeMetadataType($objWriter, 'XLRICHVALUE'); + $objWriter->endElement(); // metadataTypes + + $this->writeFutureMetadataXLDAPR($objWriter, 1); + $this->writeFutureMetadataXLRICHVALUE($objWriter, 1); + $this->writeCellMetadata($objWriter, 1); + $this->writeValueMetadata($objWriter, 1, 2); + } + + $objWriter->endElement(); // metadata + + // Return + return $objWriter->getData(); + } + private function writeMetadataType(XMLWriter $objWriter, string $name, bool $cellMeta = true): void + { $objWriter->startElement('metadataType'); - $objWriter->writeAttribute('name', 'XLRICHVALUE'); + $objWriter->writeAttribute('name', $name); $objWriter->writeAttribute('minSupportedVersion', '120000'); $objWriter->writeAttribute('copy', '1'); $objWriter->writeAttribute('pasteAll', '1'); @@ -66,64 +79,85 @@ public function writeMetadata(): string $objWriter->writeAttribute('clearComments', '1'); $objWriter->writeAttribute('assign', '1'); $objWriter->writeAttribute('coerce', '1'); - $objWriter->endElement(); // metadataType XLRICHVALUE - $objWriter->endElement(); // metadataTypes + if ($cellMeta) { + $objWriter->writeAttribute('cellMeta', '1'); + } + $objWriter->endElement(); + } + private function writeFutureMetadataXLDAPR(XMLWriter $objWriter, int $count = 1): void + { $objWriter->startElement('futureMetadata'); $objWriter->writeAttribute('name', 'XLDAPR'); - $objWriter->writeAttribute('count', '1'); - $objWriter->startElement('bk'); - $objWriter->startElement('extLst'); - $objWriter->startElement('ext'); - $objWriter->writeAttribute('uri', '{bdbb8cdc-fa1e-496e-a857-3c3f30c029c3}'); - $objWriter->startElement('xda:dynamicArrayProperties'); - $objWriter->writeAttribute('fDynamic', '1'); - $objWriter->writeAttribute('fCollapsed', '0'); - $objWriter->endElement(); // xda:dynamicArrayProperties - $objWriter->endElement(); // ext - $objWriter->endElement(); // extLst - $objWriter->endElement(); // bk + $objWriter->writeAttribute('count', (string) $count); + + for ($index = 0; $index < $count; ++$index) { + $objWriter->startElement('bk'); + $objWriter->startElement('extLst'); + $objWriter->startElement('ext'); + $objWriter->writeAttribute('uri', '{bdbb8cdc-fa1e-496e-a857-3c3f30c029c3}'); + $objWriter->startElement('xda:dynamicArrayProperties'); + $objWriter->writeAttribute('fDynamic', '1'); + $objWriter->writeAttribute('fCollapsed', '0'); + $objWriter->endElement(); // xda:dynamicArrayProperties + $objWriter->endElement(); // ext + $objWriter->endElement(); // extLst + $objWriter->endElement(); // bk + } $objWriter->endElement(); // futureMetadata XLDAPR + } + private function writeFutureMetadataXLRICHVALUE(XMLWriter $objWriter, int $count): void + { $objWriter->startElement('futureMetadata'); $objWriter->writeAttribute('name', 'XLRICHVALUE'); - $objWriter->writeAttribute('count', '1'); - $objWriter->startElement('bk'); - $objWriter->startElement('extLst'); - $objWriter->startElement('ext'); - $objWriter->writeAttribute('uri', '{3e2802c4-a4d2-4d8b-9148-e3be6c30e623}'); - $objWriter->startElement('xlrd:rvb'); - $objWriter->writeAttribute('i', '0'); - $objWriter->endElement(); // xlrd:rvb - $objWriter->endElement(); // ext - $objWriter->endElement(); // extLst - $objWriter->endElement(); // bk + $objWriter->writeAttribute('count', (string) $count); + + for ($index = 0; $index < $count; ++$index) { + $objWriter->startElement('bk'); + $objWriter->startElement('extLst'); + $objWriter->startElement('ext'); + $objWriter->writeAttribute('uri', '{3e2802c4-a4d2-4d8b-9148-e3be6c30e623}'); + $objWriter->startElement('xlrd:rvb'); + $objWriter->writeAttribute('i', (string) $index); + $objWriter->endElement(); // xlrd:rvb + $objWriter->endElement(); // ext + $objWriter->endElement(); // extLst + $objWriter->endElement(); // bk + } $objWriter->endElement(); // futureMetadata XLRICHVALUE + } + private function writeCellMetadata(XMLWriter $objWriter, int $count = 1, int $t = 1): void + { $objWriter->startElement('cellMetadata'); - $objWriter->writeAttribute('count', '1'); - $objWriter->startElement('bk'); - $objWriter->startElement('rc'); - $objWriter->writeAttribute('t', '1'); - $objWriter->writeAttribute('v', '0'); - $objWriter->endElement(); // rc - $objWriter->endElement(); // bk + $objWriter->writeAttribute('count', (string) $count); + + for ($index = 0; $index < $count; ++$index) { + $objWriter->startElement('bk'); + $objWriter->startElement('rc'); + $objWriter->writeAttribute('t', (string) $t); + $objWriter->writeAttribute('v', (string) $index); + $objWriter->endElement(); // rc + $objWriter->endElement(); // bk + } $objWriter->endElement(); // cellMetadata + } + private function writeValueMetadata(XMLWriter $objWriter, int $count = 1, int $t = 1): void + { $objWriter->startElement('valueMetadata'); - $objWriter->writeAttribute('count', '1'); - $objWriter->startElement('bk'); - $objWriter->startElement('rc'); - $objWriter->writeAttribute('t', '2'); - $objWriter->writeAttribute('v', '0'); - $objWriter->endElement(); // rc - $objWriter->endElement(); // bk - $objWriter->endElement(); // valueMetadata + $objWriter->writeAttribute('count', (string) $count); - $objWriter->endElement(); // metadata - - // Return - return $objWriter->getData(); + for ($index = 0; $index < $count; ++$index) { + $objWriter->startElement('bk'); + $objWriter->startElement('rc'); + $objWriter->writeAttribute('t', (string) $t); + $objWriter->writeAttribute('v', (string) $index); + $objWriter->endElement(); // rc + $objWriter->endElement(); // bk + } + $objWriter->endElement(); // valueMetadata } } diff --git a/src/PhpSpreadsheet/Writer/Xlsx/Rels.php b/src/PhpSpreadsheet/Writer/Xlsx/Rels.php index a913767dc3..3f798302b7 100644 --- a/src/PhpSpreadsheet/Writer/Xlsx/Rels.php +++ b/src/PhpSpreadsheet/Writer/Xlsx/Rels.php @@ -162,6 +162,14 @@ public function writeWorkbookRelationships(Spreadsheet $spreadsheet): string ++$i; //increment i if needed for an another relation } + if ($spreadsheet->getActiveSheet()->getInCellDrawingCollection()->count() > 0) { + $i = ($i + 1 + 3); + $this->writeRelationship($objWriter, $i, Namespaces::RELATIONSHIPS_RICH_VALUE, 'richData/rdrichvalue.xml'); + $this->writeRelationship($objWriter, ++$i, Namespaces::RELATIONSHIPS_RICH_VALUE_STRUCTURE, 'richData/rdrichvaluestructure.xml'); + $this->writeRelationship($objWriter, ++$i, Namespaces::RELATIONSHIPS_RICH_VALUE_TYPES, 'richData/rdRichValueTypes.xml'); + $this->writeRelationship($objWriter, ++$i, Namespaces::RELATIONSHIPS_RICH_VALUE_REL, 'richData/richValueRel.xml'); + } + $objWriter->endElement(); return $objWriter->getData(); diff --git a/src/PhpSpreadsheet/Writer/Xlsx/RichDataDrawing.php b/src/PhpSpreadsheet/Writer/Xlsx/RichDataDrawing.php index cec24f5881..44b47b40df 100644 --- a/src/PhpSpreadsheet/Writer/Xlsx/RichDataDrawing.php +++ b/src/PhpSpreadsheet/Writer/Xlsx/RichDataDrawing.php @@ -3,12 +3,12 @@ namespace PhpOffice\PhpSpreadsheet\Writer\Xlsx; use PhpOffice\PhpSpreadsheet\Shared\XMLWriter; -use PhpOffice\PhpSpreadsheet\Worksheet\BaseDrawing; -use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; +use PhpOffice\PhpSpreadsheet\Spreadsheet; +use PhpOffice\PhpSpreadsheet\Worksheet\Drawing; class RichDataDrawing { - /** @var BaseDrawing[] */ + /** @var Drawing[] */ private array $drawings = []; /** @@ -16,16 +16,26 @@ class RichDataDrawing * * @return array [path => XML content] */ - public function generateFiles(Worksheet $worksheet): array + public function generateFiles(Spreadsheet $spreadsheet): array { - $iterator = $worksheet->getDrawingCollection()->getIterator(); - while ($iterator->valid()) { - /** @var BaseDrawing $pDrawing */ - $pDrawing = $iterator->current(); - if ($pDrawing->isInCell()) { - $this->drawings[] = $pDrawing; + $worksheetCount = $spreadsheet->getSheetCount(); + + $index = 0; + for ($i = 0; $i < $worksheetCount; ++$i) { + $worksheet = $spreadsheet->getSheet($i); + $iterator = $worksheet->getInCellDrawingCollection()->getIterator(); + while ($iterator->valid()) { + /** @var Drawing $pDrawing */ + $pDrawing = $iterator->current(); + $indexedFilename = $pDrawing->getIndexedFilename(); + if (!isset($this->drawings[$indexedFilename])) { + $pDrawing->setIndex(++$index); + $this->drawings[$indexedFilename] = $pDrawing; + } else { + $pDrawing->setIndex($this->drawings[$indexedFilename]->getIndex()); + } + $iterator->next(); } - $iterator->next(); } if (count($this->drawings) === 0) { @@ -49,17 +59,12 @@ private function writeRdrichvalueXML(): string $xml->writeAttribute('xmlns', 'http://schemas.microsoft.com/office/spreadsheetml/2017/richdata'); $xml->writeAttribute('count', (string) count($this->drawings)); - foreach ($this->drawings as $index => $drawing) { - if (!$drawing->isInCell()) { - continue; - } + $index = 0; + foreach ($this->drawings as $drawing) { $xml->startElement('rv'); - $xml->writeAttribute('s', (string) $index); - - // Sample values; adapt to your needs - $xml->writeElement('v', '0'); + $xml->writeAttribute('s', '0'); + $xml->writeElement('v', (string) $index++); $xml->writeElement('v', '5'); - $xml->endElement(); // rv } @@ -74,28 +79,22 @@ private function writeRdrichvaluestructureXML(): string $xml->startDocument('1.0', 'UTF-8', 'yes'); $xml->startElement('rvStructures'); $xml->writeAttribute('xmlns', 'http://schemas.microsoft.com/office/spreadsheetml/2017/richdata'); - $xml->writeAttribute('count', (string) count($this->drawings)); + $xml->writeAttribute('count', '1'); - foreach ($this->drawings as $drawing) { - if (!$drawing->isInCell()) { - continue; - } + $xml->startElement('s'); + $xml->writeAttribute('t', '_localImage'); - $xml->startElement('s'); - $xml->writeAttribute('t', '_localImage'); + $xml->startElement('k'); + $xml->writeAttribute('n', '_rvRel:LocalImageIdentifier'); + $xml->writeAttribute('t', 'i'); + $xml->endElement(); - $xml->startElement('k'); - $xml->writeAttribute('n', '_rvRel:LocalImageIdentifier'); - $xml->writeAttribute('t', 'i'); - $xml->endElement(); + $xml->startElement('k'); + $xml->writeAttribute('n', 'CalcOrigin'); + $xml->writeAttribute('t', 'i'); + $xml->endElement(); - $xml->startElement('k'); - $xml->writeAttribute('n', 'CalcOrigin'); - $xml->writeAttribute('t', 'i'); - $xml->endElement(); - - $xml->endElement(); // s - } + $xml->endElement(); // s $xml->endElement(); // rvStructures @@ -153,12 +152,10 @@ private function writeRichValueRelXML(): string $xml->writeAttribute('xmlns', 'http://schemas.microsoft.com/office/spreadsheetml/2022/richvaluerel'); $xml->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'); - foreach ($this->drawings as $index => $drawing) { - if (!$drawing->isInCell()) { - continue; - } + $index = 0; + foreach ($this->drawings as $drawing) { $xml->startElement('rel'); - $xml->writeAttribute('r:id', 'rId' . ($index + 1)); + $xml->writeAttribute('r:id', 'rId' . ++$index); $xml->endElement(); } @@ -174,12 +171,10 @@ private function writeRichValueRelRelsXML(): string $xml->startElement('Relationships'); $xml->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships'); - foreach ($this->drawings as $index => $drawing) { - if (!$drawing->isInCell()) { - continue; - } + $index = 0; + foreach ($this->drawings as $drawing) { $xml->startElement('Relationship'); - $xml->writeAttribute('Id', 'rId' . ($index + 1)); + $xml->writeAttribute('Id', 'rId' . ++$index); $xml->writeAttribute('Type', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image'); $xml->writeAttribute('Target', '../media/' . $drawing->getIndexedFilename()); $xml->endElement(); diff --git a/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php b/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php index 2eb38c05d2..839aacdebb 100644 --- a/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php +++ b/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php @@ -18,6 +18,7 @@ use PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\ConditionalFormattingRuleExtension; use PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\ConditionalIconSet; use PhpOffice\PhpSpreadsheet\Style\Font; +use PhpOffice\PhpSpreadsheet\Worksheet\BaseDrawing; use PhpOffice\PhpSpreadsheet\Worksheet\RowDimension; use PhpOffice\PhpSpreadsheet\Worksheet\SheetView; use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet as PhpspreadsheetWorksheet; @@ -1557,10 +1558,10 @@ private function writeCellError(XMLWriter $objWriter, string $mappedType, string $objWriter->writeElement('v', $cellIsFormula ? $formulaerr : $cellValue); } - private function writeCellDrawing(XMLWriter $objWriter): void + private function writeCellDrawing(XMLWriter $objWriter, int $index): void { $objWriter->writeAttribute('t', 'e'); - $objWriter->writeAttribute('vm', '1'); + $objWriter->writeAttribute('vm', (string) $index); $objWriter->writeElement('v', '#VALUE!'); } @@ -1746,7 +1747,10 @@ private function writeCell(XMLWriter $objWriter, PhpspreadsheetWorksheet $worksh break; case 'drawingcell': // DrawingInCell - $this->writeCellDrawing($objWriter); + if ($cellValue instanceof BaseDrawing) { + $index = $cellValue->getIndex(); + $this->writeCellDrawing($objWriter, $index); + } break; case 'e': // Error diff --git a/tests/PhpSpreadsheetTests/Reader/Xlsx/DrawingInCellTest.php b/tests/PhpSpreadsheetTests/Reader/Xlsx/DrawingInCellTest.php index 3a43a959d6..22776ff9fb 100644 --- a/tests/PhpSpreadsheetTests/Reader/Xlsx/DrawingInCellTest.php +++ b/tests/PhpSpreadsheetTests/Reader/Xlsx/DrawingInCellTest.php @@ -15,9 +15,10 @@ public function testPictureInCell(): void $file = 'tests/data/Reader/XLSX/drawing_in_cell.xlsx'; $reader = new Xlsx(); $spreadsheet = $reader->load($file); - $sheet = $spreadsheet->getActiveSheet(); - $drawings = $sheet->getDrawingCollection(); - self::assertCount(1, $drawings); + + $sheet = $spreadsheet->getSheet(0); + $drawings = $sheet->getInCellDrawingCollection(); + self::assertCount(2, $drawings); if ($drawings[0] === null) { self::fail('Unexpected null drawing'); @@ -32,8 +33,24 @@ public function testPictureInCell(): void self::assertSame(154, $drawings[0]->getImageHeight()); } - $writer = IOFactory::createWriter($spreadsheet, 'Xlsx'); - $writer->save('tests/data/Reader/XLSX/drawing_in_cell-written.xlsx'); + self::assertSame($drawings[0], $sheet->getCell('B2')->getValue()); + + $sheet = $spreadsheet->getSheet(1); + $drawings = $sheet->getInCellDrawingCollection(); + self::assertCount(1, $drawings); + + if ($drawings[0] === null) { + self::fail('Unexpected null drawing'); + } else { + self::assertSame(IMAGETYPE_PNG, $drawings[0]->getType()); + self::assertSame('D7', $drawings[0]->getCoordinates()); + self::assertSame(0, $drawings[0]->getOffsetX()); + self::assertSame(0, $drawings[0]->getOffsetY()); + self::assertSame(413, $drawings[0]->getWidth()); + self::assertSame(218, $drawings[0]->getHeight()); + self::assertSame(413, $drawings[0]->getImageWidth()); + self::assertSame(218, $drawings[0]->getImageHeight()); + } $spreadsheet->disconnectWorksheets(); } diff --git a/tests/PhpSpreadsheetTests/Writer/Xlsx/DrawingInCellTest.php b/tests/PhpSpreadsheetTests/Writer/Xlsx/DrawingInCellTest.php new file mode 100644 index 0000000000..e12f8a580b --- /dev/null +++ b/tests/PhpSpreadsheetTests/Writer/Xlsx/DrawingInCellTest.php @@ -0,0 +1,64 @@ +load($file); + + // Save spreadsheet to file and read it back + $reloadedSpreadsheet = $this->writeAndReload($spreadsheet, 'Xlsx'); + + $spreadsheet->disconnectWorksheets(); + self::assertNotNull($reloadedSpreadsheet->getSheet(0)); + + $sheet = $reloadedSpreadsheet->getSheet(0); + $drawings = $sheet->getInCellDrawingCollection(); + self::assertCount(2, $drawings); + + if ($drawings[0] === null) { + self::fail('Unexpected null drawing'); + } else { + self::assertSame(IMAGETYPE_PNG, $drawings[0]->getType()); + self::assertSame('B2', $drawings[0]->getCoordinates()); + self::assertSame(0, $drawings[0]->getOffsetX()); + self::assertSame(0, $drawings[0]->getOffsetY()); + self::assertSame(296, $drawings[0]->getWidth()); + self::assertSame(154, $drawings[0]->getHeight()); + self::assertSame(296, $drawings[0]->getImageWidth()); + self::assertSame(154, $drawings[0]->getImageHeight()); + } + + self::assertSame($drawings[0], $sheet->getCell('B2')->getValue()); + + $sheet = $reloadedSpreadsheet->getSheet(1); + $drawings = $sheet->getInCellDrawingCollection(); + self::assertCount(1, $drawings); + + if ($drawings[0] === null) { + self::fail('Unexpected null drawing'); + } else { + self::assertSame(IMAGETYPE_PNG, $drawings[0]->getType()); + self::assertSame('D7', $drawings[0]->getCoordinates()); + self::assertSame(0, $drawings[0]->getOffsetX()); + self::assertSame(0, $drawings[0]->getOffsetY()); + self::assertSame(413, $drawings[0]->getWidth()); + self::assertSame(218, $drawings[0]->getHeight()); + self::assertSame(413, $drawings[0]->getImageWidth()); + self::assertSame(218, $drawings[0]->getImageHeight()); + } + + $reloadedSpreadsheet->disconnectWorksheets(); + } +} diff --git a/tests/data/Reader/XLSX/drawing_in_cell.xlsx b/tests/data/Reader/XLSX/drawing_in_cell.xlsx index 7ba1881fa12d709d63a13d4f1f3afb77512c8ec9..a350d30581a818711292594887a5d41db85b6ba0 100644 GIT binary patch delta 50742 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 delta 4512 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 diff --git a/tests/data/Writer/XLSX/drawing_in_cell.xlsx b/tests/data/Writer/XLSX/drawing_in_cell.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..a350d30581a818711292594887a5d41db85b6ba0 GIT binary patch literal 70102 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 z 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 Mw9>%`#1_i`0ZSSltN;K2 literal 0 HcmV?d00001 From 6d87aa55124d8ad7ae56b7944eab0f36ac365394 Mon Sep 17 00:00:00 2001 From: Thomas Lallement Date: Sat, 4 Oct 2025 01:37:01 +0200 Subject: [PATCH 5/8] Fix phpstan, cs & phpdoc --- src/PhpSpreadsheet/Spreadsheet.php | 2 +- src/PhpSpreadsheet/Writer/Xlsx/Metadata.php | 2 -- tests/PhpSpreadsheetTests/Writer/Xlsx/DrawingInCellTest.php | 1 - 3 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/PhpSpreadsheet/Spreadsheet.php b/src/PhpSpreadsheet/Spreadsheet.php index aa97e97403..334156faa7 100644 --- a/src/PhpSpreadsheet/Spreadsheet.php +++ b/src/PhpSpreadsheet/Spreadsheet.php @@ -413,7 +413,7 @@ public function hasRibbonBinObjects(): bool } /** - * This workbook have in cell images + * This workbook has in cell images. */ public function hasInCellDrawings(): bool { diff --git a/src/PhpSpreadsheet/Writer/Xlsx/Metadata.php b/src/PhpSpreadsheet/Writer/Xlsx/Metadata.php index 360f4e37cb..c4cf925b93 100644 --- a/src/PhpSpreadsheet/Writer/Xlsx/Metadata.php +++ b/src/PhpSpreadsheet/Writer/Xlsx/Metadata.php @@ -10,8 +10,6 @@ class Metadata extends WriterPart /** * Write content types to XML format. * - * @param int $richDataCount - * * @return string XML Output */ public function writeMetadata(int $richDataCount = 0): string diff --git a/tests/PhpSpreadsheetTests/Writer/Xlsx/DrawingInCellTest.php b/tests/PhpSpreadsheetTests/Writer/Xlsx/DrawingInCellTest.php index e12f8a580b..7a84cf6075 100644 --- a/tests/PhpSpreadsheetTests/Writer/Xlsx/DrawingInCellTest.php +++ b/tests/PhpSpreadsheetTests/Writer/Xlsx/DrawingInCellTest.php @@ -21,7 +21,6 @@ public function testPictureInCell(): void $reloadedSpreadsheet = $this->writeAndReload($spreadsheet, 'Xlsx'); $spreadsheet->disconnectWorksheets(); - self::assertNotNull($reloadedSpreadsheet->getSheet(0)); $sheet = $reloadedSpreadsheet->getSheet(0); $drawings = $sheet->getInCellDrawingCollection(); From e88ac2003924627519f7fe5001688bc04c8a9a6e Mon Sep 17 00:00:00 2001 From: Thomas Lallement Date: Sat, 4 Oct 2025 01:48:43 +0200 Subject: [PATCH 6/8] Remove unused imports --- tests/PhpSpreadsheetTests/Reader/Xlsx/DrawingInCellTest.php | 1 - tests/PhpSpreadsheetTests/Writer/Xlsx/DrawingInCellTest.php | 2 -- 2 files changed, 3 deletions(-) diff --git a/tests/PhpSpreadsheetTests/Reader/Xlsx/DrawingInCellTest.php b/tests/PhpSpreadsheetTests/Reader/Xlsx/DrawingInCellTest.php index 22776ff9fb..345e292610 100644 --- a/tests/PhpSpreadsheetTests/Reader/Xlsx/DrawingInCellTest.php +++ b/tests/PhpSpreadsheetTests/Reader/Xlsx/DrawingInCellTest.php @@ -4,7 +4,6 @@ namespace PhpOffice\PhpSpreadsheetTests\Reader\Xlsx; -use PhpOffice\PhpSpreadsheet\IOFactory; use PhpOffice\PhpSpreadsheet\Reader\Xlsx; use PHPUnit\Framework\TestCase; diff --git a/tests/PhpSpreadsheetTests/Writer/Xlsx/DrawingInCellTest.php b/tests/PhpSpreadsheetTests/Writer/Xlsx/DrawingInCellTest.php index 7a84cf6075..b170b596bd 100644 --- a/tests/PhpSpreadsheetTests/Writer/Xlsx/DrawingInCellTest.php +++ b/tests/PhpSpreadsheetTests/Writer/Xlsx/DrawingInCellTest.php @@ -4,10 +4,8 @@ namespace PhpOffice\PhpSpreadsheetTests\Writer\Xlsx; -use PhpOffice\PhpSpreadsheet\IOFactory; use PhpOffice\PhpSpreadsheet\Reader\Xlsx; use PhpOffice\PhpSpreadsheetTests\Functional\AbstractFunctional; -use PHPUnit\Framework\TestCase; class DrawingInCellTest extends AbstractFunctional { From a9581496b41061268b8896ed21fbaeb8a520a843 Mon Sep 17 00:00:00 2001 From: tlallement Date: Mon, 6 Oct 2025 15:57:26 +0200 Subject: [PATCH 7/8] Remove init offsetX & offsetY --- src/PhpSpreadsheet/Reader/Xlsx.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/PhpSpreadsheet/Reader/Xlsx.php b/src/PhpSpreadsheet/Reader/Xlsx.php index 208c44b7dd..6a7795f653 100644 --- a/src/PhpSpreadsheet/Reader/Xlsx.php +++ b/src/PhpSpreadsheet/Reader/Xlsx.php @@ -963,8 +963,6 @@ protected function loadSpreadsheetFromFile(string $filename): Spreadsheet ); $objDrawing->setCoordinates($r); - $objDrawing->setOffsetX(0); - $objDrawing->setOffsetY(0); $objDrawing->setResizeProportional(false); $objDrawing->setInCell(true); $objDrawing->setWorksheet($docSheet); From 75286c3e889e41e36d5a447609b5cfcb4534fb69 Mon Sep 17 00:00:00 2001 From: tlallement Date: Mon, 6 Oct 2025 17:57:42 +0200 Subject: [PATCH 8/8] Allow writing Drawing in Cell --- .../Cell/DefaultValueBinder.php | 9 +++++ .../Writer/Xlsx/DrawingInCellTest.php | 36 +++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/src/PhpSpreadsheet/Cell/DefaultValueBinder.php b/src/PhpSpreadsheet/Cell/DefaultValueBinder.php index 42a45a913b..daae358102 100644 --- a/src/PhpSpreadsheet/Cell/DefaultValueBinder.php +++ b/src/PhpSpreadsheet/Cell/DefaultValueBinder.php @@ -9,6 +9,7 @@ use PhpOffice\PhpSpreadsheet\Exception as SpreadsheetException; use PhpOffice\PhpSpreadsheet\RichText\RichText; use PhpOffice\PhpSpreadsheet\Shared\StringHelper; +use PhpOffice\PhpSpreadsheet\Worksheet\BaseDrawing; use Stringable; class DefaultValueBinder implements IValueBinder @@ -33,6 +34,11 @@ public function bindValue(Cell $cell, mixed $value): bool $value = $value->format('Y-m-d H:i:s'); } elseif ($value instanceof Stringable) { $value = (string) $value; + } elseif ($value instanceof BaseDrawing) { + $value->setCoordinates($cell->getCoordinate()); + $value->setResizeProportional(false); + $value->setInCell(true); + $value->setWorksheet($cell->getWorksheet()); } else { throw new SpreadsheetException('Unable to bind unstringable ' . gettype($value)); } @@ -68,6 +74,9 @@ public static function dataTypeForValue(mixed $value): string if ($value instanceof RichText) { return DataType::TYPE_INLINE; } + if ($value instanceof BaseDrawing) { + return DataType::TYPE_DRAWING_IN_CELL; + } if ($value instanceof Stringable) { $value = (string) $value; } diff --git a/tests/PhpSpreadsheetTests/Writer/Xlsx/DrawingInCellTest.php b/tests/PhpSpreadsheetTests/Writer/Xlsx/DrawingInCellTest.php index b170b596bd..eb0bff202d 100644 --- a/tests/PhpSpreadsheetTests/Writer/Xlsx/DrawingInCellTest.php +++ b/tests/PhpSpreadsheetTests/Writer/Xlsx/DrawingInCellTest.php @@ -5,6 +5,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Writer\Xlsx; use PhpOffice\PhpSpreadsheet\Reader\Xlsx; +use PhpOffice\PhpSpreadsheet\Worksheet\Drawing; use PhpOffice\PhpSpreadsheetTests\Functional\AbstractFunctional; class DrawingInCellTest extends AbstractFunctional @@ -58,4 +59,39 @@ public function testPictureInCell(): void $reloadedSpreadsheet->disconnectWorksheets(); } + + public function testWriteNewPictureInCell(): void + { + $file = 'tests/data/Writer/XLSX/drawing_in_cell.xlsx'; + $reader = new Xlsx(); + $spreadsheet = $reader->load($file); + + $objDrawing = new Drawing(); + $objDrawing->setPath('tests/data/Writer/XLSX/blue_square.png'); + + $sheet = $spreadsheet->getSheet(1); + $sheet->getCell('C10')->setValue($objDrawing); + + // Save spreadsheet to file and read it back + $reloadedSpreadsheet = $this->writeAndReload($spreadsheet, 'Xlsx'); + $spreadsheet->disconnectWorksheets(); + + $sheet = $reloadedSpreadsheet->getSheet(1); + $drawings = $sheet->getInCellDrawingCollection(); + self::assertCount(2, $drawings); + + /** @var ?Drawing $drawing */ + $drawing = $sheet->getCell('C10')->getValue(); + + if ($drawing === null) { + self::fail('Unexpected null drawing'); + } else { + self::assertSame(IMAGETYPE_PNG, $drawing->getType()); + self::assertSame('C10', $drawing->getCoordinates()); + self::assertSame(100, $drawing->getWidth()); + self::assertSame(100, $drawing->getHeight()); + } + + $reloadedSpreadsheet->disconnectWorksheets(); + } }