Basic HTML writer

This commit is contained in:
Ivan Lanin 2014-04-12 10:12:24 +07:00
parent fb35a5f80c
commit 19a69e2c39
29 changed files with 826 additions and 229 deletions

View File

@ -4,7 +4,7 @@ This is the changelog between releases of PHPWord. Releases are listed in revers
## 0.10.0 - Not yet released
This release marked heavy refactorings on internal code structure with the creation of some abstract classes to reduce code duplication. `Element` subnamespace is introduced in this release to replace `Section`. Word2007 reader capability is greatly enhanced. Endnote is introduced. List numbering is now customizable.
This release marked heavy refactorings on internal code structure with the creation of some abstract classes to reduce code duplication. `Element` subnamespace is introduced in this release to replace `Section`. Word2007 reader capability is greatly enhanced. Endnote is introduced. List numbering is now customizable. Basic HTML writer is initiated.
### Features
@ -31,6 +31,7 @@ This release marked heavy refactorings on internal code structure with the creat
- Endnote: Ability to add endnotes - @ivanlanin
- ListItem: Ability to create custom list and reset list number - @ivanlanin GH-10 GH-198
- ODT Writer: Basic table writing support - @ivanlanin
- HTML Writer: Basic HTML writer initiated - @ivanlanin
### Bugfixes

View File

@ -45,13 +45,7 @@ $section->addTextBreak();
$section->addImage('resources/_earth.jpg', array('width'=>18, 'height'=>18));
// Save file
$name = basename(__FILE__, '.php');
$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf');
foreach ($writers as $writer => $extension) {
echo date('H:i:s'), " Write to {$writer} format", EOL;
$xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer);
$xmlWriter->save("{$name}.{$extension}");
rename("{$name}.{$extension}", "results/{$name}.{$extension}");
echo write($phpWord, basename(__FILE__, '.php'), $writers);
if (!CLI) {
include_once 'Sample_Footer.php';
}
include_once 'Sample_Footer.php';

View File

@ -33,13 +33,7 @@ $section->addText("Left Aligned\tRight Aligned", null, 'rightTab');
$section->addText("\tCenter Aligned", null, 'centerTab');
// Save file
$name = basename(__FILE__, '.php');
$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf');
foreach ($writers as $writer => $extension) {
echo date('H:i:s'), " Write to {$writer} format", EOL;
$xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer);
$xmlWriter->save("{$name}.{$extension}");
rename("{$name}.{$extension}", "results/{$name}.{$extension}");
echo write($phpWord, basename(__FILE__, '.php'), $writers);
if (!CLI) {
include_once 'Sample_Footer.php';
}
include_once 'Sample_Footer.php';

View File

@ -26,13 +26,7 @@ $section->addHeader()->addText('Header');
$section->addFooter()->addText('Footer');
// Save file
$name = basename(__FILE__, '.php');
$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf');
foreach ($writers as $writer => $extension) {
echo date('H:i:s'), " Write to {$writer} format", EOL;
$xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer);
$xmlWriter->save("{$name}.{$extension}");
rename("{$name}.{$extension}", "results/{$name}.{$extension}");
echo write($phpWord, basename(__FILE__, '.php'), $writers);
if (!CLI) {
include_once 'Sample_Footer.php';
}
include_once 'Sample_Footer.php';

View File

@ -34,13 +34,7 @@ $textrun->addObject('resources/_sheet.xls');
$textrun->addText(' Here is some more text. ');
// Save file
$name = basename(__FILE__, '.php');
$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf');
foreach ($writers as $writer => $extension) {
echo date('H:i:s'), " Write to {$writer} format", EOL;
$xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer);
$xmlWriter->save("{$name}.{$extension}");
rename("{$name}.{$extension}", "results/{$name}.{$extension}");
echo write($phpWord, basename(__FILE__, '.php'), $writers);
if (!CLI) {
include_once 'Sample_Footer.php';
}
include_once 'Sample_Footer.php';

View File

