/** * Write part * * @return string */ public function write() { $parts = array('content.xml', 'meta.xml', 'styles.xml'); $xmlWriter = $this->getXmlWriter(); $xmlWriter->startDocument('1.0', 'UTF-8'); $xmlWriter->startElement('manifest:manifest'); $xmlWriter->writeAttribute('manifest:version', '1.2'); $xmlWriter->writeAttribute('xmlns:manifest', 'urn:oasis:names:tc:opendocument:xmlns:manifest:1.0'); $xmlWriter->startElement('manifest:file-entry'); $xmlWriter->writeAttribute('manifest:media-type', 'application/vnd.oasis.opendocument.text'); $xmlWriter->writeAttribute('manifest:full-path', '/'); $xmlWriter->writeAttribute('manifest:version', '1.2'); $xmlWriter->endElement(); // Parts foreach ($parts as $part) { $xmlWriter->startElement('manifest:file-entry'); $xmlWriter->writeAttribute('manifest:media-type', 'text/xml'); $xmlWriter->writeAttribute('manifest:full-path', $part); $xmlWriter->endElement(); } // Media files $media = Media::getElements('section'); foreach ($media as $medium) { if ($medium['type'] == 'image') { $xmlWriter->startElement('manifest:file-entry'); $xmlWriter->writeAttribute('manifest:media-type', $medium['imageType']); $xmlWriter->writeAttribute('manifest:full-path', 'Pictures/' . $medium['target']); $xmlWriter->endElement(); } } $xmlWriter->endElement(); // manifest:manifest return $xmlWriter->getData(); }
/** * Save PhpWord to file * * @param string $filename * @throws \PhpOffice\PhpWord\Exception\Exception */ public function save($filename = null) { if (!is_null($this->phpWord)) { $filename = $this->getTempFile($filename); $objZip = $this->getZipArchive($filename); // Add section media files $sectionMedia = Media::getElements('section'); if (!empty($sectionMedia)) { $this->addFilesToPackage($objZip, $sectionMedia); } // Add parts $objZip->addFromString('mimetype', $this->getWriterPart('mimetype')->writeMimetype()); $objZip->addFromString('content.xml', $this->getWriterPart('content')->writeContent($this->phpWord)); $objZip->addFromString('meta.xml', $this->getWriterPart('meta')->writeMeta($this->phpWord)); $objZip->addFromString('styles.xml', $this->getWriterPart('styles')->writeStyles($this->phpWord)); $objZip->addFromString('META-INF/manifest.xml', $this->getWriterPart('manifest')->writeManifest()); // Close file if ($objZip->close() === false) { throw new Exception("Could not close zip file {$filename}."); } $this->cleanupTempFile(); } else { throw new Exception("PhpWord object unassigned."); } }
/** * Save PhpWord to file * * @param string $filename */ public function save($filename = null) { $filename = $this->getTempFile($filename); $zip = $this->getZipArchive($filename); // Add section media files $sectionMedia = Media::getElements('section'); if (!empty($sectionMedia)) { $this->addFilesToPackage($zip, $sectionMedia); } // Write parts foreach ($this->parts as $partName => $fileName) { if ($fileName != '') { $zip->addFromString($fileName, $this->getWriterPart($partName)->write()); } } // Close zip archive and cleanup temp file $zip->close(); $this->cleanupTempFile(); }
/** * Add image element exception * * @expectedException Exception * @expectedExceptionMessage Image object not assigned. */ public function testAddElementImageException() { Media::addElement('section', 'image', __DIR__ . "/_files/images/mars.jpg"); }
/** * Add footnotes/endnotes * * @param \PhpOffice\PhpWord\Shared\ZipArchive $zip * @param integer &$rId * @param string $noteType * @return void */ private function addNotes(ZipArchive $zip, &$rId, $noteType = 'footnote') { $phpWord = $this->getPhpWord(); $noteType = $noteType == 'endnote' ? 'endnote' : 'footnote'; $partName = "{$noteType}s"; $method = 'get' . $partName; $collection = $phpWord->{$method}(); // Add footnotes media files, relations, and contents /** @var \PhpOffice\PhpWord\Collection\AbstractCollection $collection Type hint */ if ($collection->countItems() > 0) { $media = Media::getElements($noteType); $this->addFilesToPackage($zip, $media); $this->registerContentTypes($media); $this->contentTypes['override']["/word/{$partName}.xml"] = $partName; $this->relationships[] = array('target' => "{$partName}.xml", 'type' => $partName, 'rID' => ++$rId); // Write relationships file, e.g. word/_rels/footnotes.xml if (!empty($media)) { /** @var \PhpOffice\PhpWord\Writer\Word2007\Part\AbstractPart $writerPart Type hint */ $writerPart = $this->getWriterPart('relspart')->setMedia($media); $zip->addFromString("word/_rels/{$partName}.xml.rels", $writerPart->write()); } // Write content file, e.g. word/footnotes.xml $writerPart = $this->getWriterPart($partName)->setElements($collection->getItems()); $zip->addFromString("word/{$partName}.xml", $writerPart->write()); } }
/** * Set relation Id for media elements (link, image, object; legacy of OOXML) * * - Image element needs to be passed to Media object * - Icon needs to be set for Object element * * @return void */ private function setMediaRelation() { if (!$this instanceof Link && !$this instanceof Image && !$this instanceof Object) { return; } $elementName = substr(get_class($this), strrpos(get_class($this), '\\') + 1); $mediaPart = $this->getMediaPart(); $source = $this->getSource(); $image = null; if ($this instanceof Image) { $image = $this; } $rId = Media::addElement($mediaPart, strtolower($elementName), $source, $image); $this->setRelationId($rId); if ($this instanceof Object) { $icon = $this->getIcon(); $rId = Media::addElement($mediaPart, 'image', $icon, new Image($icon)); $this->setImageRelationId($rId); } }
/** * Set relation Id * * @param string $elementName * @param string $source */ private function setElementRelationId(AbstractElement $element, $elementName, $source) { $mediaContainer = $this->getMediaContainer(); $hasMediaRelation = in_array($elementName, array('Link', 'Image', 'Object')); $hasOtherRelation = in_array($elementName, array('Footnote', 'Endnote', 'Title')); // Set relation Id for media elements (link, image, object; legacy of OOXML) // Only Image that needs to be passed to Media class if ($hasMediaRelation) { /** @var \PhpOffice\PhpWord\Element\Image $element Type hint */ $image = $elementName == 'Image' ? $element : null; $rId = Media::addElement($mediaContainer, strtolower($elementName), $source, $image); $element->setRelationId($rId); } // Set relation Id for icon of object element if ($elementName == 'Object') { /** @var \PhpOffice\PhpWord\Element\Object $element Type hint */ $rIdIcon = Media::addElement($mediaContainer, 'image', $element->getIcon(), new Image($element->getIcon())); $element->setImageRelationId($rIdIcon); } // Set relation Id for elements that will be registered in the Collection subnamespaces if ($hasOtherRelation && $this->phpWord instanceof PhpWord) { $addMethod = "add{$elementName}"; $rId = $this->phpWord->{$addMethod}($element); $element->setRelationId($rId); } }
/** * Add footnotes/endnotes * * @param mixed $objZip * @param integer $rId * @param string $notesType */ private function addNotes($objZip, &$rId, $notesType = 'footnote') { $notesType = $notesType == 'endnote' ? 'endnote' : 'footnote'; $notesTypes = "{$notesType}s"; $collection = 'PhpOffice\\PhpWord\\' . ucfirst($notesTypes); $xmlFile = "{$notesTypes}.xml"; $relsFile = "word/_rels/{$xmlFile}.rels"; $xmlPath = "word/{$xmlFile}"; // Add footnotes media files, relations, and contents if ($collection::countElements() > 0) { $media = Media::getElements($notesType); $this->addFilesToPackage($objZip, $media); $this->registerContentTypes($media); if (!empty($media)) { $objZip->addFromString($relsFile, $this->getWriterPart('rels')->writeMediaRels($media)); } $elements = $collection::getElements(); $objZip->addFromString($xmlPath, $this->getWriterPart($notesTypes)->write($elements)); $this->cTypes['override']["/{$xmlPath}"] = $notesTypes; $this->docRels[] = array('target' => $xmlFile, 'type' => $notesTypes, 'rID' => ++$rId); } }
/** * Add OLE-object element * * All exceptions should be handled by \PhpOffice\PhpWord\Element\Object * * @param string $src * @param mixed $style * @return Object * @throws \PhpOffice\PhpWord\Exception\Exception * @todo Enable OLE object element in header and footer */ public function addObject($src, $style = null) { $this->checkValidity('object'); $elementDocPart = $this->checkElementDocPart(); $object = new Object($src, $style); $object->setDocPart($this->getDocPart(), $this->getDocPartId()); if (!is_null($object->getSource())) { $inf = pathinfo($src); $ext = $inf['extension']; if (strlen($ext) == 4 && strtolower(substr($ext, -1)) == 'x') { $ext = substr($ext, 0, -1); } $icon = realpath(__DIR__ . "/../resources/{$ext}.png"); $rId = Media::addElement($elementDocPart, 'object', $src); $object->setRelationId($rId); $rIdimg = Media::addElement($elementDocPart, 'image', $icon, new Image($icon)); $object->setImageRelationId($rIdimg); $this->addElement($object); return $object; } else { throw new InvalidObjectException(); } }
/** * Write automatic styles */ private function writeAutomaticStyles(XMLWriter $xmlWriter, PhpWord $phpWord) { $xmlWriter->startElement('office:automatic-styles'); // Font and paragraph $styles = Style::getStyles(); $paragraphStyleCount = 0; if (count($styles) > 0) { foreach ($styles as $styleName => $style) { if (preg_match('#^T[0-9]+$#', $styleName) != 0 || preg_match('#^P[0-9]+$#', $styleName) != 0) { $styleClass = str_replace('Style', 'Writer\\ODText\\Style', get_class($style)); if (class_exists($styleClass)) { $styleWriter = new $styleClass($xmlWriter, $style); $styleWriter->setIsAuto(true); $styleWriter->write(); } if ($style instanceof Paragraph) { $paragraphStyleCount++; } } } if ($paragraphStyleCount == 0) { $style = new Paragraph(); $style->setStyleName('P1'); $styleWriter = new \PhpOffice\PhpWord\Writer\ODText\Style\Paragraph($xmlWriter, $style); $styleWriter->setIsAuto(true); $styleWriter->write(); } } // Images $images = Media::getElements('section'); foreach ($images as $image) { if ($image['type'] == 'image') { $xmlWriter->startElement('style:style'); $xmlWriter->writeAttribute('style:name', 'fr' . $image['rID']); $xmlWriter->writeAttribute('style:family', 'graphic'); $xmlWriter->writeAttribute('style:parent-style-name', 'Graphics'); $xmlWriter->startElement('style:graphic-properties'); $xmlWriter->writeAttribute('style:vertical-pos', 'top'); $xmlWriter->writeAttribute('style:vertical-rel', 'baseline'); $xmlWriter->endElement(); $xmlWriter->endElement(); } } // Tables $sections = $phpWord->getSections(); $sectionCount = count($sections); if ($sectionCount > 0) { $sectionId = 0; foreach ($sections as $section) { $sectionId++; $elements = $section->getElements(); foreach ($elements as $element) { if ($elements instanceof Table) { $xmlWriter->startElement('style:style'); $xmlWriter->writeAttribute('style:name', $element->getElementId()); $xmlWriter->writeAttribute('style:family', 'table'); $xmlWriter->startElement('style:table-properties'); //$xmlWriter->writeAttribute('style:width', 'table'); $xmlWriter->writeAttribute('style:rel-width', 100); $xmlWriter->writeAttribute('table:align', 'center'); $xmlWriter->endElement(); $xmlWriter->endElement(); } } } } $xmlWriter->endElement(); // office:automatic-styles }