Files
oleibman 93c84c231f Drawing Hyperlink
Fix #993, which went stale in 2019 and is now reopened. It was not explicitly stated in the documentation, but Xlsx supports hyperlinks when clicking on a drawing. User tried to use the same format for internal hyperlink that is documented for cell internal hyperlink, and that failed (corrupt spreadsheet, hyperlink doesn't work). That was because Xlsx uses `#` rather than `sheet://`. For drawings, Xlsx Writer will now automatically convert `sheet://` to `#`, and Xlsx Reader will now convert the other way. No change is needed for cell hyperlinks. Documentation is now updated, including a statement that drawing hyperlinks work only for Xlsx.
2025-12-30 12:22:39 -08:00

107 lines
4.1 KiB
PHP

<?php
declare(strict_types=1);
namespace PhpOffice\PhpSpreadsheetTests\Writer\Xlsx;
use PhpOffice\PhpSpreadsheet\Cell\Hyperlink;
use PhpOffice\PhpSpreadsheet\Reader\Xlsx as XlsxReader;
use PhpOffice\PhpSpreadsheet\Shared\File;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Worksheet\Drawing;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx as XlsxWriter;
use PHPUnit\Framework\TestCase;
class Issue993Test extends TestCase
{
private string $outputFile = '';
protected function tearDown(): void
{
if ($this->outputFile !== '') {
unlink($this->outputFile);
$this->outputFile = '';
}
}
public function testDrawingWithPoundUrl(): void
{
$path = 'samples/images/blue_square.png';
$spreadsheet = new Spreadsheet();
$sheet1 = $spreadsheet->getActiveSheet();
$sheet1->setTitle('sheet1');
$sheet2 = $spreadsheet->createSheet();
$sheet2->setTitle('sheet2');
$drawing = new Drawing();
$drawing->setWorksheet($sheet1);
$drawing->setName('Blue Square');
$drawing->setPath($path);
$drawing->setCoordinates('E1');
$drawing->setCoordinates2('F5');
$hyperlink = new Hyperlink('#sheet2!C3', 'Click here');
$drawing->setHyperlink($hyperlink);
$writer = new XlsxWriter($spreadsheet);
$this->outputFile = File::temporaryFilename();
$writer->save($this->outputFile);
$spreadsheet->disconnectWorksheets();
$file = 'zip://';
$file .= $this->outputFile;
$file .= '#xl/drawings/_rels/drawing1.xml.rels';
$data = file_get_contents($file);
self::assertNotFalse($data);
self::assertStringContainsString('<Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink" Target="#sheet2!C3"/>', $data, 'url unchanged by write');
$reader = new XlsxReader();
$reloadedSpreadsheet = $reader->load($this->outputFile);
$rsheet1 = $reloadedSpreadsheet->getSheetByName('sheet1');
self::assertNotNull($rsheet1);
$drawings = $rsheet1->getDrawingCollection();
self::assertCount(1, $drawings);
$drawing0 = $drawings[0];
self::assertSame('sheet://sheet2!C3', $drawing0?->getHyperlink()?->getUrl(), 'url was changed on read');
$reloadedSpreadsheet->disconnectWorksheets();
}
public function testDrawingWithSheetUrl(): void
{
$path = 'samples/images/blue_square.png';
$spreadsheet = new Spreadsheet();
$sheet1 = $spreadsheet->getActiveSheet();
$sheet1->setTitle('sheet1');
$sheet2 = $spreadsheet->createSheet();
$sheet2->setTitle('sheet2');
$drawing = new Drawing();
$drawing->setWorksheet($sheet1);
$drawing->setName('Blue Square');
$drawing->setPath($path);
$drawing->setCoordinates('E1');
$drawing->setCoordinates2('F5');
$hyperlink = new Hyperlink('sheet://sheet2!C3', 'Click here');
$drawing->setHyperlink($hyperlink);
$writer = new XlsxWriter($spreadsheet);
$this->outputFile = File::temporaryFilename();
$writer->save($this->outputFile);
$spreadsheet->disconnectWorksheets();
$file = 'zip://';
$file .= $this->outputFile;
$file .= '#xl/drawings/_rels/drawing1.xml.rels';
$data = file_get_contents($file);
self::assertNotFalse($data);
self::assertStringContainsString('<Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink" Target="#sheet2!C3"/>', $data, 'url changed by write');
$reader = new XlsxReader();
$reloadedSpreadsheet = $reader->load($this->outputFile);
$rsheet1 = $reloadedSpreadsheet->getSheetByName('sheet1');
self::assertNotNull($rsheet1);
$drawings = $rsheet1->getDrawingCollection();
self::assertCount(1, $drawings);
$drawing0 = $drawings[0];
self::assertSame('sheet://sheet2!C3', $drawing0?->getHyperlink()?->getUrl(), 'url was changed back on read');
$reloadedSpreadsheet->disconnectWorksheets();
}
}