Limited Support for Chart Titles as Formulas (#2971)

This is a start in addressing issue #2965 (and earlier issue #749). Chart Titles are usually entered as strings or Rich Text strings, and PhpSpreadsheet supports that. They can also be entered as formulas (typically a pointer to a cell with the title text), and, not only did PhpSpreadsheet not support that, it threw an exception when reading a spreadsheet that did so.

This change does:
- eliminate the exception
- set a static chart title when it can determine it from the Xml

This change does not:
- fully support dynamic titles (e.g. if you change the contents of the source cell, or delete or insert cells or rows or columns)
- permit the user to set the title to a formula
- allow the use of formulas when writing a chart title to a spreadsheet
- provide styling for titles when it has read them as a formula
This commit is contained in:
oleibman 2022-08-06 17:39:18 -07:00 committed by GitHub
parent 7f0ca404fc
commit b661d31887
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 56 additions and 6 deletions

View File

@ -396,6 +396,7 @@ class Chart
foreach ($titleDetails as $titleDetailKey => $chartDetail) { foreach ($titleDetails as $titleDetailKey => $chartDetail) {
switch ($titleDetailKey) { switch ($titleDetailKey) {
case 'tx': case 'tx':
if (isset($chartDetail->rich)) {
$titleDetails = $chartDetail->rich->children($this->aNamespace); $titleDetails = $chartDetail->rich->children($this->aNamespace);
foreach ($titleDetails as $titleKey => $titleDetail) { foreach ($titleDetails as $titleKey => $titleDetail) {
switch ($titleKey) { switch ($titleKey) {
@ -404,6 +405,13 @@ class Chart
$caption[] = $this->parseRichText($titleDetailPart); $caption[] = $this->parseRichText($titleDetailPart);
} }
} }
} elseif (isset($chartDetail->strRef->strCache)) {
foreach ($chartDetail->strRef->strCache->pt as $pt) {
if (isset($pt->v)) {
$caption[] = (string) $pt->v;
}
}
}
break; break;
case 'layout': case 'layout':

View File

@ -0,0 +1,42 @@
<?php
namespace PhpOffice\PhpSpreadsheetTests\Chart;
use PhpOffice\PhpSpreadsheet\Reader\Xlsx as XlsxReader;
use PHPUnit\Framework\TestCase;
class Issue2965Test extends TestCase
{
private const DIRECTORY = 'tests' . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'Reader' . DIRECTORY_SEPARATOR . 'XLSX' . DIRECTORY_SEPARATOR;
public function testPreliminaries(): void
{
$file = 'zip://';
$file .= self::DIRECTORY . 'issue.2965.xlsx';
$file .= '#xl/charts/chart1.xml';
$data = file_get_contents($file);
// confirm that file contains expected namespaced xml tag
if ($data === false) {
self::fail('Unable to read file');
} else {
self::assertStringContainsString('<c:title><c:tx><c:strRef><c:f>Sheet1!$A$1</c:f><c:strCache><c:ptCount val="1"/><c:pt idx="0"><c:v>NewTitle</c:v></c:pt></c:strCache></c:strRef></c:tx>', $data);
}
}
public function testChartTitleFormula(): void
{
$reader = new XlsxReader();
$reader->setIncludeCharts(true);
$spreadsheet = $reader->load(self::DIRECTORY . 'issue.2965.xlsx');
$worksheet = $spreadsheet->getActiveSheet();
$charts = $worksheet->getChartCollection();
self::assertCount(1, $charts);
$originalChart1 = $charts[0];
self::assertNotNull($originalChart1);
$originalTitle1 = $originalChart1->getTitle();
self::assertNotNull($originalTitle1);
self::assertSame('NewTitle', $originalTitle1->getCaptionText());
$spreadsheet->disconnectWorksheets();
}
}

Binary file not shown.