update XE field to support formatted text + add documentation

This commit is contained in:
antoine 2017-06-11 12:56:59 +02:00
parent 6a84b8ed26
commit 8aabf812f8
7 changed files with 177 additions and 56 deletions

View File

@ -358,7 +358,35 @@ To be completed
Fields Fields
------ ------
To be completed Currently the following fields are supported:
- PAGE
- NUMPAGES
- DATE
- XE
- INDEX
.. code-block:: php
$section->addField($fieldType, [$properties], [$options], [$fieldText])
See ``\PhpOffice\PhpWord\Element\Field`` for list of properties and options available for each field type.
Options which are not specifically defined can be added. Those must start with a ``\``.
For instance for the INDEX field, you can do the following (See `Index Field for list of available options <https://support.office.com/en-us/article/Field-codes-Index-field-adafcf4a-cb30-43f6-85c7-743da1635d9e?ui=en-US&rs=en-US&ad=US>`_ ):
.. code-block:: php
//the $fieldText can be either a simple string
$fieldText = 'The index value';
//or a 'TextRun', to be able to format the text you want in the index
$fieldText = new TextRun();
$fieldText->addText('My ');
$fieldText->addText('bold index', ['bold' => true]);
$fieldText->addText(' entry');
$section->addField('INDEX', array(), array('\\e " " \\h "A" \\c "3"'), $fieldText);
Line Line
------ ------

View File

