setPhpWord($phpWord); } /** * Save PhpWord to file * * @param string $filename * @throws Exception */ public function save($filename = null) { if (!is_null($this->getPhpWord())) { $this->setTempDir(sys_get_temp_dir() . '/PHPWordWriter/'); $hFile = fopen($filename, 'w') or die("can't open file"); fwrite($hFile, $this->writeDocument()); fclose($hFile); $this->clearTempDir(); } else { throw new Exception("No PHPWord assigned."); } } /** * Get phpWord data * * @return string */ public function writeDocument() { $html = ''; $html .= '' . PHP_EOL; $html .= '' . PHP_EOL; $html .= '' . PHP_EOL; $html .= '' . PHP_EOL; $html .= $this->writeHTMLHead(); $html .= '' . PHP_EOL; $html .= '' . PHP_EOL; $html .= $this->writeHTMLBody(); $html .= $this->writeNotes(); $html .= '' . PHP_EOL; $html .= '' . PHP_EOL; return $html; } /** * Generate HTML header * * @return string */ private function writeHTMLHead() { $properties = $this->getPhpWord()->getDocumentProperties(); $propertiesMapping = array( 'creator' => 'author', 'title' => '', 'description' => '', 'subject' => '', 'keywords' => '', 'category' => '', 'company' => '', 'manager' => '' ); $title = $properties->getTitle(); $title = ($title != '') ? $title : 'PHPWord'; $html = ''; $html .= '' . PHP_EOL; $html .= '' . htmlspecialchars($title) . '' . PHP_EOL; foreach ($propertiesMapping as $key => $value) { $value = ($value == '') ? $key : $value; $method = "get" . $key; if ($properties->$method() != '') { $html .= '' . PHP_EOL; } } $html .= $this->writeStyles(); return $html; } /** * Get content * * @return string */ private function writeHTMLBody() { $phpWord = $this->getPhpWord(); $html = ''; $sections = $phpWord->getSections(); $countSections = count($sections); $pSection = 0; if ($countSections > 0) { foreach ($sections as $section) { $pSection++; $contents = $section->getElements(); foreach ($contents as $element) { if ($element instanceof Text) { $html .= $this->writeText($element); } elseif ($element instanceof TextRun) { $html .= $this->writeTextRun($element); } elseif ($element instanceof Link) { $html .= $this->writeLink($element); } elseif ($element instanceof Title) { $html .= $this->writeTitle($element); } elseif ($element instanceof PreserveText) { $html .= $this->writePreserveText($element); } elseif ($element instanceof TextBreak) { $html .= $this->writeTextBreak($element); } elseif ($element instanceof PageBreak) { $html .= $this->writePageBreak($element); } elseif ($element instanceof Table) { $html .= $this->writeTable($element); } elseif ($element instanceof ListItem) { $html .= $this->writeListItem($element); } elseif ($element instanceof Image) { $html .= $this->writeImage($element); } elseif ($element instanceof Object) { $html .= $this->writeObject($element); } elseif ($element instanceof Endnote) { $html .= $this->writeEndnote($element); } elseif ($element instanceof Footnote) { $html .= $this->writeFootnote($element); } } } } return $html; } /** * Write footnote/endnote contents */ private function writeNotes() { $footnote = Footnotes::getElements(); $endnote = Endnotes::getElements(); $html = ''; if (count($this->notes) > 0) { $html .= "
"; foreach ($this->notes as $noteId => $noteMark) { $noteAnchor = "note-{$noteId}"; list($noteType, $noteTypeId) = explode('-', $noteMark); $collection = $$noteType; if (array_key_exists($noteTypeId, $collection)) { $element = $collection[$noteTypeId]; $content = "{$noteId}" . $this->writeTextRun($element, true); $html .= "

{$content}

" . PHP_EOL; } } } return $html; } /** * Get text * * @param \PhpOffice\PhpWord\Element\Text $text * @param boolean $withoutP * @return string */ private function writeText($text, $withoutP = false) { $html = ''; $paragraphStyle = $text->getParagraphStyle(); $spIsObject = ($paragraphStyle instanceof Paragraph); $fontStyle = $text->getFontStyle(); $sfIsObject = ($fontStyle instanceof Font); if ($paragraphStyle && !$withoutP) { $html .= 'writeParagraphStyle($paragraphStyle) . '"'; } $html .= '>'; } if ($fontStyle) { $html .= 'writeFontStyle($fontStyle) . '"'; } $html .= '>'; } $html .= htmlspecialchars($text->getText()); if ($fontStyle) { $html .= ''; } if ($paragraphStyle && !$withoutP) { $html .= '

' . PHP_EOL; } return $html; } /** * Write text run content * * @param mixed $textrun * @param boolean $withoutP * @return string */ private function writeTextRun($textrun, $withoutP = false) { $html = ''; $elements = $textrun->getElements(); if (count($elements) > 0) { $paragraphStyle = $textrun->getParagraphStyle(); $spIsObject = ($paragraphStyle instanceof Paragraph); $html .= $withoutP ? 'writeParagraphStyle($paragraphStyle) . '"'; } } $html .= '>'; foreach ($elements as $element) { if ($element instanceof Text) { $html .= $this->writeText($element, true); } elseif ($element instanceof Link) { $html .= $this->writeLink($element, true); } elseif ($element instanceof TextBreak) { $html .= $this->writeTextBreak($element, true); } elseif ($element instanceof Image) { $html .= $this->writeImage($element, true); } elseif ($element instanceof Endnote) { $html .= $this->writeEndnote($element); } elseif ($element instanceof Footnote) { $html .= $this->writeFootnote($element); } } $html .= $withoutP ? '' : '

