forked from PHPOffice/PhpSpreadsheet
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Generation3 Copy With Image in Footer
Fix PHPOffice#3126. A worksheet contained an image in its footer. It could be loaded and saved as another spreadsheet. However, if you tried to load and save that spreadsheet, PhpSpreadsheet would be unable to find the footer image and would therefore throw an exception. This error was introduced a long time ago, in PhpSpreadsheet 1.3.0. The apparent cause of the problem was PR PHPOffice#435, sometime around June 2018. That change was very useful, but it had problems which exposed themselves only with a third generation copy. An additional contributor to the issue at hand was PR PHPOffice#1690 (December 2020), which again exposed itself with a third generation copy. The issue from 1690 is easier to explain and deal with. It added a 'ps' suffix to printer settings resources in Xlsx Reader (to avoid name conflicts), but did not limit itself to a single addition (so subseqent generations would have multiple ps's). It also neglected to add the suffix in Reader/Xlsx/PageSetup. As for 435, it loops through all the worksheet relationships, and uses the last that it finds as the base for header/footer drawings. It has been changed to use only the relationship whose `rId` matches the worksheet's `legacyDrawingHF` `rId`. It also needs a bit extra validation to make sure a drawing exists before adding it to its array of header/footer images. It also meant that Xlsx/Writer/Rels might write an entry with the same rId twice. I have also changed the header/footer image processing to be namespace aware (see PR PHPOffice#3137).
- Loading branch information
Showing
5 changed files
with
107 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
<?php | ||
|
||
namespace PhpOffice\PhpSpreadsheetTests\Reader\Xlsx; | ||
|
||
use PhpOffice\PhpSpreadsheet\Reader\Xlsx as XlsxReader; | ||
use PhpOffice\PhpSpreadsheet\Shared\File; | ||
use PhpOffice\PhpSpreadsheet\Writer\Xlsx as XlsxWriter; | ||
use PHPUnit\Framework\TestCase; | ||
|
||
class Issue3126Test extends TestCase | ||
{ | ||
public function testReloadXlsxWorkbookProperties(): void | ||
{ | ||
$filename = 'tests/data/Reader/XLSX/issue.3126.xlsx'; | ||
$reader = new XlsxReader(); | ||
$generation1 = $reader->load($filename); | ||
$gen1sheet = $generation1->getActiveSheet(); | ||
$gen1hf = $gen1sheet->getHeaderFooter(); | ||
$gen1Images = $gen1hf->getImages(); | ||
self::assertCount(1, $gen1Images); | ||
$gen1hfName = array_key_exists('LF', $gen1Images) ? $gen1Images['LF']->getName() : ''; | ||
self::assertSame('fleche-verte-up-right', $gen1hfName); | ||
$pageSetupRel = $generation1->getUnparsedLoadedData()['sheets']['Worksheet']['pageSetupRelId'] ?? ''; | ||
self::assertSame('rId1ps', $pageSetupRel); | ||
$pageSetupPath = $generation1->getUnparsedLoadedData()['sheets']['Worksheet']['printerSettings']['ps']['filePath'] ?? ''; | ||
self::assertSame('xl/printerSettings/printerSettings1.bin', $pageSetupPath); | ||
|
||
$generation2Name = File::temporaryFilename(); | ||
$writer = new XlsxWriter($generation1); | ||
$writer->save($generation2Name); | ||
$generation1->disconnectWorksheets(); | ||
$reader2 = new XlsxReader(); | ||
$generation2 = $reader2->load($generation2Name); | ||
$gen2sheet = $generation2->getActiveSheet(); | ||
$gen2hf = $gen2sheet->getHeaderFooter(); | ||
$gen2Images = $gen2hf->getImages(); | ||
self::assertCount(1, $gen2Images); | ||
$gen2hfName = array_key_exists('LF', $gen2Images) ? $gen2Images['LF']->getName() : ''; | ||
self::assertSame('fleche-verte-up-right', $gen2hfName); | ||
$pageSetupRel = $generation2->getUnparsedLoadedData()['sheets']['Worksheet']['pageSetupRelId'] ?? ''; | ||
self::assertSame('rId1ps', $pageSetupRel); | ||
$pageSetupPath = $generation2->getUnparsedLoadedData()['sheets']['Worksheet']['printerSettings']['ps']['filePath'] ?? ''; | ||
self::assertSame('xl/printerSettings/printerSettings1.bin', $pageSetupPath); | ||
|
||
$generation3Name = File::temporaryFilename(); | ||
$writer = new XlsxWriter($generation2); | ||
$writer->save($generation3Name); | ||
$generation2->disconnectWorksheets(); | ||
$reader3 = new XlsxReader(); | ||
$generation3 = $reader3->load($generation3Name); | ||
$gen3sheet = $generation3->getActiveSheet(); | ||
$gen3hf = $gen3sheet->getHeaderFooter(); | ||
$gen3Images = $gen3hf->getImages(); | ||
self::assertCount(1, $gen3Images); | ||
$gen3hfName = array_key_exists('LF', $gen3Images) ? $gen3Images['LF']->getName() : ''; | ||
self::assertSame('fleche-verte-up-right', $gen3hfName); | ||
$pageSetupRel = $generation3->getUnparsedLoadedData()['sheets']['Worksheet']['pageSetupRelId'] ?? ''; | ||
self::assertSame('rId1ps', $pageSetupRel); | ||
$pageSetupPath = $generation3->getUnparsedLoadedData()['sheets']['Worksheet']['printerSettings']['ps']['filePath'] ?? ''; | ||
self::assertSame('xl/printerSettings/printerSettings1.bin', $pageSetupPath); | ||
|
||
unlink($generation2Name); | ||
unlink($generation3Name); | ||
$generation3->disconnectWorksheets(); | ||
} | ||
} |
Binary file not shown.