@ -1,4 +1,6 @@
<?php <?php
use PhpOffice\PhpWord\Element\TextRun;
include_once 'Sample_Header.php'; include_once 'Sample_Header.php';
// New Word document // New Word document
@ -21,11 +23,21 @@ $section->addField('NUMPAGES', array('numformat' => '0,00', 'format' => 'Arabic'
$textrun = $section->addTextRun(); $textrun = $section->addTextRun();
$textrun->addText('An index field is '); $textrun->addText('An index field is ');
$textrun->addField('XE', array(), array('Bold'), 'FieldValue'); $textrun->addField('XE', array(), array('Italic'), 'My first index');
$textrun->addText('here:');
$indexEntryText = new TextRun();
$indexEntryText->addText('My ');
$indexEntryText->addText('bold index', ['bold' => true]);
$indexEntryText->addText(' entry');
$textrun = $section->addTextRun();
$textrun->addText('A complex index field is ');
$textrun->addField('XE', array(), array('Bold'), $indexEntryText);
$textrun->addText('here:'); $textrun->addText('here:');
$section->addText('The actual index:'); $section->addText('The actual index:');
$section->addField('INDEX', array(), array('PreserveFormat')); $section->addField('INDEX', array(), array('\\e " "'), 'right click to update the index');
$textrun = $section->addTextRun(array('alignment' => \PhpOffice\PhpWord\SimpleType\Jc::CENTER)); $textrun = $section->addTextRun(array('alignment' => \PhpOffice\PhpWord\SimpleType\Jc::CENTER));
$textrun->addText('This is the date of lunar calendar '); $textrun->addText('This is the date of lunar calendar ');

View File

@ -39,7 +39,7 @@ namespace PhpOffice\PhpWord\Element;
* @method Image addImage(string $source, mixed $style = null, bool $isWatermark = false) * @method Image addImage(string $source, mixed $style = null, bool $isWatermark = false)
* @method Object addObject(string $source, mixed $style = null) * @method Object addObject(string $source, mixed $style = null)
* @method TextBox addTextBox(mixed $style = null) * @method TextBox addTextBox(mixed $style = null)
* @method Field addField(string $type = null, array $properties = array(), array $options = array()) * @method Field addField(string $type = null, array $properties = array(), array $options = array(), mixed $text = null)
* @method Line addLine(mixed $lineStyle = null) * @method Line addLine(mixed $lineStyle = null)
* @method Shape addShape(string $type, mixed $style = null) * @method Shape addShape(string $type, mixed $style = null)
* @method Chart addChart(string $type, array $categories, array $values, array $style = null) * @method Chart addChart(string $type, array $categories, array $values, array $style = null)

View File

@ -74,7 +74,7 @@ class Field extends AbstractElement
/** /**
* Field text * Field text
* *
* @var string * @var TextRun | string
*/ */
protected $text; protected $text;
@ -98,6 +98,7 @@ class Field extends AbstractElement
* @param string $type * @param string $type
* @param array $properties * @param array $properties
* @param array $options * @param array $options
* @param TextRun | string $text
*/ */
public function __construct($type = null, $properties = array(), $options = array(), $text = null) public function __construct($type = null, $properties = array(), $options = array(), $text = null)
{ {
@ -205,16 +206,16 @@ class Field extends AbstractElement
/** /**
* Set Field text * Set Field text
* *
* @param string $text * @param string | TextRun $text
* *
* @return string * @return string | TextRun
* *
* @throws \InvalidArgumentException * @throws \InvalidArgumentException
*/ */
public function setText($text) public function setText($text)
{ {
if (isset($text)) { if (isset($text)) {
if (is_string($text)) { if (is_string($text) || $text instanceof TextRun) {
$this->text = $text; $this->text = $text;
} else { } else {
throw new \InvalidArgumentException("Invalid text"); throw new \InvalidArgumentException("Invalid text");
@ -226,7 +227,7 @@ class Field extends AbstractElement
/** /**
* Get Field text * Get Field text
* *
* @return string * @return string | TextRun
*/ */
public function getText() public function getText()
{ {

View File

@ -17,6 +17,8 @@
namespace PhpOffice\PhpWord\Writer\Word2007\Element; namespace PhpOffice\PhpWord\Writer\Word2007\Element;
use PhpOffice\PhpWord\Element\TextRun;
/** /**
* Field element writer * Field element writer
* *
@ -37,51 +39,6 @@ class Field extends Text
return; return;
} }
$instruction = ' ' . $element->getType() . ' ';
if ($element->getText() != null) {
$instruction .= '"' . $element->getText() . '" ';
}
$properties = $element->getProperties();
foreach ($properties as $propkey => $propval) {
switch ($propkey) {
case 'format':
$instruction .= '\* ' . $propval . ' ';
break;
case 'numformat':
$instruction .= '\# ' . $propval . ' ';
break;
case 'dateformat':
$instruction .= '\@ "' . $propval . '" ';
break;
}
}
$options = $element->getOptions();
foreach ($options as $option) {
switch ($option) {
case 'PreserveFormat':
$instruction .= '\* MERGEFORMAT ';
break;
case 'LunarCalendar':
$instruction .= '\h ';
break;
case 'SakaEraCalendar':
$instruction .= '\s ';
break;
case 'LastUsedFormat':
$instruction .= '\l ';
break;
case 'Bold':
$instruction .= '\b ';
break;
case 'Italic':
$instruction .= '\i ';
break;
default:
$instruction .= $option .' ';
}
}
$this->startElementP(); $this->startElementP();
$xmlWriter->startElement('w:r'); $xmlWriter->startElement('w:r');
@ -90,6 +47,17 @@ class Field extends Text
$xmlWriter->endElement(); // w:fldChar $xmlWriter->endElement(); // w:fldChar
$xmlWriter->endElement(); // w:r $xmlWriter->endElement(); // w:r
$instruction = ' ' . $element->getType() . ' ';
if ($element->getText() != null) {
if (is_string($element->getText())) {
$instruction .= '"' . $element->getText() . '" ';
$instruction .= $this->buildPropertiesAndOptions($element);
} else {
$instruction .= '"';
}
} else {
$instruction .= $this->buildPropertiesAndOptions($element);
}
$xmlWriter->startElement('w:r'); $xmlWriter->startElement('w:r');
$xmlWriter->startElement('w:instrText'); $xmlWriter->startElement('w:instrText');
$xmlWriter->writeAttribute('xml:space', 'preserve'); $xmlWriter->writeAttribute('xml:space', 'preserve');
@ -97,6 +65,27 @@ class Field extends Text
$xmlWriter->endElement(); // w:instrText $xmlWriter->endElement(); // w:instrText
$xmlWriter->endElement(); // w:r $xmlWriter->endElement(); // w:r
if ($element->getText() != null) {
if ($element->getText() instanceof TextRun) {
$containerWriter = new Container($xmlWriter, $element->getText(), true);
$containerWriter->write();
$xmlWriter->startElement('w:r');
$xmlWriter->startElement('w:instrText');
$xmlWriter->text('"' . $this->buildPropertiesAndOptions($element));
$xmlWriter->endElement(); // w:instrText
$xmlWriter->endElement(); // w:r
$xmlWriter->startElement('w:r');
$xmlWriter->startElement('w:instrText');
$xmlWriter->writeAttribute('xml:space', 'preserve');
$xmlWriter->text(' ');
$xmlWriter->endElement(); // w:instrText
$xmlWriter->endElement(); // w:r
}
}
$xmlWriter->startElement('w:r'); $xmlWriter->startElement('w:r');
$xmlWriter->startElement('w:fldChar'); $xmlWriter->startElement('w:fldChar');
$xmlWriter->writeAttribute('w:fldCharType', 'separate'); $xmlWriter->writeAttribute('w:fldCharType', 'separate');
@ -108,9 +97,9 @@ class Field extends Text
$xmlWriter->startElement('w:noProof'); $xmlWriter->startElement('w:noProof');
$xmlWriter->endElement(); // w:noProof $xmlWriter->endElement(); // w:noProof
$xmlWriter->endElement(); // w:rPr $xmlWriter->endElement(); // w:rPr
$xmlWriter->writeElement('w:t', $element->getText() == null ? '1' : $element->getText()); $xmlWriter->writeElement('w:t', $element->getText() != null && is_string($element->getText()) ? $element->getText() : '1');
$xmlWriter->endElement(); // w:r $xmlWriter->endElement(); // w:r
$xmlWriter->startElement('w:r'); $xmlWriter->startElement('w:r');
$xmlWriter->startElement('w:fldChar'); $xmlWriter->startElement('w:fldChar');
$xmlWriter->writeAttribute('w:fldCharType', 'end'); $xmlWriter->writeAttribute('w:fldCharType', 'end');
@ -119,4 +108,50 @@ class Field extends Text
$this->endElementP(); // w:p $this->endElementP(); // w:p
} }
private function buildPropertiesAndOptions(\PhpOffice\PhpWord\Element\Field $element)
{
$propertiesAndOptions = '';
$properties = $element->getProperties();
foreach ($properties as $propkey => $propval) {
switch ($propkey) {
case 'format':
$propertiesAndOptions.= '\* ' . $propval . ' ';
break;
case 'numformat':
$propertiesAndOptions.= '\# ' . $propval . ' ';
break;
case 'dateformat':
$propertiesAndOptions.= '\@ "' . $propval . '" ';
break;
}
}
$options = $element->getOptions();
foreach ($options as $option) {
switch ($option) {
case 'PreserveFormat':
$propertiesAndOptions.= '\* MERGEFORMAT ';
break;
case 'LunarCalendar':
$propertiesAndOptions.= '\h ';
break;
case 'SakaEraCalendar':
$propertiesAndOptions.= '\s ';
break;
case 'LastUsedFormat':
$propertiesAndOptions.= '\l ';
break;
case 'Bold':
$propertiesAndOptions.= '\b ';
break;
case 'Italic':
$propertiesAndOptions.= '\i ';
break;
default:
$propertiesAndOptions.= $option .' ';
}
}
return $propertiesAndOptions;
}
} }

View File

@ -84,6 +84,23 @@ class FieldTest extends \PHPUnit_Framework_TestCase
$this->assertEquals('FieldValue', $oField->getText()); $this->assertEquals('FieldValue', $oField->getText());
} }
/**
* New instance with type and properties and options and text as TextRun
*/
public function testConstructWithTypePropertiesOptionsTextAsTextRun()
{
$textRun = new TextRun();
$textRun->addText('test string');
$oField = new Field('XE', array(), array('Bold', 'Italic'), $textRun);
$this->assertInstanceOf('PhpOffice\\PhpWord\\Element\\Field', $oField);
$this->assertEquals('XE', $oField->getType());
$this->assertEquals(array(), $oField->getProperties());
$this->assertEquals(array('Bold', 'Italic'), $oField->getOptions());
$this->assertInstanceOf('PhpOffice\\PhpWord\\Element\\TextRun', $oField->getText());
}
public function testConstructWithOptionValue() public function testConstructWithOptionValue()
{ {
$oField = new Field('INDEX', array(), array('\\c "3" \\h "A"')); $oField = new Field('INDEX', array(), array('\\c "3" \\h "A"'));

View File

@ -19,6 +19,7 @@ namespace PhpOffice\PhpWord\Writer\Word2007;
use PhpOffice\Common\XMLWriter; use PhpOffice\Common\XMLWriter;
use PhpOffice\PhpWord\PhpWord; use PhpOffice\PhpWord\PhpWord;
use PhpOffice\PhpWord\TestHelperDOCX; use PhpOffice\PhpWord\TestHelperDOCX;
use PhpOffice\PhpWord\Element\TextRun;
/** /**
* Test class for PhpOffice\PhpWord\Writer\Word2007\Element subnamespace * Test class for PhpOffice\PhpWord\Writer\Word2007\Element subnamespace
@ -210,6 +211,33 @@ class ElementTest extends \PHPUnit_Framework_TestCase
$this->assertEquals(' INDEX \\c "3" ', $doc->getElement($element)->textContent); $this->assertEquals(' INDEX \\c "3" ', $doc->getElement($element)->textContent);
} }
public function testFieldElementWithComplexText()
{
$phpWord = new PhpWord();
$section = $phpWord->addSection();
$text = new TextRun();
$text->addText('test string', array('bold' => true));
$section->addField('XE', [], ['Bold', 'Italic'], $text);
$doc = TestHelperDOCX::getDocument($phpWord);
$element = '/w:document/w:body/w:p/w:r[2]/w:instrText';
$this->assertTrue($doc->elementExists($element));
$this->assertEquals(' XE "', $doc->getElement($element)->textContent);
$element = '/w:document/w:body/w:p/w:r[3]/w:rPr/w:b';
$this->assertTrue($doc->elementExists($element));
$element = '/w:document/w:body/w:p/w:r[3]/w:t';
$this->assertTrue($doc->elementExists($element));
$this->assertEquals('test string', $doc->getElement($element)->textContent);
$element = '/w:document/w:body/w:p/w:r[4]/w:instrText';
$this->assertTrue($doc->elementExists($element));
$this->assertEquals('"\\b \\i ', $doc->getElement($element)->textContent);
}
/** /**
* Test form fields * Test form fields
*/ */