'; $html .= PHP_EOL; } return $html; } /** * Write link * * @param \PhpOffice\PhpWord\Element\Link $element * @param boolean $withoutP * @return string */ private function writeLink($element, $withoutP = false) { $url = $element->getLinkSrc(); $text = $element->getLinkName(); if ($text == '') { $text = $url; } $html = ''; if (!$withoutP) { $html .= "

" . PHP_EOL; } $html .= "{$text}" . PHP_EOL; if (!$withoutP) { $html .= "

" . PHP_EOL; } return $html; } /** * Write heading * * @param \PhpOffice\PhpWord\Element\Title $element * @return string */ private function writeTitle($element) { $tag = 'h' . $element->getDepth(); $text = htmlspecialchars($element->getText()); $html = "<{$tag}>{$text}" . PHP_EOL; return $html; } /** * Write preserve text * * @param \PhpOffice\PhpWord\Element\PreserveText $element * @param boolean $withoutP * @return string */ private function writePreserveText($element, $withoutP = false) { return $this->writeUnsupportedElement($element, $withoutP); } /** * Get text break * * @param \PhpOffice\PhpWord\Element\TextBreak $element * @param boolean $withoutP * @return string */ private function writeTextBreak($element, $withoutP = false) { if ($withoutP) { $html = '
' . PHP_EOL; } else { $html = '

 

' . PHP_EOL; } return $html; } /** * Write page break * * @param \PhpOffice\PhpWord\Element\PageBreak $element * @return string */ private function writePageBreak($element) { return $this->writeUnsupportedElement($element, false); } /** * Write list item * * @param \PhpOffice\PhpWord\Element\ListItem $element * @return string */ private function writeListItem($element) { $text = htmlspecialchars($element->getTextObject()->getText()); $html = '

' . $text . '' . PHP_EOL; return $html; } /** * Write table * * @param \PhpOffice\PhpWord\Element\Table $element * @return string */ private function writeTable($element) { $html = ''; $rows = $element->getRows(); $cRows = count($rows); if ($cRows > 0) { $html .= "" . PHP_EOL; foreach ($rows as $row) { // $height = $row->getHeight(); $rowStyle = $row->getStyle(); $tblHeader = $rowStyle->getTblHeader(); $html .= "" . PHP_EOL; foreach ($row->getCells() as $cell) { $cellTag = $tblHeader ? 'th' : 'td'; $cellContents = $cell->getElements(); $html .= "<{$cellTag}>" . PHP_EOL; if (count($cellContents) > 0) { foreach ($cellContents as $content) { if ($content instanceof Text) { $html .= $this->writeText($content); } elseif ($content instanceof TextRun) { $html .= $this->writeTextRun($content); } elseif ($content instanceof Link) { $html .= $this->writeLink($content); } elseif ($content instanceof PreserveText) { $html .= $this->writePreserveText($content); } elseif ($content instanceof TextBreak) { $html .= $this->writeTextBreak($content); } elseif ($content instanceof ListItem) { $html .= $this->writeListItem($content); } elseif ($content instanceof Image) { $html .= $this->writeImage($content); } elseif ($content instanceof Object) { $html .= $this->writeObject($content); } elseif ($element instanceof Endnote) { $html .= $this->writeEndnote($element); } elseif ($element instanceof Footnote) { $html .= $this->writeFootnote($element); } } } else { $html .= $this->writeTextBreak(new TextBreak()); } $html .= "" . PHP_EOL; } $html .= "" . PHP_EOL; } $html .= "
" . PHP_EOL; } return $html; } /** * Write image * * @param \PhpOffice\PhpWord\Element\Image $element * @param boolean $withoutP * @return string */ private function writeImage($element, $withoutP = false) { $html = $this->writeUnsupportedElement($element, $withoutP); if (!$this->isPdf) { $imageData = $this->getBase64ImageData($element); if (!is_null($imageData)) { $style = $this->assembleCss(array( 'width' => $element->getStyle()->getWidth() . 'px', 'height' => $element->getStyle()->getHeight() . 'px', )); $html = ""; if (!$withoutP) { $html = "

{$html}