@ -36,13 +36,7 @@ $section = $phpWord->addSection(array('breakType' => 'continuous'));
$section->addText('Normal paragraph again.');
// Save file
$name = basename(__FILE__, '.php');
$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf');
foreach ($writers as $writer => $extension) {
echo date('H:i:s'), " Write to {$writer} format", EOL;
$xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer);
$xmlWriter->save("{$name}.{$extension}");
rename("{$name}.{$extension}", "results/{$name}.{$extension}");
echo write($phpWord, basename(__FILE__, '.php'), $writers);
if (!CLI) {
include_once 'Sample_Footer.php';
}
include_once 'Sample_Footer.php';

View File

@ -38,13 +38,7 @@ $footnote = $section->addFootnote();
$footnote->addText('The reference for this is wrapped in its own line');
// Save file
$name = basename(__FILE__, '.php');
$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf');
foreach ($writers as $writer => $extension) {
echo date('H:i:s'), " Write to {$writer} format", EOL;
$xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer);
$xmlWriter->save("{$name}.{$extension}");
rename("{$name}.{$extension}", "results/{$name}.{$extension}");
echo write($phpWord, basename(__FILE__, '.php'), $writers);
if (!CLI) {
include_once 'Sample_Footer.php';
}
include_once 'Sample_Footer.php';

View File

@ -46,13 +46,7 @@ $section->addText('Paragraph with pageBreakBefore = true (default: false). ' .
null, array('pageBreakBefore' => true));
// Save file
$name = basename(__FILE__, '.php');
$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf');
foreach ($writers as $writer => $extension) {
echo date('H:i:s'), " Write to {$writer} format", EOL;
$xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer);
$xmlWriter->save("{$name}.{$extension}");
rename("{$name}.{$extension}", "results/{$name}.{$extension}");
echo write($phpWord, basename(__FILE__, '.php'), $writers);
if (!CLI) {
include_once 'Sample_Footer.php';
}
include_once 'Sample_Footer.php';

View File

@ -85,13 +85,7 @@ $table->addCell(2000, $cellVCentered)->addText('D', null, $cellHCentered);
$table->addCell(null, $cellRowContinue);
// Save file
$name = basename(__FILE__, '.php');
$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf');
foreach ($writers as $writer => $extension) {
echo date('H:i:s'), " Write to {$writer} format", EOL;
$xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer);
$xmlWriter->save("{$name}.{$extension}");
rename("{$name}.{$extension}", "results/{$name}.{$extension}");
echo write($phpWord, basename(__FILE__, '.php'), $writers);
if (!CLI) {
include_once 'Sample_Footer.php';
}
include_once 'Sample_Footer.php';

View File

@ -10,13 +10,7 @@ $header = array('size' => 16, 'bold' => true);
$section->addText('中文楷体样式测试',array('name' => '楷体', 'size' => 16, 'color' => '1B2232'));
// Save file
$name = basename(__FILE__, '.php');
$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf');
foreach ($writers as $writer => $extension) {
echo date('H:i:s'), " Write to {$writer} format", EOL;
$xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer);
$xmlWriter->save("{$name}.{$extension}");
rename("{$name}.{$extension}", "results/{$name}.{$extension}");
echo write($phpWord, basename(__FILE__, '.php'), $writers);
if (!CLI) {
include_once 'Sample_Footer.php';
}
include_once 'Sample_Footer.php';

View File

@ -7,13 +7,8 @@ $source = "resources/{$name}.docx";
echo date('H:i:s'), " Reading contents from `{$source}`", EOL;
$phpWord = \PhpOffice\PhpWord\IOFactory::load($source);
// (Re)write contents
$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf');
foreach ($writers as $writer => $extension) {
echo date('H:i:s'), " Write to {$writer} format", EOL;
$xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer);
$xmlWriter->save("{$name}.{$extension}");
rename("{$name}.{$extension}", "results/{$name}.{$extension}");
// Save file
echo write($phpWord, basename(__FILE__, '.php'), $writers);
if (!CLI) {
include_once 'Sample_Footer.php';
}
include_once 'Sample_Footer.php';

View File

