Add support for cellSpacing for tables (#1040)

* Add cellSpacing  into table
* add word 2007 reader
* add tests
* add documentation
This commit is contained in:
dox07 2018-02-18 02:10:10 +03:00 committed by troosan
parent ba035185c7
commit 04d0c02e23
10 changed files with 168 additions and 32 deletions

View File

@ -6,11 +6,12 @@ This project adheres to [Semantic Versioning](http://semver.org/).
v0.15.0 (?? ??? 2018)
----------------------
### Added
- Parsing of "align" HTML attribute - @troosan #1231
- Parsing of `align` HTML attribute - @troosan #1231
- Parse formatting inside HTML lists - @troosan @samimussbach #1239 #945 #1215 #508
- Parsing of CSS `direction` instruction, HTML `lang` attribute, formatting inside table cell - @troosan #1273 #1252 #1254
- Add support for Track changes @Cip @troosan #354 #1262
- Add support for fixed Table Layout @aoloe @ekopach @troosan #841 #1276
- Add support for Cell Spacing @dox07 @troosan #1040
### Fixed
- Fix reading of docx default style - @troosan #1238

View File

@ -103,7 +103,9 @@ Available Table style options:
- ``border(Top|Right|Bottom|Left)Size``. Border size in *twip*.
- ``cellMargin(Top|Right|Bottom|Left)``. Cell margin in *twip*.
- ``width``. Table width in percent.
- ``unit``. The unit to use for the width. One of ``\PhpOffice\PhpWord\SimpleType\TblWidth``. Defaults to *auto*.
- ``layout``. Table layout, either *fixed* or *autofit* See ``\PhpOffice\PhpWord\Style\Table`` for constants.
- ``cellSpacing`` Cell spacing in *twip*
Available Row style options:

View File

@ -27,7 +27,7 @@ $section->addTextBreak(1);
$section->addText('Fancy table', $header);
$fancyTableStyleName = 'Fancy Table';
$fancyTableStyle = array('borderSize' => 6, 'borderColor' => '006699', 'cellMargin' => 80, 'alignment' => \PhpOffice\PhpWord\SimpleType\JcTable::CENTER);
$fancyTableStyle = array('borderSize' => 6, 'borderColor' => '006699', 'cellMargin' => 80, 'alignment' => \PhpOffice\PhpWord\SimpleType\JcTable::CENTER, 'cellSpacing' => 50);
$fancyTableFirstRowStyle = array('borderBottomSize' => 18, 'borderBottomColor' => '0000FF', 'bgColor' => '66BBFF');
$fancyTableCellStyle = array('valign' => 'center');
$fancyTableCellBtlrStyle = array('valign' => 'center', 'textDirection' => \PhpOffice\PhpWord\Style\Cell::TEXT_DIR_BTLR);

View File

@ -426,6 +426,7 @@ abstract class AbstractPart
$styleDefs["border{$ucfSide}Style"] = array(self::READ_VALUE, "w:tblBorders/w:$side", 'w:val');
}
$styleDefs['layout'] = array(self::READ_VALUE, 'w:tblLayout', 'w:type');
$styleDefs['cellSpacing'] = array(self::READ_VALUE, 'w:tblCellSpacing', 'w:w');
$style = $this->readStyleDefs($xmlReader, $styleNode, $styleDefs);
}
}

View File

@ -0,0 +1,42 @@
<?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.
*
* @see https://github.com/PHPOffice/PHPWord
* @copyright 2010-2017 PHPWord contributors
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
namespace PhpOffice\PhpWord\SimpleType;
use PhpOffice\PhpWord\Shared\AbstractEnum;
/**
* Table Width Units
*
* @since 0.15.0
*
* @see http://www.datypic.com/sc/ooxml/t-w_ST_TblWidth.html
*/
final class TblWidth extends AbstractEnum
{
//No Width
const NIL = 'nil';
//Automatically Determined Width
const AUTO = 'auto';
//Width in Fiftieths of a Percent
const PERCENT = 'pct';
//Width in Twentieths of a Point
const TWIP = 'dxa';
}

View File

