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
|
- 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
|
- 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
|
- 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
|
### Bugfixes
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,13 @@ use PhpOffice\PhpWord\Style\AbstractStyle as Style;
|
||||||
*/
|
*/
|
||||||
abstract class AbstractStyle
|
abstract class AbstractStyle
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Parent writer
|
||||||
|
*
|
||||||
|
* @var \PhpOffice\PhpWord\Writer\AbstractWriter
|
||||||
|
*/
|
||||||
|
private $parentWriter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Style
|
* Style
|
||||||
*
|
*
|
||||||
|
|
@ -48,6 +55,26 @@ abstract class AbstractStyle
|
||||||
$this->style = $style;
|
$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
|
* Get style
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -19,11 +19,13 @@ namespace PhpOffice\PhpWord\Writer\RTF\Part;
|
||||||
|
|
||||||
use PhpOffice\PhpWord\Settings;
|
use PhpOffice\PhpWord\Settings;
|
||||||
use PhpOffice\PhpWord\Writer\RTF\Element\Container;
|
use PhpOffice\PhpWord\Writer\RTF\Element\Container;
|
||||||
|
use PhpOffice\PhpWord\Writer\RTF\Style\Section as SectionStyleWriter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RTF document part writer
|
* RTF document part writer
|
||||||
*
|
*
|
||||||
* @since 0.11.0
|
* @since 0.11.0
|
||||||
|
* @link http://www.biblioscape.com/rtf15_spec.htm#Heading24
|
||||||
*/
|
*/
|
||||||
class Document extends AbstractPart
|
class Document extends AbstractPart
|
||||||
{
|
{
|
||||||
|
|
@ -103,12 +105,19 @@ class Document extends AbstractPart
|
||||||
*/
|
*/
|
||||||
private function writeSections()
|
private function writeSections()
|
||||||
{
|
{
|
||||||
|
|
||||||
$content = '';
|
$content = '';
|
||||||
|
|
||||||
$sections = $this->getParentWriter()->getPhpWord()->getSections();
|
$sections = $this->getParentWriter()->getPhpWord()->getSections();
|
||||||
foreach ($sections as $section) {
|
foreach ($sections as $section) {
|
||||||
$writer = new Container($this->getParentWriter(), $section);
|
$styleWriter = new SectionStyleWriter($section->getSettings());
|
||||||
$content .= $writer->write();
|
$styleWriter->setParentWriter($this->getParentWriter());
|
||||||
|
$content .= $styleWriter->write();
|
||||||
|
|
||||||
|
$elementWriter = new Container($this->getParentWriter(), $section);
|
||||||
|
$content .= $elementWriter->write();
|
||||||
|
|
||||||
|
$content .= '\sect' . PHP_EOL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $content;
|
return $content;
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,15 @@ use PhpOffice\PhpWord\Style\Font;
|
||||||
/**
|
/**
|
||||||
* RTF header part writer
|
* 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
|
* @since 0.11.0
|
||||||
|
* @link http://www.biblioscape.com/rtf15_spec.htm#Heading6
|
||||||
*/
|
*/
|
||||||
class Header extends AbstractPart
|
class Header extends AbstractPart
|
||||||
{
|
{
|
||||||
|
|
@ -141,10 +149,10 @@ class Header extends AbstractPart
|
||||||
$content = '';
|
$content = '';
|
||||||
|
|
||||||
$content .= '{';
|
$content .= '{';
|
||||||
$content .= '\colortbl';
|
$content .= '\colortbl;';
|
||||||
foreach ($this->colorTable as $color) {
|
foreach ($this->colorTable as $color) {
|
||||||
list($red, $green, $blue) = Drawing::htmlToRGB($color);
|
list($red, $green, $blue) = Drawing::htmlToRGB($color);
|
||||||
$content .= ";\\red{$red}\\green{$green}\\blue{$blue}";
|
$content .= "\\red{$red}\\green{$green}\\blue{$blue};";
|
||||||
}
|
}
|
||||||
$content .= '}';
|
$content .= '}';
|
||||||
$content .= PHP_EOL;
|
$content .= PHP_EOL;
|
||||||
|
|
@ -185,6 +193,7 @@ class Header extends AbstractPart
|
||||||
$sections = $phpWord->getSections();
|
$sections = $phpWord->getSections();
|
||||||
foreach ($sections as $section) {
|
foreach ($sections as $section) {
|
||||||
$elements = $section->getElements();
|
$elements = $section->getElements();
|
||||||
|
$this->registerBorderColor($section->getSettings());
|
||||||
foreach ($elements as $element) {
|
foreach ($elements as $element) {
|
||||||
if (method_exists($element, 'getFontStyle')) {
|
if (method_exists($element, 'getFontStyle')) {
|
||||||
$style = $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
|
* Register fonts and colors
|
||||||
*
|
*
|
||||||
|
|
@ -205,9 +229,9 @@ class Header extends AbstractPart
|
||||||
$defaultColor = Settings::DEFAULT_FONT_COLOR;
|
$defaultColor = Settings::DEFAULT_FONT_COLOR;
|
||||||
|
|
||||||
if ($style instanceof Font) {
|
if ($style instanceof Font) {
|
||||||
$this->registerFontItem($this->fontTable, $style->getName(), $defaultFont);
|
$this->registerTableItem($this->fontTable, $style->getName(), $defaultFont);
|
||||||
$this->registerFontItem($this->colorTable, $style->getColor(), $defaultColor);
|
$this->registerTableItem($this->colorTable, $style->getColor(), $defaultColor);
|
||||||
$this->registerFontItem($this->colorTable, $style->getFgColor(), $defaultColor);
|
$this->registerTableItem($this->colorTable, $style->getFgColor(), $defaultColor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -218,7 +242,7 @@ class Header extends AbstractPart
|
||||||
* @param string $value
|
* @param string $value
|
||||||
* @param string $default
|
* @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) {
|
if (in_array($value, $table) === false && $value !== null && $value != $default) {
|
||||||
$table[] = $value;
|
$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()
|
public function testEmptyStyles()
|
||||||
{
|
{
|
||||||
$styles = array('Font', 'Paragraph');
|
$styles = array('Font', 'Paragraph', 'Section');
|
||||||
foreach ($styles as $style) {
|
foreach ($styles as $style) {
|
||||||
$objectClass = 'PhpOffice\\PhpWord\\Writer\\RTF\\Style\\' . $style;
|
$objectClass = 'PhpOffice\\PhpWord\\Writer\\RTF\\Style\\' . $style;
|
||||||
$object = new $objectClass();
|
$object = new $objectClass();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue