Skip to content

Commit 5d88c6b

Browse files
author
Mark Baker
authored
Merge branch 'master' into Issue-2551_Enable-Array-Readiness-for-Functions-Maths
2 parents 75213f5 + 0eeba6d commit 5d88c6b

File tree

10 files changed

+117
-7
lines changed

10 files changed

+117
-7
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org).
77

88
## Unreleased - TBD
99

10+
- Fixed `ReferenceHelper@insertNewBefore` behavior when removing column before last column with null value
11+
1012
### Added
1113

1214
- Improved support for passing of array arguments to Excel function implementations to return array results (where appropriate). [Issue #2551](https://github.com/PHPOffice/PhpSpreadsheet/issues/2551)

samples/Basic/02_Types.php

+6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<?php
22

3+
use PhpOffice\PhpSpreadsheet\Cell\DataType;
34
use PhpOffice\PhpSpreadsheet\RichText\RichText;
45
use PhpOffice\PhpSpreadsheet\Shared\Date;
56
use PhpOffice\PhpSpreadsheet\Spreadsheet;
@@ -144,6 +145,11 @@
144145
$spreadsheet->getActiveSheet()
145146
->setCellValue('C18', '=HYPERLINK("mailto:[email protected]","[email protected]")');
146147

148+
$spreadsheet->getActiveSheet()
149+
->setCellValue('A20', 'String')
150+
->setCellValue('B20', 'inline')
151+
->setCellValueExplicit('C20', 'This will not be added to sharedStrings.xml', DataType::TYPE_INLINE);
152+
147153
$spreadsheet->getActiveSheet()
148154
->getColumnDimension('B')
149155
->setAutoSize(true);

src/PhpSpreadsheet/Reader/Xlsx.php

+10-6
Original file line numberDiff line numberDiff line change
@@ -1691,13 +1691,17 @@ private function parseRichText(?SimpleXMLElement $is)
16911691
} else {
16921692
$objText = $value->createTextRun(StringHelper::controlCharacterOOXML2PHP((string) $run->t));
16931693

1694-
$attr = $run->rPr->rFont->attributes();
1695-
if (isset($attr['val'])) {
1696-
$objText->getFont()->setName((string) $attr['val']);
1694+
if (isset($run->rPr->rFont)) {
1695+
$attr = $run->rPr->rFont->attributes();
1696+
if (isset($attr['val'])) {
1697+
$objText->getFont()->setName((string) $attr['val']);
1698+
}
16971699
}
1698-
$attr = $run->rPr->sz->attributes();
1699-
if (isset($attr['val'])) {
1700-
$objText->getFont()->setSize((float) $attr['val']);
1700+
if (isset($run->rPr->sz)) {
1701+
$attr = $run->rPr->sz->attributes();
1702+
if (isset($attr['val'])) {
1703+
$objText->getFont()->setSize((float) $attr['val']);
1704+
}
17011705
}
17021706
if (isset($run->rPr->color)) {
17031707
$objText->getFont()->setColor(new Color($this->styleReader->readColor($run->rPr->color)));

src/PhpSpreadsheet/ReferenceHelper.php

+20
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,26 @@ public function insertNewBefore($beforeCellAddress, $numberOfColumns, $numberOfR
398398
}
399399
}
400400

401+
// Find missing coordinates. This is important when inserting column before the last column
402+
$missingCoordinates = array_filter(
403+
array_map(function ($row) use ($highestColumn) {
404+
return $highestColumn . $row;
405+
}, range(1, $highestRow)),
406+
function ($coordinate) use ($allCoordinates) {
407+
return !in_array($coordinate, $allCoordinates);
408+
}
409+
);
410+
411+
// Create missing cells with null values
412+
if (!empty($missingCoordinates)) {
413+
foreach ($missingCoordinates as $coordinate) {
414+
$worksheet->createNewCell($coordinate);
415+
}
416+
417+
// Refresh all coordinates
418+
$allCoordinates = $worksheet->getCoordinates();
419+
}
420+
401421
// Loop through cells, bottom-up, and change cell coordinate
402422
if ($remove) {
403423
// It's faster to reverse and pop than to use unshift, especially with large cell collections

src/PhpSpreadsheet/Worksheet/Worksheet.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -1291,7 +1291,7 @@ public function getCellByColumnAndRow($columnIndex, $row): Cell
12911291
*
12921292
* @return Cell Cell that was created
12931293
*/
1294-
private function createNewCell($coordinate)
1294+
public function createNewCell($coordinate)
12951295
{
12961296
$cell = new Cell(null, DataType::TYPE_NULL, $this);
12971297
$this->cellCollection->add($coordinate, $cell);

src/PhpSpreadsheet/Writer/Xls/Worksheet.php

+1
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,7 @@ public function close(): void
433433
} else {
434434
switch ($cell->getDatatype()) {
435435
case DataType::TYPE_STRING:
436+
case DataType::TYPE_INLINE:
436437
case DataType::TYPE_NULL:
437438
if ($cVal === '' || $cVal === null) {
438439
$this->writeBlank($row, $column, $xfIndex);

src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php

+2
Original file line numberDiff line numberDiff line change
@@ -1189,10 +1189,12 @@ private function writeCellInlineStr(XMLWriter $objWriter, string $mappedType, $c
11891189
{
11901190
$objWriter->writeAttribute('t', $mappedType);
11911191
if (!$cellValue instanceof RichText) {
1192+
$objWriter->startElement('is');
11921193
$objWriter->writeElement(
11931194
't',
11941195
StringHelper::controlCharacterPHP2OOXML(htmlspecialchars($cellValue, Settings::htmlEntityFlags()))
11951196
);
1197+
$objWriter->endElement();
11961198
} elseif ($cellValue instanceof RichText) {
11971199
$objWriter->startElement('is');
11981200
$this->getParentWriter()->getWriterPartstringtable()->writeRichText($objWriter, $cellValue);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
3+
namespace PhpOffice\PhpSpreadsheetTests\Reader\Xlsx;
4+
5+
use PhpOffice\PhpSpreadsheet\Reader\Xlsx;
6+
use PhpOffice\PhpSpreadsheet\RichText\RichText;
7+
use PHPUnit\Framework\TestCase;
8+
9+
class Issue2542Test extends TestCase
10+
{
11+
/**
12+
* @var string
13+
*/
14+
private static $testbook = 'tests/data/Reader/XLSX/issue.2542.xlsx';
15+
16+
public function testPreliminaries(): void
17+
{
18+
// Rich text without 'sz' tag
19+
$file = 'zip://';
20+
$file .= self::$testbook;
21+
$file .= '#xl/sharedStrings.xml';
22+
$data = file_get_contents($file);
23+
24+
// confirm that file contains expected namespaced xml tag
25+
if ($data === false) {
26+
self::fail('Unable to read file sharedStrings.xml');
27+
} else {
28+
self::assertStringContainsString('<si><r><rPr><rFont val="Arial"/><b/><color theme="1"/></rPr><t xml:space="preserve">Factor group
29+
</t></r><r><rPr><rFont val="Arial"/><b val="0"/><color theme="1"/></rPr><t>(for Rental items only)</t></r></si>', $data);
30+
}
31+
}
32+
33+
public function testIssue2542(): void
34+
{
35+
$filename = self::$testbook;
36+
$reader = new Xlsx();
37+
$spreadsheet = $reader->load($filename);
38+
$sheet = $spreadsheet->getActiveSheet();
39+
$value = $sheet->getCell('P1')->getValue();
40+
if ($value instanceof RichText) {
41+
self::assertSame("Factor group\n(for Rental items only)", $value->getPlainText());
42+
} else {
43+
self::fail('Cell P1 is not RichText');
44+
}
45+
$spreadsheet->disconnectWorksheets();
46+
}
47+
}

tests/PhpSpreadsheetTests/ReferenceHelperTest.php

+28
Original file line numberDiff line numberDiff line change
@@ -149,4 +149,32 @@ public function testInsertNewBeforeRetainDataType(): void
149149
self::assertSame($oldValue, $newValue);
150150
self::assertSame($oldDataType, $newDataType);
151151
}
152+
153+
public function testRemoveColumnShiftsCorrectColumnValueIntoRemovedColumnCoordinates(): void
154+
{
155+
$spreadsheet = new Spreadsheet();
156+
$sheet = $spreadsheet->getActiveSheet();
157+
$sheet->fromArray([
158+
['a1', 'b1', 'c1'],
159+
['a2', 'b2', null],
160+
]);
161+
162+
$cells = $sheet->toArray();
163+
self::assertSame('a1', $cells[0][0]);
164+
self::assertSame('b1', $cells[0][1]);
165+
self::assertSame('c1', $cells[0][2]);
166+
self::assertSame('a2', $cells[1][0]);
167+
self::assertSame('b2', $cells[1][1]);
168+
self::assertNull($cells[1][2]);
169+
170+
$sheet->removeColumn('B');
171+
172+
$cells = $sheet->toArray();
173+
self::assertSame('a1', $cells[0][0]);
174+
self::assertSame('c1', $cells[0][1]);
175+
self::assertArrayNotHasKey(2, $cells[0]);
176+
self::assertSame('a2', $cells[1][0]);
177+
self::assertNull($cells[1][1]);
178+
self::assertArrayNotHasKey(2, $cells[1]);
179+
}
152180
}
15.2 KB
Binary file not shown.

0 commit comments

Comments
 (0)