@ -19,14 +19,21 @@ namespace PhpOffice\PhpWord\Style;
use PhpOffice\PhpWord\SimpleType\Jc;
use PhpOffice\PhpWord\SimpleType\JcTable;
use PhpOffice\PhpWord\SimpleType\TblWidth;
class Table extends Border
{
/**
* @const string Table width units http://www.schemacentral.com/sc/ooxml/t-w_ST_TblWidth.html
* @deprecated Use \PhpOffice\PhpWord\SimpleType\TblWidth::AUTO instead
*/
const WIDTH_AUTO = 'auto'; // Automatically determined width
/**
* @deprecated Use \PhpOffice\PhpWord\SimpleType\TblWidth::PERCENT instead
*/
const WIDTH_PERCENT = 'pct'; // Width in fiftieths (1/50) of a percent (1% = 50 unit)
/**
* @deprecated Use \PhpOffice\PhpWord\SimpleType\TblWidth::TWIP instead
*/
const WIDTH_TWIP = 'dxa'; // Width in twentieths (1/20) of a point (twip)
//values for http://www.datypic.com/sc/ooxml/t-w_ST_TblLayoutType.html
@ -133,7 +140,12 @@ class Table extends Border
/**
* @var string Width unit
*/
private $unit = self::WIDTH_AUTO;
private $unit = TblWidth::AUTO;
/**
* @var int|float cell spacing value
*/
protected $cellSpacing = null;
/**
* @var string Table Layout
@ -152,7 +164,7 @@ class Table extends Border
if ($firstRowStyle !== null && is_array($firstRowStyle)) {
$this->firstRowStyle = clone $this;
$this->firstRowStyle->isFirstRow = true;
unset($this->firstRowStyle->firstRowStyle, $this->firstRowStyle->borderInsideHSize, $this->firstRowStyle->borderInsideHColor, $this->firstRowStyle->borderInsideVSize, $this->firstRowStyle->borderInsideVColor, $this->firstRowStyle->cellMarginTop, $this->firstRowStyle->cellMarginLeft, $this->firstRowStyle->cellMarginRight, $this->firstRowStyle->cellMarginBottom);
unset($this->firstRowStyle->firstRowStyle, $this->firstRowStyle->borderInsideHSize, $this->firstRowStyle->borderInsideHColor, $this->firstRowStyle->borderInsideVSize, $this->firstRowStyle->borderInsideVColor, $this->firstRowStyle->cellMarginTop, $this->firstRowStyle->cellMarginLeft, $this->firstRowStyle->cellMarginRight, $this->firstRowStyle->cellMarginBottom, $this->firstRowStyle->cellSpacing);
$this->firstRowStyle->setStyleByArray($firstRowStyle);
}
@ -161,6 +173,22 @@ class Table extends Border
}
}
/**
* @param float|int $cellSpacing
*/
public function setCellSpacing($cellSpacing = null)
{
$this->cellSpacing = $cellSpacing;
}
/**
* @return float|int
*/
public function getCellSpacing()
{
return $this->cellSpacing;
}
/**
* Set first row
*
@ -595,8 +623,8 @@ class Table extends Border
*/
public function setUnit($value = null)
{
$enum = array(self::WIDTH_AUTO, self::WIDTH_PERCENT, self::WIDTH_TWIP);
$this->unit = $this->setEnumVal($value, $enum, $this->unit);
TblWidth::validate($value);
$this->unit = $value;
return $this;
}

View File

@ -18,6 +18,7 @@
namespace PhpOffice\PhpWord\Writer\Word2007\Style;
use PhpOffice\Common\XMLWriter;
use PhpOffice\PhpWord\SimpleType\TblWidth;
use PhpOffice\PhpWord\Style\Table as TableStyle;
use PhpOffice\PhpWord\Writer\Word2007\Element\TableAlignment;
@ -49,7 +50,7 @@ class Table extends AbstractStyle
$xmlWriter->writeAttribute('w:val', $style);
$xmlWriter->endElement();
if (null !== $this->width) {
$this->writeWidth($xmlWriter, $this->width, 'pct');
$this->writeTblWidth($xmlWriter, 'w:tblW', TblWidth::PERCENT, $this->width);
}
$xmlWriter->endElement();
}
@ -76,7 +77,8 @@ class Table extends AbstractStyle
$xmlWriter->endElement();
}
$this->writeWidth($xmlWriter, $style->getWidth(), $style->getUnit());
$this->writeTblWidth($xmlWriter, 'w:tblW', $style->getUnit(), $style->getWidth());
$this->writeTblWidth($xmlWriter, 'w:tblCellSpacing', TblWidth::TWIP, $style->getCellSpacing());
$this->writeLayout($xmlWriter, $style->getLayout());
$this->writeMargin($xmlWriter, $style);
$this->writeBorder($xmlWriter, $style);
@ -92,21 +94,6 @@ class Table extends AbstractStyle
}
}
/**
* Write width.
*
* @param \PhpOffice\Common\XMLWriter $xmlWriter
* @param int $width
* @param string $unit
*/
private function writeWidth(XMLWriter $xmlWriter, $width, $unit)
{
$xmlWriter->startElement('w:tblW');
$xmlWriter->writeAttribute('w:w', $width);
$xmlWriter->writeAttribute('w:type', $unit);
$xmlWriter->endElement(); // w:tblW
}
/**
* Enable/Disable automatic resizing of the table
*
@ -159,6 +146,25 @@ class Table extends AbstractStyle
}
}
/**
* Writes a table width
*
* @param \PhpOffice\Common\XMLWriter $xmlWriter
* @param string $elementName
* @param string $unit
* @param int|float $width
*/
private function writeTblWidth(XMLWriter $xmlWriter, $elementName, $unit, $width = null)
{
if (null === $width) {
return;
}
$xmlWriter->startElement($elementName);
$xmlWriter->writeAttributeIf(null !== $width, 'w:w', $width);
$xmlWriter->writeAttribute('w:type', $unit);
$xmlWriter->endElement();
}
/**
* Write row style.
*

View File

@ -18,6 +18,7 @@
namespace PhpOffice\PhpWord\Reader\Word2007;
use PhpOffice\PhpWord\AbstractTestReader;
use PhpOffice\PhpWord\SimpleType\TblWidth;
use PhpOffice\PhpWord\Style\Table;
/**
@ -43,4 +44,26 @@ class StyleTest extends AbstractTestReader
$this->assertInstanceOf('PhpOffice\PhpWord\Style\Table', $elements[0]->getStyle());
$this->assertEquals(Table::LAYOUT_FIXED, $elements[0]->getStyle()->getLayout());
}
/**
* Test reading of cell spacing
*/
public function testReadCellSpacing()
{
$documentXml = '<w:tbl>
<w:tblPr>
<w:tblCellSpacing w:w="10.5" w:type="dxa"/>
</w:tblPr>
</w:tbl>';
$phpWord = $this->getDocumentFromString($documentXml);
$elements = $this->get($phpWord->getSections(), 0)->getElements();
$this->assertInstanceOf('PhpOffice\PhpWord\Element\Table', $elements[0]);
$this->assertInstanceOf('PhpOffice\PhpWord\Style\Table', $elements[0]->getStyle());
$this->assertEquals(TblWidth::AUTO, $elements[0]->getStyle()->getUnit());
/** @var \PhpOffice\PhpWord\Style\Table $tableStyle */
$tableStyle = $elements[0]->getStyle();
$this->assertEquals(10.5, $tableStyle->getCellSpacing());
}
}

