Merge pull request #1894 from PHPOffice/Writer-Cleanup-Parsing-Defined-Names

Refactoring and Clean-up of Xlsx/Xls Writer Defined Names quick-fix
This commit is contained in:
Adrien Crivelli 2021-03-28 20:42:23 +09:00 committed by GitHub
commit aff1d35e4a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 56 additions and 51 deletions

View File

@ -69,58 +69,13 @@ class DefinedNames
$this->objWriter->startElement('definedName');
$this->objWriter->writeAttribute('name', $pDefinedName->getName());
if ($pDefinedName->getLocalOnly() && $pDefinedName->getScope() !== null) {
$this->objWriter->writeAttribute('localSheetId', $pDefinedName->getScope()->getParent()->getIndex($pDefinedName->getScope()));
}
$definedRange = $pDefinedName->getValue();
$splitCount = preg_match_all(
'/' . Calculation::CALCULATION_REGEXP_CELLREF_RELATIVE . '/mui',
$definedRange,
$splitRanges,
PREG_OFFSET_CAPTURE
$this->objWriter->writeAttribute(
'localSheetId',
$pDefinedName->getScope()->getParent()->getIndex($pDefinedName->getScope())
);
$lengths = array_map('strlen', array_column($splitRanges[0], 0));
$offsets = array_column($splitRanges[0], 1);
$worksheets = $splitRanges[2];
$columns = $splitRanges[6];
$rows = $splitRanges[7];
while ($splitCount > 0) {
--$splitCount;
$length = $lengths[$splitCount];
$offset = $offsets[$splitCount];
$worksheet = $worksheets[$splitCount][0];
$column = $columns[$splitCount][0];
$row = $rows[$splitCount][0];
$newRange = '';
if (empty($worksheet)) {
if (($offset === 0) || ($definedRange[$offset - 1] !== ':')) {
// We should have a worksheet
$worksheet = $pDefinedName->getWorksheet() ? $pDefinedName->getWorksheet()->getTitle() : null;
}
} else {
$worksheet = str_replace("''", "'", trim($worksheet, "'"));
}
if (!empty($worksheet)) {
$newRange = "'" . str_replace("'", "''", $worksheet) . "'!";
}
if (!empty($column)) {
$newRange .= $column;
}
if (!empty($row)) {
$newRange .= $row;
}
$definedRange = substr($definedRange, 0, $offset) . $newRange . substr($definedRange, $offset + $length);
}
if (substr($definedRange, 0, 1) === '=') {
$definedRange = substr($definedRange, 1);
}
$definedRange = $this->getDefinedRange($pDefinedName);
$this->objWriter->writeRawData($definedRange);
@ -144,7 +99,7 @@ class DefinedNames
$range = Coordinate::splitRange($autoFilterRange);
$range = $range[0];
// Strip any worksheet ref so we can make the cell ref absolute
[$ws, $range[0]] = Worksheet::extractSheetTitle($range[0], true);
[, $range[0]] = Worksheet::extractSheetTitle($range[0], true);
$range[0] = Coordinate::absoluteCoordinate($range[0]);
$range[1] = Coordinate::absoluteCoordinate($range[1]);
@ -220,4 +175,54 @@ class DefinedNames
$this->objWriter->endElement();
}
}
private function getDefinedRange(DefinedName $pDefinedName): string
{
$definedRange = $pDefinedName->getValue();
$splitCount = preg_match_all(
'/' . Calculation::CALCULATION_REGEXP_CELLREF_RELATIVE . '/mui',
$definedRange,
$splitRanges,
PREG_OFFSET_CAPTURE
);
$lengths = array_map('strlen', array_column($splitRanges[0], 0));
$offsets = array_column($splitRanges[0], 1);
$worksheets = $splitRanges[2];
$columns = $splitRanges[6];
$rows = $splitRanges[7];
while ($splitCount > 0) {
--$splitCount;
$length = $lengths[$splitCount];
$offset = $offsets[$splitCount];
$worksheet = $worksheets[$splitCount][0];
$column = $columns[$splitCount][0];
$row = $rows[$splitCount][0];
$newRange = '';
if (empty($worksheet)) {
if (($offset === 0) || ($definedRange[$offset - 1] !== ':')) {
// We should have a worksheet
$worksheet = $pDefinedName->getWorksheet() ? $pDefinedName->getWorksheet()->getTitle() : null;
}
} else {
$worksheet = str_replace("''", "'", trim($worksheet, "'"));
}
if (!empty($worksheet)) {
$newRange = "'" . str_replace("'", "''", $worksheet) . "'!";
}
$newRange = "{$newRange}{$column}{$row}";
$definedRange = substr($definedRange, 0, $offset) . $newRange . substr($definedRange, $offset + $length);
}
if (substr($definedRange, 0, 1) === '=') {
$definedRange = substr($definedRange, 1);
}
return $definedRange;
}
}