Skip to content

Commit 5cfb7b3

Browse files
authored
Merge branch 'master' into freezeselected
2 parents 421a15a + fb79600 commit 5cfb7b3

File tree

15 files changed

+465
-112
lines changed

15 files changed

+465
-112
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ and this project adheres to [Semantic Versioning](https://semver.org).
2828
- Check if Coordinate is Inside Range [PR #3779](https://github.com/PHPOffice/PhpSpreadsheet/pull/3779)
2929
- Flipping Images [Issue #731](https://github.com/PHPOffice/PhpSpreadsheet/issues/731) [PR #3801](https://github.com/PHPOffice/PhpSpreadsheet/pull/3801)
3030
- Chart Dynamic Title and Font Properties [Issue #3797](https://github.com/PHPOffice/PhpSpreadsheet/issues/3797) [PR #3800](https://github.com/PHPOffice/PhpSpreadsheet/pull/3800)
31+
- Chart Axis Display Units and Logarithmic Scale. [Issue #3833](https://github.com/PHPOffice/PhpSpreadsheet/pull/3833) [PR #3836](https://github.com/PHPOffice/PhpSpreadsheet/pull/3836)
3132

3233
### Changed
3334

@@ -85,6 +86,7 @@ and this project adheres to [Semantic Versioning](https://semver.org).
8586
- Strip `xlfn.` and `xlws.` from Formula Translations. [Issue #3819](https://github.com/PHPOffice/PhpSpreadsheet/issues/3819) [PR #3828](https://github.com/PHPOffice/PhpSpreadsheet/pull/3828)
8687
- Recurse directories searching for font file. [Issue #2809](https://github.com/PHPOffice/PhpSpreadsheet/issues/2809) [PR #3830](https://github.com/PHPOffice/PhpSpreadsheet/pull/3830)
8788
- Reduce memory consumption of Worksheet::rangeToArray() when many empty rows are read. [Issue #3814](https://github.com/PHPOffice/PhpSpreadsheet/pull/3814) [PR #3834](https://github.com/PHPOffice/PhpSpreadsheet/pull/3834)
89+
- Reduce time used by Worksheet::rangeToArray() when many empty rows are read. [PR #3839](https://github.com/PHPOffice/PhpSpreadsheet/pull/3839)
8890

8991
## 1.29.0 - 2023-06-15
9092

samples/Chart/33_Chart_create_line_dateaxis.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,7 @@
335335
$spreadsheet->setActiveSheetIndex(1);
336336

337337
// Save Excel 2007 file
338-
$helper->write($spreadsheet, __FILE__, ['Xlsx'], true);
338+
$helper->write($spreadsheet, __FILE__, ['Xlsx'], true, resetActiveSheet: false);
339339
$spreadsheet->disconnectWorksheets();
340340

341341
function dateRange(int $nrows, Spreadsheet $wrkbk): array

samples/Chart/33_Chart_create_scatter5_trendlines.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,4 +270,4 @@
270270
$spreadsheet->setActiveSheetIndex(1);
271271

272272
// Save Excel 2007 file
273-
$helper->write($spreadsheet, __FILE__, ['Xlsx'], true);
273+
$helper->write($spreadsheet, __FILE__, ['Xlsx'], true, resetActiveSheet: false);

samples/Chart/33_Chart_create_scatter6_value_xaxis.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,4 +131,4 @@
131131
$spreadsheet->setActiveSheetIndex(1);
132132

133133
// Save Excel 2007 file
134-
$helper->write($spreadsheet, __FILE__, ['Xlsx'], true);
134+
$helper->write($spreadsheet, __FILE__, ['Xlsx'], true, resetActiveSheet: false);

src/PhpSpreadsheet/Chart/Axis.php

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ public function __construct()
4949

5050
private ?AxisText $axisText = null;
5151

52+
private ?Title $dispUnitsTitle = null;
53+
5254
/**
5355
* Axis Options.
5456
*
@@ -70,6 +72,28 @@ public function __construct()
7072
'majorTimeUnit' => self::TIME_UNIT_YEARS,
7173
'minorTimeUnit' => self::TIME_UNIT_MONTHS,
7274
'baseTimeUnit' => self::TIME_UNIT_DAYS,
75+
'logBase' => null,
76+
'dispUnitsBuiltIn' => null,
77+
];
78+
public const DISP_UNITS_HUNDREDS = 'hundreds';
79+
public const DISP_UNITS_THOUSANDS = 'thousands';
80+
public const DISP_UNITS_TEN_THOUSANDS = 'tenThousands';
81+
public const DISP_UNITS_HUNDRED_THOUSANDS = 'hundredThousands';
82+
public const DISP_UNITS_MILLIONS = 'millions';
83+
public const DISP_UNITS_TEN_MILLIONS = 'tenMillions';
84+
public const DISP_UNITS_HUNDRED_MILLIONS = 'hundredMillions';
85+
public const DISP_UNITS_BILLIONS = 'billions';
86+
public const DISP_UNITS_TRILLIONS = 'trillions';
87+
public const DISP_UNITS_BUILTIN_INT = [
88+
100 => self::DISP_UNITS_HUNDREDS,
89+
1000 => self::DISP_UNITS_THOUSANDS,
90+
10000 => self::DISP_UNITS_TEN_THOUSANDS,
91+
100000 => self::DISP_UNITS_HUNDRED_THOUSANDS,
92+
1000000 => self::DISP_UNITS_MILLIONS,
93+
10000000 => self::DISP_UNITS_TEN_MILLIONS,
94+
100000000 => self::DISP_UNITS_HUNDRED_MILLIONS,
95+
1000000000 => self::DISP_UNITS_BILLIONS,
96+
1000000000000 => self::DISP_UNITS_TRILLIONS,
7397
];
7498

7599
/**
@@ -149,7 +173,9 @@ public function setAxisOptionsProperties(
149173
?string $hidden = null,
150174
?string $baseTimeUnit = null,
151175
?string $majorTimeUnit = null,
152-
?string $minorTimeUnit = null
176+
?string $minorTimeUnit = null,
177+
null|float|int|string $logBase = null,
178+
?string $dispUnitsBuiltIn = null
153179
): void {
154180
$this->axisOptions['axis_labels'] = $axisLabels;
155181
$this->setAxisOption('horizontal_crosses_value', $horizontalCrossesValue);
@@ -166,6 +192,8 @@ public function setAxisOptionsProperties(
166192
$this->setAxisOption('baseTimeUnit', $baseTimeUnit);
167193
$this->setAxisOption('majorTimeUnit', $majorTimeUnit);
168194
$this->setAxisOption('minorTimeUnit', $minorTimeUnit);
195+
$this->setAxisOption('logBase', $logBase);
196+
$this->setAxisOption('dispUnitsBuiltIn', $dispUnitsBuiltIn);
169197
}
170198

171199
/**
@@ -317,6 +345,18 @@ public function getNoFill(): bool
317345
return $this->noFill;
318346
}
319347

348+
public function setDispUnitsTitle(?Title $dispUnitsTitle): self
349+
{
350+
$this->dispUnitsTitle = $dispUnitsTitle;
351+
352+
return $this;
353+
}
354+
355+
public function getDispUnitsTitle(): ?Title
356+
{
357+
return $this->dispUnitsTitle;
358+
}
359+
320360
/**
321361
* Implement PHP __clone to create a deep clone, not just a shallow copy.
322362
*/
@@ -326,6 +366,7 @@ public function __clone()
326366
$this->majorGridlines = ($this->majorGridlines === null) ? null : clone $this->majorGridlines;
327367
$this->majorGridlines = ($this->minorGridlines === null) ? null : clone $this->minorGridlines;
328368
$this->axisText = ($this->axisText === null) ? null : clone $this->axisText;
369+
$this->dispUnitsTitle = ($this->dispUnitsTitle === null) ? null : clone $this->dispUnitsTitle;
329370
$this->fillColor = clone $this->fillColor;
330371
}
331372
}

src/PhpSpreadsheet/Chart/Title.php

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ class Title
1616
/**
1717
* Title Caption.
1818
*
19-
* @var array|RichText|string
19+
* @var null|array|RichText|string may be null
2020
*/
2121
private $caption = '';
2222

@@ -39,7 +39,7 @@ class Title
3939
/**
4040
* Create a new Title.
4141
*
42-
* @param array|RichText|string $caption
42+
* @param null|array|RichText|string $caption may be null
4343
* @param bool $overlay
4444
*/
4545
public function __construct($caption = '', ?Layout $layout = null, $overlay = false)
@@ -52,7 +52,7 @@ public function __construct($caption = '', ?Layout $layout = null, $overlay = fa
5252
/**
5353
* Get caption.
5454
*
55-
* @return array|RichText|string
55+
* @return null|array|RichText|string may be null
5656
*/
5757
public function getCaption()
5858
{
@@ -68,6 +68,9 @@ public function getCaptionText(?Spreadsheet $spreadsheet = null): string
6868
}
6969
}
7070
$caption = $this->caption;
71+
if ($caption === null) {
72+
return '';
73+
}
7174
if (is_string($caption)) {
7275
return $caption;
7376
}
@@ -91,7 +94,7 @@ public function getCaptionText(?Spreadsheet $spreadsheet = null): string
9194
/**
9295
* Set caption.
9396
*
94-
* @param array|RichText|string $caption
97+
* @param null|array|RichText|string $caption may be null
9598
*
9699
* @return $this
97100
*/

src/PhpSpreadsheet/Collection/Cells.php

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,18 @@ public function getSortedCoordinates(): array
144144
return array_keys($this->index);
145145
}
146146

147+
/**
148+
* Get a sorted list of all cell coordinates currently held in the collection by index (16384*row+column).
149+
*
150+
* @return int[]
151+
*/
152+
public function getSortedCoordinatesInt(): array
153+
{
154+
asort($this->index);
155+
156+
return array_values($this->index);
157+
}
158+
147159
/**
148160
* Return the cell coordinate of the currently active cell object.
149161
*
@@ -188,9 +200,9 @@ public function getHighestRowAndColumn(): array
188200
// Lookup highest column and highest row
189201
$maxRow = $maxColumn = 1;
190202
foreach ($this->index as $coordinate) {
191-
$row = (int) floor($coordinate / self::MAX_COLUMN_ID) + 1;
203+
$row = (int) floor(($coordinate - 1) / self::MAX_COLUMN_ID) + 1;
192204
$maxRow = ($maxRow > $row) ? $maxRow : $row;
193-
$column = $coordinate % self::MAX_COLUMN_ID;
205+
$column = ($coordinate % self::MAX_COLUMN_ID) ?: self::MAX_COLUMN_ID;
194206
$maxColumn = ($maxColumn > $column) ? $maxColumn : $column;
195207
}
196208

@@ -226,7 +238,7 @@ public function getHighestColumn($row = null)
226238
if ($coordinate < $fromRow || $coordinate >= $toRow) {
227239
continue;
228240
}
229-
$column = $coordinate % self::MAX_COLUMN_ID;
241+
$column = ($coordinate % self::MAX_COLUMN_ID) ?: self::MAX_COLUMN_ID;
230242
$maxColumn = $maxColumn > $column ? $maxColumn : $column;
231243
}
232244

src/PhpSpreadsheet/Helper/Sample.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,13 +111,14 @@ public function getSamples(): array
111111
/**
112112
* Write documents.
113113
*
114-
* @param string $filename
115114
* @param string[] $writers
116115
*/
117-
public function write(Spreadsheet $spreadsheet, $filename, array $writers = ['Xlsx', 'Xls'], bool $withCharts = false, ?callable $writerCallback = null): void
116+
public function write(Spreadsheet $spreadsheet, string $filename, array $writers = ['Xlsx', 'Xls'], bool $withCharts = false, ?callable $writerCallback = null, bool $resetActiveSheet = true): void
118117
{
119118
// Set active sheet index to the first sheet, so Excel opens this as the first sheet
120-
$spreadsheet->setActiveSheetIndex(0);
119+
if ($resetActiveSheet) {
120+
$spreadsheet->setActiveSheetIndex(0);
121+
}
121122

122123
// Write documents
123124
foreach ($writers as $writerType) {

src/PhpSpreadsheet/Reader/Xlsx/Chart.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -494,7 +494,7 @@ public function readChart(SimpleXMLElement $chartElements, $chartName): \PhpOffi
494494

495495
private function chartTitle(SimpleXMLElement $titleDetails): Title
496496
{
497-
$caption = [];
497+
$caption = null;
498498
$titleLayout = null;
499499
$titleOverlay = false;
500500
$titleFormula = null;
@@ -503,6 +503,7 @@ private function chartTitle(SimpleXMLElement $titleDetails): Title
503503
$chartDetail = Xlsx::testSimpleXml($chartDetail);
504504
switch ($titleDetailKey) {
505505
case 'tx':
506+
$caption = [];
506507
if (isset($chartDetail->rich)) {
507508
$titleDetails = $chartDetail->rich->children($this->aNamespace);
508509
foreach ($titleDetails as $titleKey => $titleDetail) {
@@ -1518,6 +1519,13 @@ private function setAxisProperties(SimpleXMLElement $chartDetail, ?Axis $whichAx
15181519
if (isset($chartDetail->crossBetween)) {
15191520
$whichAxis->setCrossBetween((string) self::getAttributeString($chartDetail->crossBetween, 'val'));
15201521
}
1522+
if (isset($chartDetail->dispUnits, $chartDetail->dispUnits->builtInUnit)) {
1523+
$whichAxis->setAxisOption('dispUnitsBuiltIn', (string) self::getAttributeString($chartDetail->dispUnits->builtInUnit, 'val'));
1524+
if (isset($chartDetail->dispUnits->dispUnitsLbl)) {
1525+
$whichAxis->setDispUnitsTitle(new Title());
1526+
// TODO parse title elements
1527+
}
1528+
}
15211529
if (isset($chartDetail->majorTickMark)) {
15221530
$whichAxis->setAxisOption('major_tick_mark', (string) self::getAttributeString($chartDetail->majorTickMark, 'val'));
15231531
}
@@ -1533,6 +1541,9 @@ private function setAxisProperties(SimpleXMLElement $chartDetail, ?Axis $whichAx
15331541
if (isset($chartDetail->crossesAt)) {
15341542
$whichAxis->setAxisOption('horizontal_crosses_value', (string) self::getAttributeString($chartDetail->crossesAt, 'val'));
15351543
}
1544+
if (isset($chartDetail->scaling->logBase)) {
1545+
$whichAxis->setAxisOption('logBase', (string) self::getAttributeString($chartDetail->scaling->logBase, 'val'));
1546+
}
15361547
if (isset($chartDetail->scaling->orientation)) {
15371548
$whichAxis->setAxisOption('orientation', (string) self::getAttributeString($chartDetail->scaling->orientation, 'val'));
15381549
}

0 commit comments

Comments
 (0)