View File

@ -18,6 +18,7 @@
namespace PhpOffice\PhpWord\Style;
use PhpOffice\PhpWord\SimpleType\JcTable;
use PhpOffice\PhpWord\SimpleType\TblWidth;
/**
* Test class for PhpOffice\PhpWord\Style\Table
@ -38,9 +39,6 @@ class TableTest extends \PHPUnit\Framework\TestCase
$styleTable = array('bgColor' => 'FF0000');
$styleFirstRow = array('borderBottomSize' => 3);
$object = new Table();
$this->assertNull($object->getBgColor());
$object = new Table($styleTable, $styleFirstRow);
$this->assertEquals('FF0000', $object->getBgColor());
@ -49,6 +47,18 @@ class TableTest extends \PHPUnit\Framework\TestCase
$this->assertEquals(3, $firstRow->getBorderBottomSize());
}
/**
* Test default values when passing no style
*/
public function testDefaultValues()
{
$object = new Table();
$this->assertNull($object->getBgColor());
$this->assertEquals(Table::LAYOUT_AUTO, $object->getLayout());
$this->assertEquals(TblWidth::AUTO, $object->getUnit());
}
/**
* Test setting style with normal value
*/
@ -77,6 +87,7 @@ class TableTest extends \PHPUnit\Framework\TestCase
'alignment' => JcTable::CENTER,
'width' => 100,
'unit' => 'pct',
'layout' => Table::LAYOUT_FIXED,
);
foreach ($attributes as $key => $value) {
$set = "set{$key}";
@ -174,13 +185,14 @@ class TableTest extends \PHPUnit\Framework\TestCase
}
/**
* Tests table layout
* Tests table cell spacing
*/
public function testTableLayout()
public function testTableCellSpacing()
{
$object = new Table();
$this->assertEquals(Table::LAYOUT_AUTO, $object->getLayout());
$object->setLayout(Table::LAYOUT_FIXED);
$this->assertEquals(Table::LAYOUT_FIXED, $object->getLayout());
$this->assertNull($object->getCellSpacing());
$object = new Table(array('cellSpacing' => 20));
$this->assertEquals(20, $object->getCellSpacing());
}
}

View File

@ -55,4 +55,25 @@ class TableTest extends \PHPUnit\Framework\TestCase
$this->assertTrue($doc->elementExists($path));
$this->assertEquals(Table::LAYOUT_FIXED, $doc->getElementAttribute($path, 'w:type'));
}
/**
* Test write styles
*/
public function testCellSpacing()
{
$tableStyle = new Table();
$tableStyle->setCellSpacing(10.3);
$phpWord = new \PhpOffice\PhpWord\PhpWord();
$section = $phpWord->addSection();
$table = $section->addTable($tableStyle);
$table->addRow();
$doc = TestHelperDOCX::getDocument($phpWord, 'Word2007');
$path = '/w:document/w:body/w:tbl/w:tblPr/w:tblCellSpacing';
$this->assertTrue($doc->elementExists($path));
$this->assertEquals(10.3, $doc->getElementAttribute($path, 'w:w'));
$this->assertEquals(\PhpOffice\PhpWord\SimpleType\TblWidth::TWIP, $doc->getElementAttribute($path, 'w:type'));
}
}