" . PHP_EOL; } } } return $html; } /** * Write object * * @param \PhpOffice\PhpWord\Element\Object $element * @param boolean $withoutP * @return string */ private function writeObject($element, $withoutP = false) { return $this->writeUnsupportedElement($element, $withoutP); } /** * Write footnote * * @param \PhpOffice\PhpWord\Element\Footnote $element * @return string */ private function writeFootnote($element) { return $this->writeNote($element); } /** * Write endnote * * @param \PhpOffice\PhpWord\Element\Endnote $element * @return string */ private function writeEndnote($element) { return $this->writeNote($element); } /** * Write footnote/endnote marks * * @param mixed $element * @return string */ private function writeNote($element) { $index = count($this->notes) + 1; $prefix = ($element instanceof Endnote) ? 'endnote' : 'footnote'; $noteMark = $prefix . '-' . $element->getRelationId(); $noteAnchor = "note-{$index}"; $this->notes[$index] = $noteMark; $html = "{$index}"; return $html; } /** * Write unsupported element * * @param mixed $element * @param boolean $withoutP * @return string */ private function writeUnsupportedElement($element, $withoutP = false) { $elementClass = get_class($element); $elementMark = str_replace('PhpOffice\\PhpWord\\Element\\', '', $elementClass); $elementMark = htmlentities("<{$elementMark}>"); if ($withoutP) { $html = "{$elementMark}" . PHP_EOL; } else { $html = "

{$elementMark}

" . PHP_EOL; } return $html; } /** * Get styles * * @return string */ private function writeStyles() { $css = '' . PHP_EOL; return $css; } /** * Get font style * * @param \PhpOffice\PhpWord\Style\Font $style * @param boolean $curlyBracket * @return string */ private function writeFontStyle($style, $curlyBracket = false) { $css = array(); if (PHPWord::DEFAULT_FONT_NAME != $style->getName()) { $css['font-family'] = "'" . $style->getName() . "'"; } if (PHPWord::DEFAULT_FONT_SIZE != $style->getSize()) { $css['font-size'] = $style->getSize() . 'pt'; } if (PHPWord::DEFAULT_FONT_COLOR != $style->getColor()) { $css['color'] = '#' . $style->getColor(); } $css['background'] = $style->getFgColor(); if ($style->getBold()) { $css['font-weight'] = 'bold'; } if ($style->getItalic()) { $css['font-style'] = 'italic'; } if ($style->getSuperScript()) { $css['vertical-align'] = 'super'; } elseif ($style->getSubScript()) { $css['vertical-align'] = 'sub'; } $css['text-decoration'] = ''; if ($style->getUnderline() != Font::UNDERLINE_NONE) { $css['text-decoration'] .= 'underline '; } if ($style->getStrikethrough()) { $css['text-decoration'] .= 'line-through '; } return $this->assembleCss($css, $curlyBracket); } /** * Get paragraph style * * @param \PhpOffice\PhpWord\Style\Paragraph $style * @param boolean $curlyBracket * @return string */ private function writeParagraphStyle($style, $curlyBracket = false) { $css = array(); if ($style->getAlign()) { $css['text-align'] = $style->getAlign(); } return $this->assembleCss($css, $curlyBracket); } /** * Takes array where of CSS properties / values and converts to CSS string * * @param array $css * @param boolean $curlyBracket * @return string */ private function assembleCss($css, $curlyBracket = false) { $pairs = array(); foreach ($css as $key => $value) { if ($value != '') { $pairs[] = $key . ': ' . $value; } } $string = implode('; ', $pairs); if ($curlyBracket) { $string = '{ ' . $string . ' }'; } return $string; } /** * Get Base64 image data * * @return string|null */ private function getBase64ImageData(Image $element) { $source = $element->getSource(); $imageType = $element->getImageType(); $imageData = null; $imageBinary = null; $actualSource = null; // Get actual source from archive image or other source // Return null if not found if ($element->getSourceType() == Image::SOURCE_ARCHIVE) { $source = substr($source, 6); list($zipFilename, $imageFilename) = explode('#', $source); $zipClass = \PhpOffice\PhpWord\Settings::getZipClass(); $zip = new $zipClass(); if ($zip->open($zipFilename) !== false) { if ($zip->locateName($imageFilename)) { $zip->extractTo($this->getTempDir(), $imageFilename); $actualSource = $this->getTempDir() . DIRECTORY_SEPARATOR . $imageFilename; } } $zip->close(); } else { $actualSource = $source; } if (is_null($actualSource)) { return null; } // Read image binary data and convert into Base64 if ($element->getSourceType() == Image::SOURCE_GD) { $imageResource = call_user_func($element->getImageCreateFunction(), $actualSource); ob_start(); call_user_func($element->getImageFunction(), $imageResource); $imageBinary = ob_get_contents(); ob_end_clean(); } else { if ($fp = fopen($actualSource, 'rb', false)) { $imageBinary = fread($fp, filesize($actualSource)); fclose($fp); } } if (!is_null($imageBinary)) { $base64 = chunk_split(base64_encode($imageBinary)); $imageData = 'data:' . $imageType . ';base64,' . $base64; } return $imageData; } }