Skip to content

Commit ef1d6b6

Browse files
authored
Fix sheet reference (#16)
fix #15 Fix `XlsxFastEditor::getWorksheetNumber()` which was not returning the proper number in case of workbooks in which sheets have been reordered or removed.
1 parent 9434749 commit ef1d6b6

File tree

4 files changed

+24
-7
lines changed

4 files changed

+24
-7
lines changed

phpstan.neon

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,7 @@ parameters:
2727
missingCheckedExceptionInThrows: true
2828
tooWideThrowType: true
2929
implicitThrows: false
30+
ignoreErrors:
31+
- '#Only booleans are allowed in (a negated boolean|a ternary operator condition|an elseif condition|an if condition|&&|\|\|), (bool|false|int(<[0-9, max]+>)?|true|null|\|)+ given.*#'
3032
includes:
3133
- vendor/phpstan/phpstan-strict-rules/rules.neon

src/XlsxFastEditor.php

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ final class XlsxFastEditor
2727
private const CALC_CHAIN_CACHE_PATH = 'xl/calcChain.xml';
2828
private const SHARED_STRINGS_PATH = 'xl/sharedStrings.xml';
2929
private const WORKBOOK_PATH = 'xl/workbook.xml';
30+
private const WORKBOOK_RELS_PATH = 'xl/_rels/workbook.xml.rels';
3031

3132
private \ZipArchive $zip;
3233

@@ -280,9 +281,24 @@ public function getWorksheetCount(): int
280281
public function getWorksheetNumber(string $sheetName): int
281282
{
282283
$xpath = $this->getXPathFromPath(self::WORKBOOK_PATH);
283-
$sheetId = $xpath->evaluate("normalize-space(/o:workbook/o:sheets/o:sheet[@name='$sheetName'][1]/@sheetId)");
284-
if (is_string($sheetId)) {
285-
return (int)$sheetId;
284+
$xpath->registerNamespace('r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships');
285+
$rId = $xpath->evaluate("normalize-space(/o:workbook/o:sheets/o:sheet[@name='$sheetName'][1]/@r:id)");
286+
if (!is_string($rId) || $rId === '') {
287+
return -1;
288+
}
289+
290+
try {
291+
$xpath = $this->getXPathFromPath(self::WORKBOOK_RELS_PATH);
292+
$xpath->registerNamespace('pr', 'http://schemas.openxmlformats.org/package/2006/relationships');
293+
$target = $xpath->evaluate("normalize-space(/pr:Relationships/pr:Relationship[@Id='$rId'][1]/@Target)");
294+
if (is_string($target) && preg_match('/(\d+)/i', $target, $matches)) {
295+
return (int)$matches[1];
296+
}
297+
} catch (XlsxFastEditorFileFormatException $ex) { // phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedCatch
298+
}
299+
300+
if (preg_match('/(\d+)/i', $rId, $matches)) {
301+
return (int)$matches[1];
286302
}
287303
return -1;
288304
}
@@ -297,7 +313,7 @@ public function getWorksheetNumber(string $sheetName): int
297313
public function getWorksheetName(int $sheetNumber): ?string
298314
{
299315
$xpath = $this->getXPathFromPath(self::WORKBOOK_PATH);
300-
$sheetName = $xpath->evaluate("normalize-space(/o:workbook/o:sheets/o:sheet[$sheetNumber][1]/@name)");
316+
$sheetName = $xpath->evaluate("normalize-space(/o:workbook/o:sheets/o:sheet[$sheetNumber]/@name)");
301317
return is_string($sheetName) ? $sheetName : null;
302318
}
303319

tests/test.php

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
assert(XlsxFastEditor::excelDateToDateTime(44865, 1904)->format('c') === '2026-11-01T00:00:00+00:00');
2727

2828
$sheet1 = $xlsxFastEditor->getWorksheetNumber('Sheet1');
29-
assert($sheet1 === 1);
29+
assert($sheet1 === 3);
3030

3131
assert($xlsxFastEditor->deleteRow($sheet1, 5) === true);
3232

@@ -42,7 +42,6 @@
4242
assert($xlsxFastEditor->readHyperlink($sheet1, 'C3') === null);
4343

4444
$sheet2 = $xlsxFastEditor->getWorksheetNumber('Sheet2');
45-
assert($sheet2 === 2);
4645
assert($xlsxFastEditor->getWorksheetName($sheet2) === 'Sheet2');
4746

4847
assert($xlsxFastEditor->readFormula($sheet2, 'c2') === '=Sheet1!C2*2');
@@ -66,7 +65,7 @@
6665
assert($xlsxFastEditor->getLastRow($sheet1)?->number() === 4);
6766

6867
$sheet3 = $xlsxFastEditor->getWorksheetNumber('Sheet3');
69-
assert($sheet3 === 3);
68+
assert($xlsxFastEditor->getWorksheetName($sheet3) === 'Sheet3');
7069
assert($xlsxFastEditor->getHighestColumnName($sheet3) === 'G');
7170

7271
$row4 = $xlsxFastEditor->getRow($sheet1, 4);

tests/test.xlsx

97 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)