Differences Between: [Versions 310 and 311] [Versions 310 and 400] [Versions 310 and 401] [Versions 310 and 402] [Versions 310 and 403]
1 <?php 2 3 namespace PhpOffice\PhpSpreadsheet\Writer\Xlsx; 4 5 use PhpOffice\PhpSpreadsheet\Shared\XMLWriter; 6 use PhpOffice\PhpSpreadsheet\Spreadsheet; 7 use PhpOffice\PhpSpreadsheet\Worksheet\MemoryDrawing; 8 use PhpOffice\PhpSpreadsheet\Writer\Exception as WriterException; 9 10 class Rels extends WriterPart 11 { 12 /** 13 * Write relationships to XML format. 14 * 15 * @param Spreadsheet $spreadsheet 16 * 17 * @throws WriterException 18 * 19 * @return string XML Output 20 */ 21 public function writeRelationships(Spreadsheet $spreadsheet) 22 { 23 // Create XML writer 24 $objWriter = null; 25 if ($this->getParentWriter()->getUseDiskCaching()) { 26 $objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); 27 } else { 28 $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY); 29 } 30 31 // XML header 32 $objWriter->startDocument('1.0', 'UTF-8', 'yes'); 33 34 // Relationships 35 $objWriter->startElement('Relationships'); 36 $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships'); 37 38 $customPropertyList = $spreadsheet->getProperties()->getCustomProperties(); 39 if (!empty($customPropertyList)) { 40 // Relationship docProps/app.xml 41 $this->writeRelationship( 42 $objWriter, 43 4, 44 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties', 45 'docProps/custom.xml' 46 ); 47 } 48 49 // Relationship docProps/app.xml 50 $this->writeRelationship( 51 $objWriter, 52 3, 53 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties', 54 'docProps/app.xml' 55 ); 56 57 // Relationship docProps/core.xml 58 $this->writeRelationship( 59 $objWriter, 60 2, 61 'http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties', 62 'docProps/core.xml' 63 ); 64 65 // Relationship xl/workbook.xml 66 $this->writeRelationship( 67 $objWriter, 68 1, 69 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument', 70 'xl/workbook.xml' 71 ); 72 // a custom UI in workbook ? 73 if ($spreadsheet->hasRibbon()) { 74 $this->writeRelationShip( 75 $objWriter, 76 5, 77 'http://schemas.microsoft.com/office/2006/relationships/ui/extensibility', 78 $spreadsheet->getRibbonXMLData('target') 79 ); 80 } 81 82 $objWriter->endElement(); 83 84 return $objWriter->getData(); 85 } 86 87 /** 88 * Write workbook relationships to XML format. 89 * 90 * @param Spreadsheet $spreadsheet 91 * 92 * @throws WriterException 93 * 94 * @return string XML Output 95 */ 96 public function writeWorkbookRelationships(Spreadsheet $spreadsheet) 97 { 98 // Create XML writer 99 $objWriter = null; 100 if ($this->getParentWriter()->getUseDiskCaching()) { 101 $objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); 102 } else { 103 $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY); 104 } 105 106 // XML header 107 $objWriter->startDocument('1.0', 'UTF-8', 'yes'); 108 109 // Relationships 110 $objWriter->startElement('Relationships'); 111 $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships'); 112 113 // Relationship styles.xml 114 $this->writeRelationship( 115 $objWriter, 116 1, 117 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles', 118 'styles.xml' 119 ); 120 121 // Relationship theme/theme1.xml 122 $this->writeRelationship( 123 $objWriter, 124 2, 125 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme', 126 'theme/theme1.xml' 127 ); 128 129 // Relationship sharedStrings.xml 130 $this->writeRelationship( 131 $objWriter, 132 3, 133 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings', 134 'sharedStrings.xml' 135 ); 136 137 // Relationships with sheets 138 $sheetCount = $spreadsheet->getSheetCount(); 139 for ($i = 0; $i < $sheetCount; ++$i) { 140 $this->writeRelationship( 141 $objWriter, 142 ($i + 1 + 3), 143 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet', 144 'worksheets/sheet' . ($i + 1) . '.xml' 145 ); 146 } 147 // Relationships for vbaProject if needed 148 // id : just after the last sheet 149 if ($spreadsheet->hasMacros()) { 150 $this->writeRelationShip( 151 $objWriter, 152 ($i + 1 + 3), 153 'http://schemas.microsoft.com/office/2006/relationships/vbaProject', 154 'vbaProject.bin' 155 ); 156 ++$i; //increment i if needed for an another relation 157 } 158 159 $objWriter->endElement(); 160 161 return $objWriter->getData(); 162 } 163 164 /** 165 * Write worksheet relationships to XML format. 166 * 167 * Numbering is as follows: 168 * rId1 - Drawings 169 * rId_hyperlink_x - Hyperlinks 170 * 171 * @param \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $pWorksheet 172 * @param int $pWorksheetId 173 * @param bool $includeCharts Flag indicating if we should write charts 174 * 175 * @throws WriterException 176 * 177 * @return string XML Output 178 */ 179 public function writeWorksheetRelationships(\PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $pWorksheet, $pWorksheetId = 1, $includeCharts = false) 180 { 181 // Create XML writer 182 $objWriter = null; 183 if ($this->getParentWriter()->getUseDiskCaching()) { 184 $objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); 185 } else { 186 $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY); 187 } 188 189 // XML header 190 $objWriter->startDocument('1.0', 'UTF-8', 'yes'); 191 192 // Relationships 193 $objWriter->startElement('Relationships'); 194 $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships'); 195 196 // Write drawing relationships? 197 $d = 0; 198 $drawingOriginalIds = []; 199 $unparsedLoadedData = $pWorksheet->getParent()->getUnparsedLoadedData(); 200 if (isset($unparsedLoadedData['sheets'][$pWorksheet->getCodeName()]['drawingOriginalIds'])) { 201 $drawingOriginalIds = $unparsedLoadedData['sheets'][$pWorksheet->getCodeName()]['drawingOriginalIds']; 202 } 203 204 if ($includeCharts) { 205 $charts = $pWorksheet->getChartCollection(); 206 } else { 207 $charts = []; 208 } 209 210 if (($pWorksheet->getDrawingCollection()->count() > 0) || (count($charts) > 0) || $drawingOriginalIds) { 211 $relPath = '../drawings/drawing' . $pWorksheetId . '.xml'; 212 $rId = ++$d; 213 214 if (isset($drawingOriginalIds[$relPath])) { 215 $rId = (int) (substr($drawingOriginalIds[$relPath], 3)); 216 } 217 218 $this->writeRelationship( 219 $objWriter, 220 $rId, 221 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing', 222 $relPath 223 ); 224 } 225 226 // Write hyperlink relationships? 227 $i = 1; 228 foreach ($pWorksheet->getHyperlinkCollection() as $hyperlink) { 229 if (!$hyperlink->isInternal()) { 230 $this->writeRelationship( 231 $objWriter, 232 '_hyperlink_' . $i, 233 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink', 234 $hyperlink->getUrl(), 235 'External' 236 ); 237 238 ++$i; 239 } 240 } 241 242 // Write comments relationship? 243 $i = 1; 244 if (count($pWorksheet->getComments()) > 0) { 245 $this->writeRelationship( 246 $objWriter, 247 '_comments_vml' . $i, 248 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing', 249 '../drawings/vmlDrawing' . $pWorksheetId . '.vml' 250 ); 251 252 $this->writeRelationship( 253 $objWriter, 254 '_comments' . $i, 255 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments', 256 '../comments' . $pWorksheetId . '.xml' 257 ); 258 } 259 260 // Write header/footer relationship? 261 $i = 1; 262 if (count($pWorksheet->getHeaderFooter()->getImages()) > 0) { 263 $this->writeRelationship( 264 $objWriter, 265 '_headerfooter_vml' . $i, 266 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing', 267 '../drawings/vmlDrawingHF' . $pWorksheetId . '.vml' 268 ); 269 } 270 271 $this->writeUnparsedRelationship($pWorksheet, $objWriter, 'ctrlProps', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/ctrlProp'); 272 $this->writeUnparsedRelationship($pWorksheet, $objWriter, 'vmlDrawings', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing'); 273 $this->writeUnparsedRelationship($pWorksheet, $objWriter, 'printerSettings', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/printerSettings'); 274 275 $objWriter->endElement(); 276 277 return $objWriter->getData(); 278 } 279 280 private function writeUnparsedRelationship(\PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $pWorksheet, XMLWriter $objWriter, $relationship, $type) 281 { 282 $unparsedLoadedData = $pWorksheet->getParent()->getUnparsedLoadedData(); 283 if (!isset($unparsedLoadedData['sheets'][$pWorksheet->getCodeName()][$relationship])) { 284 return; 285 } 286 287 foreach ($unparsedLoadedData['sheets'][$pWorksheet->getCodeName()][$relationship] as $rId => $value) { 288 $this->writeRelationship( 289 $objWriter, 290 $rId, 291 $type, 292 $value['relFilePath'] 293 ); 294 } 295 } 296 297 /** 298 * Write drawing relationships to XML format. 299 * 300 * @param \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $pWorksheet 301 * @param int &$chartRef Chart ID 302 * @param bool $includeCharts Flag indicating if we should write charts 303 * 304 * @throws WriterException 305 * 306 * @return string XML Output 307 */ 308 public function writeDrawingRelationships(\PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $pWorksheet, &$chartRef, $includeCharts = false) 309 { 310 // Create XML writer 311 $objWriter = null; 312 if ($this->getParentWriter()->getUseDiskCaching()) { 313 $objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); 314 } else { 315 $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY); 316 } 317 318 // XML header 319 $objWriter->startDocument('1.0', 'UTF-8', 'yes'); 320 321 // Relationships 322 $objWriter->startElement('Relationships'); 323 $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships'); 324 325 // Loop through images and write relationships 326 $i = 1; 327 $iterator = $pWorksheet->getDrawingCollection()->getIterator(); 328 while ($iterator->valid()) { 329 if ($iterator->current() instanceof \PhpOffice\PhpSpreadsheet\Worksheet\Drawing 330 || $iterator->current() instanceof MemoryDrawing) { 331 // Write relationship for image drawing 332 /** @var \PhpOffice\PhpSpreadsheet\Worksheet\Drawing $drawing */ 333 $drawing = $iterator->current(); 334 $this->writeRelationship( 335 $objWriter, 336 $i, 337 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image', 338 '../media/' . str_replace(' ', '', $drawing->getIndexedFilename()) 339 ); 340 341 $i = $this->writeDrawingHyperLink($objWriter, $drawing, $i); 342 } 343 344 $iterator->next(); 345 ++$i; 346 } 347 348 if ($includeCharts) { 349 // Loop through charts and write relationships 350 $chartCount = $pWorksheet->getChartCount(); 351 if ($chartCount > 0) { 352 for ($c = 0; $c < $chartCount; ++$c) { 353 $this->writeRelationship( 354 $objWriter, 355 $i++, 356 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart', 357 '../charts/chart' . ++$chartRef . '.xml' 358 ); 359 } 360 } 361 } 362 363 $objWriter->endElement(); 364 365 return $objWriter->getData(); 366 } 367 368 /** 369 * Write header/footer drawing relationships to XML format. 370 * 371 * @param \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $pWorksheet 372 * 373 * @throws WriterException 374 * 375 * @return string XML Output 376 */ 377 public function writeHeaderFooterDrawingRelationships(\PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $pWorksheet) 378 { 379 // Create XML writer 380 $objWriter = null; 381 if ($this->getParentWriter()->getUseDiskCaching()) { 382 $objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); 383 } else { 384 $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY); 385 } 386 387 // XML header 388 $objWriter->startDocument('1.0', 'UTF-8', 'yes'); 389 390 // Relationships 391 $objWriter->startElement('Relationships'); 392 $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships'); 393 394 // Loop through images and write relationships 395 foreach ($pWorksheet->getHeaderFooter()->getImages() as $key => $value) { 396 // Write relationship for image drawing 397 $this->writeRelationship( 398 $objWriter, 399 $key, 400 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image', 401 '../media/' . $value->getIndexedFilename() 402 ); 403 } 404 405 $objWriter->endElement(); 406 407 return $objWriter->getData(); 408 } 409 410 /** 411 * Write Override content type. 412 * 413 * @param XMLWriter $objWriter XML Writer 414 * @param int $pId Relationship ID. rId will be prepended! 415 * @param string $pType Relationship type 416 * @param string $pTarget Relationship target 417 * @param string $pTargetMode Relationship target mode 418 * 419 * @throws WriterException 420 */ 421 private function writeRelationship(XMLWriter $objWriter, $pId, $pType, $pTarget, $pTargetMode = '') 422 { 423 if ($pType != '' && $pTarget != '') { 424 // Write relationship 425 $objWriter->startElement('Relationship'); 426 $objWriter->writeAttribute('Id', 'rId' . $pId); 427 $objWriter->writeAttribute('Type', $pType); 428 $objWriter->writeAttribute('Target', $pTarget); 429 430 if ($pTargetMode != '') { 431 $objWriter->writeAttribute('TargetMode', $pTargetMode); 432 } 433 434 $objWriter->endElement(); 435 } else { 436 throw new WriterException('Invalid parameters passed.'); 437 } 438 } 439 440 /** 441 * @param $objWriter 442 * @param \PhpOffice\PhpSpreadsheet\Worksheet\Drawing $drawing 443 * @param $i 444 * 445 * @throws WriterException 446 * 447 * @return int 448 */ 449 private function writeDrawingHyperLink($objWriter, $drawing, $i) 450 { 451 if ($drawing->getHyperlink() === null) { 452 return $i; 453 } 454 455 ++$i; 456 $this->writeRelationship( 457 $objWriter, 458 $i, 459 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink', 460 $drawing->getHyperlink()->getUrl(), 461 $drawing->getHyperlink()->getTypeHyperlink() 462 ); 463 464 return $i; 465 } 466 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body