<?php
namespace PhpOffice\PhpSpreadsheet\Writer\Xlsx;
use PhpOffice\PhpSpreadsheet\Shared\XMLWriter;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Worksheet\MemoryDrawing;
use PhpOffice\PhpSpreadsheet\Writer\Exception as WriterException;
class Rels extends WriterPart
{
public function writeRelationships(Spreadsheet $spreadsheet)
{
$objWriter = null;
if ($this->getParentWriter()->getUseDiskCaching()) {
$objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
} else {
$objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
}
$objWriter->startDocument('1.0', 'UTF-8', 'yes');
$objWriter->startElement('Relationships');
$objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships');
$customPropertyList = $spreadsheet->getProperties()->getCustomProperties();
if (!empty($customPropertyList)) {
$this->writeRelationship(
$objWriter,
4,
'http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties',
'docProps/custom.xml'
);
}
$this->writeRelationship(
$objWriter,
3,
'http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties',
'docProps/app.xml'
);
$this->writeRelationship(
$objWriter,
2,
'http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties',
'docProps/core.xml'
);
$this->writeRelationship(
$objWriter,
1,
'http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument',
'xl/workbook.xml'
);
if ($spreadsheet->hasRibbon()) {
$this->writeRelationShip(
$objWriter,
5,
'http://schemas.microsoft.com/office/2006/relationships/ui/extensibility',
$spreadsheet->getRibbonXMLData('target')
);
}
$objWriter->endElement();
return $objWriter->getData();
}
public function writeWorkbookRelationships(Spreadsheet $spreadsheet)
{
$objWriter = null;
if ($this->getParentWriter()->getUseDiskCaching()) {
$objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
} else {
$objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
}
$objWriter->startDocument('1.0', 'UTF-8', 'yes');
$objWriter->startElement('Relationships');
$objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships');
$this->writeRelationship(
$objWriter,
1,
'http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles',
'styles.xml'
);
$this->writeRelationship(
$objWriter,
2,
'http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme',
'theme/theme1.xml'
);
$this->writeRelationship(
$objWriter,
3,
'http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings',
'sharedStrings.xml'
);
$sheetCount = $spreadsheet->getSheetCount();
for ($i = 0; $i < $sheetCount; ++$i) {
$this->writeRelationship(
$objWriter,
($i + 1 + 3),
'http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet',
'worksheets/sheet' . ($i + 1) . '.xml'
);
}
if ($spreadsheet->hasMacros()) {
$this->writeRelationShip(
$objWriter,
($i + 1 + 3),
'http://schemas.microsoft.com/office/2006/relationships/vbaProject',
'vbaProject.bin'
);
++$i; }
$objWriter->endElement();
return $objWriter->getData();
}
public function writeWorksheetRelationships(\PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $pWorksheet, $pWorksheetId = 1, $includeCharts = false)
{
$objWriter = null;
if ($this->getParentWriter()->getUseDiskCaching()) {
$objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
} else {
$objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
}
$objWriter->startDocument('1.0', 'UTF-8', 'yes');
$objWriter->startElement('Relationships');
$objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships');
$drawingOriginalIds = [];
$unparsedLoadedData = $pWorksheet->getParent()->getUnparsedLoadedData();
if (isset($unparsedLoadedData['sheets'][$pWorksheet->getCodeName()]['drawingOriginalIds'])) {
$drawingOriginalIds = $unparsedLoadedData['sheets'][$pWorksheet->getCodeName()]['drawingOriginalIds'];
}
if ($includeCharts) {
$charts = $pWorksheet->getChartCollection();
} else {
$charts = [];
}
if (($pWorksheet->getDrawingCollection()->count() > 0) || (count($charts) > 0) || $drawingOriginalIds) {
$rId = 1;
reset($drawingOriginalIds);
$relPath = key($drawingOriginalIds);
if (isset($drawingOriginalIds[$relPath])) {
$rId = (int) (substr($drawingOriginalIds[$relPath], 3));
}
$relPath = '../drawings/drawing' . $pWorksheetId . '.xml';
$this->writeRelationship(
$objWriter,
$rId,
'http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing',
$relPath
);
}
$i = 1;
foreach ($pWorksheet->getHyperlinkCollection() as $hyperlink) {
if (!$hyperlink->isInternal()) {
$this->writeRelationship(
$objWriter,
'_hyperlink_' . $i,
'http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink',
$hyperlink->getUrl(),
'External'
);
++$i;
}
}
$i = 1;
if (count($pWorksheet->getComments()) > 0) {
$this->writeRelationship(
$objWriter,
'_comments_vml' . $i,
'http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing',
'../drawings/vmlDrawing' . $pWorksheetId . '.vml'
);
$this->writeRelationship(
$objWriter,
'_comments' . $i,
'http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments',
'../comments' . $pWorksheetId . '.xml'
);
}
$i = 1;
if (count($pWorksheet->getHeaderFooter()->getImages()) > 0) {
$this->writeRelationship(
$objWriter,
'_headerfooter_vml' . $i,
'http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing',
'../drawings/vmlDrawingHF' . $pWorksheetId . '.vml'
);
}
$this->writeUnparsedRelationship($pWorksheet, $objWriter, 'ctrlProps', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/ctrlProp');
$this->writeUnparsedRelationship($pWorksheet, $objWriter, 'vmlDrawings', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing');
$this->writeUnparsedRelationship($pWorksheet, $objWriter, 'printerSettings', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/printerSettings');
$objWriter->endElement();
return $objWriter->getData();
}
private function writeUnparsedRelationship(\PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $pWorksheet, XMLWriter $objWriter, $relationship, $type): void
{
$unparsedLoadedData = $pWorksheet->getParent()->getUnparsedLoadedData();
if (!isset($unparsedLoadedData['sheets'][$pWorksheet->getCodeName()][$relationship])) {
return;
}
foreach ($unparsedLoadedData['sheets'][$pWorksheet->getCodeName()][$relationship] as $rId => $value) {
$this->writeRelationship(
$objWriter,
$rId,
$type,
$value['relFilePath']
);
}
}
public function writeDrawingRelationships(\PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $pWorksheet, &$chartRef, $includeCharts = false)
{
$objWriter = null;
if ($this->getParentWriter()->getUseDiskCaching()) {
$objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
} else {
$objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
}
$objWriter->startDocument('1.0', 'UTF-8', 'yes');
$objWriter->startElement('Relationships');
$objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships');
$i = 1;
$iterator = $pWorksheet->getDrawingCollection()->getIterator();
while ($iterator->valid()) {
if (
$iterator->current() instanceof \PhpOffice\PhpSpreadsheet\Worksheet\Drawing
|| $iterator->current() instanceof MemoryDrawing
) {
$drawing = $iterator->current();
$this->writeRelationship(
$objWriter,
$i,
'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image',
'../media/' . str_replace(' ', '', $drawing->getIndexedFilename())
);
$i = $this->writeDrawingHyperLink($objWriter, $drawing, $i);
}
$iterator->next();
++$i;
}
if ($includeCharts) {
$chartCount = $pWorksheet->getChartCount();
if ($chartCount > 0) {
for ($c = 0; $c < $chartCount; ++$c) {
$this->writeRelationship(
$objWriter,
$i++,
'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart',
'../charts/chart' . ++$chartRef . '.xml'
);
}
}
}
$objWriter->endElement();
return $objWriter->getData();
}
public function writeHeaderFooterDrawingRelationships(\PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $pWorksheet)
{
$objWriter = null;
if ($this->getParentWriter()->getUseDiskCaching()) {
$objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
} else {
$objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
}
$objWriter->startDocument('1.0', 'UTF-8', 'yes');
$objWriter->startElement('Relationships');
$objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships');
foreach ($pWorksheet->getHeaderFooter()->getImages() as $key => $value) {
$this->writeRelationship(
$objWriter,
$key,
'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image',
'../media/' . $value->getIndexedFilename()
);
}
$objWriter->endElement();
return $objWriter->getData();
}
private function writeRelationship(XMLWriter $objWriter, $pId, $pType, $pTarget, $pTargetMode = ''): void
{
if ($pType != '' && $pTarget != '') {
$objWriter->startElement('Relationship');
$objWriter->writeAttribute('Id', 'rId' . $pId);
$objWriter->writeAttribute('Type', $pType);
$objWriter->writeAttribute('Target', $pTarget);
if ($pTargetMode != '') {
$objWriter->writeAttribute('TargetMode', $pTargetMode);
}
$objWriter->endElement();
} else {
throw new WriterException('Invalid parameters passed.');
}
}
private function writeDrawingHyperLink($objWriter, $drawing, $i)
{
if ($drawing->getHyperlink() === null) {
return $i;
}
++$i;
$this->writeRelationship(
$objWriter,
$i,
'http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink',
$drawing->getHyperlink()->getUrl(),
$drawing->getHyperlink()->getTypeHyperlink()
);
return $i;
}
}