2014-04-12 10:12:24 +07:00
|
|
|
<?php
|
|
|
|
|
/**
|
|
|
|
|
* PHPWord
|
|
|
|
|
*
|
|
|
|
|
* @link https://github.com/PHPOffice/PHPWord
|
|
|
|
|
* @copyright 2014 PHPWord
|
|
|
|
|
* @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
namespace PhpOffice\PhpWord\Writer;
|
|
|
|
|
|
2014-04-17 16:19:23 +07:00
|
|
|
use PhpOffice\PhpWord\Endnotes;
|
|
|
|
|
use PhpOffice\PhpWord\Footnotes;
|
|
|
|
|
use PhpOffice\PhpWord\PhpWord;
|
|
|
|
|
use PhpOffice\PhpWord\Style;
|
2014-04-12 10:12:24 +07:00
|
|
|
use PhpOffice\PhpWord\Element\Endnote;
|
|
|
|
|
use PhpOffice\PhpWord\Element\Footnote;
|
|
|
|
|
use PhpOffice\PhpWord\Element\Image;
|
|
|
|
|
use PhpOffice\PhpWord\Element\Link;
|
|
|
|
|
use PhpOffice\PhpWord\Element\ListItem;
|
|
|
|
|
use PhpOffice\PhpWord\Element\Object;
|
|
|
|
|
use PhpOffice\PhpWord\Element\PageBreak;
|
2014-04-13 23:17:39 +07:00
|
|
|
use PhpOffice\PhpWord\Element\PreserveText;
|
2014-04-12 10:12:24 +07:00
|
|
|
use PhpOffice\PhpWord\Element\Table;
|
|
|
|
|
use PhpOffice\PhpWord\Element\Text;
|
|
|
|
|
use PhpOffice\PhpWord\Element\TextBreak;
|
|
|
|
|
use PhpOffice\PhpWord\Element\TextRun;
|
|
|
|
|
use PhpOffice\PhpWord\Element\Title;
|
|
|
|
|
use PhpOffice\PhpWord\Exception\Exception;
|
|
|
|
|
use PhpOffice\PhpWord\Style\Font;
|
|
|
|
|
use PhpOffice\PhpWord\Style\Paragraph;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* HTML writer
|
|
|
|
|
*
|
|
|
|
|
* @since 0.10.0
|
|
|
|
|
*/
|
|
|
|
|
class HTML extends AbstractWriter implements WriterInterface
|
|
|
|
|
{
|
2014-04-16 12:12:32 +07:00
|
|
|
/**
|
|
|
|
|
* Is the current writer creating PDF?
|
|
|
|
|
*
|
|
|
|
|
* @var boolean
|
|
|
|
|
*/
|
|
|
|
|
protected $isPdf = false;
|
|
|
|
|
|
2014-04-16 17:17:42 +07:00
|
|
|
/**
|
|
|
|
|
* Footnotes and endnotes collection
|
|
|
|
|
*
|
|
|
|
|
* @var array
|
|
|
|
|
*/
|
|
|
|
|
protected $notes = array();
|
|
|
|
|
|
2014-04-12 10:12:24 +07:00
|
|
|
/**
|
|
|
|
|
* Create new instance
|
|
|
|
|
*/
|
|
|
|
|
public function __construct(PhpWord $phpWord = null)
|
|
|
|
|
{
|
|
|
|
|
$this->setPhpWord($phpWord);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Save PhpWord to file
|
|
|
|
|
*
|
|
|
|
|
* @param string $filename
|
|
|
|
|
* @throws Exception
|
|
|
|
|
*/
|
|
|
|
|
public function save($filename = null)
|
|
|
|
|
{
|
|
|
|
|
if (!is_null($this->getPhpWord())) {
|
2014-04-16 13:37:48 +07:00
|
|
|
$this->setTempDir(sys_get_temp_dir() . '/PHPWordWriter/');
|
2014-04-22 17:25:10 +07:00
|
|
|
$hFile = fopen($filename, 'w');
|
|
|
|
|
if ($hFile !== false) {
|
|
|
|
|
fwrite($hFile, $this->writeDocument());
|
|
|
|
|
fclose($hFile);
|
|
|
|
|
} else {
|
|
|
|
|
throw new Exception("Can't open file");
|
|
|
|
|
}
|
2014-04-16 12:12:32 +07:00
|
|
|
$this->clearTempDir();
|
2014-04-12 10:12:24 +07:00
|
|
|
} else {
|
|
|
|
|
throw new Exception("No PHPWord assigned.");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get phpWord data
|
|
|
|
|
*
|
|
|
|
|
* @return string
|
|
|
|
|
*/
|
2014-04-13 23:17:39 +07:00
|
|
|
public function writeDocument()
|
2014-04-12 10:12:24 +07:00
|
|
|
{
|
|
|
|
|
$html = '';
|
|
|
|
|
$html .= '<!DOCTYPE html>' . PHP_EOL;
|
|
|
|
|
$html .= '<!-- Generated by PHPWord -->' . PHP_EOL;
|
|
|
|
|
$html .= '<html>' . PHP_EOL;
|
|
|
|
|
$html .= '<head>' . PHP_EOL;
|
|
|
|
|
$html .= $this->writeHTMLHead();
|
|
|
|
|
$html .= '</head>' . PHP_EOL;
|
|
|
|
|
$html .= '<body>' . PHP_EOL;
|
|
|
|
|
$html .= $this->writeHTMLBody();
|
2014-04-16 17:17:42 +07:00
|
|
|
$html .= $this->writeNotes();
|
2014-04-12 10:12:24 +07:00
|
|
|
$html .= '</body>' . PHP_EOL;
|
|
|
|
|
$html .= '</html>' . PHP_EOL;
|
|
|
|
|
|
|
|
|
|
return $html;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Generate HTML header
|
|
|
|
|
*
|
|
|
|
|
* @return string
|
|
|
|
|
*/
|
2014-04-13 23:17:39 +07:00
|
|
|
private function writeHTMLHead()
|
2014-04-12 10:12:24 +07:00
|
|
|
{
|
|
|
|
|
$properties = $this->getPhpWord()->getDocumentProperties();
|
|
|
|
|
$propertiesMapping = array(
|
|
|
|
|
'creator' => 'author',
|
|
|
|
|
'title' => '',
|
|
|
|
|
'description' => '',
|
|
|
|
|
'subject' => '',
|
|
|
|
|
'keywords' => '',
|
|
|
|
|
'category' => '',
|
|
|
|
|
'company' => '',
|
|
|
|
|
'manager' => ''
|
|
|
|
|
);
|
|
|
|
|
$title = $properties->getTitle();
|
|
|
|
|
$title = ($title != '') ? $title : 'PHPWord';
|
|
|
|
|
|
|
|
|
|
$html = '';
|
|
|
|
|
$html .= '<meta charset="UTF-8" />' . PHP_EOL;
|
|
|
|
|
$html .= '<title>' . htmlspecialchars($title) . '</title>' . PHP_EOL;
|
|
|
|
|
foreach ($propertiesMapping as $key => $value) {
|
|
|
|
|
$value = ($value == '') ? $key : $value;
|
|
|
|
|
$method = "get" . $key;
|
|
|
|
|
if ($properties->$method() != '') {
|
|
|
|
|
$html .= '<meta name="' . $value . '" content="' .
|
|
|
|
|
htmlspecialchars($properties->$method()) . '" />' . PHP_EOL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
$html .= $this->writeStyles();
|
|
|
|
|
|
|
|
|
|
return $html;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get content
|
|
|
|
|
*
|
|
|
|
|
* @return string
|
|
|
|
|
*/
|
2014-04-13 23:17:39 +07:00
|
|
|
private function writeHTMLBody()
|
2014-04-12 10:12:24 +07:00
|
|
|
{
|
|
|
|
|
$phpWord = $this->getPhpWord();
|
|
|
|
|
$html = '';
|
|
|
|
|
|
|
|
|
|
$sections = $phpWord->getSections();
|
|
|
|
|
$countSections = count($sections);
|
|
|
|
|
$pSection = 0;
|
|
|
|
|
|
|
|
|
|
if ($countSections > 0) {
|
|
|
|
|
foreach ($sections as $section) {
|
|
|
|
|
$pSection++;
|
2014-04-13 23:17:39 +07:00
|
|
|
$contents = $section->getElements();
|
|
|
|
|
foreach ($contents as $element) {
|
2014-04-12 10:12:24 +07:00
|
|
|
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) {
|
2014-04-13 23:17:39 +07:00
|
|
|
$html .= $this->writeEndnote($element);
|
2014-04-16 14:45:43 +07:00
|
|
|
} elseif ($element instanceof Footnote) {
|
|
|
|
|
$html .= $this->writeFootnote($element);
|
2014-04-12 10:12:24 +07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $html;
|
|
|
|
|
}
|
|
|
|
|
|
2014-04-16 17:17:42 +07:00
|
|
|
/**
|
|
|
|
|
* Write footnote/endnote contents
|
|
|
|
|
*/
|
|
|
|
|
private function writeNotes()
|
|
|
|
|
{
|
|
|
|
|
$footnote = Footnotes::getElements();
|
|
|
|
|
$endnote = Endnotes::getElements();
|
|
|
|
|
$html = '';
|
|
|
|
|
|
|
|
|
|
if (count($this->notes) > 0) {
|
|
|
|
|
$html .= "<hr />";
|
|
|
|
|
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 = "<a href=\"#{$noteMark}\" class=\"NoteRef\"><sup>{$noteId}</sup></a>" . $this->writeTextRun($element, true);
|
|
|
|
|
$html .= "<p><a name=\"{$noteAnchor}\" />{$content}</p>" . PHP_EOL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $html;
|
|
|
|
|
}
|
|
|
|
|
|
2014-04-12 10:12:24 +07:00
|
|
|
/**
|
|
|
|
|
* Get text
|
|
|
|
|
*
|
2014-04-16 22:24:25 +07:00
|
|
|
* @param \PhpOffice\PhpWord\Element\Text $text
|
2014-04-12 10:12:24 +07:00
|
|
|
* @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 .= '<p';
|
|
|
|
|
if (!$spIsObject) {
|
|
|
|
|
$html .= ' class="' . $paragraphStyle . '"';
|
|
|
|
|
} else {
|
|
|
|
|
$html .= ' style="' . $this->writeParagraphStyle($paragraphStyle) . '"';
|
|
|
|
|
}
|
|
|
|
|
$html .= '>';
|
|
|
|
|
}
|
|
|
|
|
if ($fontStyle) {
|
|
|
|
|
$html .= '<span';
|
|
|
|
|
if (!$sfIsObject) {
|
|
|
|
|
$html .= ' class="' . $fontStyle . '"';
|
|
|
|
|
} else {
|
|
|
|
|
$html .= ' style="' . $this->writeFontStyle($fontStyle) . '"';
|
|
|
|
|
}
|
|
|
|
|
$html .= '>';
|
|
|
|
|
}
|
|
|
|
|
$html .= htmlspecialchars($text->getText());
|
|
|
|
|
if ($fontStyle) {
|
|
|
|
|
$html .= '</span>';
|
|
|
|
|
}
|
|
|
|
|
if ($paragraphStyle && !$withoutP) {
|
|
|
|
|
$html .= '</p>' . PHP_EOL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $html;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2014-04-16 17:17:42 +07:00
|
|
|
* Write text run content
|
2014-04-12 10:12:24 +07:00
|
|
|
*
|
2014-04-16 22:24:25 +07:00
|
|
|
* @param mixed $textrun
|
|
|
|
|
* @param boolean $withoutP
|
2014-04-12 10:12:24 +07:00
|
|
|
* @return string
|
|
|
|
|
*/
|
2014-04-16 17:17:42 +07:00
|
|
|
private function writeTextRun($textrun, $withoutP = false)
|
2014-04-12 10:12:24 +07:00
|
|
|
{
|
|
|
|
|
$html = '';
|
|
|
|
|
$elements = $textrun->getElements();
|
|
|
|
|
if (count($elements) > 0) {
|
|
|
|
|
$paragraphStyle = $textrun->getParagraphStyle();
|
|
|
|
|
$spIsObject = ($paragraphStyle instanceof Paragraph);
|
2014-04-16 17:17:42 +07:00
|
|
|
|
|
|
|
|
$html .= $withoutP ? '<span' : '<p';
|
2014-04-12 10:12:24 +07:00
|
|
|
if ($paragraphStyle) {
|
|
|
|
|
if (!$spIsObject) {
|
|
|
|
|
$html .= ' class="' . $paragraphStyle . '"';
|
|
|
|
|
} else {
|
|
|
|
|
$html .= ' style="' . $this->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) {
|
2014-04-13 23:17:39 +07:00
|
|
|
$html .= $this->writeEndnote($element);
|
2014-04-16 14:45:43 +07:00
|
|
|
} elseif ($element instanceof Footnote) {
|
|
|
|
|
$html .= $this->writeFootnote($element);
|
2014-04-12 10:12:24 +07:00
|
|
|
}
|
|
|
|
|
}
|
2014-04-16 17:17:42 +07:00
|
|
|
$html .= $withoutP ? '</span>' : '</p>';
|
|
|
|
|
$html .= PHP_EOL;
|
2014-04-12 10:12:24 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $html;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Write link
|
|
|
|
|
*
|
2014-04-16 22:24:25 +07:00
|
|
|
* @param \PhpOffice\PhpWord\Element\Link $element
|
2014-04-13 23:17:39 +07:00
|
|
|
* @param boolean $withoutP
|
2014-04-12 10:12:24 +07:00
|
|
|
* @return string
|
|
|
|
|
*/
|
|
|
|
|
private function writeLink($element, $withoutP = false)
|
|
|
|
|
{
|
|
|
|
|
$url = $element->getLinkSrc();
|
|
|
|
|
$text = $element->getLinkName();
|
2014-04-16 17:17:42 +07:00
|
|
|
if ($text == '') {
|
|
|
|
|
$text = $url;
|
|
|
|
|
}
|
2014-04-12 10:12:24 +07:00
|
|
|
$html = '';
|
|
|
|
|
if (!$withoutP) {
|
|
|
|
|
$html .= "<p>" . PHP_EOL;
|
|
|
|
|
}
|
2014-04-16 17:17:42 +07:00
|
|
|
$html .= "<a href=\"{$url}\">{$text}</a>" . PHP_EOL;
|
2014-04-12 10:12:24 +07:00
|
|
|
if (!$withoutP) {
|
|
|
|
|
$html .= "</p>" . PHP_EOL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $html;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Write heading
|
|
|
|
|
*
|
2014-04-16 22:24:25 +07:00
|
|
|
* @param \PhpOffice\PhpWord\Element\Title $element
|
2014-04-12 10:12:24 +07:00
|
|
|
* @return string
|
|
|
|
|
*/
|
|
|
|
|
private function writeTitle($element)
|
|
|
|
|
{
|
|
|
|
|
$tag = 'h' . $element->getDepth();
|
|
|
|
|
$text = htmlspecialchars($element->getText());
|
|
|
|
|
$html = "<{$tag}>{$text}</{$tag}>" . PHP_EOL;
|
|
|
|
|
|
|
|
|
|
return $html;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Write preserve text
|
|
|
|
|
*
|
2014-04-16 22:24:25 +07:00
|
|
|
* @param \PhpOffice\PhpWord\Element\PreserveText $element
|
2014-04-13 23:17:39 +07:00
|
|
|
* @param boolean $withoutP
|
2014-04-12 10:12:24 +07:00
|
|
|
* @return string
|
|
|
|
|
*/
|
|
|
|
|
private function writePreserveText($element, $withoutP = false)
|
|
|
|
|
{
|
|
|
|
|
return $this->writeUnsupportedElement($element, $withoutP);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get text break
|
|
|
|
|
*
|
2014-04-16 22:24:25 +07:00
|
|
|
* @param \PhpOffice\PhpWord\Element\TextBreak $element
|
2014-04-12 10:12:24 +07:00
|
|
|
* @param boolean $withoutP
|
|
|
|
|
* @return string
|
|
|
|
|
*/
|
|
|
|
|
private function writeTextBreak($element, $withoutP = false)
|
|
|
|
|
{
|
|
|
|
|
if ($withoutP) {
|
|
|
|
|
$html = '<br />' . PHP_EOL;
|
|
|
|
|
} else {
|
|
|
|
|
$html = '<p> </p>' . PHP_EOL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $html;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Write page break
|
|
|
|
|
*
|
2014-04-16 22:24:25 +07:00
|
|
|
* @param \PhpOffice\PhpWord\Element\PageBreak $element
|
2014-04-12 10:12:24 +07:00
|
|
|
* @return string
|
|
|
|
|
*/
|
|
|
|
|
private function writePageBreak($element)
|
|
|
|
|
{
|
|
|
|
|
return $this->writeUnsupportedElement($element, false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Write list item
|
|
|
|
|
*
|
2014-04-16 22:24:25 +07:00
|
|
|
* @param \PhpOffice\PhpWord\Element\ListItem $element
|
2014-04-12 10:12:24 +07:00
|
|
|
* @return string
|
|
|
|
|
*/
|
|
|
|
|
private function writeListItem($element)
|
|
|
|
|
{
|
2014-04-16 07:12:57 +07:00
|
|
|
$text = htmlspecialchars($element->getTextObject()->getText());
|
|
|
|
|
$html = '<p>' . $text . '</{$p}>' . PHP_EOL;
|
|
|
|
|
|
|
|
|
|
return $html;
|
2014-04-12 10:12:24 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Write table
|
|
|
|
|
*
|
2014-04-16 22:24:25 +07:00
|
|
|
* @param \PhpOffice\PhpWord\Element\Table $element
|
2014-04-12 10:12:24 +07:00
|
|
|
* @return string
|
|
|
|
|
*/
|
|
|
|
|
private function writeTable($element)
|
|
|
|
|
{
|
|
|
|
|
$html = '';
|
|
|
|
|
$rows = $element->getRows();
|
|
|
|
|
$cRows = count($rows);
|
|
|
|
|
if ($cRows > 0) {
|
|
|
|
|
$html .= "<table>" . PHP_EOL;
|
|
|
|
|
foreach ($rows as $row) {
|
2014-04-13 23:17:39 +07:00
|
|
|
// $height = $row->getHeight();
|
2014-04-12 10:12:24 +07:00
|
|
|
$rowStyle = $row->getStyle();
|
|
|
|
|
$tblHeader = $rowStyle->getTblHeader();
|
|
|
|
|
$html .= "<tr>" . 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) {
|
2014-04-13 23:17:39 +07:00
|
|
|
$html .= $this->writeEndnote($element);
|
2014-04-16 14:45:43 +07:00
|
|
|
} elseif ($element instanceof Footnote) {
|
|
|
|
|
$html .= $this->writeFootnote($element);
|
2014-04-12 10:12:24 +07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
2014-04-13 23:17:39 +07:00
|
|
|
$html .= $this->writeTextBreak(new TextBreak());
|
2014-04-12 10:12:24 +07:00
|
|
|
}
|
|
|
|
|
$html .= "</td>" . PHP_EOL;
|
|
|
|
|
}
|
|
|
|
|
$html .= "</tr>" . PHP_EOL;
|
|
|
|
|
}
|
|
|
|
|
$html .= "</table>" . PHP_EOL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $html;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Write image
|
|
|
|
|
*
|
2014-04-16 22:24:25 +07:00
|
|
|
* @param \PhpOffice\PhpWord\Element\Image $element
|
2014-04-13 23:17:39 +07:00
|
|
|
* @param boolean $withoutP
|
2014-04-12 10:12:24 +07:00
|
|
|
* @return string
|
|
|
|
|
*/
|
|
|
|
|
private function writeImage($element, $withoutP = false)
|
|
|
|
|
{
|
2014-04-16 12:12:32 +07:00
|
|
|
$html = $this->writeUnsupportedElement($element, $withoutP);
|
|
|
|
|
if (!$this->isPdf) {
|
|
|
|
|
$imageData = $this->getBase64ImageData($element);
|
|
|
|
|
if (!is_null($imageData)) {
|
2014-04-16 14:45:43 +07:00
|
|
|
$style = $this->assembleCss(array(
|
|
|
|
|
'width' => $element->getStyle()->getWidth() . 'px',
|
|
|
|
|
'height' => $element->getStyle()->getHeight() . 'px',
|
|
|
|
|
));
|
|
|
|
|
$html = "<img border=\"0\" style=\"{$style}\" src=\"{$imageData}\"/>";
|
2014-04-16 12:12:32 +07:00
|
|
|
if (!$withoutP) {
|
2014-04-16 14:45:43 +07:00
|
|
|
$html = "<p>{$html}</p>" . PHP_EOL;
|
2014-04-16 12:12:32 +07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $html;
|
2014-04-12 10:12:24 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Write object
|
|
|
|
|
*
|
2014-04-16 22:24:25 +07:00
|
|
|
* @param \PhpOffice\PhpWord\Element\Object $element
|
2014-04-13 23:17:39 +07:00
|
|
|
* @param boolean $withoutP
|
2014-04-12 10:12:24 +07:00
|
|
|
* @return string
|
|
|
|
|
*/
|
|
|
|
|
private function writeObject($element, $withoutP = false)
|
|
|
|
|
{
|
|
|
|
|
return $this->writeUnsupportedElement($element, $withoutP);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Write footnote
|
|
|
|
|
*
|
2014-04-16 22:24:25 +07:00
|
|
|
* @param \PhpOffice\PhpWord\Element\Footnote $element
|
2014-04-12 10:12:24 +07:00
|
|
|
* @return string
|
|
|
|
|
*/
|
|
|
|
|
private function writeFootnote($element)
|
|
|
|
|
{
|
2014-04-16 17:17:42 +07:00
|
|
|
return $this->writeNote($element);
|
2014-04-12 10:12:24 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Write endnote
|
|
|
|
|
*
|
2014-04-16 22:24:25 +07:00
|
|
|
* @param \PhpOffice\PhpWord\Element\Endnote $element
|
2014-04-12 10:12:24 +07:00
|
|
|
* @return string
|
|
|
|
|
*/
|
|
|
|
|
private function writeEndnote($element)
|
|
|
|
|
{
|
2014-04-16 17:17:42 +07:00
|
|
|
return $this->writeNote($element);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Write footnote/endnote marks
|
|
|
|
|
*
|
2014-04-16 22:24:25 +07:00
|
|
|
* @param mixed $element
|
2014-04-16 17:17:42 +07:00
|
|
|
* @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 = "<a name=\"{$noteMark}\"><a href=\"#{$noteAnchor}\" class=\"NoteRef\"><sup>{$index}</sup></a>";
|
|
|
|
|
|
|
|
|
|
return $html;
|
2014-04-12 10:12:24 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 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 = "<span class=\"other-elm\">{$elementMark}</span>" . PHP_EOL;
|
|
|
|
|
} else {
|
|
|
|
|
$html = "<p>{$elementMark}</p>" . PHP_EOL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $html;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get styles
|
|
|
|
|
*
|
|
|
|
|
* @return string
|
|
|
|
|
*/
|
|
|
|
|
private function writeStyles()
|
|
|
|
|
{
|
|
|
|
|
$css = '<style>' . PHP_EOL;
|
2014-04-13 23:17:39 +07:00
|
|
|
|
2014-04-12 10:12:24 +07:00
|
|
|
// Default styles
|
2014-04-16 17:17:42 +07:00
|
|
|
$defaultStyles = array(
|
|
|
|
|
'*' => array(
|
|
|
|
|
'font-family' => $this->getPhpWord()->getDefaultFontName(),
|
|
|
|
|
'font-size' => $this->getPhpWord()->getDefaultFontSize() . 'pt',
|
|
|
|
|
),
|
|
|
|
|
'a.NoteRef' => array(
|
|
|
|
|
'text-decoration' => 'none',
|
|
|
|
|
),
|
|
|
|
|
'hr' => array(
|
|
|
|
|
'height' => '1px',
|
|
|
|
|
'padding' => '0',
|
|
|
|
|
'margin' => '1em 0',
|
|
|
|
|
'border' => '0',
|
|
|
|
|
'border-top' => '1px solid #CCC',
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
foreach ($defaultStyles as $selector => $style) {
|
|
|
|
|
$css .= $selector . ' ' . $this->assembleCss($style, true) . PHP_EOL;
|
|
|
|
|
}
|
2014-04-13 23:17:39 +07:00
|
|
|
|
2014-04-12 10:12:24 +07:00
|
|
|
// Custom styles
|
2014-04-16 17:17:42 +07:00
|
|
|
$customStyles = Style::getStyles();
|
|
|
|
|
if (is_array($customStyles)) {
|
|
|
|
|
foreach ($customStyles as $name => $style) {
|
2014-04-12 10:12:24 +07:00
|
|
|
if ($style instanceof Font) {
|
|
|
|
|
if ($style->getStyleType() == 'title') {
|
|
|
|
|
$name = str_replace('Heading_', 'h', $name);
|
|
|
|
|
} else {
|
|
|
|
|
$name = '.' . $name;
|
|
|
|
|
}
|
|
|
|
|
$css .= "{$name} " . $this->writeFontStyle($style, true) . PHP_EOL;
|
|
|
|
|
} elseif ($style instanceof Paragraph) {
|
|
|
|
|
$name = '.' . $name;
|
|
|
|
|
$css .= "{$name} " . $this->writeParagraphStyle($style, true) . PHP_EOL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
$css .= '</style>' . PHP_EOL;
|
|
|
|
|
|
|
|
|
|
return $css;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get font style
|
|
|
|
|
*
|
2014-04-16 22:24:25 +07:00
|
|
|
* @param \PhpOffice\PhpWord\Style\Font $style
|
2014-04-12 10:12:24 +07:00
|
|
|
* @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
|
|
|
|
|
*
|
2014-04-16 22:24:25 +07:00
|
|
|
* @param \PhpOffice\PhpWord\Style\Paragraph $style
|
2014-04-12 10:12:24 +07:00
|
|
|
* @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;
|
|
|
|
|
}
|
2014-04-16 12:12:32 +07:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get Base64 image data
|
|
|
|
|
*
|
|
|
|
|
* @return string|null
|
|
|
|
|
*/
|
|
|
|
|
private function getBase64ImageData(Image $element)
|
|
|
|
|
{
|
|
|
|
|
$source = $element->getSource();
|
|
|
|
|
$imageType = $element->getImageType();
|
2014-04-17 16:19:23 +07:00
|
|
|
$imageData = null;
|
|
|
|
|
$imageBinary = null;
|
|
|
|
|
$actualSource = null;
|
2014-04-16 12:12:32 +07:00
|
|
|
|
2014-04-17 16:19:23 +07:00
|
|
|
// Get actual source from archive image or other source
|
|
|
|
|
// Return null if not found
|
2014-04-16 14:45:43 +07:00
|
|
|
if ($element->getSourceType() == Image::SOURCE_ARCHIVE) {
|
2014-04-16 12:12:32 +07:00
|
|
|
$source = substr($source, 6);
|
|
|
|
|
list($zipFilename, $imageFilename) = explode('#', $source);
|
2014-04-18 01:58:03 +07:00
|
|
|
|
|
|
|
|
$zipClass = \PhpOffice\PhpWord\Settings::getZipClass();
|
|
|
|
|
$zip = new $zipClass();
|
2014-04-16 12:12:32 +07:00
|
|
|
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;
|
|
|
|
|
}
|
2014-04-17 16:19:23 +07:00
|
|
|
if (is_null($actualSource)) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
2014-04-16 12:12:32 +07:00
|
|
|
|
|
|
|
|
// Read image binary data and convert into Base64
|
2014-04-16 14:45:43 +07:00
|
|
|
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 {
|
2014-04-22 17:25:10 +07:00
|
|
|
if ($fileHandle = fopen($actualSource, 'rb', false)) {
|
|
|
|
|
$imageBinary = fread($fileHandle, filesize($actualSource));
|
|
|
|
|
fclose($fileHandle);
|
2014-04-16 14:45:43 +07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!is_null($imageBinary)) {
|
|
|
|
|
$base64 = chunk_split(base64_encode($imageBinary));
|
2014-04-16 12:12:32 +07:00
|
|
|
$imageData = 'data:' . $imageType . ';base64,' . $base64;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $imageData;
|
|
|
|
|
}
|
2014-04-12 10:12:24 +07:00
|
|
|
}
|