@ -59,15 +59,8 @@ $sec2Header->addText("All pages in Section 2 will Have this!");
$section2->addTextBreak();
$section2->addText('Some text...');
// Save file
$name = basename(__FILE__, '.php');
$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf');
foreach ($writers as $writer => $extension) {
echo date('H:i:s'), " Write to {$writer} format", EOL;
$xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer);
$xmlWriter->save("{$name}.{$extension}");
rename("{$name}.{$extension}", "results/{$name}.{$extension}");
echo write($phpWord, basename(__FILE__, '.php'), $writers);
if (!CLI) {
include_once 'Sample_Footer.php';
}
include_once 'Sample_Footer.php';

View File

@ -18,16 +18,9 @@ $section->addTextBreak(2);
$source = 'http://php.net/images/logos/php-med-trans-light.gif';
$section->addText("Remote image from: {$source}");
$section->addImage($source);
// End code
// Save file
$name = basename(__FILE__, '.php');
$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf');
foreach ($writers as $writer => $extension) {
echo date('H:i:s'), " Write to {$writer} format", EOL;
$xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer);
$xmlWriter->save("{$name}.{$extension}");
rename("{$name}.{$extension}", "results/{$name}.{$extension}");
echo write($phpWord, basename(__FILE__, '.php'), $writers);
if (!CLI) {
include_once 'Sample_Footer.php';
}
include_once 'Sample_Footer.php';

View File

