RTF Writer: Support for sections, margins, and borders #249
This commit is contained in:
parent
d97602fa98
commit
49f4e6ba64
|
|
@ -9,6 +9,7 @@ This is the changelog between releases of PHPWord. Releases are listed in revers
|
|||
- Element: Ability to add drawing shapes (arc, curve, line, polyline, rect, oval) using new `Shape` element - @ivanlanin GH-123
|
||||
- Font: New `scale`, `spacing`, and `kerning` property of font style - @ivanlanin
|
||||
- Paragraph: Added shading to the paragraph style for full width shading - @lrobert GH-264
|
||||
- RTF Writer: Support for sections, margins, and borders - @ivanlanin GH-249
|
||||
|
||||
### Bugfixes
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,13 @@ use PhpOffice\PhpWord\Style\AbstractStyle as Style;
|
|||
*/
|
||||
abstract class AbstractStyle
|
||||
{
|
||||
/**
|
||||
* Parent writer
|
||||
*
|
||||
* @var \PhpOffice\PhpWord\Writer\AbstractWriter
|
||||
*/
|
||||
private $parentWriter;
|
||||
|
||||
/**
|
||||
* Style
|
||||
*
|
||||
|
|
@ -48,6 +55,26 @@ abstract class AbstractStyle
|
|||
$this->style = $style;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set parent writer
|
||||
*
|
||||
* @param \PhpOffice\PhpWord\Writer\AbstractWriter $writer
|
||||
*/
|
||||
public function setParentWriter($writer)
|
||||
{
|
||||
$this->parentWriter = $writer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get parent writer
|
||||
*
|
||||
* @return \PhpOffice\PhpWord\Writer\AbstractWriter
|
||||
*/
|
||||
public function getParentWriter()
|
||||
{
|
||||
return $this->parentWriter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get style
|
||||
*
|
||||
|
|
|
|||
|
|
@ -19,11 +19,13 @@ namespace PhpOffice\PhpWord\Writer\RTF\Part;
|
|||
|
||||
use PhpOffice\PhpWord\Settings;
|
||||
use PhpOffice\PhpWord\Writer\RTF\Element\Container;
|
||||
use PhpOffice\PhpWord\Writer\RTF\Style\Section as SectionStyleWriter;
|
||||
|
||||
/**
|
||||
* RTF document part writer
|
||||
*
|
||||
* @since 0.11.0
|
||||
* @link http://www.biblioscape.com/rtf15_spec.htm#Heading24
|
||||
*/
|
||||
class Document extends AbstractPart
|
||||
{
|
||||
|
|
@ -103,12 +105,19 @@ class Document extends AbstractPart
|
|||
*/
|
||||
private function writeSections()
|
||||
{
|
||||
|
||||
$content = '';
|
||||
|
||||
$sections = $this->getParentWriter()->getPhpWord()->getSections();
|
||||
foreach ($sections as $section) {
|
||||
$writer = new Container($this->getParentWriter(), $section);
|
||||
$content .= $writer->write();
|
||||
$styleWriter = new SectionStyleWriter($section->getSettings());
|
||||
$styleWriter->setParentWriter($this->getParentWriter());
|
||||
$content .= $styleWriter->write();
|
||||
|
||||
$elementWriter = new Container($this->getParentWriter(), $section);
|
||||
$content .= $elementWriter->write();
|
||||
|
||||
$content .= '\sect' . PHP_EOL;
|
||||
}
|
||||
|
||||
return $content;
|
||||
|
|
|
|||
|
|
@ -25,7 +25,15 @@ use PhpOffice\PhpWord\Style\Font;
|
|||
/**
|
||||
* RTF header part writer
|
||||
*
|
||||
* - Character set
|
||||
* - Font table
|
||||
* - File table (not supported yet)
|
||||
* - Color table
|
||||
* - Style sheet (not supported yet)
|
||||
* - List table (not supported yet)
|
||||
*
|
||||
* @since 0.11.0
|
||||
* @link http://www.biblioscape.com/rtf15_spec.htm#Heading6
|
||||
*/
|
||||
class Header extends AbstractPart
|
||||
{
|
||||
|
|
@ -141,10 +149,10 @@ class Header extends AbstractPart
|
|||
$content = '';
|
||||
|
||||
$content .= '{';
|
||||
$content .= '\colortbl';
|
||||
$content .= '\colortbl;';
|
||||
foreach ($this->colorTable as $color) {
|
||||
list($red, $green, $blue) = Drawing::htmlToRGB($color);
|
||||
$content .= ";\\red{$red}\\green{$green}\\blue{$blue}";
|
||||
$content .= "\\red{$red}\\green{$green}\\blue{$blue};";
|
||||
}
|
||||
$content .= '}';
|
||||
$content .= PHP_EOL;
|
||||
|
|
@ -185,6 +193,7 @@ class Header extends AbstractPart
|
|||
$sections = $phpWord->getSections();
|
||||
foreach ($sections as $section) {
|
||||
$elements = $section->getElements();
|
||||
$this->registerBorderColor($section->getSettings());
|
||||
foreach ($elements as $element) {
|
||||
if (method_exists($element, 'getFontStyle')) {
|
||||
$style = $element->getFontStyle();
|
||||
|
|
@ -194,6 +203,21 @@ class Header extends AbstractPart
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register border colors
|
||||
*
|
||||
* @param \PhpOffice\PhpWord\Style\Border $style
|
||||
*/
|
||||
private function registerBorderColor($style)
|
||||
{
|
||||
$colors = $style->getBorderColor();
|
||||
foreach ($colors as $color) {
|
||||
if ($color !== null) {
|
||||
$this->registerTableItem($this->colorTable, $color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register fonts and colors
|
||||
*
|
||||
|
|
@ -205,9 +229,9 @@ class Header extends AbstractPart
|
|||
$defaultColor = Settings::DEFAULT_FONT_COLOR;
|
||||
|
||||
if ($style instanceof Font) {
|
||||
$this->registerFontItem($this->fontTable, $style->getName(), $defaultFont);
|
||||
$this->registerFontItem($this->colorTable, $style->getColor(), $defaultColor);
|
||||
$this->registerFontItem($this->colorTable, $style->getFgColor(), $defaultColor);
|
||||
$this->registerTableItem($this->fontTable, $style->getName(), $defaultFont);
|
||||
$this->registerTableItem($this->colorTable, $style->getColor(), $defaultColor);
|
||||
$this->registerTableItem($this->colorTable, $style->getFgColor(), $defaultColor);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -218,7 +242,7 @@ class Header extends AbstractPart
|
|||
* @param string $value
|
||||
* @param string $default
|
||||
*/
|
||||
private function registerFontItem(&$table, $value, $default)
|
||||
private function registerTableItem(&$table, $value, $default = null)
|
||||
{
|
||||
if (in_array($value, $table) === false && $value !== null && $value != $default) {
|
||||
$table[] = $value;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,124 @@
|
|||
<?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\RTF\Style;
|
||||
|
||||
use PhpOffice\PhpWord\Shared\XMLWriter;
|
||||
|
||||
/**
|
||||
* Border style writer
|
||||
*
|
||||
* @since 0.12.0
|
||||
*/
|
||||
class Border extends AbstractStyle
|
||||
{
|
||||
/**
|
||||
* Sizes
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $sizes = array();
|
||||
|
||||
/**
|
||||
* Colors
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $colors = array();
|
||||
|
||||
/**
|
||||
* Write style
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function write()
|
||||
{
|
||||
$content = '';
|
||||
|
||||
$sides = array('top', 'left', 'right', 'bottom');
|
||||
$sizeCount = count($this->sizes) - 1;
|
||||
|
||||
// Page border measure
|
||||
// 8 = from text, infront off; 32 = from edge, infront on; 40 = from edge, infront off
|
||||
$content .= '\pgbrdropt32';
|
||||
|
||||
for ($i = 0; $i < $sizeCount; $i++) {
|
||||
if ($this->sizes[$i] !== null) {
|
||||
$color = null;
|
||||
if (isset($this->colors[$i])) {
|
||||
$color = $this->colors[$i];
|
||||
}
|
||||
$content .= $this->writeSide($sides[$i], $this->sizes[$i], $color);
|
||||
}
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write side
|
||||
*
|
||||
* @param string $side
|
||||
* @param int $width
|
||||
* @param string $color
|
||||
* @return string
|
||||
*/
|
||||
private function writeSide($side, $width, $color = '')
|
||||
{
|
||||
/** @var \PhpOffice\PhpWord\Writer\RTF $rtfWriter */
|
||||
$rtfWriter = $this->getParentWriter();
|
||||
$colorIndex = 0;
|
||||
if ($rtfWriter !== null) {
|
||||
$colorTable = $rtfWriter->getColorTable();
|
||||
$index = array_search($color, $colorTable);
|
||||
if ($index !== false && $colorIndex !== null) {
|
||||
$colorIndex = $index + 1;
|
||||
}
|
||||
}
|
||||
|
||||
$content = '';
|
||||
|
||||
$content .= '\pgbrdr' . substr($side, 0, 1);
|
||||
$content .= '\brdrs'; // Single-thickness border; @todo Get other type of border
|
||||
$content .= '\brdrw' . $width; // Width
|
||||
$content .= '\brdrcf' . $colorIndex; // Color
|
||||
$content .= '\brsp480'; // Space in twips between borders and the paragraph (24pt, following OOXML)
|
||||
$content .= ' ';
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set sizes
|
||||
*
|
||||
* @param integer[] $value
|
||||
*/
|
||||
public function setSizes($value)
|
||||
{
|
||||
$this->sizes = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set colors
|
||||
*
|
||||
* @param string[] $value
|
||||
*/
|
||||
public function setColors($value)
|
||||
{
|
||||
$this->colors = $value;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
<?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\RTF\Style;
|
||||
|
||||
use PhpOffice\PhpWord\Style\Section as SectionStyle;
|
||||
|
||||
/**
|
||||
* RTF section style writer
|
||||
*
|
||||
* @since 0.12.0
|
||||
*/
|
||||
class Section extends AbstractStyle
|
||||
{
|
||||
/**
|
||||
* Write style
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function write()
|
||||
{
|
||||
$style = $this->getStyle();
|
||||
if (!$style instanceof SectionStyle) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$content = '';
|
||||
|
||||
$content .= '\sectd ';
|
||||
|
||||
// Size & margin
|
||||
$content .= $this->getValueIf($style->getPageSizeW(), '\pgwsxn' . $style->getPageSizeW());
|
||||
$content .= $this->getValueIf($style->getPageSizeH(), '\pghsxn' . $style->getPageSizeH());
|
||||
$content .= ' ';
|
||||
$content .= $this->getValueIf($style->getMarginTop(), '\margtsxn' . $style->getMarginTop());
|
||||
$content .= $this->getValueIf($style->getMarginRight(), '\margrsxn' . $style->getMarginRight());
|
||||
$content .= $this->getValueIf($style->getMarginBottom(), '\margbsxn' . $style->getMarginBottom());
|
||||
$content .= $this->getValueIf($style->getMarginLeft(), '\marglsxn' . $style->getMarginLeft());
|
||||
$content .= $this->getValueIf($style->getHeaderHeight(), '\headery' . $style->getHeaderHeight());
|
||||
$content .= $this->getValueIf($style->getFooterHeight(), '\footery' . $style->getFooterHeight());
|
||||
$content .= $this->getValueIf($style->getGutter(), '\guttersxn' . $style->getGutter());
|
||||
$content .= ' ';
|
||||
|
||||
// Borders
|
||||
if ($style->hasBorder()) {
|
||||
$styleWriter = new Border($style);
|
||||
$styleWriter->setParentWriter($this->getParentWriter());
|
||||
$styleWriter->setSizes($style->getBorderSize());
|
||||
$styleWriter->setColors($style->getBorderColor());
|
||||
$content .= $styleWriter->write();
|
||||
}
|
||||
|
||||
return $content . PHP_EOL;
|
||||
}
|
||||
}
|
||||
|
|
@ -28,7 +28,7 @@ class StyleTest extends \PHPUnit_Framework_TestCase
|
|||
*/
|
||||
public function testEmptyStyles()
|
||||
{
|
||||
$styles = array('Font', 'Paragraph');
|
||||
$styles = array('Font', 'Paragraph', 'Section');
|
||||
foreach ($styles as $style) {
|
||||
$objectClass = 'PhpOffice\\PhpWord\\Writer\\RTF\\Style\\' . $style;
|
||||
$object = new $objectClass();
|
||||
|
|
|
|||
Loading…
Reference in New Issue