Differences Between: [Versions 311 and 400] [Versions 311 and 401] [Versions 311 and 402] [Versions 311 and 403]
1 <?php 2 3 namespace PhpOffice\PhpSpreadsheet\Writer\Ods; 4 5 use PhpOffice\PhpSpreadsheet\Calculation\Calculation; 6 use PhpOffice\PhpSpreadsheet\DefinedName; 7 use PhpOffice\PhpSpreadsheet\Shared\XMLWriter; 8 use PhpOffice\PhpSpreadsheet\Spreadsheet; 9 use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; 10 11 class NamedExpressions 12 { 13 private $objWriter; 14 15 private $spreadsheet; 16 17 private $formulaConvertor; 18 19 public function __construct(XMLWriter $objWriter, Spreadsheet $spreadsheet, $formulaConvertor) 20 { 21 $this->objWriter = $objWriter; 22 $this->spreadsheet = $spreadsheet; 23 $this->formulaConvertor = $formulaConvertor; 24 } 25 26 public function write(): void 27 { 28 $this->objWriter->startElement('table:named-expressions'); 29 $this->writeExpressions(); 30 $this->objWriter->endElement(); 31 } 32 33 private function writeExpressions(): void 34 { 35 $definedNames = $this->spreadsheet->getDefinedNames(); 36 37 foreach ($definedNames as $definedName) { 38 if ($definedName->isFormula()) { 39 $this->objWriter->startElement('table:named-expression'); 40 $this->writeNamedFormula($definedName, $this->spreadsheet->getActiveSheet()); 41 } else { 42 $this->objWriter->startElement('table:named-range'); 43 $this->writeNamedRange($definedName); 44 } 45 46 $this->objWriter->endElement(); 47 } 48 } 49 50 private function writeNamedFormula(DefinedName $definedName, Worksheet $defaultWorksheet): void 51 { 52 $this->objWriter->writeAttribute('table:name', $definedName->getName()); 53 $this->objWriter->writeAttribute( 54 'table:expression', 55 $this->formulaConvertor->convertFormula($definedName->getValue(), $definedName->getWorksheet()->getTitle()) 56 ); 57 $this->objWriter->writeAttribute('table:base-cell-address', $this->convertAddress( 58 $definedName, 59 "'" . (($definedName->getWorksheet() !== null) ? $definedName->getWorksheet()->getTitle() : $defaultWorksheet->getTitle()) . "'!\$A\$1" 60 )); 61 } 62 63 private function writeNamedRange(DefinedName $definedName): void 64 { 65 $this->objWriter->writeAttribute('table:name', $definedName->getName()); 66 $this->objWriter->writeAttribute('table:base-cell-address', $this->convertAddress( 67 $definedName, 68 "'" . $definedName->getWorksheet()->getTitle() . "'!\$A\$1" 69 )); 70 $this->objWriter->writeAttribute('table:cell-range-address', $this->convertAddress($definedName, $definedName->getValue())); 71 } 72 73 private function convertAddress(DefinedName $definedName, string $address): string 74 { 75 $splitCount = preg_match_all( 76 '/' . Calculation::CALCULATION_REGEXP_CELLREF_RELATIVE . '/mui', 77 $address, 78 $splitRanges, 79 PREG_OFFSET_CAPTURE 80 ); 81 82 $lengths = array_map('strlen', array_column($splitRanges[0], 0)); 83 $offsets = array_column($splitRanges[0], 1); 84 85 $worksheets = $splitRanges[2]; 86 $columns = $splitRanges[6]; 87 $rows = $splitRanges[7]; 88 89 while ($splitCount > 0) { 90 --$splitCount; 91 $length = $lengths[$splitCount]; 92 $offset = $offsets[$splitCount]; 93 $worksheet = $worksheets[$splitCount][0]; 94 $column = $columns[$splitCount][0]; 95 $row = $rows[$splitCount][0]; 96 97 $newRange = ''; 98 if (empty($worksheet)) { 99 if (($offset === 0) || ($address[$offset - 1] !== ':')) { 100 // We need a worksheet 101 $worksheet = $definedName->getWorksheet()->getTitle(); 102 } 103 } else { 104 $worksheet = str_replace("''", "'", trim($worksheet, "'")); 105 } 106 if (!empty($worksheet)) { 107 $newRange = "'" . str_replace("'", "''", $worksheet) . "'."; 108 } 109 110 if (!empty($column)) { 111 $newRange .= $column; 112 } 113 if (!empty($row)) { 114 $newRange .= $row; 115 } 116 117 $address = substr($address, 0, $offset) . $newRange . substr($address, $offset + $length); 118 } 119 120 if (substr($address, 0, 1) === '=') { 121 $address = substr($address, 1); 122 } 123 124 return $address; 125 } 126 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body