nfTlWNl rn Ѻq$³*4A8t+Sjįq;m ^*Ogص\`Lٔ*ܝIcQj Q@~DmvJ4Y Ѻq$³*AӪ}# | Z܇RsGrJsf]ZV h_zPV9ظ|4؀%$*in]UPgn&aIYurQ,%/Gna\l-<~P,ۑL_v xV8UANGziu ])V1U.mާ3wR =-f0ߗʍ(o_B=y^J%Wa1t9'|(KT?|8`xLIy%;oG7:`̦CRȺrN; "ndBcW eX], Ṿؖ qN,gGQdOP89X0YP^BmMXysP1JGJa|"#:C7Ք14B'bbL`÷_a v,t8Mw/ _&N(Cy(=.3JIqV@DUatp #cAxN!/Ep`- 0j:2rnO3>=޲& f2URL#E&zw \p dIWR$} eZ씺/w9'NP."$%G]` !V;4ͥndf@"L :Mt$rMe Q: TArALrPwb?É^ EzS7ЍT-d݄\wrZmgE5Δek*hSꐛ(tdzO|TQ_$)mR3*am /p)}ܢȚ.0nJk9ǭQ(,~͑8qk Ltc#jq9M侪0/fXpB?N!d\Oc x>peeS$!iZ9AȖCN=qKY,!8ڙ}hÔKOԜ{0 WS~x]-ЍS *S~f iko+ ۮGwd91 rNVzNhb9ruFh|ov%x%F"{XӔu`+TƀDLE[E* ڒ?LAѫ_,D/y+ĔST.MV765aW.((T: |+&sS9,T'&V0i!0$ڗ;\!->^!;*E璻kZ'>D5AĕGfXpB?N!d\|isUȌ N*gOQ1CN=qKY,!8۬hUn*=]5[3kDTK E$XXvi="Fs%Rt8A,oo݈5`V}&`@_# g~˽b; tMנÇ@w%KM&.R߷E蚾(§\[=M!Y,Hub)WA3h?Ɛ\Ev׫i7XH`FOk'*m9;4G};L}-U";Ők0Kl/@"qm#Gt#duyjCv, Z9Pc V-zr֢XFk% qpID^Ԍkܮbh iDR @jjM%.aﴷ03*LPd{R qH䦂}X$S-T k0e0qJCjo-M2`!W?œ[g'Z6ohlXt8pF#9/,,bߕ%DֹF;UB=&@;Q0( U^E{]wص<(6,rA,?<"dK/c5` 0wӤiNj@&e}H%Ayi ȱgMxڭ|6 ˆe`]|1_~r&W\5yȰ$h4W2hzYv90pȮ-(CB [,!RB_6ɿF%/ER@PDoFt2Rг`#C3?ʎyȢQh|XǓ{` oWx3l?KYuf(:E?-v)^%.´ ]iy(mۄ1BVA{WkgIìaﴷ03*LPR 7nogԱUhd7hBކs,%ǚ2 !Yd$( ^t{/d,78_tHÏp Fsa.z +B6E$V)J\O43R Aӛ;@ϛE@1fjjXྀn60PƉodF,'<툼FȰQ>p4E* ڒ?LAѫ_,D/y+ĔS^gHLa.uv7"nBx{π¬ŠE^!h?3|g.M1iJ9ӺBAzxPjd+~^5 -z ˀ?y$^ט6X10;௟*B 0@fϿ@Z{ ([2P 4yaٳeΏV iko+ aNÓʑ.[m$ј:C-T Namespaces::WORKSHEET, 'worksheets/sheet' . ($i + 1) . '.xml' ); } // Relationships for vbaProject if needed // id : just after the last sheet if ($spreadsheet->hasMacros()) { $this->writeRelationShip( $objWriter, ($i + 1 + 3), Namespaces::VBA, 'vbaProject.bin' ); ++$i; //increment i if needed for an another relation } $objWriter->endElement(); return $objWriter->getData(); } /** * Write worksheet relationships to XML format. * * Numbering is as follows: * rId1 - Drawings * rId_hyperlink_x - Hyperlinks * * @param int $worksheetId * @param bool $includeCharts Flag indicating if we should write charts * @param int $tableRef Table ID * * @return string XML Output */ public function writeWorksheetRelationships(\PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $worksheet, $worksheetId = 1, $includeCharts = false, $tableRef = 1) { // Create XML writer $objWriter = null; if ($this->getParentWriter()->getUseDiskCaching()) { $objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); } else { $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY); } // XML header $objWriter->startDocument('1.0', 'UTF-8', 'yes'); // Relationships $objWriter->startElement('Relationships'); $objWriter->writeAttribute('xmlns', Namespaces::RELATIONSHIPS); // Write drawing relationships? $drawingOriginalIds = []; $unparsedLoadedData = $worksheet->getParentOrThrow()->getUnparsedLoadedData(); if (isset($unparsedLoadedData['sheets'][$worksheet->getCodeName()]['drawingOriginalIds'])) { $drawingOriginalIds = $unparsedLoadedData['sheets'][$worksheet->getCodeName()]['drawingOriginalIds']; } if ($includeCharts) { $charts = $worksheet->getChartCollection(); } else { $charts = []; } if (($worksheet->getDrawingCollection()->count() > 0) || (count($charts) > 0) || $drawingOriginalIds) { $rId = 1; // Use original $relPath to get original $rId. // Take first. In future can be overwritten. // (! synchronize with \PhpOffice\PhpSpreadsheet\Writer\Xlsx\Worksheet::writeDrawings) reset($drawingOriginalIds); $relPath = key($drawingOriginalIds); if (isset($drawingOriginalIds[$relPath])) { $rId = (int) (substr($drawingOriginalIds[$relPath], 3)); } // Generate new $relPath to write drawing relationship $relPath = '../drawings/drawing' . $worksheetId . '.xml'; $this->writeRelationship( $objWriter, $rId, Namespaces::RELATIONSHIPS_DRAWING, $relPath ); } // Write hyperlink relationships? $i = 1; foreach ($worksheet->getHyperlinkCollection() as $hyperlink) { if (!$hyperlink->isInternal()) { $this->writeRelationship( $objWriter, '_hyperlink_' . $i, Namespaces::HYPERLINK, $hyperlink->getUrl(), 'External' ); ++$i; } } // Write comments relationship? $i = 1; if (count($worksheet->getComments()) > 0 || isset($unparsedLoadedData['sheets'][$worksheet->getCodeName()]['legacyDrawing'])) { $this->writeRelationship( $objWriter, '_comments_vml' . $i, Namespaces::VML, '../drawings/vmlDrawing' . $worksheetId . '.vml' ); } if (count($worksheet->getComments()) > 0) { $this->writeRelationship( $objWriter, '_comments' . $i, Namespaces::COMMENTS, '../comments' . $worksheetId . '.xml' ); } // Write Table $tableCount = $worksheet->getTableCollection()->count(); for ($i = 1; $i <= $tableCount; ++$i) { $this->writeRelationship( $objWriter, '_table_' . $i, Namespaces::RELATIONSHIPS_TABLE, '../tables/table' . $tableRef++ . '.xml' ); } // Write header/footer relationship? $i = 1; if (count($worksheet->getHeaderFooter()->getImages()) > 0) { $this->writeRelationship( $objWriter, '_headerfooter_vml' . $i, Namespaces::VML, '../drawings/vmlDrawingHF' . $worksheetId . '.vml' ); } $this->writeUnparsedRelationship($worksheet, $objWriter, 'ctrlProps', Namespaces::RELATIONSHIPS_CTRLPROP); $this->writeUnparsedRelationship($worksheet, $objWriter, 'vmlDrawings', Namespaces::VML); $this->writeUnparsedRelationship($worksheet, $objWriter, 'printerSettings', Namespaces::RELATIONSHIPS_PRINTER_SETTINGS); $objWriter->endElement(); return $objWriter->getData(); } private function writeUnparsedRelationship(\PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $worksheet, XMLWriter $objWriter, string $relationship, string $type): void { $unparsedLoadedData = $worksheet->getParentOrThrow()->getUnparsedLoadedData(); if (!isset($unparsedLoadedData['sheets'][$worksheet->getCodeName()][$relationship])) { return; } foreach ($unparsedLoadedData['sheets'][$worksheet->getCodeName()][$relationship] as $rId => $value) { if (substr($rId, 0, 17) !== '_headerfooter_vml') { $this->writeRelationship( $objWriter, $rId, $type, $value['relFilePath'] ); } } } /** * Write drawing relationships to XML format. * * @param int $chartRef Chart ID * @param bool $includeCharts Flag indicating if we should write charts * * @return string XML Output */ public function writeDrawingRelationships(\PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $worksheet, &$chartRef, $includeCharts = false) { // Create XML writer $objWriter = null; if ($this->getParentWriter()->getUseDiskCaching()) { $objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); } else { $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY); } // XML header $objWriter->startDocument('1.0', 'UTF-8', 'yes'); // Relationships $objWriter->startElement('Relationships'); $objWriter->writeAttribute('xmlns', Namespaces::RELATIONSHIPS); // Loop through images and write relationships $i = 1; $iterator = $worksheet->getDrawingCollection()->getIterator(); while ($iterator->valid()) { $drawing = $iterator->current(); if ( $drawing instanceof \PhpOffice\PhpSpreadsheet\Worksheet\Drawing || $drawing instanceof MemoryDrawing ) { // Write relationship for image drawing $this->writeRelationship( $objWriter, $i, Namespaces::IMAGE, '../media/' . $drawing->getIndexedFilename() ); $i = $this->writeDrawingHyperLink($objWriter, $drawing, $i); } $iterator->next(); ++$i; } if ($includeCharts) { // Loop through charts and write relationships $chartCount = $worksheet->getChartCount(); if ($chartCount > 0) { for ($c = 0; $c < $chartCount; ++$c) { $this->writeRelationship( $objWriter, $i++, Namespaces::RELATIONSHIPS_CHART, '../charts/chart' . ++$chartRef . '.xml' ); } } } $objWriter->endElement(); return $objWriter->getData(); } /** * Write header/footer drawing relationships to XML format. * * @return string XML Output */ public function writeHeaderFooterDrawingRelationships(\PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $worksheet) { // Create XML writer $objWriter = null; if ($this->getParentWriter()->getUseDiskCaching()) { $objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); } else { $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY); } // XML header $objWriter->startDocument('1.0', 'UTF-8', 'yes'); // Relationships $objWriter->startElement('Relationships'); $objWriter->writeAttribute('xmlns', Namespaces::RELATIONSHIPS); // Loop through images and write relationships foreach ($worksheet->getHeaderFooter()->getImages() as $key => $value) { // Write relationship for image drawing $this->writeRelationship( $objWriter, $key, Namespaces::IMAGE, '../media/' . $value->getIndexedFilename() ); } $objWriter->endElement(); return $objWriter->getData(); } public function writeVMLDrawingRelationships(\PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $worksheet): string { // Create XML writer $objWriter = null; if ($this->getParentWriter()->getUseDiskCaching()) { $objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); } else { $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY); } // XML header $objWriter->startDocument('1.0', 'UTF-8', 'yes'); // Relationships $objWriter->startElement('Relationships'); $objWriter->writeAttribute('xmlns', Namespaces::RELATIONSHIPS); // Loop through images and write relationships foreach ($worksheet->getComments() as $comment) { if (!$comment->hasBackgroundImage()) { continue; } $bgImage = $comment->getBackgroundImage(); $this->writeRelationship( $objWriter, $bgImage->getImageIndex(), Namespaces::IMAGE, '../media/' . $bgImage->getMediaFilename() ); } $objWriter->endElement(); return $objWriter->getData(); } /** * Write Override content type. * * @param int|string $id Relationship ID. rId will be prepended! * @param string $type Relationship type * @param string $target Relationship target * @param string $targetMode Relationship target mode */ private function writeRelationship(XMLWriter $objWriter, $id, $type, $target, $targetMode = ''): void { if ($type != '' && $target != '') { // Write relationship $objWriter->startElement('Relationship'); $objWriter->writeAttribute('Id', 'rId' . $id); $objWriter->writeAttribute('Type', $type); $objWriter->writeAttribute('Target', $target); if ($targetMode != '') { $objWriter->writeAttribute('TargetMode', $targetMode); } $objWriter->endElement(); } else { throw new WriterException('Invalid parameters passed.'); } } private function writeDrawingHyperLink(XMLWriter $objWriter, BaseDrawing $drawing, int $i): int { if ($drawing->getHyperlink() === null) { return $i; } ++$i; $this->writeRelationship( $objWriter, $i, Namespaces::HYPERLINK, $drawing->getHyperlink()->getUrl(), $drawing->getHyperlink()->getTypeHyperlink() ); return $i; } }