@ -54,15 +54,8 @@ $section->addListItem('List Item 6', 1, 'myOwnStyle', $predefinedMultilevel, 'P-
$section->addListItem('List Item 7', 0, 'myOwnStyle', $predefinedMultilevel, 'P-Style');
$section->addTextBreak(2);
// Save file
$name = basename(__FILE__, '.php');
$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf');
foreach ($writers as $writer => $extension) {
echo date('H:i:s'), " Write to {$writer} format", EOL;
$xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer);
$xmlWriter->save("{$name}.{$extension}");
rename("{$name}.{$extension}", "results/{$name}.{$extension}");
echo write($phpWord, basename(__FILE__, '.php'), $writers);
if (!CLI) {
include_once 'Sample_Footer.php';
}
include_once 'Sample_Footer.php';

View File

@ -16,16 +16,8 @@ $phpWord->addLinkStyle('myOwnLinkStyle', array('bold'=>true, 'color'=>'808000'))
$section->addLink('http://www.bing.com', null, 'myOwnLinkStyle');
$section->addLink('http://www.yahoo.com', null, 'myOwnLinkStyle');
// End code
// Save file
$name = basename(__FILE__, '.php');
$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf');
foreach ($writers as $writer => $extension) {
echo date('H:i:s'), " Write to {$writer} format", EOL;
$xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer);
$xmlWriter->save("{$name}.{$extension}");
rename("{$name}.{$extension}", "results/{$name}.{$extension}");
echo write($phpWord, basename(__FILE__, '.php'), $writers);
if (!CLI) {
include_once 'Sample_Footer.php';
}
include_once 'Sample_Footer.php';

View File

@ -11,16 +11,8 @@ $section->addText('You can open this OLE object by double clicking on the icon:'
$section->addTextBreak(2);
$section->addObject('resources/_sheet.xls');
// End code
// Save file
$name = basename(__FILE__, '.php');
$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf');
foreach ($writers as $writer => $extension) {
echo date('H:i:s'), " Write to {$writer} format", EOL;
$xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer);
$xmlWriter->save("{$name}.{$extension}");
rename("{$name}.{$extension}", "results/{$name}.{$extension}");
echo write($phpWord, basename(__FILE__, '.php'), $writers);
if (!CLI) {
include_once 'Sample_Footer.php';
}
include_once 'Sample_Footer.php';

View File

@ -67,16 +67,9 @@ $section->addTitle('Subtitle 3.1.2', 3);
$section->addText('Text');
echo date('H:i:s'), " Note: Please refresh TOC manually.", EOL;
// End code
// Save file
$name = basename(__FILE__, '.php');
$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf');
foreach ($writers as $writer => $extension) {
echo date('H:i:s'), " Write to {$writer} format", EOL;
$xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer);
$xmlWriter->save("{$name}.{$extension}");
rename("{$name}.{$extension}", "results/{$name}.{$extension}");
echo write($phpWord, basename(__FILE__, '.php'), $writers);
if (!CLI) {
include_once 'Sample_Footer.php';
}
include_once 'Sample_Footer.php';

View File

@ -12,16 +12,8 @@ $header = $section->addHeader();
$header->addWatermark('resources/_earth.jpg', array('marginTop' => 200, 'marginLeft' => 55));
$section->addText('The header reference to the current section includes a watermark image.');
// End code
// Save file
$name = basename(__FILE__, '.php');
$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf');
foreach ($writers as $writer => $extension) {
echo date('H:i:s'), " Write to {$writer} format", EOL;
$xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer);
$xmlWriter->save("{$name}.{$extension}");
rename("{$name}.{$extension}", "results/{$name}.{$extension}");
echo write($phpWord, basename(__FILE__, '.php'), $writers);
if (!CLI) {
include_once 'Sample_Footer.php';
}
include_once 'Sample_Footer.php';

View File

@ -25,16 +25,8 @@ $section->addText('Text break with inline paragraph style:');
$section->addTextBreak(1, null, $paragraphStyle);
$section->addText('Done.');
// End code
// Save file
$name = basename(__FILE__, '.php');
$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf');
foreach ($writers as $writer => $extension) {
echo date('H:i:s'), " Write to {$writer} format", EOL;
$xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer);
$xmlWriter->save("{$name}.{$extension}");
rename("{$name}.{$extension}", "results/{$name}.{$extension}");
echo write($phpWord, basename(__FILE__, '.php'), $writers);
if (!CLI) {
include_once 'Sample_Footer.php';
}
include_once 'Sample_Footer.php';

View File

@ -11,13 +11,7 @@ $section->addText("This one uses bgColor and is using hex value (0xfbbb10)", arr
$section->addText("Compatible with font colors", array("color"=>"0000ff", "bgColor" => "fbbb10"));
// Save file
$name = basename(__FILE__, '.php');
$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf');
foreach ($writers as $writer => $extension) {
echo date('H:i:s'), " Write to {$writer} format", EOL;
$xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer);
$xmlWriter->save("{$name}.{$extension}");
rename("{$name}.{$extension}", "results/{$name}.{$extension}");
echo write($phpWord, basename(__FILE__, '.php'), $writers);
if (!CLI) {
include_once 'Sample_Footer.php';
}
include_once 'Sample_Footer.php';

View File

@ -28,13 +28,7 @@ $section->addText("In this example, image is 250px height. Rows are calculated i
$section->addText("So: $"."table2->addRow(3750, array('exactHeight'=>true));");
// Save file
$name = basename(__FILE__, '.php');
$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf');
foreach ($writers as $writer => $extension) {
echo date('H:i:s'), " Write to {$writer} format", EOL;
$xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer);
$xmlWriter->save("{$name}.{$extension}");
rename("{$name}.{$extension}", "results/{$name}.{$extension}");
echo write($phpWord, basename(__FILE__, '.php'), $writers);
if (!CLI) {
include_once 'Sample_Footer.php';
}
include_once 'Sample_Footer.php';

View File

@ -15,13 +15,7 @@ $cell = $table->addCell();
$cell->addCheckBox('chkBox2', 'Checkbox 2');
// Save file
$name = basename(__FILE__, '.php');
$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf');
foreach ($writers as $writer => $extension) {
echo date('H:i:s'), " Write to {$writer} format", EOL;
$xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer);
$xmlWriter->save("{$name}.{$extension}");
rename("{$name}.{$extension}", "results/{$name}.{$extension}");
echo write($phpWord, basename(__FILE__, '.php'), $writers);
if (!CLI) {
include_once 'Sample_Footer.php';
}
include_once 'Sample_Footer.php';

View File

@ -2,33 +2,10 @@
/**
* Footer file
*/
// Do not show execution time for index
if (!IS_INDEX) {
echo date('H:i:s'), " Done writing file(s)", EOL;
echo date('H:i:s'), " Peak memory usage: ", (memory_get_peak_usage(true) / 1024 / 1024), " MB", EOL;
}
// Show message when executed with CLI, show links when using browsers
if (CLI) {
echo 'The results are stored in the "results" subdirectory.', EOL;
} else {
if (!IS_INDEX) {
$types = array('docx', 'odt', 'rtf');
echo '<p>&nbsp;</p>';
echo '<p>Results: ';
foreach ($types as $type) {
$result = 'results/' . SCRIPT_FILENAME . '.' . $type;
if (file_exists($result)) {
echo "<a href='{$result}' class='btn btn-primary'>{$type}</a> ";
}
}
echo '</p>';
}
?>
</div>
<script src="bootstrap/js/jquery.min.js"></script>
<script src="bootstrap/js/bootstrap.min.js"></script>
</body>
</html>
<?php
} // if (CLI)

View File

@ -21,6 +21,10 @@ $pageHeading = str_replace('_', ' ', SCRIPT_FILENAME);
$pageTitle = IS_INDEX ? 'Welcome to ' : "{$pageHeading} - ";
$pageTitle .= 'PHPWord';
$pageHeading = IS_INDEX ? '' : "<h1>{$pageHeading}</h1>";
// Set writers
$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf', 'HTML' => 'html');
// Populate samples
$files = '';
if ($handle = opendir('.')) {
@ -32,6 +36,52 @@ if ($handle = opendir('.')) {
}
closedir($handle);
}
/**
* Get results
*
* @param array $writers
* @param string $filename
* @return string
*/
function write($phpWord, $filename, $writers)
{
$result = '';
// Write
foreach ($writers as $writer => $extension) {
$result .= date('H:i:s') . " Write to {$writer} format" . EOL;
$xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer);
$xmlWriter->save("{$filename}.{$extension}");
rename("{$filename}.{$extension}", "results/{$filename}.{$extension}");
}
// Do not show execution time for index
if (!IS_INDEX) {
$result .= date('H:i:s') . " Done writing file(s)" . EOL;
$result .= date('H:i:s') . " Peak memory usage: " . (memory_get_peak_usage(true) / 1024 / 1024) . " MB" . EOL;
}
// Return
if (CLI) {
$result .= 'The results are stored in the "results" subdirectory.' . EOL;
} else {
if (!IS_INDEX) {
$types = array_values($writers);
$result .= '<p>&nbsp;</p>';
$result .= '<p>Results: ';
foreach ($types as $type) {
$resultFile = 'results/' . SCRIPT_FILENAME . '.' . $type;
if (file_exists($resultFile)) {
$result .= "<a href='{$resultFile}' class='btn btn-primary'>{$type}</a> ";
}
}
$result .= '</p>';
}
}
return $result;
}
?>
<title><?php echo $pageTitle; ?></title>
<meta charset="utf-8">

View File

@ -24,5 +24,7 @@ foreach ($requirements as $key => $value) {
echo "<li>{$value[0]} ... <span class='{$status}'>{$status}</span></li>";
}
echo "</ul>";
} // if (!CLI)
include_once 'Sample_Footer.php';
}
if (!CLI) {
include_once 'Sample_Footer.php';
}

View File

@ -119,6 +119,16 @@ class Title extends AbstractElement
return $this->text;
}
/**
* Get depth
*
* @return integer
*/
public function getDepth()
{
return $this->depth;
}
/**
* Get Title style
*

View File

@ -28,7 +28,7 @@ abstract class IOFactory
*/
public static function createWriter(PhpWord $phpWord, $name = 'Word2007')
{
if ($name !== 'WriterInterface' && $name !== 'ODText' && $name !== 'RTF' && $name !== 'Word2007') {
if (!in_array($name, array('WriterInterface', 'Word2007', 'ODText', 'RTF', 'HTML'))) {
throw new Exception("\"{$name}\" is not a valid writer.");
}
@ -45,7 +45,7 @@ abstract class IOFactory
*/
public static function createReader($name = 'Word2007')
{
if ($name !== 'ReaderInterface' && $name !== 'Word2007') {
if (!in_array($name, array('ReaderInterface', 'Word2007'))) {
throw new Exception("\"{$name}\" is not a valid reader.");
}

589
src/PhpWord/Writer/HTML.php Normal file
View File

@ -0,0 +1,589 @@
<?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;
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;
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\PhpWord;
use PhpOffice\PhpWord\Style;
use PhpOffice\PhpWord\Style\Font;
use PhpOffice\PhpWord\Style\Paragraph;
use PhpOffice\PhpWord\TOC;
/**
* HTML writer
*
* @since 0.10.0
*/
class HTML extends AbstractWriter implements WriterInterface
{
/**
* 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())) {
$hFile = fopen($filename, 'w') or die("can't open file");
fwrite($hFile, $this->writeDocument());
fclose($hFile);
} else {
throw new Exception("No PHPWord assigned.");
}
}
/**
* Get phpWord data
*
* @return string
*/
private 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 .= '</body>' . PHP_EOL;
$html .= '</html>' . PHP_EOL;
return $html;
}
/**
* Generate HTML header
*
* @return string
*/
public 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
*/
public function writeHTMLBody()
{
$phpWord = $this->getPhpWord();
$html = '';
$sections = $phpWord->getSections();
$countSections = count($sections);
$pSection = 0;
if ($countSections > 0) {
foreach ($sections as $section) {
$pSection++;
$cellContents = $section->getElements();
foreach ($cellContents 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 Footnote) {
$html .= $this->writeFootnote($element, true);
} elseif ($element instanceof Endnote) {
$html .= $this->writeEndnote($element, true);
}
}
}
}
return $html;
}
/**
* Get text
*
* @param 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 .= '<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;
}
/**
* Get text run content
*
* @param TextRun $textrun
* @return string
*/
private function writeTextRun($textrun)
{
$html = '';
$elements = $textrun->getElements();
if (count($elements) > 0) {
$paragraphStyle = $textrun->getParagraphStyle();
$spIsObject = ($paragraphStyle instanceof Paragraph);
$html .= '<p';
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 Footnote) {
$html .= $this->writeFootnote($element, true);
} elseif ($element instanceof Endnote) {
$html .= $this->writeEndnote($element, true);
}
}
$html .= '</p>' . PHP_EOL;
}
return $html;
}
/**
* Write link
*
* @param Link $element
* @return string
*/
private function writeLink($element, $withoutP = false)
{
$url = $element->getLinkSrc();
$text = $element->getLinkName();
$html = '';
if (!$withoutP) {
$html .= "<p>" . PHP_EOL;
}
$html .= "<a href=\"{$url}'\">{$text}</a>" . PHP_EOL;
if (!$withoutP) {
$html .= "</p>" . PHP_EOL;
}
return $html;
}
/**
* Write heading
*
* @param Title $element
* @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
*
* @param PreserveText $element
* @return string
*/
private function writePreserveText($element, $withoutP = false)
{
return $this->writeUnsupportedElement($element, $withoutP);
}
/**
* Get text break
*
* @param TextBreak $element
* @param boolean $withoutP
* @return string
*/
private function writeTextBreak($element, $withoutP = false)
{
if ($withoutP) {
$html = '<br />' . PHP_EOL;
} else {
$html = '<p>&nbsp;</p>' . PHP_EOL;
}
return $html;
}
/**
* Write page break
*
* @param PageBreak $element
* @return string
*/
private function writePageBreak($element)
{
return $this->writeUnsupportedElement($element, false);
}
/**
* Write list item
*
* @param ListItem $element
* @return string
*/
private function writeListItem($element)
{
return $this->writeUnsupportedElement($element, false);
}
/**
* Write table
*
* @param Title $element
* @return string
*/
private function writeTable($element)
{
$html = '';
$rows = $element->getRows();
$cRows = count($rows);
if ($cRows > 0) {
$html .= "<table>" . PHP_EOL;
foreach ($rows as $row) {
$height = $row->getHeight();
$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 Footnote) {
$html .= $this->writeFootnote($element, true);
} elseif ($element instanceof Endnote) {
$html .= $this->writeEndnote($element, true);
}
}
} else {
$this->writeTextBreak($content);
}
$html .= "</td>" . PHP_EOL;
}
$html .= "</tr>" . PHP_EOL;
}
$html .= "</table>" . PHP_EOL;
}
return $html;
}
/**
* Write image
*
* @param Image $element
* @return string
*/
private function writeImage($element, $withoutP = false)
{
return $this->writeUnsupportedElement($element, $withoutP);
}
/**
* Write object
*
* @param Object $element
* @return string
*/
private function writeObject($element, $withoutP = false)
{
return $this->writeUnsupportedElement($element, $withoutP);
}
/**
* Write footnote
*
* @param Footnote $element
* @return string
*/
private function writeFootnote($element)
{
return $this->writeUnsupportedElement($element, true);
}
/**
* Write endnote
*
* @param Endnote $element
* @return string
*/
private function writeEndnote($element)
{
return $this->writeUnsupportedElement($element, true);
}
/**
* 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;
// Default styles
$bodyCss['font-family'] = "'" . $this->getPhpWord()->getDefaultFontName() . "'";
$bodyCss['font-size'] = $this->getPhpWord()->getDefaultFontSize() . 'pt';
$css .= '* ' . $this->assembleCss($bodyCss, true) . PHP_EOL;
// Custom styles
$styles = Style::getStyles();
if (is_array($styles)) {
foreach ($styles as $name => $style) {
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
*
* @param 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 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;
}
}

View File

@ -0,0 +1,105 @@
<?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\Tests\Writer;
use PhpOffice\PhpWord\PhpWord;
use PhpOffice\PhpWord\Writer\HTML;
/**
* Test class for PhpOffice\PhpWord\Writer\HTML
*
* @runTestsInSeparateProcesses
*/
class HTMLTest extends \PHPUnit_Framework_TestCase
{
/**
* Construct
*/
public function testConstruct()
{
$object = new HTML(new PhpWord);
$this->assertInstanceOf('PhpOffice\\PhpWord\\PhpWord', $object->getPhpWord());
}
/**
* Construct with null
*
* @expectedException \PhpOffice\PhpWord\Exception\Exception
* @expectedExceptionMessage No PhpWord assigned.
*/
public function testConstructWithNull()
{
$object = new HTML();
$object->getPhpWord();
}
/**
* Save
*/
public function testSave()
{
$imageSrc = __DIR__ . "/../_files/images/PhpWord.png";
$objectSrc = __DIR__ . "/../_files/documents/sheet.xls";
$file = __DIR__ . "/../_files/temp.html";
$phpWord = new PhpWord();
$docProps = $phpWord->getDocumentProperties();
$docProps->setTitle('HTML Test');
$phpWord->addFontStyle('Font', array('name' => 'Verdana', 'size' => 11, 'color' => 'FF0000', 'fgColor' => 'FF0000'));
$phpWord->addParagraphStyle('Paragraph', array('align' => 'center'));
$section = $phpWord->addSection();
$section->addText('Test 1', 'Font', 'Paragraph');
$section->addTextBreak();
$section->addText('Test 2', array('name' => 'Tahoma', 'bold' => true, 'italic' => true));
$section->addLink('http://test.com');
$section->addTitle('Test', 1);
$section->addPageBreak();
$section->addListItem('Test');
$section->addImage($imageSrc);
$section->addObject($objectSrc);
$section->addFootnote();
$section->addEndnote();
$section = $phpWord->addSection();
$textrun = $section->addTextRun(array('align' => 'center'));
$textrun->addText('Test 3');
$textrun->addTextBreak();
$textrun = $section->addTextRun('Paragraph');
$textrun->addLink('http://test.com');
$textrun->addImage($imageSrc);
$textrun->addFootnote();
$textrun->addEndnote();
$section = $phpWord->addSection();
$table = $section->addTable();
$cell = $table->addRow()->addCell();
$cell->addText('Test 1', array('superscript' => true, 'underline' => 'dash', 'strikethrough' => true));
$cell->addTextRun();
$cell->addLink('http://test.com');
$cell->addTextBreak();
$cell->addListItem('Test');
$cell->addImage($imageSrc);
$cell->addObject($objectSrc);
$cell->addFootnote();
$cell->addEndnote();
$writer = new HTML($phpWord);
$writer->save($file);
$this->assertTrue(file_exists($file));
unlink($file);
}
}