Skip to content

Commit 2205377

Browse files
committed
#245: Basic table support in RTF writer
1 parent e7540c0 commit 2205377

File tree

11 files changed

+177
-10
lines changed

11 files changed

+177
-10
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ This release marked the change of PHPWord license from LGPL 2.1 to LGPL 3. Four
3434
- Element: New `Line` element - @basjan GH-253
3535
- Title: Ability to apply numbering in heading - @ivanlanin GH-193
3636
- HTML Reader: Basic HTML reader - @ivanlanin GH-80 GH-254
37+
- RTF Writer: Basic table writing - @ivanlanin GH-245
3738

3839
### Bugfixes
3940

docs/elements.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ column shows the containers while the rows lists the elements.
2525
+-------+-----------------+-----------+----------+----------+---------+------------+------------+
2626
| 8 | List | v | v | v | v | - | - |
2727
+-------+-----------------+-----------+----------+----------+---------+------------+------------+
28-
| 9 | Table | v | v | v | ? | - | - |
28+
| 9 | Table | v | v | v | v | - | - |
2929
+-------+-----------------+-----------+----------+----------+---------+------------+------------+
3030
| 10 | Image | v | v | v | v | v | v |
3131
+-------+-----------------+-----------+----------+----------+---------+------------+------------+

docs/intro.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ Writers
8181
+---------------------------+----------------------+--------+-------+-------+--------+-------+
8282
| | List || | | | |
8383
+---------------------------+----------------------+--------+-------+-------+--------+-------+
84-
| | Table ||| |||
84+
| | Table ||| |||
8585
+---------------------------+----------------------+--------+-------+-------+--------+-------+
8686
| | Image ||||| |
8787
+---------------------------+----------------------+--------+-------+-------+--------+-------+

docs/src/documentation.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,9 @@ Below are the supported features for each file formats.
9090
| | Link ||||||
9191
| | Preserve Text || | | | |
9292
| | Text Break ||||||
93-
| | Page Break || | | | |
93+
| | Page Break || || | |
9494
| | List || | | | |
95-
| | Table ||| |||
95+
| | Table ||| |||
9696
| | Image ||||| |
9797
| | Object || | | | |
9898
| | Watermark || | | | |
@@ -454,7 +454,7 @@ Below are the matrix of element availability in each container. The column shows
454454
| 6 | Text Break | v | v | v | v | v | v |
455455
| 7 | Page Break | v | - | - | - | - | - |
456456
| 8 | List | v | v | v | v | - | - |
457-
| 9 | Table | v | v | v | ? | - | - |
457+
| 9 | Table | v | v | v | v | - | - |
458458
| 10 | Image | v | v | v | v | v | v |
459459
| 11 | Watermark | - | v | - | - | - | - |
460460
| 12 | Object | v | v | v | v | v | v |

src/PhpWord/Writer/RTF/Element/AbstractElement.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ protected function writeOpening()
9898
}
9999

100100
$styleWriter = new ParagraphStyleWriter($this->paragraphStyle);
101+
$styleWriter->setNestedLevel($this->element->getNestedLevel());
101102
return $styleWriter->write();
102103
}
103104

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
<?php
2+
/**
3+
* This file is part of PHPWord - A pure PHP library for reading and writing
4+
* word processing documents.
5+
*
6+
* PHPWord is free software distributed under the terms of the GNU Lesser
7+
* General Public License version 3 as published by the Free Software Foundation.
8+
*
9+
* For the full copyright and license information, please read the LICENSE
10+
* file that was distributed with this source code. For the full list of
11+
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
12+
*
13+
* @link https://github.com/PHPOffice/PHPWord
14+
* @copyright 2010-2014 PHPWord contributors
15+
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
16+
*/
17+
18+
namespace PhpOffice\PhpWord\Writer\RTF\Element;
19+
20+
use PhpOffice\PhpWord\Element\Cell as CellElement;
21+
use PhpOffice\PhpWord\Element\Row as RowElement;
22+
use PhpOffice\PhpWord\Element\Table as TableElement;
23+
24+
/**
25+
* Table element RTF writer
26+
*
27+
* @since 0.11.0
28+
*/
29+
class Table extends AbstractElement
30+
{
31+
/**
32+
* Write element
33+
*
34+
* @return string
35+
*/
36+
public function write()
37+
{
38+
if (!$this->element instanceof TableElement) {
39+
return '';
40+
}
41+
$element = $this->element;
42+
// No nesting table for now
43+
if ($element->getNestedLevel() >= 1) {
44+
return '';
45+
}
46+
47+
$content = '';
48+
$rows = $element->getRows();
49+
$rowCount = count($rows);
50+
51+
if ($rowCount > 0) {
52+
$content .= '\pard' . PHP_EOL;
53+
54+
for ($i = 0; $i < $rowCount; $i++) {
55+
$content .= '\trowd ';
56+
$content .= $this->writeRowDef($rows[$i]);
57+
$content .= PHP_EOL;
58+
$content .= $this->writeRow($rows[$i]);
59+
$content .= '\row' . PHP_EOL;
60+
}
61+
}
62+
63+
return $content;
64+
}
65+
66+
/**
67+
* Write column
68+
*
69+
* @return string
70+
*/
71+
private function writeRowDef(RowElement $row)
72+
{
73+
$content = '';
74+
75+
$rightMargin = 0;
76+
foreach ($row->getCells() as $cell) {
77+
$width = $cell->getWidth();
78+
$vMerge = $this->getVMerge($cell->getStyle()->getVMerge());
79+
if ($width === null) {
80+
$width = 720; // Arbitrary default width
81+
}
82+
$rightMargin += $width;
83+
$content .= "{$vMerge}\cellx{$rightMargin} ";
84+
}
85+
86+
return $content;
87+
}
88+
89+
/**
90+
* Write row
91+
*
92+
* @return string
93+
*/
94+
private function writeRow(RowElement $row)
95+
{
96+
$content = '';
97+
98+
// Write cells
99+
foreach ($row->getCells() as $cell) {
100+
$content .= $this->writeCell($cell);
101+
}
102+
103+
return $content;
104+
}
105+
106+
/**
107+
* Write cell
108+
*
109+
* @return string
110+
*/
111+
private function writeCell(CellElement $cell)
112+
{
113+
$content = '\intbl' . PHP_EOL;
114+
115+
// Write content
116+
$writer = new Container($this->parentWriter, $cell);
117+
$content .= $writer->write();
118+
119+
$content .= '\cell' . PHP_EOL;
120+
121+
return $content;
122+
}
123+
124+
/**
125+
* Get vertical merge style
126+
*
127+
* @param string $value
128+
* @return string
129+
* @todo Move to style
130+
*/
131+
private function getVMerge($value)
132+
{
133+
$style = '';
134+
if ($value == 'restart') {
135+
$style = '\clvmgf';
136+
} elseif ($value == 'continue') {
137+
$style = '\clvmrg';
138+
}
139+
140+
return $style;
141+
}
142+
}

