Skip to content

Commit b661d31

Browse files
authored
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
1 parent 7f0ca40 commit b661d31

File tree

3 files changed

+56
-6
lines changed

3 files changed

+56
-6
lines changed

src/PhpSpreadsheet/Reader/Xlsx/Chart.php

+14-6
Original file line numberDiff line numberDiff line change
@@ -396,12 +396,20 @@ private function chartTitle(SimpleXMLElement $titleDetails): Title
396396
foreach ($titleDetails as $titleDetailKey => $chartDetail) {
397397
switch ($titleDetailKey) {
398398
case 'tx':
399-
$titleDetails = $chartDetail->rich->children($this->aNamespace);
400-
foreach ($titleDetails as $titleKey => $titleDetail) {
401-
switch ($titleKey) {
402-
case 'p':
403-
$titleDetailPart = $titleDetail->children($this->aNamespace);
404-
$caption[] = $this->parseRichText($titleDetailPart);
399+
if (isset($chartDetail->rich)) {
400+
$titleDetails = $chartDetail->rich->children($this->aNamespace);
401+
foreach ($titleDetails as $titleKey => $titleDetail) {
402+
switch ($titleKey) {
403+
case 'p':
404+
$titleDetailPart = $titleDetail->children($this->aNamespace);
405+
$caption[] = $this->parseRichText($titleDetailPart);
406+
}
407+
}
408+
} elseif (isset($chartDetail->strRef->strCache)) {
409+
foreach ($chartDetail->strRef->strCache->pt as $pt) {
410+
if (isset($pt->v)) {
411+
$caption[] = (string) $pt->v;
412+
}
405413
}
406414
}
407415

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
namespace PhpOffice\PhpSpreadsheetTests\Chart;
4+
5+
use PhpOffice\PhpSpreadsheet\Reader\Xlsx as XlsxReader;
6+
use PHPUnit\Framework\TestCase;
7+
8+
class Issue2965Test extends TestCase
9+
{
10+
private const DIRECTORY = 'tests' . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'Reader' . DIRECTORY_SEPARATOR . 'XLSX' . DIRECTORY_SEPARATOR;
11+
12+
public function testPreliminaries(): void
13+
{
14+
$file = 'zip://';
15+
$file .= self::DIRECTORY . 'issue.2965.xlsx';
16+
$file .= '#xl/charts/chart1.xml';
17+
$data = file_get_contents($file);
18+
// confirm that file contains expected namespaced xml tag
19+
if ($data === false) {
20+
self::fail('Unable to read file');
21+
} else {
22+
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);
23+
}
24+
}
25+
26+
public function testChartTitleFormula(): void
27+
{
28+
$reader = new XlsxReader();
29+
$reader->setIncludeCharts(true);
30+
$spreadsheet = $reader->load(self::DIRECTORY . 'issue.2965.xlsx');
31+
$worksheet = $spreadsheet->getActiveSheet();
32+
$charts = $worksheet->getChartCollection();
33+
self::assertCount(1, $charts);
34+
$originalChart1 = $charts[0];
35+
self::assertNotNull($originalChart1);
36+
$originalTitle1 = $originalChart1->getTitle();
37+
self::assertNotNull($originalTitle1);
38+
self::assertSame('NewTitle', $originalTitle1->getCaptionText());
39+
40+
$spreadsheet->disconnectWorksheets();
41+
}
42+
}
13.2 KB
Binary file not shown.

0 commit comments

Comments
 (0)