PHPWord/src/PhpWord/Writer/HTML.php

281 lines
7.9 KiB
PHP

<?php
/**
* This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
*
* @link https://github.com/PHPOffice/PHPWord
* @copyright 2010-2014 PHPWord contributors
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
namespace PhpOffice\PhpWord\Writer;
use PhpOffice\PhpWord\Exception\Exception;
use PhpOffice\PhpWord\PhpWord;
use PhpOffice\PhpWord\Settings;
use PhpOffice\PhpWord\Style;
use PhpOffice\PhpWord\Style\Font;
use PhpOffice\PhpWord\Style\Paragraph;
use PhpOffice\PhpWord\Writer\HTML\Element\Container;
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 \PhpOffice\PhpWord\Exception\Exception
*/
public function save($filename = null)
{
$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();
}
/**
* Get phpWord data
*
* @return string
*/
public function writeDocument()
{
$content = '';
$content .= '<!DOCTYPE html>' . PHP_EOL;
$content .= '<!-- Generated by PHPWord -->' . PHP_EOL;
$content .= '<html>' . PHP_EOL;
$content .= '<head>' . PHP_EOL;
$content .= $this->writeHead();
$content .= '</head>' . PHP_EOL;
$content .= '<body>' . PHP_EOL;
$content .= $this->writeBody();
$content .= $this->writeNotes();
$content .= '</body>' . PHP_EOL;
$content .= '</html>' . PHP_EOL;
return $content;
}
/**
* Generate HTML header
*
* @return string
*/
private function writeHead()
{
$phpWord = $this->getPhpWord();
$properties = $phpWord->getDocumentProperties();
$propertiesMapping = array(
'creator' => 'author',
'title' => '',
'description' => '',
'subject' => '',
'keywords' => '',
'category' => '',
'company' => '',
'manager' => ''
);
$title = $properties->getTitle();
$title = ($title != '') ? $title : 'PHPWord';
$content = '';
$content .= '<meta charset="UTF-8" />' . PHP_EOL;
$content .= '<title>' . htmlspecialchars($title) . '</title>' . PHP_EOL;
foreach ($propertiesMapping as $key => $value) {
$value = ($value == '') ? $key : $value;
$method = "get" . $key;
if ($properties->$method() != '') {
$content .= '<meta name="' . $value . '" content="' .
htmlspecialchars($properties->$method()) . '" />' . PHP_EOL;
}
}
$content .= $this->writeStyles();
return $content;
}
/**
* Get content
*
* @return string
*/
private function writeBody()
{
$phpWord = $this->getPhpWord();
$content = '';
$sections = $phpWord->getSections();
$countSections = count($sections);
if ($countSections > 0) {
foreach ($sections as $section) {
$writer = new Container($this, $section);
$content .= $writer->write();
}
}
return $content;
}
/**
* Get styles
*
* @return string
*/
private function writeStyles()
{
$css = '<style>' . PHP_EOL;
// Default styles
$defaultStyles = array(
'*' => array(
'font-family' => Settings::getDefaultFontName(),
'font-size' => Settings::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;
}
/**
* Write footnote/endnote contents as textruns
*/
private function writeNotes()
{
$phpWord = $this->getPhpWord();
$content = PHP_EOL;
if (!empty($this->notes)) {
$content .= "<hr />" . PHP_EOL;
foreach ($this->notes as $noteId => $noteMark) {
list($noteType, $noteTypeId) = explode('-', $noteMark);
$method = 'get' . ($noteType == 'endnote' ? 'Endnotes' : 'Footnotes');
$collection = $phpWord->$method()->getItems();
if (array_key_exists($noteTypeId, $collection)) {
$element = $collection[$noteTypeId];
$noteAnchor = "<a name=\"note-{$noteId}\" />";
$noteAnchor .= "<a href=\"#{$noteMark}\" class=\"NoteRef\"><sup>{$noteId}</sup></a>";
$writer = new TextRunWriter($this, $element);
$writer->setOpeningText($noteAnchor);
$content .= $writer->write();
}
}
}
return $content;
}
/**
* 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;
}
}