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) v0.15.0 (?? ??? 2018)
---------------------- ----------------------
### Added ### 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 - 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 - 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 Track changes @Cip @troosan #354 #1262
- Add support for fixed Table Layout @aoloe @ekopach @troosan #841 #1276 - Add support for fixed Table Layout @aoloe @ekopach @troosan #841 #1276
- Add support for Cell Spacing @dox07 @troosan #1040
### Fixed ### Fixed
- Fix reading of docx default style - @troosan #1238 - 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*. - ``border(Top|Right|Bottom|Left)Size``. Border size in *twip*.
- ``cellMargin(Top|Right|Bottom|Left)``. Cell margin in *twip*. - ``cellMargin(Top|Right|Bottom|Left)``. Cell margin in *twip*.
- ``width``. Table width in percent. - ``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. - ``layout``. Table layout, either *fixed* or *autofit* See ``\PhpOffice\PhpWord\Style\Table`` for constants.
- ``cellSpacing`` Cell spacing in *twip*
Available Row style options: Available Row style options:

View File

@ -27,7 +27,7 @@ $section->addTextBreak(1);
$section->addText('Fancy table', $header); $section->addText('Fancy table', $header);
$fancyTableStyleName = 'Fancy Table'; $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'); $fancyTableFirstRowStyle = array('borderBottomSize' => 18, 'borderBottomColor' => '0000FF', 'bgColor' => '66BBFF');
$fancyTableCellStyle = array('valign' => 'center'); $fancyTableCellStyle = array('valign' => 'center');
$fancyTableCellBtlrStyle = array('valign' => 'center', 'textDirection' => \PhpOffice\PhpWord\Style\Cell::TEXT_DIR_BTLR); $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["border{$ucfSide}Style"] = array(self::READ_VALUE, "w:tblBorders/w:$side", 'w:val');
} }
$styleDefs['layout'] = array(self::READ_VALUE, 'w:tblLayout', 'w:type'); $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); $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\Jc;
use PhpOffice\PhpWord\SimpleType\JcTable; use PhpOffice\PhpWord\SimpleType\JcTable;
use PhpOffice\PhpWord\SimpleType\TblWidth;
class Table extends Border 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 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) 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) 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 //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 * @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 * @var string Table Layout
@ -152,7 +164,7 @@ class Table extends Border
if ($firstRowStyle !== null && is_array($firstRowStyle)) { if ($firstRowStyle !== null && is_array($firstRowStyle)) {
$this->firstRowStyle = clone $this; $this->firstRowStyle = clone $this;
$this->firstRowStyle->isFirstRow = true; $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); $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 * Set first row
* *
@ -595,8 +623,8 @@ class Table extends Border
*/ */
public function setUnit($value = null) public function setUnit($value = null)
{ {
$enum = array(self::WIDTH_AUTO, self::WIDTH_PERCENT, self::WIDTH_TWIP); TblWidth::validate($value);
$this->unit = $this->setEnumVal($value, $enum, $this->unit); $this->unit = $value;
return $this; return $this;
} }

View File

@ -18,6 +18,7 @@
namespace PhpOffice\PhpWord\Writer\Word2007\Style; namespace PhpOffice\PhpWord\Writer\Word2007\Style;
use PhpOffice\Common\XMLWriter; use PhpOffice\Common\XMLWriter;
use PhpOffice\PhpWord\SimpleType\TblWidth;
use PhpOffice\PhpWord\Style\Table as TableStyle; use PhpOffice\PhpWord\Style\Table as TableStyle;
use PhpOffice\PhpWord\Writer\Word2007\Element\TableAlignment; use PhpOffice\PhpWord\Writer\Word2007\Element\TableAlignment;
@ -49,7 +50,7 @@ class Table extends AbstractStyle
$xmlWriter->writeAttribute('w:val', $style); $xmlWriter->writeAttribute('w:val', $style);
$xmlWriter->endElement(); $xmlWriter->endElement();
if (null !== $this->width) { if (null !== $this->width) {
$this->writeWidth($xmlWriter, $this->width, 'pct'); $this->writeTblWidth($xmlWriter, 'w:tblW', TblWidth::PERCENT, $this->width);
} }
$xmlWriter->endElement(); $xmlWriter->endElement();
} }
@ -76,7 +77,8 @@ class Table extends AbstractStyle
$xmlWriter->endElement(); $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->writeLayout($xmlWriter, $style->getLayout());
$this->writeMargin($xmlWriter, $style); $this->writeMargin($xmlWriter, $style);
$this->writeBorder($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 * 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. * Write row style.
* *

View File

@ -18,6 +18,7 @@
namespace PhpOffice\PhpWord\Reader\Word2007; namespace PhpOffice\PhpWord\Reader\Word2007;
use PhpOffice\PhpWord\AbstractTestReader; use PhpOffice\PhpWord\AbstractTestReader;
use PhpOffice\PhpWord\SimpleType\TblWidth;
use PhpOffice\PhpWord\Style\Table; use PhpOffice\PhpWord\Style\Table;
/** /**
@ -43,4 +44,26 @@ class StyleTest extends AbstractTestReader
$this->assertInstanceOf('PhpOffice\PhpWord\Style\Table', $elements[0]->getStyle()); $this->assertInstanceOf('PhpOffice\PhpWord\Style\Table', $elements[0]->getStyle());
$this->assertEquals(Table::LAYOUT_FIXED, $elements[0]->getStyle()->getLayout()); $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; namespace PhpOffice\PhpWord\Style;
use PhpOffice\PhpWord\SimpleType\JcTable; use PhpOffice\PhpWord\SimpleType\JcTable;
use PhpOffice\PhpWord\SimpleType\TblWidth;
/** /**
* Test class for PhpOffice\PhpWord\Style\Table * Test class for PhpOffice\PhpWord\Style\Table
@ -38,9 +39,6 @@ class TableTest extends \PHPUnit\Framework\TestCase
$styleTable = array('bgColor' => 'FF0000'); $styleTable = array('bgColor' => 'FF0000');
$styleFirstRow = array('borderBottomSize' => 3); $styleFirstRow = array('borderBottomSize' => 3);
$object = new Table();
$this->assertNull($object->getBgColor());
$object = new Table($styleTable, $styleFirstRow); $object = new Table($styleTable, $styleFirstRow);
$this->assertEquals('FF0000', $object->getBgColor()); $this->assertEquals('FF0000', $object->getBgColor());
@ -49,6 +47,18 @@ class TableTest extends \PHPUnit\Framework\TestCase
$this->assertEquals(3, $firstRow->getBorderBottomSize()); $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 * Test setting style with normal value
*/ */
@ -77,6 +87,7 @@ class TableTest extends \PHPUnit\Framework\TestCase
'alignment' => JcTable::CENTER, 'alignment' => JcTable::CENTER,
'width' => 100, 'width' => 100,
'unit' => 'pct', 'unit' => 'pct',
'layout' => Table::LAYOUT_FIXED,
); );
foreach ($attributes as $key => $value) { foreach ($attributes as $key => $value) {
$set = "set{$key}"; $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(); $object = new Table();
$this->assertEquals(Table::LAYOUT_AUTO, $object->getLayout()); $this->assertNull($object->getCellSpacing());
$object->setLayout(Table::LAYOUT_FIXED);
$this->assertEquals(Table::LAYOUT_FIXED, $object->getLayout()); $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->assertTrue($doc->elementExists($path));
$this->assertEquals(Table::LAYOUT_FIXED, $doc->getElementAttribute($path, 'w:type')); $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'));
}
} }