PHPWord/src/PhpWord/Writer/HTML.php

276 lines
7.7 KiB
PHP

<?php
/**
* PHPWord
*
* @link https://github.com/PHPOffice/PHPWord
* @copyright 2014 PHPWord
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
namespace PhpOffice\PhpWord\Writer;
use PhpOffice\PhpWord\Element\AbstractElement;
use PhpOffice\PhpWord\Exception\Exception;
use PhpOffice\PhpWord\PhpWord;
use PhpOffice\PhpWord\Style\Font;
use PhpOffice\PhpWord\Style\Paragraph;
use PhpOffice\PhpWord\Style;
use PhpOffice\PhpWord\Writer\HTML\Element\Element as ElementWriter;
use PhpOffice\PhpWord\Writer\HTML\Element\TextRun as TextRunWriter;
use PhpOffice\PhpWord\Writer\HTML\Style\Font as FontStyleWriter;
use PhpOffice\PhpWord\Writer\HTML\Style\Generic as GenericStyleWriter;
use PhpOffice\PhpWord\Writer\HTML\Style\Paragraph as ParagraphStyleWriter;
/**
* HTML writer
*
* Not supported: PreserveText, PageBreak, Object
* @since 0.10.0
*/
class HTML extends AbstractWriter implements WriterInterface
{
/**
* Is the current writer creating PDF?
*
* @var boolean
*/
protected $isPdf = false;
/**
* Footnotes and endnotes collection
*
* @var array
*/
protected $notes = array();
/**
* 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())) {
$this->setTempDir(sys_get_temp_dir() . '/PHPWordWriter/');
$hFile = fopen($filename, 'w');
if ($hFile !== false) {
fwrite($hFile, $this->writeDocument());
fclose($hFile);
} else {
throw new Exception("Can't open file");
}
$this->clearTempDir();
} else {
throw new Exception("No PHPWord assigned.");
}
}
/**
* Get phpWord data
*
* @return string
*/
public function writeDocument()
{
$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();
$html .= $this->writeNotes();
$html .= '</body>' . PHP_EOL;
$html .= '</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 .= '<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
*/
private function writeHTMLBody()
{
$phpWord = $this->getPhpWord();
$html = '';
$sections = $phpWord->getSections();
$countSections = count($sections);
if ($countSections > 0) {
foreach ($sections as $section) {
$elements = $section->getElements();
foreach ($elements as $element) {
if ($element instanceof AbstractElement) {
$elementWriter = new ElementWriter($this, $element, false);
$html .= $elementWriter->write();
}
}
}
}
return $html;
}
/**
* Write footnote/endnote contents as textruns
*/
private function writeNotes()
{
$html = '';
if (!empty($this->notes)) {
$html .= "<hr />";
foreach ($this->notes as $noteId => $noteMark) {
$noteAnchor = "note-{$noteId}";
list($noteType, $noteTypeId) = explode('-', $noteMark);
$collectionObject = 'PhpOffice\\PhpWord\\' . ($noteType == 'endnote' ? 'Endnotes' : 'Footnotes');
$collection = $collectionObject::getElements();
if (array_key_exists($noteTypeId, $collection)) {
$element = $collection[$noteTypeId];
$elmWriter = new TextRunWriter($this, $element, true);
$content = "<a href=\"#{$noteMark}\" class=\"NoteRef\"><sup>{$noteId}</sup></a>" . $elmWriter->write();
$html .= "<p><a name=\"{$noteAnchor}\" />{$content}</p>" . PHP_EOL;
}
}
}
return $html;
}
/**
* Get styles
*
* @return string
*/
private function writeStyles()
{
$css = '<style>' . PHP_EOL;
// Default styles
$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) {
$styleWriter = new GenericStyleWriter($style);
$css .= $selector . ' {' . $styleWriter->write() . '}' . PHP_EOL;
}
// Custom styles
$customStyles = Style::getStyles();
if (is_array($customStyles)) {
foreach ($customStyles as $name => $style) {
if ($style instanceof Font) {
$styleWriter = new FontStyleWriter($style);
if ($style->getStyleType() == 'title') {
$name = str_replace('Heading_', 'h', $name);
} else {
$name = '.' . $name;
}
$css .= "{$name} {" . $styleWriter->write() . '}' . PHP_EOL;
} elseif ($style instanceof Paragraph) {
$styleWriter = new ParagraphStyleWriter($style);
$name = '.' . $name;
$css .= "{$name} {" . $styleWriter->write() . '}' . PHP_EOL;
}
}
}
$css .= '</style>' . PHP_EOL;
return $css;
}
/**
* Get is PDF
*
* @return bool
*/
public function isPdf()
{
return $this->isPdf;
}
/**
* Get notes
*
* @return array
*/
public function getNotes()
{
return $this->notes;
}
/**
* Add note
*
* @param int $noteId
* @param string $noteMark
*/
public function addNote($noteId, $noteMark)
{
$this->notes[$noteId] = $noteMark;
}
}