Skip to content

Commit

Permalink
Special Characters in Image File Name
Browse files Browse the repository at this point in the history
Fix PHPOffice#2415. Fix PHPOffice#1470. If path name of image contains anything other than ASCII, or if it contains # or space or probably other exceptions, PhpSpreadsheet creates a file that Excel cannot, for whatever reason, read (it is valid xml). When adding an image to a spreadsheet, Excel does not retain the original path name; PhpSpreadsheet does, but probably shouldn't. It is changed to save the image file in the zip as the MD5 hash of the original path name. This produces a file that Excel can read. In addition, it ensures that, if the image is used in multiple places, it is saved in the Excel file only once.

Because this error becomes evident only when opening the file in Excel, it is difficult to write a test case. I have instead duplicated sample Basic/05... using image files whose names match the reported error conditions.
  • Loading branch information
oleibman committed Nov 27, 2021
1 parent 290c18e commit cfe5cc1
Show file tree
Hide file tree
Showing 7 changed files with 395 additions and 4 deletions.
7 changes: 7 additions & 0 deletions samples/Basic/05_UnexpectedCharacters.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php

require __DIR__ . '/../Header.php';
$spreadsheet = require __DIR__ . '/../templates/sampleSpreadsheet2.php';

// Save
$helper->write($spreadsheet, __FILE__);
Binary file added samples/images/terms con#ditions.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added samples/images/サンプル.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
384 changes: 384 additions & 0 deletions samples/templates/sampleSpreadsheet2.php

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/PhpSpreadsheet/Worksheet/Drawing.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public function getIndexedFilename(): string
$fileName = $this->getFilename();
$fileName = str_replace(' ', '_', $fileName);

return str_replace('.' . $this->getExtension(), '', $fileName) . $this->getImageIndex() . '.' . $this->getExtension();
return md5($this->path) . '.' . $this->getExtension();
}

/**
Expand Down
4 changes: 2 additions & 2 deletions src/PhpSpreadsheet/Writer/Xlsx.php
Original file line number Diff line number Diff line change
Expand Up @@ -486,7 +486,7 @@ public function save($filename, int $flags = 0): void
$imageContents = file_get_contents($imagePath);
}

$zipContent['xl/media/' . str_replace(' ', '_', $this->getDrawingHashTable()->getByIndex($i)->getIndexedFilename())] = $imageContents;
$zipContent['xl/media/' . $this->getDrawingHashTable()->getByIndex($i)->getIndexedFilename()] = $imageContents;
} elseif ($this->getDrawingHashTable()->getByIndex($i) instanceof MemoryDrawing) {
ob_start();
call_user_func(
Expand All @@ -496,7 +496,7 @@ public function save($filename, int $flags = 0): void
$imageContents = ob_get_contents();
ob_end_clean();

$zipContent['xl/media/' . str_replace(' ', '_', $this->getDrawingHashTable()->getByIndex($i)->getIndexedFilename())] = $imageContents;
$zipContent['xl/media/' . $this->getDrawingHashTable()->getByIndex($i)->getIndexedFilename()] = $imageContents;
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/PhpSpreadsheet/Writer/Xlsx/Rels.php
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ public function writeDrawingRelationships(\PhpOffice\PhpSpreadsheet\Worksheet\Wo
$objWriter,
$i,
'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image',
'../media/' . str_replace(' ', '', $drawing->getIndexedFilename())
'../media/' . $drawing->getIndexedFilename()
);

$i = $this->writeDrawingHyperLink($objWriter, $drawing, $i);
Expand Down

0 comments on commit cfe5cc1

Please sign in to comment.