src/PhpWord/Writer/RTF/Element/TextBreak.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,6 @@ public function write()
3535
$parentWriter = $this->parentWriter;
3636
$parentWriter->setLastParagraphStyle();
3737

38-
return '\par' . PHP_EOL;
38+
return '\pard\par' . PHP_EOL;
3939
}
4040
}

src/PhpWord/Writer/RTF/Style/Paragraph.php

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,16 @@
2626
*/
2727
class Paragraph extends AbstractStyle
2828
{
29+
30+
/**
31+
* Depth of table container nested level; Primarily used for RTF writer/reader
32+
*
33+
* 0 = Not in a table; 1 = in a table; 2 = in a table inside another table, etc.
34+
*
35+
* @var int
36+
*/
37+
private $nestedLevel = 0;
38+
2939
/**
3040
* Write style
3141
*
@@ -49,7 +59,10 @@ public function write()
4959
$spaceAfter = $style->getSpaceAfter();
5060
$spaceBefore = $style->getSpaceBefore();
5161

52-
$content = '\pard\nowidctlpar';
62+
$content = '';
63+
if ($this->nestedLevel == 0) {
64+
$content .= '\pard\nowidctlpar ';
65+
}
5366
if (isset($alignments[$align])) {
5467
$content .= $alignments[$align];
5568
}
@@ -58,4 +71,14 @@ public function write()
5871

5972
return $content;
6073
}
74+
75+
/**
76+
* Set nested level
77+
*
78+
* @param int $value
79+
*/
80+
public function setNestedLevel($value)
81+
{
82+
$this->nestedLevel = $value;
83+
}
6184
}

tests/PhpWord/Tests/Writer/ODTextTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ public function testSave()
7979
$section->addLink('http://test.com');
8080
$section->addTitle('Test', 1);
8181
$section->addPageBreak();
82-
$section->addTable();
82+
$section->addTable()->addRow()->addCell()->addText('Test');
8383
$section->addListItem('Test');
8484
$section->addImage($imageSrc);
8585
$section->addObject($objectSrc);

tests/PhpWord/Tests/Writer/RTF/ElementTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class ElementTest extends \PHPUnit_Framework_TestCase
2828
*/
2929
public function testUnmatchedElements()
3030
{
31-
$elements = array('Container', 'Text', 'Title', 'Link');
31+
$elements = array('Container', 'Text', 'Title', 'Link', 'Table');
3232
foreach ($elements as $element) {
3333
$objectClass = 'PhpOffice\\PhpWord\\Writer\\RTF\\Element\\' . $element;
3434
$parentWriter = new RTF();

tests/PhpWord/Tests/Writer/RTFTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ public function testSave()
6868
$section->addLink('http://test.com');
6969
$section->addTitle('Test', 1);
7070
$section->addPageBreak();
71-
$section->addTable();
71+
$section->addTable()->addRow()->addCell()->addText('Test');
7272
$section->addListItem('Test');
7373
$section->addImage($imageSrc);
7474
$section->addObject($objectSrc);

0 commit comments

Comments
 (0)