Better Support of Hyperlink Display Attribute

This attribute is written by Xlsx Writer, using the `tooltip` attribute, introduced by PR #904 in 2019. It is ignored by Excel, but may be used by Google Sheets (see issue #807). If it is used by anyone, it should be supported by Xlsx Reader, and exist as its own attribute in the `Hyperlink` class. Writer will continue to use tooltip if the new attribute isn't set.
This commit is contained in:
oleibman
2025-12-31 09:32:02 -08:00
parent 93c84c231f
commit b24daf8d8a
5 changed files with 81 additions and 7 deletions
+23
View File
@@ -14,6 +14,8 @@ class Hyperlink
*/
private string $tooltip;
private string $display = '';
/**
* Create a new Hyperlink.
*
@@ -80,6 +82,23 @@ class Hyperlink
return $this->isInternal() ? '' : 'External';
}
public function getDisplay(): string
{
return $this->display;
}
/**
* This can be displayed in cell rather than actual cell contents.
* It seems to be ignored by Excel.
* It may be used by Google Sheets.
*/
public function setDisplay(string $display): self
{
$this->display = $display;
return $this;
}
/**
* Get hash code.
*
@@ -89,7 +108,11 @@ class Hyperlink
{
return md5(
$this->url
. ','
. $this->tooltip
. ','
. $this->display
. ','
. __CLASS__
);
}
@@ -58,6 +58,10 @@ class Hyperlinks
if (isset($attributes['tooltip'])) {
$cell->getHyperlink()->setTooltip((string) $attributes['tooltip']);
}
if (isset($attributes['display'])) {
$cell->getHyperlink()->setDisplay((string) $attributes['display']);
}
}
}
}
@@ -1085,6 +1085,13 @@ class Worksheet extends WriterPart
if ($hyperlink->getTooltip() !== '') {
$objWriter->writeAttribute('tooltip', $hyperlink->getTooltip());
}
if ($hyperlink->getDisplay() !== '') {
$objWriter->writeAttribute('display', $hyperlink->getDisplay());
} elseif ($hyperlink->getTooltip() !== '') {
// Probably shouldn't do this,
// but avoids a breaking change.
// This was introduced in PR 904 in 2019.
$objWriter->writeAttribute('display', $hyperlink->getTooltip());
}
@@ -69,13 +69,18 @@ class HyperlinkTest extends TestCase
public function testGetHashCode(): void
{
$urlValue = 'https://www.example.com';
$tooltipValue = 'PhpSpreadsheet Web Site';
$initialExpectedHash = '3a8d5a682dba27276dce538c39402437';
$url1 = 'https://www.example.com';
$tooltip1 = 'PhpSpreadsheet Web Site';
$url2 = 'https://www.example.com';
$tooltip2 = 'PhpSpreadsheet Web Site';
$url3 = 'https://www.example.com';
$tooltip3 = 'PhpSpreadsheet Web Site '; // note extra space
$testInstance = new Hyperlink($urlValue, $tooltipValue);
$result = $testInstance->getHashCode();
self::assertEquals($initialExpectedHash, $result);
$hy1 = new Hyperlink($url1, $tooltip1);
$hy2 = new Hyperlink($url2, $tooltip2);
$hy3 = new Hyperlink($url3, $tooltip3);
self::assertNotSame($hy1, $hy2);
self::assertSame($hy1->getHashCode(), $hy2->getHashCode());
self::assertNotEquals($hy1->getHashCode(), $hy3->getHashCode());
}
}
@@ -95,4 +95,39 @@ class HyperlinkTest extends AbstractFunctional
$reloadedSpreadsheet->disconnectWorksheets();
}
public function testDisplay(): void
{
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$sheet->getCell('A1')->setValue('A1 text');
$hy1 = $sheet->getCell('A1')->getHyperlink();
$hy1->setUrl('http://www.example.com');
$hy1->setTooltip('Go to example.com');
$sheet->getCell('A2')->setValue('A2 text');
$hy2 = $sheet->getCell('A2')->getHyperlink();
$hy2->setUrl('http://www.example.org');
$hy2->setTooltip('Go to example.org');
$hy2->setDisplay('A2 display');
$reloadedSpreadsheet = $this->writeAndReload($spreadsheet, 'Xlsx');
$spreadsheet->disconnectWorksheets();
$rsheet = $reloadedSpreadsheet->getActiveSheet();
self::assertSame('A1 text', $rsheet->getCell('A1')->getValue());
$rhy1 = $rsheet->getCell('A1')->getHyperlink();
self::assertSame('http://www.example.com', $rhy1->getUrl());
self::assertSame('Go to example.com', $rhy1->getTooltip());
self::assertSame('Go to example.com', $rhy1->getDisplay(), 'display is set to tooltip if unset');
self::assertSame('A2 text', $rsheet->getCell('A2')->getValue());
$rhy2 = $rsheet->getCell('A2')->getHyperlink();
self::assertSame('http://www.example.org', $rhy2->getUrl());
self::assertSame('Go to example.org', $rhy2->getTooltip());
self::assertSame('A2 display', $rhy2->getDisplay(), 'display is explicitly set');
$reloadedSpreadsheet->disconnectWorksheets();
}
}