| 1 |
<?php |
| 2 |
|
| 3 |
namespace TablePress\PhpOffice\PhpSpreadsheet\Reader\Ods; |
| 4 |
|
| 5 |
use DOMElement; |
| 6 |
use TablePress\PhpOffice\PhpSpreadsheet\DefinedName; |
| 7 |
use TablePress\PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; |
| 8 |
|
| 9 |
class DefinedNames extends BaseLoader |
| 10 |
{ |
| 11 |
public function read(DOMElement $workbookData): void |
| 12 |
{ |
| 13 |
$this->readDefinedRanges($workbookData); |
| 14 |
$this->readDefinedExpressions($workbookData); |
| 15 |
} |
| 16 |
|
| 17 |
/** |
| 18 |
* Read any Named Ranges that are defined in this spreadsheet. |
| 19 |
*/ |
| 20 |
protected function readDefinedRanges(DOMElement $workbookData): void |
| 21 |
{ |
| 22 |
$namedRanges = $workbookData->getElementsByTagNameNS($this->tableNs, 'named-range'); |
| 23 |
foreach ($namedRanges as $definedNameElement) { |
| 24 |
$definedName = $definedNameElement->getAttributeNS($this->tableNs, 'name'); |
| 25 |
$baseAddress = $definedNameElement->getAttributeNS($this->tableNs, 'base-cell-address'); |
| 26 |
$range = $definedNameElement->getAttributeNS($this->tableNs, 'cell-range-address'); |
| 27 |
|
| 28 |
/** @var non-empty-string $baseAddress */ |
| 29 |
$baseAddress = FormulaTranslator::convertToExcelAddressValue($baseAddress); |
| 30 |
$range = FormulaTranslator::convertToExcelAddressValue($range); |
| 31 |
|
| 32 |
$this->addDefinedName($baseAddress, $definedName, $range); |
| 33 |
} |
| 34 |
} |
| 35 |
|
| 36 |
/** |
| 37 |
* Read any Named Formulae that are defined in this spreadsheet. |
| 38 |
*/ |
| 39 |
protected function readDefinedExpressions(DOMElement $workbookData): void |
| 40 |
{ |
| 41 |
$namedExpressions = $workbookData->getElementsByTagNameNS($this->tableNs, 'named-expression'); |
| 42 |
foreach ($namedExpressions as $definedNameElement) { |
| 43 |
$definedName = $definedNameElement->getAttributeNS($this->tableNs, 'name'); |
| 44 |
$baseAddress = $definedNameElement->getAttributeNS($this->tableNs, 'base-cell-address'); |
| 45 |
$expression = $definedNameElement->getAttributeNS($this->tableNs, 'expression'); |
| 46 |
|
| 47 |
/** @var non-empty-string $baseAddress */ |
| 48 |
$baseAddress = FormulaTranslator::convertToExcelAddressValue($baseAddress); |
| 49 |
$expression = (string) substr($expression, strpos($expression, ':=') + 1); |
| 50 |
$expression = FormulaTranslator::convertToExcelFormulaValue($expression); |
| 51 |
|
| 52 |
$this->addDefinedName($baseAddress, $definedName, $expression); |
| 53 |
} |
| 54 |
} |
| 55 |
|
| 56 |
/** |
| 57 |
* Assess scope and store the Defined Name. |
| 58 |
* |
| 59 |
* @param non-empty-string $baseAddress |
| 60 |
*/ |
| 61 |
private function addDefinedName(string $baseAddress, string $definedName, string $value): void |
| 62 |
{ |
| 63 |
[$sheetReference] = Worksheet::extractSheetTitle($baseAddress, true, true); |
| 64 |
$worksheet = $this->spreadsheet->getSheetByName($sheetReference); |
| 65 |
// Worksheet might still be null if we're only loading selected sheets rather than the full spreadsheet |
| 66 |
if ($worksheet !== null) { |
| 67 |
$this->spreadsheet->addDefinedName(DefinedName::createInstance((string) $definedName, $worksheet, $value)); |
| 68 |
} |
| 69 |
} |
| 70 |
} |
| 71 |
|