Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix saving XLSX with drawings #1462

Merged
merged 12 commits into from
May 23, 2020
Merged
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org).
- Fix RATE, PRICE, XIRR, and XNPV Functions [#1456](https://github.com/PHPOffice/PhpSpreadsheet/pull/1456)
- Save Excel 2010+ functions properly in XLSX [#1461](https://github.com/PHPOffice/PhpSpreadsheet/pull/1461)
- Several improvements in HTML writer [#1464](https://github.com/PHPOffice/PhpSpreadsheet/pull/1464)
- Fix incorrect behaviour when saving XLSX file with drawings [#1462](https://github.com/PHPOffice/PhpSpreadsheet/pull/1462),
- Fix Crash while trying setting a cell the value "123456\n" [#1476](https://github.com/PHPOffice/PhpSpreadsheet/pull/1481)

### Changed
Expand Down
11 changes: 8 additions & 3 deletions src/PhpSpreadsheet/Writer/Xlsx/Rels.php
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,6 @@ public function writeWorksheetRelationships(\PhpOffice\PhpSpreadsheet\Worksheet\
$objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships');

// Write drawing relationships?
$d = 0;
Vagir-dev marked this conversation as resolved.
Show resolved Hide resolved
$drawingOriginalIds = [];
$unparsedLoadedData = $pWorksheet->getParent()->getUnparsedLoadedData();
if (isset($unparsedLoadedData['sheets'][$pWorksheet->getCodeName()]['drawingOriginalIds'])) {
Expand All @@ -197,13 +196,19 @@ public function writeWorksheetRelationships(\PhpOffice\PhpSpreadsheet\Worksheet\
}

if (($pWorksheet->getDrawingCollection()->count() > 0) || (count($charts) > 0) || $drawingOriginalIds) {
$relPath = '../drawings/drawing' . $pWorksheetId . '.xml';
Vagir-dev marked this conversation as resolved.
Show resolved Hide resolved
$rId = ++$d;
Vagir-dev marked this conversation as resolved.
Show resolved Hide resolved
$rId = 1;

// Use original $relPath to get original $rId.
// Take first. In future can be overwritten.
// (! synchronize with \PhpOffice\PhpSpreadsheet\Writer\Xlsx\Worksheet::writeDrawings)
reset($drawingOriginalIds);
$relPath = key($drawingOriginalIds);
if (isset($drawingOriginalIds[$relPath])) {
$rId = (int) (substr($drawingOriginalIds[$relPath], 3));
}

// Generate new $relPath to write drawing relationship
$relPath = '../drawings/drawing' . $pWorksheetId . '.xml';
$this->writeRelationship(
$objWriter,
$rId,
Expand Down
1 change: 1 addition & 0 deletions src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php
Original file line number Diff line number Diff line change
Expand Up @@ -1215,6 +1215,7 @@ private function writeDrawings(XMLWriter $objWriter, PhpspreadsheetWorksheet $pS
if (isset($unparsedLoadedData['sheets'][$pSheet->getCodeName()]['drawingOriginalIds'])) {
$drawingOriginalIds = $unparsedLoadedData['sheets'][$pSheet->getCodeName()]['drawingOriginalIds'];
// take first. In future can be overriten
// (! synchronize with \PhpOffice\PhpSpreadsheet\Writer\Xlsx\Rels::writeWorksheetRelationships)
$rId = reset($drawingOriginalIds);
}

Expand Down
45 changes: 45 additions & 0 deletions tests/PhpSpreadsheetTests/Writer/Xlsx/DrawingsTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

namespace PhpOffice\PhpSpreadsheetTests\Writer\Xlsx;

use PhpOffice\PhpSpreadsheet\Reader\Xlsx;
use PhpOffice\PhpSpreadsheet\Settings;
use PhpOffice\PhpSpreadsheetTests\Functional\AbstractFunctional;

class DrawingsTest extends AbstractFunctional
{
/**
* @var int
*/
protected $prevValue;

protected function setUp(): void
{
$this->prevValue = Settings::getLibXmlLoaderOptions();

// Disable validating XML with the DTD
Settings::setLibXmlLoaderOptions($this->prevValue & ~LIBXML_DTDVALID & ~LIBXML_DTDATTR & ~LIBXML_DTDLOAD);
}

protected function tearDown(): void
{
Settings::setLibXmlLoaderOptions($this->prevValue);
}

/**
* Test save and load XLSX file with drawing on 2nd worksheet.
*/
public function testSaveLoadWithDrawingOn2ndWorksheet(): void
{
// Read spreadsheet from file
$inputFilename = 'tests/data/Writer/XLSX/drawing_on_2nd_page.xlsx';
$reader = new Xlsx();
$spreadsheet = $reader->load($inputFilename);

// Save spreadsheet to file and read it back
$reloadedSpreadsheet = $this->writeAndReload($spreadsheet, 'Xlsx');

// Fake assert. The only thing we need is to ensure the file is loaded without exception
self::assertNotNull($reloadedSpreadsheet);
}
}
Binary file added tests/data/Writer/XLSX/drawing_on_2nd_page.xlsx
Binary file not shown.