Ability to create custom list #10 and to read list definition from DOCX
This commit is contained in:
parent
f837381238
commit
47669f501a
|
|
@ -4,7 +4,7 @@ This is the changelog between releases of PHPWord. Releases are listed in revers
|
||||||
|
|
||||||
## 0.9.2 - Not yet released
|
## 0.9.2 - Not yet released
|
||||||
|
|
||||||
This release marked heavy refactorings on internal code structure with the creation of some abstract classes to reduce code duplication. `Element` subnamespace is introduced in this release to replace `Section`. Word2007 reader capability is greatly enhanced. Endnote is introduced.
|
This release marked heavy refactorings on internal code structure with the creation of some abstract classes to reduce code duplication. `Element` subnamespace is introduced in this release to replace `Section`. Word2007 reader capability is greatly enhanced. Endnote is introduced. List numbering is now customizable.
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
|
|
@ -27,8 +27,9 @@ This release marked heavy refactorings on internal code structure with the creat
|
||||||
- Object: Ability to add object in header, footer, textrun, and footnote - @ivanlanin GH-187
|
- Object: Ability to add object in header, footer, textrun, and footnote - @ivanlanin GH-187
|
||||||
- Media: Add `Media::resetElements()` to reset all media data - @juzi GH-19
|
- Media: Add `Media::resetElements()` to reset all media data - @juzi GH-19
|
||||||
- General: Add `Style::resetStyles()`, `Footnote::resetElements()`, and `TOC::resetTitles()` - @ivanlanin GH-187
|
- General: Add `Style::resetStyles()`, `Footnote::resetElements()`, and `TOC::resetTitles()` - @ivanlanin GH-187
|
||||||
- Reader: Ability to read header, footer, footnotes, link, preservetext, textbreak, pagebreak, table - @ivanlanin
|
- Reader: Ability to read header, footer, footnotes, link, preservetext, textbreak, pagebreak, table, and list - @ivanlanin
|
||||||
- Endnote: Ability to add endnotes - @ivanlanin
|
- Endnote: Ability to add endnotes - @ivanlanin
|
||||||
|
- ListItem: Ability to create custom list and reset list number - @ivanlanin GH-10
|
||||||
|
|
||||||
### Bugfixes
|
### Bugfixes
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,41 +8,52 @@ $phpWord = new \PhpOffice\PhpWord\PhpWord();
|
||||||
// Begin code
|
// Begin code
|
||||||
$section = $phpWord->addSection();
|
$section = $phpWord->addSection();
|
||||||
|
|
||||||
// Add listitem elements
|
// Style definition
|
||||||
$section->addListItem('List Item 1', 0);
|
|
||||||
$section->addListItem('List Item 2', 0);
|
|
||||||
$section->addListItem('List Item 3', 0);
|
|
||||||
$section->addTextBreak(2);
|
|
||||||
|
|
||||||
// Add listitem elements
|
|
||||||
$section->addListItem('List Item 1', 0);
|
|
||||||
$section->addListItem('List Item 1.1', 1);
|
|
||||||
$section->addListItem('List Item 1.2', 1);
|
|
||||||
$section->addListItem('List Item 1.3 (styled)', 1, array('bold'=>true));
|
|
||||||
$section->addListItem('List Item 1.3.1', 2);
|
|
||||||
$section->addListItem('List Item 1.3.2', 2);
|
|
||||||
$section->addTextBreak(2);
|
|
||||||
|
|
||||||
// Add listitem elements
|
|
||||||
$listStyle = array('listType' => \PhpOffice\PhpWord\Style\ListItem::TYPE_NUMBER);
|
|
||||||
$section->addListItem('List Item 1', 0, null, $listStyle);
|
|
||||||
$section->addListItem('List Item 2', 0, null, $listStyle);
|
|
||||||
$section->addListItem('List Item 3', 0, null, $listStyle);
|
|
||||||
$section->addTextBreak(2);
|
|
||||||
|
|
||||||
// Add listitem elements
|
|
||||||
$phpWord->addFontStyle('myOwnStyle', array('color'=>'FF0000'));
|
$phpWord->addFontStyle('myOwnStyle', array('color'=>'FF0000'));
|
||||||
$phpWord->addParagraphStyle('P-Style', array('spaceAfter'=>95));
|
$phpWord->addParagraphStyle('P-Style', array('spaceAfter'=>95));
|
||||||
$listStyle = array('listType' => \PhpOffice\PhpWord\Style\ListItem::TYPE_NUMBER_NESTED);
|
$phpWord->addNumberingStyle(
|
||||||
$section->addListItem('List Item 1', 0, 'myOwnStyle', $listStyle, 'P-Style');
|
'multilevel',
|
||||||
$section->addListItem('List Item 2', 0, 'myOwnStyle', $listStyle, 'P-Style');
|
array('type' => 'multilevel', 'levels' => array(
|
||||||
$section->addListItem('List Item 3', 1, 'myOwnStyle', $listStyle, 'P-Style');
|
array('format' => 'decimal', 'text' => '%1.', 'left' => 360, 'hanging' => 360, 'tabPos' => 360),
|
||||||
$section->addListItem('List Item 4', 1, 'myOwnStyle', $listStyle, 'P-Style');
|
array('format' => 'upperLetter', 'text' => '%2.', 'left' => 720, 'hanging' => 360, 'tabPos' => 720),
|
||||||
$section->addListItem('List Item 5', 2, 'myOwnStyle', $listStyle, 'P-Style');
|
)
|
||||||
$section->addListItem('List Item 6', 1, 'myOwnStyle', $listStyle, 'P-Style');
|
)
|
||||||
$section->addListItem('List Item 7', 0, 'myOwnStyle', $listStyle, 'P-Style');
|
);
|
||||||
|
$predefinedMultilevel = array('listType' => \PhpOffice\PhpWord\Style\ListItem::TYPE_NUMBER_NESTED);
|
||||||
|
|
||||||
|
// Lists
|
||||||
|
|
||||||
|
$section->addText('Multilevel list.');
|
||||||
|
$section->addListItem('List Item I', 0, null, 'multilevel');
|
||||||
|
$section->addListItem('List Item I.a', 1, null, 'multilevel');
|
||||||
|
$section->addListItem('List Item I.b', 1, null, 'multilevel');
|
||||||
|
$section->addListItem('List Item II', 0, null, 'multilevel');
|
||||||
|
$section->addListItem('List Item II.a', 1, null, 'multilevel');
|
||||||
|
$section->addListItem('List Item III', 0, null, 'multilevel');
|
||||||
|
$section->addTextBreak(2);
|
||||||
|
|
||||||
|
$section->addText('Basic simple bulleted list.');
|
||||||
|
$section->addListItem('List Item 1');
|
||||||
|
$section->addListItem('List Item 2');
|
||||||
|
$section->addListItem('List Item 3');
|
||||||
|
$section->addTextBreak(2);
|
||||||
|
|
||||||
|
$section->addText('Continue from multilevel list above.');
|
||||||
|
$section->addListItem('List Item IV', 0, null, 'multilevel');
|
||||||
|
$section->addListItem('List Item IV.a', 1, null, 'multilevel');
|
||||||
|
$section->addTextBreak(2);
|
||||||
|
|
||||||
|
$section->addText('Multilevel predefined list.');
|
||||||
|
$section->addListItem('List Item 1', 0, 'myOwnStyle', $predefinedMultilevel, 'P-Style');
|
||||||
|
$section->addListItem('List Item 2', 0, 'myOwnStyle', $predefinedMultilevel, 'P-Style');
|
||||||
|
$section->addListItem('List Item 3', 1, 'myOwnStyle', $predefinedMultilevel, 'P-Style');
|
||||||
|
$section->addListItem('List Item 4', 1, 'myOwnStyle', $predefinedMultilevel, 'P-Style');
|
||||||
|
$section->addListItem('List Item 5', 2, 'myOwnStyle', $predefinedMultilevel, 'P-Style');
|
||||||
|
$section->addListItem('List Item 6', 1, 'myOwnStyle', $predefinedMultilevel, 'P-Style');
|
||||||
|
$section->addListItem('List Item 7', 0, 'myOwnStyle', $predefinedMultilevel, 'P-Style');
|
||||||
|
$section->addTextBreak(2);
|
||||||
|
|
||||||
// End code
|
|
||||||
|
|
||||||
// Save file
|
// Save file
|
||||||
$name = basename(__FILE__, '.php');
|
$name = basename(__FILE__, '.php');
|
||||||
|
|
|
||||||
|
|
@ -469,9 +469,6 @@ abstract class AbstractElement
|
||||||
{
|
{
|
||||||
if (!is_null($styleValue) && is_array($styleValue)) {
|
if (!is_null($styleValue) && is_array($styleValue)) {
|
||||||
foreach ($styleValue as $key => $value) {
|
foreach ($styleValue as $key => $value) {
|
||||||
if (substr($key, 0, 1) == '_') {
|
|
||||||
$key = substr($key, 1);
|
|
||||||
}
|
|
||||||
$styleObject->setStyleValue($key, $value);
|
$styleObject->setStyleValue($key, $value);
|
||||||
}
|
}
|
||||||
$style = $styleObject;
|
$style = $styleObject;
|
||||||
|
|
|
||||||
|
|
@ -44,15 +44,21 @@ class ListItem extends AbstractElement
|
||||||
*
|
*
|
||||||
* @param string $text
|
* @param string $text
|
||||||
* @param int $depth
|
* @param int $depth
|
||||||
* @param mixed $styleFont
|
* @param mixed $fontStyle
|
||||||
* @param mixed $styleList
|
* @param array|string|null $listStyle
|
||||||
* @param mixed $styleParagraph
|
* @param mixed $paragraphStyle
|
||||||
*/
|
*/
|
||||||
public function __construct($text, $depth = 0, $styleFont = null, $styleList = null, $styleParagraph = null)
|
public function __construct($text, $depth = 0, $fontStyle = null, $listStyle = null, $paragraphStyle = null)
|
||||||
{
|
{
|
||||||
$this->textObject = new Text($text, $styleFont, $styleParagraph);
|
$this->textObject = new Text($text, $fontStyle, $paragraphStyle);
|
||||||
$this->depth = $depth;
|
$this->depth = $depth;
|
||||||
$this->style = $this->setStyle(new ListItemStyle(), $styleList, true);
|
|
||||||
|
// Version >= 0.9.2 will pass numbering style name. Older version will use old method
|
||||||
|
if (!is_null($listStyle) && is_string($listStyle)) {
|
||||||
|
$this->style = new ListItemStyle($listStyle);
|
||||||
|
} else {
|
||||||
|
$this->style = $this->setStyle(new ListItemStyle(), $listStyle, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,6 @@
|
||||||
|
|
||||||
namespace PhpOffice\PhpWord;
|
namespace PhpOffice\PhpWord;
|
||||||
|
|
||||||
use PhpOffice\PhpWord\Media;
|
|
||||||
use PhpOffice\PhpWord\Element\Endnote;
|
use PhpOffice\PhpWord\Element\Endnote;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -214,6 +214,17 @@ class PhpWord
|
||||||
Style::addLinkStyle($styleName, $styles);
|
Style::addLinkStyle($styleName, $styles);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a numbering style
|
||||||
|
*
|
||||||
|
* @param string $styleName
|
||||||
|
* @param mixed $styles
|
||||||
|
*/
|
||||||
|
public function addNumberingStyle($styleName, $styles)
|
||||||
|
{
|
||||||
|
Style::addNumberingStyle($styleName, $styles);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get all sections
|
* Get all sections
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,6 @@ namespace PhpOffice\PhpWord\Reader;
|
||||||
|
|
||||||
use PhpOffice\PhpWord\PhpWord;
|
use PhpOffice\PhpWord\PhpWord;
|
||||||
use PhpOffice\PhpWord\Settings;
|
use PhpOffice\PhpWord\Settings;
|
||||||
use PhpOffice\PhpWord\Footnote;
|
|
||||||
use PhpOffice\PhpWord\Endnotes;
|
|
||||||
use PhpOffice\PhpWord\DocumentProperties;
|
use PhpOffice\PhpWord\DocumentProperties;
|
||||||
use PhpOffice\PhpWord\Shared\XMLReader;
|
use PhpOffice\PhpWord\Shared\XMLReader;
|
||||||
use PhpOffice\PhpWord\Element\Section;
|
use PhpOffice\PhpWord\Element\Section;
|
||||||
|
|
@ -52,6 +50,19 @@ class Word2007 extends AbstractReader implements ReaderInterface
|
||||||
|
|
||||||
$this->readRelationships($filename);
|
$this->readRelationships($filename);
|
||||||
|
|
||||||
|
|
||||||
|
// Read styles and numbering first
|
||||||
|
foreach ($this->rels['document'] as $rId => $rel) {
|
||||||
|
switch ($rel['type']) {
|
||||||
|
case 'styles':
|
||||||
|
$this->readStyles($filename, $rel['target']);
|
||||||
|
break;
|
||||||
|
case 'numbering':
|
||||||
|
$this->readNumbering($filename, $rel['target']);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Read main relationship
|
// Read main relationship
|
||||||
foreach ($this->rels['main'] as $rId => $rel) {
|
foreach ($this->rels['main'] as $rId => $rel) {
|
||||||
switch ($rel['type']) {
|
switch ($rel['type']) {
|
||||||
|
|
@ -87,14 +98,9 @@ class Word2007 extends AbstractReader implements ReaderInterface
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read document relationships
|
// Read footnotes and endnotes
|
||||||
foreach ($this->rels['document'] as $rId => $rel) {
|
foreach ($this->rels['document'] as $rId => $rel) {
|
||||||
switch ($rel['type']) {
|
switch ($rel['type']) {
|
||||||
|
|
||||||
case 'styles':
|
|
||||||
$this->readStyles($filename, $rel['target']);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'footnotes':
|
case 'footnotes':
|
||||||
case 'endnotes':
|
case 'endnotes':
|
||||||
$this->readNotes($filename, $rel['target'], $rel['type']);
|
$this->readNotes($filename, $rel['target'], $rel['type']);
|
||||||
|
|
@ -178,7 +184,6 @@ class Word2007 extends AbstractReader implements ReaderInterface
|
||||||
$nodes = $xmlReader->getElements('*');
|
$nodes = $xmlReader->getElements('*');
|
||||||
if ($nodes->length > 0) {
|
if ($nodes->length > 0) {
|
||||||
foreach ($nodes as $node) {
|
foreach ($nodes as $node) {
|
||||||
$nodeName = $node->nodeName;
|
|
||||||
$propertyName = $xmlReader->getAttribute('name', $node);
|
$propertyName = $xmlReader->getAttribute('name', $node);
|
||||||
$attributeNode = $xmlReader->getElement('*', $node);
|
$attributeNode = $xmlReader->getElement('*', $node);
|
||||||
$attributeType = $attributeNode->nodeName;
|
$attributeType = $attributeNode->nodeName;
|
||||||
|
|
@ -206,6 +211,7 @@ class Word2007 extends AbstractReader implements ReaderInterface
|
||||||
$section = $this->phpWord->addSection();
|
$section = $this->phpWord->addSection();
|
||||||
foreach ($nodes as $node) {
|
foreach ($nodes as $node) {
|
||||||
switch ($node->nodeName) {
|
switch ($node->nodeName) {
|
||||||
|
|
||||||
case 'w:p': // Paragraph
|
case 'w:p': // Paragraph
|
||||||
if ($xmlReader->getAttribute('w:type', $node, 'w:r/w:br') == 'page') {
|
if ($xmlReader->getAttribute('w:type', $node, 'w:r/w:br') == 'page') {
|
||||||
$section->addPageBreak(); // PageBreak
|
$section->addPageBreak(); // PageBreak
|
||||||
|
|
@ -221,9 +227,11 @@ class Word2007 extends AbstractReader implements ReaderInterface
|
||||||
$section = $this->phpWord->addSection();
|
$section = $this->phpWord->addSection();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'w:tbl': // Table
|
case 'w:tbl': // Table
|
||||||
$this->readTable($xmlReader, $node, $section, 'document');
|
$this->readTable($xmlReader, $node, $section, 'document');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'w:sectPr': // Last section
|
case 'w:sectPr': // Last section
|
||||||
$settings = $this->readSectionStyle($xmlReader, $node);
|
$settings = $this->readSectionStyle($xmlReader, $node);
|
||||||
$section->setSettings($settings);
|
$section->setSettings($settings);
|
||||||
|
|
@ -255,6 +263,7 @@ class Word2007 extends AbstractReader implements ReaderInterface
|
||||||
}
|
}
|
||||||
// $default = ($xmlReader->getAttribute('w:default', $node) == 1);
|
// $default = ($xmlReader->getAttribute('w:default', $node) == 1);
|
||||||
switch ($type) {
|
switch ($type) {
|
||||||
|
|
||||||
case 'paragraph':
|
case 'paragraph':
|
||||||
$pStyle = $this->readParagraphStyle($xmlReader, $node);
|
$pStyle = $this->readParagraphStyle($xmlReader, $node);
|
||||||
$fStyle = $this->readFontStyle($xmlReader, $node);
|
$fStyle = $this->readFontStyle($xmlReader, $node);
|
||||||
|
|
@ -264,12 +273,14 @@ class Word2007 extends AbstractReader implements ReaderInterface
|
||||||
$this->phpWord->addFontStyle($name, $fStyle, $pStyle);
|
$this->phpWord->addFontStyle($name, $fStyle, $pStyle);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'character':
|
case 'character':
|
||||||
$fStyle = $this->readFontStyle($xmlReader, $node);
|
$fStyle = $this->readFontStyle($xmlReader, $node);
|
||||||
if (!empty($fStyle)) {
|
if (!empty($fStyle)) {
|
||||||
$this->phpWord->addFontStyle($name, $fStyle);
|
$this->phpWord->addFontStyle($name, $fStyle);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'table':
|
case 'table':
|
||||||
$tStyle = $this->readTableStyle($xmlReader, $node);
|
$tStyle = $this->readTableStyle($xmlReader, $node);
|
||||||
if (!empty($tStyle)) {
|
if (!empty($tStyle)) {
|
||||||
|
|
@ -281,6 +292,98 @@ class Word2007 extends AbstractReader implements ReaderInterface
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read numbering.xml
|
||||||
|
*
|
||||||
|
* @param string $filename
|
||||||
|
* @param string $xmlFile
|
||||||
|
*/
|
||||||
|
private function readNumbering($filename, $xmlFile)
|
||||||
|
{
|
||||||
|
$abstracts = array();
|
||||||
|
$numberings = array();
|
||||||
|
$xmlReader = new XMLReader();
|
||||||
|
$xmlReader->getDomFromZip($filename, $xmlFile);
|
||||||
|
|
||||||
|
// Abstract numbering definition
|
||||||
|
$nodes = $xmlReader->getElements('w:abstractNum');
|
||||||
|
if ($nodes->length > 0) {
|
||||||
|
foreach ($nodes as $node) {
|
||||||
|
$abstractId = $xmlReader->getAttribute('w:abstractNumId', $node);
|
||||||
|
$abstracts[$abstractId] = array('levels' => array());
|
||||||
|
$abstract = &$abstracts[$abstractId];
|
||||||
|
$subnodes = $xmlReader->getElements('*', $node);
|
||||||
|
foreach ($subnodes as $subnode) {
|
||||||
|
switch ($subnode->nodeName) {
|
||||||
|
case 'w:multiLevelType':
|
||||||
|
$abstract['type'] = $xmlReader->getAttribute('w:val', $subnode);
|
||||||
|
break;
|
||||||
|
case 'w:lvl':
|
||||||
|
$levelId = $xmlReader->getAttribute('w:ilvl', $subnode);
|
||||||
|
$abstract['levels'][$levelId] = $this->readNumberingLevel($xmlReader, $subnode, $levelId);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Numbering instance definition
|
||||||
|
$nodes = $xmlReader->getElements('w:num');
|
||||||
|
if ($nodes->length > 0) {
|
||||||
|
foreach ($nodes as $node) {
|
||||||
|
$numId = $xmlReader->getAttribute('w:numId', $node);
|
||||||
|
$abstractId = $xmlReader->getAttribute('w:val', $node, 'w:abstractNumId');
|
||||||
|
$numberings[$numId] = $abstracts[$abstractId];
|
||||||
|
$numberings[$numId]['numId'] = $numId;
|
||||||
|
$subnodes = $xmlReader->getElements('w:lvlOverride/w:lvl', $node);
|
||||||
|
foreach ($subnodes as $subnode) {
|
||||||
|
$levelId = $xmlReader->getAttribute('w:ilvl', $subnode);
|
||||||
|
$overrides = $this->readNumberingLevel($xmlReader, $subnode, $levelId);
|
||||||
|
foreach ($overrides as $key => $value) {
|
||||||
|
$numberings[$numId]['levels'][$levelId][$key] = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Push to Style collection
|
||||||
|
foreach ($numberings as $numId => $numbering) {
|
||||||
|
$this->phpWord->addNumberingStyle("PHPWordList{$numId}", $numbering);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read numbering level definition from w:abstractNum and w:num
|
||||||
|
*
|
||||||
|
* @param integer $levelId
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
private function readNumberingLevel(XMLReader $xmlReader, \DOMElement $subnode, $levelId)
|
||||||
|
{
|
||||||
|
$level = array();
|
||||||
|
|
||||||
|
$level['level'] = $levelId;
|
||||||
|
$level['start'] = $xmlReader->getAttribute('w:val', $subnode, 'w:start');
|
||||||
|
$level['format'] = $xmlReader->getAttribute('w:val', $subnode, 'w:numFmt');
|
||||||
|
$level['restart'] = $xmlReader->getAttribute('w:val', $subnode, 'w:lvlRestart');
|
||||||
|
$level['suffix'] = $xmlReader->getAttribute('w:val', $subnode, 'w:suff');
|
||||||
|
$level['text'] = $xmlReader->getAttribute('w:val', $subnode, 'w:lvlText');
|
||||||
|
$level['align'] = $xmlReader->getAttribute('w:val', $subnode, 'w:lvlJc');
|
||||||
|
$level['tab'] = $xmlReader->getAttribute('w:pos', $subnode, 'w:pPr/w:tabs/w:tab');
|
||||||
|
$level['left'] = $xmlReader->getAttribute('w:left', $subnode, 'w:pPr/w:ind');
|
||||||
|
$level['hanging'] = $xmlReader->getAttribute('w:hanging', $subnode, 'w:pPr/w:ind');
|
||||||
|
$level['font'] = $xmlReader->getAttribute('w:ascii', $subnode, 'w:rPr/w:rFonts');
|
||||||
|
$level['hint'] = $xmlReader->getAttribute('w:hint', $subnode, 'w:rPr/w:rFonts');
|
||||||
|
|
||||||
|
foreach ($level as $key => $value) {
|
||||||
|
if (is_null($value)) {
|
||||||
|
unset($level[$key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $level;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read header footer
|
* Read header footer
|
||||||
*
|
*
|
||||||
|
|
@ -325,6 +428,7 @@ class Word2007 extends AbstractReader implements ReaderInterface
|
||||||
*
|
*
|
||||||
* @param string $filename
|
* @param string $filename
|
||||||
* @param string $xmlFile
|
* @param string $xmlFile
|
||||||
|
* @param string $notesType
|
||||||
*/
|
*/
|
||||||
private function readNotes($filename, $xmlFile, $notesType = 'footnotes')
|
private function readNotes($filename, $xmlFile, $notesType = 'footnotes')
|
||||||
{
|
{
|
||||||
|
|
@ -362,7 +466,7 @@ class Word2007 extends AbstractReader implements ReaderInterface
|
||||||
*
|
*
|
||||||
* @todo Get font style for preserve text
|
* @todo Get font style for preserve text
|
||||||
*/
|
*/
|
||||||
private function readParagraph(XMLReader $xmlReader, \DOMNode $domNode, &$parent, $docPart)
|
private function readParagraph(XMLReader $xmlReader, \DOMElement $domNode, &$parent, $docPart)
|
||||||
{
|
{
|
||||||
// Paragraph style
|
// Paragraph style
|
||||||
$pStyle = null;
|
$pStyle = null;
|
||||||
|
|
@ -396,6 +500,17 @@ class Word2007 extends AbstractReader implements ReaderInterface
|
||||||
}
|
}
|
||||||
$parent->addPreserveText($textContent, $fStyle, $pStyle);
|
$parent->addPreserveText($textContent, $fStyle, $pStyle);
|
||||||
|
|
||||||
|
// List item
|
||||||
|
} elseif ($xmlReader->elementExists('w:pPr/w:numPr', $domNode)) {
|
||||||
|
$textContent = '';
|
||||||
|
$numId = $xmlReader->getAttribute('w:val', $domNode, 'w:pPr/w:numPr/w:numId');
|
||||||
|
$levelId = $xmlReader->getAttribute('w:val', $domNode, 'w:pPr/w:numPr/w:ilvl');
|
||||||
|
$nodes = $xmlReader->getElements('w:r', $domNode);
|
||||||
|
foreach ($nodes as $node) {
|
||||||
|
$textContent .= $xmlReader->getValue('w:t', $node);
|
||||||
|
}
|
||||||
|
$parent->addListItem($textContent, $levelId, null, "PHPWordList{$numId}", $pStyle);
|
||||||
|
|
||||||
// Text and TextRun
|
// Text and TextRun
|
||||||
} else {
|
} else {
|
||||||
$runCount = $xmlReader->countElements('w:r', $domNode);
|
$runCount = $xmlReader->countElements('w:r', $domNode);
|
||||||
|
|
@ -421,13 +536,15 @@ class Word2007 extends AbstractReader implements ReaderInterface
|
||||||
/**
|
/**
|
||||||
* Read w:r
|
* Read w:r
|
||||||
*
|
*
|
||||||
|
* @param \PhpOffice\PhpWord\Shared\XMLReader $xmlReader
|
||||||
|
* @param \DOMElement $domNode
|
||||||
* @param mixed $parent
|
* @param mixed $parent
|
||||||
* @param string $docPart
|
* @param string $docPart
|
||||||
* @param mixed $pStyle
|
* @param mixed $pStyle
|
||||||
*
|
*
|
||||||
* @todo Footnote paragraph style
|
* @todo Footnote paragraph style
|
||||||
*/
|
*/
|
||||||
private function readRun(XMLReader $xmlReader, \DOMNode $domNode, &$parent, $docPart, $pStyle = null)
|
private function readRun(XMLReader $xmlReader, \DOMElement $domNode, &$parent, $docPart, $pStyle = null)
|
||||||
{
|
{
|
||||||
if (!in_array($domNode->nodeName, array('w:r', 'w:hyperlink'))) {
|
if (!in_array($domNode->nodeName, array('w:r', 'w:hyperlink'))) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -484,7 +601,7 @@ class Word2007 extends AbstractReader implements ReaderInterface
|
||||||
* @param mixed $parent
|
* @param mixed $parent
|
||||||
* @param string $docPart
|
* @param string $docPart
|
||||||
*/
|
*/
|
||||||
private function readTable(XMLReader $xmlReader, \DOMNode $domNode, &$parent, $docPart)
|
private function readTable(XMLReader $xmlReader, \DOMElement $domNode, &$parent, $docPart)
|
||||||
{
|
{
|
||||||
// Table style
|
// Table style
|
||||||
$tblStyle = null;
|
$tblStyle = null;
|
||||||
|
|
@ -539,7 +656,7 @@ class Word2007 extends AbstractReader implements ReaderInterface
|
||||||
*
|
*
|
||||||
* @return array|null
|
* @return array|null
|
||||||
*/
|
*/
|
||||||
private function readSectionStyle(XMLReader $xmlReader, \DOMNode $domNode)
|
private function readSectionStyle(XMLReader $xmlReader, \DOMElement $domNode)
|
||||||
{
|
{
|
||||||
$ret = null;
|
$ret = null;
|
||||||
$mapping = array(
|
$mapping = array(
|
||||||
|
|
@ -554,6 +671,7 @@ class Word2007 extends AbstractReader implements ReaderInterface
|
||||||
}
|
}
|
||||||
$property = $mapping[$node->nodeName];
|
$property = $mapping[$node->nodeName];
|
||||||
switch ($node->nodeName) {
|
switch ($node->nodeName) {
|
||||||
|
|
||||||
case 'w:type':
|
case 'w:type':
|
||||||
$ret['breakType'] = $xmlReader->getAttribute('w:val', $node);
|
$ret['breakType'] = $xmlReader->getAttribute('w:val', $node);
|
||||||
break;
|
break;
|
||||||
|
|
@ -598,7 +716,7 @@ class Word2007 extends AbstractReader implements ReaderInterface
|
||||||
*
|
*
|
||||||
* @return string|array|null
|
* @return string|array|null
|
||||||
*/
|
*/
|
||||||
private function readParagraphStyle(XMLReader $xmlReader, \DOMNode $domNode)
|
private function readParagraphStyle(XMLReader $xmlReader, \DOMElement $domNode)
|
||||||
{
|
{
|
||||||
$style = null;
|
$style = null;
|
||||||
if ($xmlReader->elementExists('w:pPr', $domNode)) {
|
if ($xmlReader->elementExists('w:pPr', $domNode)) {
|
||||||
|
|
@ -620,6 +738,7 @@ class Word2007 extends AbstractReader implements ReaderInterface
|
||||||
}
|
}
|
||||||
$property = $mapping[$node->nodeName];
|
$property = $mapping[$node->nodeName];
|
||||||
switch ($node->nodeName) {
|
switch ($node->nodeName) {
|
||||||
|
|
||||||
case 'w:ind':
|
case 'w:ind':
|
||||||
$style['indent'] = $xmlReader->getAttribute('w:left', $node);
|
$style['indent'] = $xmlReader->getAttribute('w:left', $node);
|
||||||
$style['hanging'] = $xmlReader->getAttribute('w:hanging', $node);
|
$style['hanging'] = $xmlReader->getAttribute('w:hanging', $node);
|
||||||
|
|
@ -660,7 +779,7 @@ class Word2007 extends AbstractReader implements ReaderInterface
|
||||||
*
|
*
|
||||||
* @return string|array|null
|
* @return string|array|null
|
||||||
*/
|
*/
|
||||||
private function readFontStyle(XMLReader $xmlReader, \DOMNode $domNode)
|
private function readFontStyle(XMLReader $xmlReader, \DOMElement $domNode)
|
||||||
{
|
{
|
||||||
$style = null;
|
$style = null;
|
||||||
// Hyperlink has an extra w:r child
|
// Hyperlink has an extra w:r child
|
||||||
|
|
@ -686,6 +805,7 @@ class Word2007 extends AbstractReader implements ReaderInterface
|
||||||
}
|
}
|
||||||
$property = $mapping[$node->nodeName];
|
$property = $mapping[$node->nodeName];
|
||||||
switch ($node->nodeName) {
|
switch ($node->nodeName) {
|
||||||
|
|
||||||
case 'w:rFonts':
|
case 'w:rFonts':
|
||||||
$style['name'] = $xmlReader->getAttribute('w:ascii', $node);
|
$style['name'] = $xmlReader->getAttribute('w:ascii', $node);
|
||||||
$style['hint'] = $xmlReader->getAttribute('w:hint', $node);
|
$style['hint'] = $xmlReader->getAttribute('w:hint', $node);
|
||||||
|
|
@ -729,7 +849,7 @@ class Word2007 extends AbstractReader implements ReaderInterface
|
||||||
* @return string|array|null
|
* @return string|array|null
|
||||||
* @todo Capture w:tblStylePr w:type="firstRow"
|
* @todo Capture w:tblStylePr w:type="firstRow"
|
||||||
*/
|
*/
|
||||||
private function readTableStyle(XMLReader $xmlReader, \DOMNode $domNode)
|
private function readTableStyle(XMLReader $xmlReader, \DOMElement $domNode)
|
||||||
{
|
{
|
||||||
$style = null;
|
$style = null;
|
||||||
$margins = array('top', 'left', 'bottom', 'right');
|
$margins = array('top', 'left', 'bottom', 'right');
|
||||||
|
|
@ -752,6 +872,7 @@ class Word2007 extends AbstractReader implements ReaderInterface
|
||||||
}
|
}
|
||||||
// $property = $mapping[$node->nodeName];
|
// $property = $mapping[$node->nodeName];
|
||||||
switch ($node->nodeName) {
|
switch ($node->nodeName) {
|
||||||
|
|
||||||
case 'w:tblCellMar':
|
case 'w:tblCellMar':
|
||||||
foreach ($margins as $side) {
|
foreach ($margins as $side) {
|
||||||
$ucfSide = ucfirst($side);
|
$ucfSide = ucfirst($side);
|
||||||
|
|
@ -779,7 +900,7 @@ class Word2007 extends AbstractReader implements ReaderInterface
|
||||||
*
|
*
|
||||||
* @return array|null
|
* @return array|null
|
||||||
*/
|
*/
|
||||||
private function readCellStyle(XMLReader $xmlReader, \DOMNode $domNode)
|
private function readCellStyle(XMLReader $xmlReader, \DOMElement $domNode)
|
||||||
{
|
{
|
||||||
$style = null;
|
$style = null;
|
||||||
$mapping = array(
|
$mapping = array(
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,7 @@ class XMLReader
|
||||||
* @param string $path
|
* @param string $path
|
||||||
* @return \DOMNodeList
|
* @return \DOMNodeList
|
||||||
*/
|
*/
|
||||||
public function getElements($path, \DOMNode $contextNode = null)
|
public function getElements($path, \DOMElement $contextNode = null)
|
||||||
{
|
{
|
||||||
if ($this->dom === null) {
|
if ($this->dom === null) {
|
||||||
return array();
|
return array();
|
||||||
|
|
@ -86,9 +86,9 @@ class XMLReader
|
||||||
* Get element
|
* Get element
|
||||||
*
|
*
|
||||||
* @param string $path
|
* @param string $path
|
||||||
* @return \DOMNode|null
|
* @return \DOMElement|null
|
||||||
*/
|
*/
|
||||||
public function getElement($path, \DOMNode $contextNode)
|
public function getElement($path, \DOMElement $contextNode)
|
||||||
{
|
{
|
||||||
$elements = $this->getElements($path, $contextNode);
|
$elements = $this->getElements($path, $contextNode);
|
||||||
if ($elements->length > 0) {
|
if ($elements->length > 0) {
|
||||||
|
|
@ -105,7 +105,7 @@ class XMLReader
|
||||||
* @param string $path
|
* @param string $path
|
||||||
* @return string|null
|
* @return string|null
|
||||||
*/
|
*/
|
||||||
public function getAttribute($attribute, \DOMNode $contextNode, $path = null)
|
public function getAttribute($attribute, \DOMElement $contextNode, $path = null)
|
||||||
{
|
{
|
||||||
if (is_null($path)) {
|
if (is_null($path)) {
|
||||||
$return = $contextNode->getAttribute($attribute);
|
$return = $contextNode->getAttribute($attribute);
|
||||||
|
|
@ -127,7 +127,7 @@ class XMLReader
|
||||||
* @param string $path
|
* @param string $path
|
||||||
* @return string|null
|
* @return string|null
|
||||||
*/
|
*/
|
||||||
public function getValue($path, \DOMNode $contextNode)
|
public function getValue($path, \DOMElement $contextNode)
|
||||||
{
|
{
|
||||||
$elements = $this->getElements($path, $contextNode);
|
$elements = $this->getElements($path, $contextNode);
|
||||||
if ($elements->length > 0) {
|
if ($elements->length > 0) {
|
||||||
|
|
@ -143,7 +143,7 @@ class XMLReader
|
||||||
* @param string $path
|
* @param string $path
|
||||||
* @return integer
|
* @return integer
|
||||||
*/
|
*/
|
||||||
public function countElements($path, \DOMNode $contextNode)
|
public function countElements($path, \DOMElement $contextNode)
|
||||||
{
|
{
|
||||||
$elements = $this->getElements($path, $contextNode);
|
$elements = $this->getElements($path, $contextNode);
|
||||||
|
|
||||||
|
|
@ -156,7 +156,7 @@ class XMLReader
|
||||||
* @param string $path
|
* @param string $path
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
public function elementExists($path, \DOMNode $contextNode)
|
public function elementExists($path, \DOMElement $contextNode)
|
||||||
{
|
{
|
||||||
return $this->getElements($path, $contextNode)->length > 0;
|
return $this->getElements($path, $contextNode)->length > 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ namespace PhpOffice\PhpWord;
|
||||||
use PhpOffice\PhpWord\Style\Font;
|
use PhpOffice\PhpWord\Style\Font;
|
||||||
use PhpOffice\PhpWord\Style\Paragraph;
|
use PhpOffice\PhpWord\Style\Paragraph;
|
||||||
use PhpOffice\PhpWord\Style\Table;
|
use PhpOffice\PhpWord\Style\Table;
|
||||||
|
use PhpOffice\PhpWord\Style\Numbering;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Style collection
|
* Style collection
|
||||||
|
|
@ -68,11 +69,7 @@ class Style
|
||||||
*/
|
*/
|
||||||
public static function addTableStyle($styleName, $styleTable, $styleFirstRow = null)
|
public static function addTableStyle($styleName, $styleTable, $styleFirstRow = null)
|
||||||
{
|
{
|
||||||
if (!array_key_exists($styleName, self::$styles)) {
|
self::setStyleValues($styleName, null, new Table($styleTable, $styleFirstRow));
|
||||||
$style = new Table($styleTable, $styleFirstRow);
|
|
||||||
|
|
||||||
self::$styles[$styleName] = $style;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -84,12 +81,36 @@ class Style
|
||||||
*/
|
*/
|
||||||
public static function addTitleStyle($titleCount, $styleFont, $styleParagraph = null)
|
public static function addTitleStyle($titleCount, $styleFont, $styleParagraph = null)
|
||||||
{
|
{
|
||||||
$styleName = 'Heading_' . $titleCount;
|
|
||||||
self::setStyleValues("Heading_{$titleCount}", $styleFont, new Font('title', $styleParagraph));
|
self::setStyleValues("Heading_{$titleCount}", $styleFont, new Font('title', $styleParagraph));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add numbering style
|
||||||
|
*
|
||||||
|
* @param string $styleName
|
||||||
|
* @param array $styleValues
|
||||||
|
* @return Numbering
|
||||||
|
* @since 0.9.2
|
||||||
|
*/
|
||||||
|
public static function addNumberingStyle($styleName, $styleValues)
|
||||||
|
{
|
||||||
|
self::setStyleValues($styleName, $styleValues, new Numbering());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Count styles
|
||||||
|
*
|
||||||
|
* @return integer
|
||||||
|
* @since 0.9.2
|
||||||
|
*/
|
||||||
|
public static function countStyles()
|
||||||
|
{
|
||||||
|
return count(self::$styles);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reset styles
|
* Reset styles
|
||||||
|
* @since 0.9.2
|
||||||
*/
|
*/
|
||||||
public static function resetStyles()
|
public static function resetStyles()
|
||||||
{
|
{
|
||||||
|
|
@ -120,6 +141,7 @@ class Style
|
||||||
* Get style by name
|
* Get style by name
|
||||||
*
|
*
|
||||||
* @param string $styleName
|
* @param string $styleName
|
||||||
|
* @return Paragraph|Font|Table|Numbering|null
|
||||||
*/
|
*/
|
||||||
public static function getStyle($styleName)
|
public static function getStyle($styleName)
|
||||||
{
|
{
|
||||||
|
|
@ -131,24 +153,21 @@ class Style
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set style values
|
* Set style values and put it to static style collection
|
||||||
*
|
*
|
||||||
* @param string $styleName
|
* @param string $styleName
|
||||||
* @param array $styleValues
|
* @param array $styleValues
|
||||||
* @param mixed $styleObject
|
* @param Paragraph|Font|Table|Numbering $styleObject
|
||||||
*/
|
*/
|
||||||
private static function setStyleValues($styleName, $styleValues, $styleObject)
|
private static function setStyleValues($styleName, $styleValues, $styleObject)
|
||||||
{
|
{
|
||||||
if (!array_key_exists($styleName, self::$styles)) {
|
if (!array_key_exists($styleName, self::$styles)) {
|
||||||
if (is_array($styleValues)) {
|
if (is_array($styleValues)) {
|
||||||
foreach ($styleValues as $key => $value) {
|
foreach ($styleValues as $key => $value) {
|
||||||
if (substr($key, 0, 1) == '_') {
|
|
||||||
$key = substr($key, 1);
|
|
||||||
}
|
|
||||||
$styleObject->setStyleValue($key, $value);
|
$styleObject->setStyleValue($key, $value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
$styleObject->setIndex(self::countStyles() + 1); // One based index
|
||||||
self::$styles[$styleName] = $styleObject;
|
self::$styles[$styleName] = $styleObject;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,37 @@ namespace PhpOffice\PhpWord\Style;
|
||||||
*/
|
*/
|
||||||
abstract class AbstractStyle
|
abstract class AbstractStyle
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Index number in Style collection for named style
|
||||||
|
*
|
||||||
|
* This number starts from one and defined in Style::setStyleValues()
|
||||||
|
*
|
||||||
|
* @var integer|null
|
||||||
|
*/
|
||||||
|
protected $index;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get index number
|
||||||
|
*
|
||||||
|
* @return integer|null
|
||||||
|
*/
|
||||||
|
public function getIndex()
|
||||||
|
{
|
||||||
|
return $this->index;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set index number
|
||||||
|
*
|
||||||
|
* @param integer|null $value
|
||||||
|
*/
|
||||||
|
public function setIndex($value = null)
|
||||||
|
{
|
||||||
|
$this->index = $this->setIntVal($value, $this->index);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set style value template method
|
* Set style value template method
|
||||||
*
|
*
|
||||||
|
|
@ -23,8 +54,7 @@ abstract class AbstractStyle
|
||||||
*
|
*
|
||||||
* @param string $key
|
* @param string $key
|
||||||
* @param string $value
|
* @param string $value
|
||||||
*
|
* @return self
|
||||||
* @todo Implement type check mechanism, e.g. boolean, integer, enum, defaults
|
|
||||||
*/
|
*/
|
||||||
public function setStyleValue($key, $value)
|
public function setStyleValue($key, $value)
|
||||||
{
|
{
|
||||||
|
|
@ -39,5 +69,88 @@ abstract class AbstractStyle
|
||||||
if (method_exists($this, $method)) {
|
if (method_exists($this, $method)) {
|
||||||
$this->$method($value);
|
$this->$method($value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set style by using associative array
|
||||||
|
*
|
||||||
|
* @param array $styles
|
||||||
|
* @return self
|
||||||
|
*/
|
||||||
|
public function setStyleByArray($styles = array())
|
||||||
|
{
|
||||||
|
foreach ($styles as $key => $value) {
|
||||||
|
$this->setStyleValue($key, $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set boolean value
|
||||||
|
*
|
||||||
|
* @param mixed $value
|
||||||
|
* @param boolean|null $default
|
||||||
|
* @return boolean|null
|
||||||
|
*/
|
||||||
|
protected function setBoolVal($value, $default = null)
|
||||||
|
{
|
||||||
|
if (!is_bool($value)) {
|
||||||
|
$value = $default;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set integer value
|
||||||
|
*
|
||||||
|
* @param mixed $value
|
||||||
|
* @param integer|null $default
|
||||||
|
* @return integer|null
|
||||||
|
*/
|
||||||
|
protected function setIntVal($value, $default = null)
|
||||||
|
{
|
||||||
|
$value = intval($value);
|
||||||
|
if (!is_int($value)) {
|
||||||
|
$value = $default;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set float value
|
||||||
|
*
|
||||||
|
* @param mixed $value
|
||||||
|
* @param float|null $default
|
||||||
|
* @return float|null
|
||||||
|
*/
|
||||||
|
protected function setFloatVal($value, $default = null)
|
||||||
|
{
|
||||||
|
$value = floatval($value);
|
||||||
|
if (!is_float($value)) {
|
||||||
|
$value = $default;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set enum value
|
||||||
|
*
|
||||||
|
* @param mixed $value
|
||||||
|
* @param array $enum
|
||||||
|
* @param mixed $default
|
||||||
|
*/
|
||||||
|
protected function setEnumVal($value, $enum, $default = null)
|
||||||
|
{
|
||||||
|
if (!in_array($value, $enum)) {
|
||||||
|
$value = $default;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,46 +9,240 @@
|
||||||
|
|
||||||
namespace PhpOffice\PhpWord\Style;
|
namespace PhpOffice\PhpWord\Style;
|
||||||
|
|
||||||
|
use PhpOffice\PhpWord\Style;
|
||||||
|
use PhpOffice\PhpWord\Style\Numbering;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List item style
|
* List item style
|
||||||
|
*
|
||||||
|
* Before version 0.9.2, numbering style is defined statically with $listType.
|
||||||
|
* After version 0.9.2, numbering style is defined by using Numbering and
|
||||||
|
* recorded by $numStyle. $listStyle is maintained for backward compatility
|
||||||
*/
|
*/
|
||||||
class ListItem extends AbstractStyle
|
class ListItem extends AbstractStyle
|
||||||
{
|
{
|
||||||
|
const TYPE_SQUARE_FILLED = 1;
|
||||||
|
const TYPE_BULLET_FILLED = 3; // default
|
||||||
|
const TYPE_BULLET_EMPTY = 5;
|
||||||
const TYPE_NUMBER = 7;
|
const TYPE_NUMBER = 7;
|
||||||
const TYPE_NUMBER_NESTED = 8;
|
const TYPE_NUMBER_NESTED = 8;
|
||||||
const TYPE_ALPHANUM = 9;
|
const TYPE_ALPHANUM = 9;
|
||||||
const TYPE_BULLET_FILLED = 3;
|
|
||||||
const TYPE_BULLET_EMPTY = 5;
|
|
||||||
const TYPE_SQUARE_FILLED = 1;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List Type
|
* Legacy list type
|
||||||
|
*
|
||||||
|
* @var integer
|
||||||
*/
|
*/
|
||||||
private $listType;
|
private $listType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new ListItem Style
|
* Numbering style name
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
* @since 0.9.2
|
||||||
*/
|
*/
|
||||||
public function __construct()
|
private $numStyle;
|
||||||
{
|
|
||||||
$this->listType = self::TYPE_BULLET_FILLED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set List Type
|
* Numbering definition instance ID
|
||||||
*
|
*
|
||||||
* @param int $pValue
|
* @var integer
|
||||||
|
* @since 0.9.2
|
||||||
*/
|
*/
|
||||||
public function setListType($pValue = self::TYPE_BULLET_FILLED)
|
private $numId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create new instance
|
||||||
|
*
|
||||||
|
* @param string $numStyle
|
||||||
|
*/
|
||||||
|
public function __construct($numStyle = null)
|
||||||
{
|
{
|
||||||
$this->listType = $pValue;
|
if (!is_null($numStyle)) {
|
||||||
|
$this->setNumStyle($numStyle);
|
||||||
|
} else {
|
||||||
|
$this->setListType();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get List Type
|
* Get List Type
|
||||||
|
*
|
||||||
|
* @return integer
|
||||||
*/
|
*/
|
||||||
public function getListType()
|
public function getListType()
|
||||||
{
|
{
|
||||||
return $this->listType;
|
return $this->listType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set legacy list type for version < 0.9.2
|
||||||
|
*
|
||||||
|
* @param integer $value
|
||||||
|
*/
|
||||||
|
public function setListType($value = self::TYPE_BULLET_FILLED)
|
||||||
|
{
|
||||||
|
$enum = array(self::TYPE_SQUARE_FILLED, self::TYPE_BULLET_FILLED,
|
||||||
|
self::TYPE_BULLET_EMPTY, self::TYPE_NUMBER,
|
||||||
|
self::TYPE_NUMBER_NESTED, self::TYPE_ALPHANUM);
|
||||||
|
$this->listType = $this->setEnumVal($value, $enum, $this->listType);
|
||||||
|
$this->getListTypeStyle();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get numbering style name
|
||||||
|
*
|
||||||
|
* @return integer
|
||||||
|
*/
|
||||||
|
public function getNumStyle()
|
||||||
|
{
|
||||||
|
return $this->numStyle;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set numbering style name
|
||||||
|
*
|
||||||
|
* @param string $value
|
||||||
|
*/
|
||||||
|
public function setNumStyle($value)
|
||||||
|
{
|
||||||
|
$this->numStyle = $value;
|
||||||
|
$numStyleObject = Style::getStyle($this->numStyle);
|
||||||
|
if (!is_null($numStyleObject)) {
|
||||||
|
$this->numId = $numStyleObject->getIndex();
|
||||||
|
$numStyleObject->setNumId($this->numId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get numbering Id
|
||||||
|
*
|
||||||
|
* @return integer
|
||||||
|
*/
|
||||||
|
public function getNumId()
|
||||||
|
{
|
||||||
|
return $this->numId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get legacy numbering definition
|
||||||
|
*
|
||||||
|
* @param integer $listType
|
||||||
|
* @return array
|
||||||
|
* @since 0.9.2
|
||||||
|
*/
|
||||||
|
private function getListTypeStyle()
|
||||||
|
{
|
||||||
|
// Check if legacy style already registered in global Style collection
|
||||||
|
$numStyle = "PHPWordList{$this->listType}";
|
||||||
|
if (!is_null(Style::getStyle($numStyle))) {
|
||||||
|
$this->setNumStyle($numStyle);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Property mapping for numbering level information
|
||||||
|
$properties = array('start', 'format', 'text', 'align', 'tabPos', 'left', 'hanging', 'font', 'hint');
|
||||||
|
|
||||||
|
// Legacy level information
|
||||||
|
$listTypeStyles = array(
|
||||||
|
self::TYPE_SQUARE_FILLED => array(
|
||||||
|
'type' => 'hybridMultilevel',
|
||||||
|
'levels' => array(
|
||||||
|
0 => '1, bullet, , left, 720, 720, 360, Wingdings, default',
|
||||||
|
1 => '1, bullet, o, left, 1440, 1440, 360, Courier New, default',
|
||||||
|
2 => '1, bullet, , left, 2160, 2160, 360, Wingdings, default',
|
||||||
|
3 => '1, bullet, , left, 2880, 2880, 360, Symbol, default',
|
||||||
|
4 => '1, bullet, o, left, 3600, 3600, 360, Courier New, default',
|
||||||
|
5 => '1, bullet, , left, 4320, 4320, 360, Wingdings, default',
|
||||||
|
6 => '1, bullet, , left, 5040, 5040, 360, Symbol, default',
|
||||||
|
7 => '1, bullet, o, left, 5760, 5760, 360, Courier New, default',
|
||||||
|
8 => '1, bullet, , left, 6480, 6480, 360, Wingdings, default',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
self::TYPE_BULLET_FILLED => array(
|
||||||
|
'type' => 'hybridMultilevel',
|
||||||
|
'levels' => array(
|
||||||
|
0 => '1, bullet, , left, 720, 720, 360, Symbol, default',
|
||||||
|
1 => '1, bullet, o, left, 1440, 1440, 360, Courier New, default',
|
||||||
|
2 => '1, bullet, , left, 2160, 2160, 360, Wingdings, default',
|
||||||
|
3 => '1, bullet, , left, 2880, 2880, 360, Symbol, default',
|
||||||
|
4 => '1, bullet, o, left, 3600, 3600, 360, Courier New, default',
|
||||||
|
5 => '1, bullet, , left, 4320, 4320, 360, Wingdings, default',
|
||||||
|
6 => '1, bullet, , left, 5040, 5040, 360, Symbol, default',
|
||||||
|
7 => '1, bullet, o, left, 5760, 5760, 360, Courier New, default',
|
||||||
|
8 => '1, bullet, , left, 6480, 6480, 360, Wingdings, default',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
self::TYPE_BULLET_EMPTY => array(
|
||||||
|
'type' => 'hybridMultilevel',
|
||||||
|
'levels' => array(
|
||||||
|
0 => '1, bullet, o, left, 720, 720, 360, Courier New, default',
|
||||||
|
1 => '1, bullet, o, left, 1440, 1440, 360, Courier New, default',
|
||||||
|
2 => '1, bullet, , left, 2160, 2160, 360, Wingdings, default',
|
||||||
|
3 => '1, bullet, , left, 2880, 2880, 360, Symbol, default',
|
||||||
|
4 => '1, bullet, o, left, 3600, 3600, 360, Courier New, default',
|
||||||
|
5 => '1, bullet, , left, 4320, 4320, 360, Wingdings, default',
|
||||||
|
6 => '1, bullet, , left, 5040, 5040, 360, Symbol, default',
|
||||||
|
7 => '1, bullet, o, left, 5760, 5760, 360, Courier New, default',
|
||||||
|
8 => '1, bullet, , left, 6480, 6480, 360, Wingdings, default',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
self::TYPE_NUMBER => array(
|
||||||
|
'type' => 'hybridMultilevel',
|
||||||
|
'levels' => array(
|
||||||
|
0 => '1, decimal, %1., left, 720, 720, 360, , default',
|
||||||
|
1 => '1, bullet, o, left, 1440, 1440, 360, Courier New, default',
|
||||||
|
2 => '1, bullet, , left, 2160, 2160, 360, Wingdings, default',
|
||||||
|
3 => '1, bullet, , left, 2880, 2880, 360, Symbol, default',
|
||||||
|
4 => '1, bullet, o, left, 3600, 3600, 360, Courier New, default',
|
||||||
|
5 => '1, bullet, , left, 4320, 4320, 360, Wingdings, default',
|
||||||
|
6 => '1, bullet, , left, 5040, 5040, 360, Symbol, default',
|
||||||
|
7 => '1, bullet, o, left, 5760, 5760, 360, Courier New, default',
|
||||||
|
8 => '1, bullet, , left, 6480, 6480, 360, Wingdings, default',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
self::TYPE_NUMBER_NESTED => array(
|
||||||
|
'type' => 'multilevel',
|
||||||
|
'levels' => array(
|
||||||
|
0 => '1, decimal, %1., left, 360, 360, 360, , ',
|
||||||
|
1 => '1, decimal, %1.%2., left, 792, 792, 432, , ',
|
||||||
|
2 => '1, decimal, %1.%2.%3., left, 1224, 1224, 504, , ',
|
||||||
|
3 => '1, decimal, %1.%2.%3.%4., left, 1800, 1728, 648, , ',
|
||||||
|
4 => '1, decimal, %1.%2.%3.%4.%5., left, 2520, 2232, 792, , ',
|
||||||
|
5 => '1, decimal, %1.%2.%3.%4.%5.%6., left, 2880, 2736, 936, , ',
|
||||||
|
6 => '1, decimal, %1.%2.%3.%4.%5.%6.%7., left, 3600, 3240, 1080, , ',
|
||||||
|
7 => '1, decimal, %1.%2.%3.%4.%5.%6.%7.%8., left, 3960, 3744, 1224, , ',
|
||||||
|
8 => '1, decimal, %1.%2.%3.%4.%5.%6.%7.%8.%9., left, 4680, 4320, 1440, , ',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
self::TYPE_ALPHANUM => array(
|
||||||
|
'type' => 'multilevel',
|
||||||
|
'levels' => array(
|
||||||
|
0 => '1, decimal, %1., left, 720, 720, 360, , ',
|
||||||
|
1 => '1, lowerLetter, %2., left, 1440, 1440, 360, , ',
|
||||||
|
2 => '1, lowerRoman, %3., right, 2160, 2160, 180, , ',
|
||||||
|
3 => '1, decimal, %4., left, 2880, 2880, 360, , ',
|
||||||
|
4 => '1, lowerLetter, %5., left, 3600, 3600, 360, , ',
|
||||||
|
5 => '1, lowerRoman, %6., right, 4320, 4320, 180, , ',
|
||||||
|
6 => '1, decimal, %7., left, 5040, 5040, 360, , ',
|
||||||
|
7 => '1, lowerLetter, %8., left, 5760, 5760, 360, , ',
|
||||||
|
8 => '1, lowerRoman, %9., right, 6480, 6480, 180, , ',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Populate style and register to global Style register
|
||||||
|
$style = $listTypeStyles[$this->listType];
|
||||||
|
foreach ($style['levels'] as $key => $value) {
|
||||||
|
$levelProperties = explode(', ', $value);
|
||||||
|
$level['level'] = $key;
|
||||||
|
for ($i = 0; $i < count($properties); $i++) {
|
||||||
|
$property = $properties[$i];
|
||||||
|
$level[$property] = $levelProperties[$i];
|
||||||
|
}
|
||||||
|
$style['levels'][$key] = $level;
|
||||||
|
}
|
||||||
|
Style::addNumberingStyle($numStyle, $style);
|
||||||
|
$this->setNumStyle($numStyle);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,123 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* PHPWord
|
||||||
|
*
|
||||||
|
* @link https://github.com/PHPOffice/PHPWord
|
||||||
|
* @copyright 2014 PHPWord
|
||||||
|
* @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace PhpOffice\PhpWord\Style;
|
||||||
|
|
||||||
|
use PhpOffice\PhpWord\Style\NumberingLevel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Numbering style
|
||||||
|
*
|
||||||
|
* @link http://www.schemacentral.com/sc/ooxml/e-w_numbering.html
|
||||||
|
* @link http://www.schemacentral.com/sc/ooxml/e-w_abstractNum-1.html
|
||||||
|
* @link http://www.schemacentral.com/sc/ooxml/e-w_num-1.html
|
||||||
|
* @since 0.9.2
|
||||||
|
*/
|
||||||
|
class Numbering extends AbstractStyle
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Numbering definition instance ID
|
||||||
|
*
|
||||||
|
* @var int
|
||||||
|
* @link http://www.schemacentral.com/sc/ooxml/e-w_num-1.html
|
||||||
|
*/
|
||||||
|
private $numId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multilevel type singleLevel|multilevel|hybridMultilevel
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
* @link http://www.schemacentral.com/sc/ooxml/a-w_val-67.html
|
||||||
|
*/
|
||||||
|
private $type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Numbering levels
|
||||||
|
*
|
||||||
|
* @var NumberingLevel[]
|
||||||
|
*/
|
||||||
|
private $levels = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Id
|
||||||
|
*
|
||||||
|
* @return integer
|
||||||
|
*/
|
||||||
|
public function getNumId()
|
||||||
|
{
|
||||||
|
return $this->numId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Id
|
||||||
|
*
|
||||||
|
* @param integer $value
|
||||||
|
* @return self
|
||||||
|
*/
|
||||||
|
public function setNumId($value)
|
||||||
|
{
|
||||||
|
$this->numId = $this->setIntVal($value, $this->numId);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get multilevel type
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getType()
|
||||||
|
{
|
||||||
|
return $this->type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set multilevel type
|
||||||
|
*
|
||||||
|
* @param string $value
|
||||||
|
* @return self
|
||||||
|
*/
|
||||||
|
public function setType($value)
|
||||||
|
{
|
||||||
|
$enum = array('singleLevel', 'multilevel', 'hybridMultilevel');
|
||||||
|
$this->type = $this->setEnumVal($value, $enum, $this->type);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get levels
|
||||||
|
*
|
||||||
|
* @return NumberingLevel[]
|
||||||
|
*/
|
||||||
|
public function getLevels()
|
||||||
|
{
|
||||||
|
return $this->levels;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set multilevel type
|
||||||
|
*
|
||||||
|
* @param array $values
|
||||||
|
* @return self
|
||||||
|
*/
|
||||||
|
public function setLevels($values)
|
||||||
|
{
|
||||||
|
if (is_array($values)) {
|
||||||
|
foreach ($values as $key => $value) {
|
||||||
|
$numberingLevel = new NumberingLevel();
|
||||||
|
if (is_array($value)) {
|
||||||
|
$numberingLevel->setStyleByArray($value);
|
||||||
|
$numberingLevel->setLevel($key);
|
||||||
|
}
|
||||||
|
$this->levels[$key] = $numberingLevel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,378 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* PHPWord
|
||||||
|
*
|
||||||
|
* @link https://github.com/PHPOffice/PHPWord
|
||||||
|
* @copyright 2014 PHPWord
|
||||||
|
* @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace PhpOffice\PhpWord\Style;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Numbering level definition
|
||||||
|
*
|
||||||
|
* @link http://www.schemacentral.com/sc/ooxml/e-w_lvl-1.html
|
||||||
|
* @since 0.9.2
|
||||||
|
*/
|
||||||
|
class NumberingLevel extends AbstractStyle
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Level number, 0 to 8 (total 9 levels)
|
||||||
|
*
|
||||||
|
* @var integer
|
||||||
|
*/
|
||||||
|
private $level = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starting value w:start
|
||||||
|
*
|
||||||
|
* @var integer
|
||||||
|
* @link http://www.schemacentral.com/sc/ooxml/e-w_start-1.html
|
||||||
|
*/
|
||||||
|
private $start = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Numbering format bullet|decimal|upperRoman|lowerRoman|upperLetter|lowerLetter
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
* @link http://www.schemacentral.com/sc/ooxml/t-w_ST_NumberFormat.html
|
||||||
|
*/
|
||||||
|
private $format;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restart numbering level symbol w:lvlRestart
|
||||||
|
*
|
||||||
|
* @var integer
|
||||||
|
* @link http://www.schemacentral.com/sc/ooxml/e-w_lvlRestart-1.html
|
||||||
|
*/
|
||||||
|
private $restart;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Content between numbering symbol and paragraph text
|
||||||
|
*
|
||||||
|
* @var string tab|space|nothing
|
||||||
|
* @link http://www.schemacentral.com/sc/ooxml/e-w_suff-1.html
|
||||||
|
*/
|
||||||
|
private $suffix = 'tab';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Numbering level text e.g. %1 for nonbullet or bullet character
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
* @link http://www.schemacentral.com/sc/ooxml/e-w_lvlText-1.html
|
||||||
|
*/
|
||||||
|
private $text;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Align left|center|right|both
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
* @link http://www.schemacentral.com/sc/ooxml/e-w_lvlJc-1.html
|
||||||
|
*/
|
||||||
|
private $align;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Left
|
||||||
|
*
|
||||||
|
* @var integer
|
||||||
|
*/
|
||||||
|
private $left;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hanging
|
||||||
|
*
|
||||||
|
* @var integer
|
||||||
|
*/
|
||||||
|
private $hanging;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tab position
|
||||||
|
*
|
||||||
|
* @var integer
|
||||||
|
*/
|
||||||
|
private $tabPos;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Font family
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $font;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hint default|eastAsia|cs
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
* @link http://www.schemacentral.com/sc/ooxml/a-w_hint-1.html
|
||||||
|
*/
|
||||||
|
private $hint;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get level
|
||||||
|
*
|
||||||
|
* @return integer
|
||||||
|
*/
|
||||||
|
public function getLevel()
|
||||||
|
{
|
||||||
|
return $level->level;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set level
|
||||||
|
*
|
||||||
|
* @param integer $value
|
||||||
|
* @return self
|
||||||
|
*/
|
||||||
|
public function setLevel($value)
|
||||||
|
{
|
||||||
|
$this->level = $this->setIntVal($value, $this->level);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get start
|
||||||
|
*
|
||||||
|
* @return integer
|
||||||
|
*/
|
||||||
|
public function getStart()
|
||||||
|
{
|
||||||
|
return $this->start;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set start
|
||||||
|
*
|
||||||
|
* @param integer $value
|
||||||
|
* @return self
|
||||||
|
*/
|
||||||
|
public function setStart($value)
|
||||||
|
{
|
||||||
|
$this->start = $this->setIntVal($value, $this->start);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get format
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getFormat()
|
||||||
|
{
|
||||||
|
return $this->format;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set format
|
||||||
|
*
|
||||||
|
* @param string $value
|
||||||
|
* @return self
|
||||||
|
*/
|
||||||
|
public function setFormat($value)
|
||||||
|
{
|
||||||
|
$enum = array('bullet', 'decimal', 'upperRoman', 'lowerRoman', 'upperLetter', 'lowerLetter');
|
||||||
|
$this->format = $this->setEnumVal($value, $enum, $this->format);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get start
|
||||||
|
*
|
||||||
|
* @return integer
|
||||||
|
*/
|
||||||
|
public function getRestart()
|
||||||
|
{
|
||||||
|
return $this->restart;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set start
|
||||||
|
*
|
||||||
|
* @param integer $value
|
||||||
|
* @return self
|
||||||
|
*/
|
||||||
|
public function setRestart($value)
|
||||||
|
{
|
||||||
|
$this->restart = $this->setIntVal($value, $this->restart);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get suffix
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getSuffix()
|
||||||
|
{
|
||||||
|
return $this->suffix;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set suffix
|
||||||
|
*
|
||||||
|
* @param string $value
|
||||||
|
* @return self
|
||||||
|
*/
|
||||||
|
public function setSuffix($value)
|
||||||
|
{
|
||||||
|
$enum = array('tab', 'space', 'nothing');
|
||||||
|
$this->suffix = $this->setEnumVal($value, $enum, $this->suffix);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get text
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getText()
|
||||||
|
{
|
||||||
|
return $this->text;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set text
|
||||||
|
*
|
||||||
|
* @param string $value
|
||||||
|
* @return self
|
||||||
|
*/
|
||||||
|
public function setText($value)
|
||||||
|
{
|
||||||
|
$this->text = $value;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get align
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getAlign()
|
||||||
|
{
|
||||||
|
return $this->align;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set align
|
||||||
|
*
|
||||||
|
* @param string $value
|
||||||
|
* @return self
|
||||||
|
*/
|
||||||
|
public function setAlign($value)
|
||||||
|
{
|
||||||
|
$enum = array('left', 'center', 'right', 'both');
|
||||||
|
$this->align = $this->setEnumVal($value, $enum, $this->align);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get left
|
||||||
|
*
|
||||||
|
* @return integer
|
||||||
|
*/
|
||||||
|
public function getLeft()
|
||||||
|
{
|
||||||
|
return $this->left;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set left
|
||||||
|
*
|
||||||
|
* @param integer $value
|
||||||
|
* @return self
|
||||||
|
*/
|
||||||
|
public function setLeft($value)
|
||||||
|
{
|
||||||
|
$this->left = $this->setIntVal($value, $this->left);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get hanging
|
||||||
|
*
|
||||||
|
* @return integer
|
||||||
|
*/
|
||||||
|
public function getHanging()
|
||||||
|
{
|
||||||
|
return $this->hanging;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set hanging
|
||||||
|
*
|
||||||
|
* @param integer $value
|
||||||
|
* @return self
|
||||||
|
*/
|
||||||
|
public function setHanging($value)
|
||||||
|
{
|
||||||
|
$this->hanging = $this->setIntVal($value, $this->hanging);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get tab
|
||||||
|
*
|
||||||
|
* @return integer
|
||||||
|
*/
|
||||||
|
public function getTabPos()
|
||||||
|
{
|
||||||
|
return $this->tabPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set tab
|
||||||
|
*
|
||||||
|
* @param integer $value
|
||||||
|
* @return self
|
||||||
|
*/
|
||||||
|
public function setTabPos($value)
|
||||||
|
{
|
||||||
|
$this->tabPos = $this->setIntVal($value, $this->tabPos);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get font
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getFont()
|
||||||
|
{
|
||||||
|
return $this->font;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set font
|
||||||
|
*
|
||||||
|
* @param string $value
|
||||||
|
* @return self
|
||||||
|
*/
|
||||||
|
public function setFont($value)
|
||||||
|
{
|
||||||
|
$this->font = $value;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get hint
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getHint()
|
||||||
|
{
|
||||||
|
return $this->hint;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set hint
|
||||||
|
*
|
||||||
|
* @param string $value
|
||||||
|
* @return self
|
||||||
|
*/
|
||||||
|
public function setHint($value)
|
||||||
|
{
|
||||||
|
$enum = array('default', 'eastAsia', 'cs');
|
||||||
|
$this->hint = $this->setEnumVal($value, $enum, $this->hint);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -432,6 +432,6 @@ class Template
|
||||||
*/
|
*/
|
||||||
public function deleteTemplateBlock($blockname, $replacement = '')
|
public function deleteTemplateBlock($blockname, $replacement = '')
|
||||||
{
|
{
|
||||||
$this->deleteBlock($blockname, $replacement);
|
$this->deleteBlock($blockname);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,17 +9,18 @@
|
||||||
|
|
||||||
namespace PhpOffice\PhpWord\Writer;
|
namespace PhpOffice\PhpWord\Writer;
|
||||||
|
|
||||||
use PhpOffice\PhpWord\Exception\Exception;
|
|
||||||
use PhpOffice\PhpWord\PhpWord;
|
|
||||||
use PhpOffice\PhpWord\Media;
|
|
||||||
use PhpOffice\PhpWord\Element\Section;
|
use PhpOffice\PhpWord\Element\Section;
|
||||||
|
use PhpOffice\PhpWord\Exception\Exception;
|
||||||
|
use PhpOffice\PhpWord\Media;
|
||||||
|
use PhpOffice\PhpWord\PhpWord;
|
||||||
use PhpOffice\PhpWord\Writer\Word2007\ContentTypes;
|
use PhpOffice\PhpWord\Writer\Word2007\ContentTypes;
|
||||||
use PhpOffice\PhpWord\Writer\Word2007\Rels;
|
|
||||||
use PhpOffice\PhpWord\Writer\Word2007\DocProps;
|
use PhpOffice\PhpWord\Writer\Word2007\DocProps;
|
||||||
use PhpOffice\PhpWord\Writer\Word2007\Document;
|
use PhpOffice\PhpWord\Writer\Word2007\Document;
|
||||||
use PhpOffice\PhpWord\Writer\Word2007\Footer;
|
use PhpOffice\PhpWord\Writer\Word2007\Footer;
|
||||||
use PhpOffice\PhpWord\Writer\Word2007\Notes;
|
|
||||||
use PhpOffice\PhpWord\Writer\Word2007\Header;
|
use PhpOffice\PhpWord\Writer\Word2007\Header;
|
||||||
|
use PhpOffice\PhpWord\Writer\Word2007\Notes;
|
||||||
|
use PhpOffice\PhpWord\Writer\Word2007\Numbering;
|
||||||
|
use PhpOffice\PhpWord\Writer\Word2007\Rels;
|
||||||
use PhpOffice\PhpWord\Writer\Word2007\Styles;
|
use PhpOffice\PhpWord\Writer\Word2007\Styles;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -57,6 +58,7 @@ class Word2007 extends AbstractWriter implements WriterInterface
|
||||||
$this->writerParts['docprops'] = new DocProps();
|
$this->writerParts['docprops'] = new DocProps();
|
||||||
$this->writerParts['document'] = new Document();
|
$this->writerParts['document'] = new Document();
|
||||||
$this->writerParts['styles'] = new Styles();
|
$this->writerParts['styles'] = new Styles();
|
||||||
|
$this->writerParts['numbering'] = new Numbering();
|
||||||
$this->writerParts['header'] = new Header();
|
$this->writerParts['header'] = new Header();
|
||||||
$this->writerParts['footer'] = new Footer();
|
$this->writerParts['footer'] = new Footer();
|
||||||
$this->writerParts['footnotes'] = new Notes();
|
$this->writerParts['footnotes'] = new Notes();
|
||||||
|
|
@ -97,7 +99,6 @@ class Word2007 extends AbstractWriter implements WriterInterface
|
||||||
$this->addHeaderFooterMedia($objZip, 'footer');
|
$this->addHeaderFooterMedia($objZip, 'footer');
|
||||||
|
|
||||||
// Add header/footer contents
|
// Add header/footer contents
|
||||||
$overrides = array();
|
|
||||||
$rId = Media::countElements('section') + 6; // @see Rels::writeDocRels for 6 first elements
|
$rId = Media::countElements('section') + 6; // @see Rels::writeDocRels for 6 first elements
|
||||||
$sections = $this->phpWord->getSections();
|
$sections = $this->phpWord->getSections();
|
||||||
foreach ($sections as $section) {
|
foreach ($sections as $section) {
|
||||||
|
|
@ -116,9 +117,9 @@ class Word2007 extends AbstractWriter implements WriterInterface
|
||||||
$objZip->addFromString('word/_rels/document.xml.rels', $this->getWriterPart('rels')->writeDocRels($this->docRels));
|
$objZip->addFromString('word/_rels/document.xml.rels', $this->getWriterPart('rels')->writeDocRels($this->docRels));
|
||||||
$objZip->addFromString('word/document.xml', $this->getWriterPart('document')->writeDocument($this->phpWord));
|
$objZip->addFromString('word/document.xml', $this->getWriterPart('document')->writeDocument($this->phpWord));
|
||||||
$objZip->addFromString('word/styles.xml', $this->getWriterPart('styles')->writeStyles($this->phpWord));
|
$objZip->addFromString('word/styles.xml', $this->getWriterPart('styles')->writeStyles($this->phpWord));
|
||||||
|
$objZip->addFromString('word/numbering.xml', $this->getWriterPart('numbering')->writeNumbering());
|
||||||
|
|
||||||
// Write static files
|
// Write static files
|
||||||
$objZip->addFile(__DIR__ . '/../_staticDocParts/numbering.xml', 'word/numbering.xml');
|
|
||||||
$objZip->addFile(__DIR__ . '/../_staticDocParts/settings.xml', 'word/settings.xml');
|
$objZip->addFile(__DIR__ . '/../_staticDocParts/settings.xml', 'word/settings.xml');
|
||||||
$objZip->addFile(__DIR__ . '/../_staticDocParts/theme1.xml', 'word/theme/theme1.xml');
|
$objZip->addFile(__DIR__ . '/../_staticDocParts/theme1.xml', 'word/theme/theme1.xml');
|
||||||
$objZip->addFile(__DIR__ . '/../_staticDocParts/webSettings.xml', 'word/webSettings.xml');
|
$objZip->addFile(__DIR__ . '/../_staticDocParts/webSettings.xml', 'word/webSettings.xml');
|
||||||
|
|
@ -224,8 +225,8 @@ class Word2007 extends AbstractWriter implements WriterInterface
|
||||||
* Add footnotes/endnotes
|
* Add footnotes/endnotes
|
||||||
*
|
*
|
||||||
* @param mixed $objZip
|
* @param mixed $objZip
|
||||||
* @param string $elmType
|
|
||||||
* @param integer $rId
|
* @param integer $rId
|
||||||
|
* @param string $notesType
|
||||||
*/
|
*/
|
||||||
private function addNotes($objZip, &$rId, $notesType = 'footnote')
|
private function addNotes($objZip, &$rId, $notesType = 'footnote')
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -279,7 +279,7 @@ class Base extends AbstractWriterPart
|
||||||
{
|
{
|
||||||
$textObject = $listItem->getTextObject();
|
$textObject = $listItem->getTextObject();
|
||||||
$depth = $listItem->getDepth();
|
$depth = $listItem->getDepth();
|
||||||
$listType = $listItem->getStyle()->getListType();
|
$numId = $listItem->getStyle()->getNumId();
|
||||||
$styleParagraph = $textObject->getParagraphStyle();
|
$styleParagraph = $textObject->getParagraphStyle();
|
||||||
|
|
||||||
$xmlWriter->startElement('w:p');
|
$xmlWriter->startElement('w:p');
|
||||||
|
|
@ -290,7 +290,7 @@ class Base extends AbstractWriterPart
|
||||||
$xmlWriter->writeAttribute('w:val', $depth);
|
$xmlWriter->writeAttribute('w:val', $depth);
|
||||||
$xmlWriter->endElement(); // w:ilvl
|
$xmlWriter->endElement(); // w:ilvl
|
||||||
$xmlWriter->startElement('w:numId');
|
$xmlWriter->startElement('w:numId');
|
||||||
$xmlWriter->writeAttribute('w:val', $listType);
|
$xmlWriter->writeAttribute('w:val', $numId);
|
||||||
$xmlWriter->endElement(); // w:numId
|
$xmlWriter->endElement(); // w:numId
|
||||||
$xmlWriter->endElement(); // w:numPr
|
$xmlWriter->endElement(); // w:numPr
|
||||||
$xmlWriter->endElement(); // w:pPr
|
$xmlWriter->endElement(); // w:pPr
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,7 @@ class Notes extends Base
|
||||||
// Content
|
// Content
|
||||||
foreach ($elements as $element) {
|
foreach ($elements as $element) {
|
||||||
if ($element instanceof Footnote || $element instanceof Endnote) {
|
if ($element instanceof Footnote || $element instanceof Endnote) {
|
||||||
$this->writeNote($xmlWriter, $element, null, $notesTypes);
|
$this->writeNote($xmlWriter, $element, $notesTypes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -83,10 +83,9 @@ class Notes extends Base
|
||||||
*
|
*
|
||||||
* @param XMLWriter $xmlWriter
|
* @param XMLWriter $xmlWriter
|
||||||
* @param Footnote|Endnote $element
|
* @param Footnote|Endnote $element
|
||||||
* @param boolean $withoutP
|
|
||||||
* @param string $notesTypes
|
* @param string $notesTypes
|
||||||
*/
|
*/
|
||||||
protected function writeNote(XMLWriter $xmlWriter, $element, $withoutP = false, $notesTypes = 'footnotes')
|
protected function writeNote(XMLWriter $xmlWriter, $element, $notesTypes = 'footnotes')
|
||||||
{
|
{
|
||||||
$isFootnote = ($notesTypes == 'footnotes');
|
$isFootnote = ($notesTypes == 'footnotes');
|
||||||
$elementNode = $isFootnote ? 'w:footnote' : 'w:endnote';
|
$elementNode = $isFootnote ? 'w:footnote' : 'w:endnote';
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,177 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* PHPWord
|
||||||
|
*
|
||||||
|
* @link https://github.com/PHPOffice/PHPWord
|
||||||
|
* @copyright 2014 PHPWord
|
||||||
|
* @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace PhpOffice\PhpWord\Writer\Word2007;
|
||||||
|
|
||||||
|
use PhpOffice\PhpWord\Style;
|
||||||
|
use PhpOffice\PhpWord\Style\Numbering as NumberingStyle;
|
||||||
|
use PhpOffice\PhpWord\Style\NumberingLevel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Word2007 numbering part writer
|
||||||
|
*/
|
||||||
|
class Numbering extends Base
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Write word/numbering.xml
|
||||||
|
*/
|
||||||
|
public function writeNumbering()
|
||||||
|
{
|
||||||
|
$styles = Style::getStyles();
|
||||||
|
|
||||||
|
$xmlWriter = $this->getXmlWriter();
|
||||||
|
|
||||||
|
$xmlWriter->startDocument('1.0', 'UTF-8', 'yes');
|
||||||
|
$xmlWriter->startElement('w:numbering');
|
||||||
|
$xmlWriter->writeAttribute('xmlns:ve', 'http://schemas.openxmlformats.org/markup-compatibility/2006');
|
||||||
|
$xmlWriter->writeAttribute('xmlns:o', 'urn:schemas-microsoft-com:office:office');
|
||||||
|
$xmlWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships');
|
||||||
|
$xmlWriter->writeAttribute('xmlns:m', 'http://schemas.openxmlformats.org/officeDocument/2006/math');
|
||||||
|
$xmlWriter->writeAttribute('xmlns:v', 'urn:schemas-microsoft-com:vml');
|
||||||
|
$xmlWriter->writeAttribute('xmlns:wp', 'http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing');
|
||||||
|
$xmlWriter->writeAttribute('xmlns:w10', 'urn:schemas-microsoft-com:office:word');
|
||||||
|
$xmlWriter->writeAttribute('xmlns:w', 'http://schemas.openxmlformats.org/wordprocessingml/2006/main');
|
||||||
|
$xmlWriter->writeAttribute('xmlns:wne', 'http://schemas.microsoft.com/office/word/2006/wordml');
|
||||||
|
|
||||||
|
// Abstract numbering definitions
|
||||||
|
foreach ($styles as $style) {
|
||||||
|
if ($style instanceof NumberingStyle) {
|
||||||
|
$levels = $style->getLevels();
|
||||||
|
|
||||||
|
$xmlWriter->startElement('w:abstractNum');
|
||||||
|
$xmlWriter->writeAttribute('w:abstractNumId', $style->getNumId());
|
||||||
|
|
||||||
|
$xmlWriter->startElement('w:nsid');
|
||||||
|
$xmlWriter->writeAttribute('w:val', $this->getRandomHexNumber());
|
||||||
|
$xmlWriter->endElement(); // w:nsid
|
||||||
|
|
||||||
|
$xmlWriter->startElement('w:multiLevelType');
|
||||||
|
$xmlWriter->writeAttribute('w:val', $style->getType());
|
||||||
|
$xmlWriter->endElement(); // w:multiLevelType
|
||||||
|
|
||||||
|
if (is_array($levels)) {
|
||||||
|
foreach ($levels as $levelNum => $levelObject) {
|
||||||
|
if ($levelObject instanceof NumberingLevel) {
|
||||||
|
$start = $levelObject->getStart();
|
||||||
|
$format = $levelObject->getFormat();
|
||||||
|
$restart = $levelObject->getRestart();
|
||||||
|
$suffix = $levelObject->getSuffix();
|
||||||
|
$text = $levelObject->getText();
|
||||||
|
$align = $levelObject->getAlign();
|
||||||
|
$tabPos = $levelObject->getTabPos();
|
||||||
|
$left = $levelObject->getLeft();
|
||||||
|
$hanging = $levelObject->getHanging();
|
||||||
|
$font = $levelObject->getFont();
|
||||||
|
$hint = $levelObject->getHint();
|
||||||
|
|
||||||
|
$xmlWriter->startElement('w:lvl');
|
||||||
|
$xmlWriter->writeAttribute('w:ilvl', $levelNum);
|
||||||
|
|
||||||
|
if (!is_null($start)) {
|
||||||
|
$xmlWriter->startElement('w:start');
|
||||||
|
$xmlWriter->writeAttribute('w:val', $start);
|
||||||
|
$xmlWriter->endElement(); // w:start
|
||||||
|
}
|
||||||
|
if (!is_null($format)) {
|
||||||
|
$xmlWriter->startElement('w:numFmt');
|
||||||
|
$xmlWriter->writeAttribute('w:val', $format);
|
||||||
|
$xmlWriter->endElement(); // w:numFmt
|
||||||
|
}
|
||||||
|
if (!is_null($restart)) {
|
||||||
|
$xmlWriter->startElement('w:lvlRestart');
|
||||||
|
$xmlWriter->writeAttribute('w:val', $restart);
|
||||||
|
$xmlWriter->endElement(); // w:lvlRestart
|
||||||
|
}
|
||||||
|
if (!is_null($suffix)) {
|
||||||
|
$xmlWriter->startElement('w:suff');
|
||||||
|
$xmlWriter->writeAttribute('w:val', $suffix);
|
||||||
|
$xmlWriter->endElement(); // w:suff
|
||||||
|
}
|
||||||
|
if (!is_null($text)) {
|
||||||
|
$xmlWriter->startElement('w:lvlText');
|
||||||
|
$xmlWriter->writeAttribute('w:val', $text);
|
||||||
|
$xmlWriter->endElement(); // w:start
|
||||||
|
}
|
||||||
|
if (!is_null($align)) {
|
||||||
|
$xmlWriter->startElement('w:lvlJc');
|
||||||
|
$xmlWriter->writeAttribute('w:val', $align);
|
||||||
|
$xmlWriter->endElement(); // w:lvlJc
|
||||||
|
}
|
||||||
|
if (!is_null($tabPos) || !is_null($left) || !is_null($hanging)) {
|
||||||
|
$xmlWriter->startElement('w:pPr');
|
||||||
|
if (!is_null($tabPos)) {
|
||||||
|
$xmlWriter->startElement('w:tabs');
|
||||||
|
$xmlWriter->startElement('w:tab');
|
||||||
|
$xmlWriter->writeAttribute('w:val', 'num');
|
||||||
|
$xmlWriter->writeAttribute('w:pos', $tabPos);
|
||||||
|
$xmlWriter->endElement(); // w:tab
|
||||||
|
$xmlWriter->endElement(); // w:tabs
|
||||||
|
}
|
||||||
|
if (!is_null($left) || !is_null($hanging)) {
|
||||||
|
$xmlWriter->startElement('w:ind');
|
||||||
|
if (!is_null($left)) {
|
||||||
|
$xmlWriter->writeAttribute('w:left', $left);
|
||||||
|
}
|
||||||
|
if (!is_null($hanging)) {
|
||||||
|
$xmlWriter->writeAttribute('w:hanging', $hanging);
|
||||||
|
}
|
||||||
|
$xmlWriter->endElement(); // w:ind
|
||||||
|
}
|
||||||
|
$xmlWriter->endElement(); // w:pPr
|
||||||
|
}
|
||||||
|
if (!is_null($font) || !is_null($hint)) {
|
||||||
|
$xmlWriter->startElement('w:rPr');
|
||||||
|
$xmlWriter->startElement('w:rFonts');
|
||||||
|
if (!is_null($font)) {
|
||||||
|
$xmlWriter->writeAttribute('w:ascii', $font);
|
||||||
|
$xmlWriter->writeAttribute('w:hAnsi', $font);
|
||||||
|
$xmlWriter->writeAttribute('w:cs', $font);
|
||||||
|
}
|
||||||
|
if (!is_null($hint)) {
|
||||||
|
$xmlWriter->writeAttribute('w:hint', $hint);
|
||||||
|
}
|
||||||
|
$xmlWriter->endElement(); // w:rFonts
|
||||||
|
$xmlWriter->endElement(); // w:rPr
|
||||||
|
}
|
||||||
|
$xmlWriter->endElement(); // w:lvl
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$xmlWriter->endElement(); // w:abstractNum
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Numbering definition instances
|
||||||
|
foreach ($styles as $style) {
|
||||||
|
if ($style instanceof NumberingStyle) {
|
||||||
|
$xmlWriter->startElement('w:num');
|
||||||
|
$xmlWriter->writeAttribute('w:numId', $style->getNumId());
|
||||||
|
$xmlWriter->startElement('w:abstractNumId');
|
||||||
|
$xmlWriter->writeAttribute('w:val', $style->getNumId());
|
||||||
|
$xmlWriter->endElement(); // w:abstractNumId
|
||||||
|
$xmlWriter->endElement(); // w:num
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$xmlWriter->endElement();
|
||||||
|
|
||||||
|
return $xmlWriter->getData();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get random hexadecimal number value
|
||||||
|
*
|
||||||
|
* @param int $length
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private function getRandomHexNumber($length = 8)
|
||||||
|
{
|
||||||
|
return strtoupper(substr(md5(rand()), 0, $length));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -15,9 +15,12 @@ use PhpOffice\PhpWord\Style;
|
||||||
use PhpOffice\PhpWord\Style\Font;
|
use PhpOffice\PhpWord\Style\Font;
|
||||||
use PhpOffice\PhpWord\Style\Paragraph;
|
use PhpOffice\PhpWord\Style\Paragraph;
|
||||||
use PhpOffice\PhpWord\Style\Table;
|
use PhpOffice\PhpWord\Style\Table;
|
||||||
|
use PhpOffice\PhpWord\Style\Numbering;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Word2007 styles part writer
|
* Word2007 styles part writer
|
||||||
|
*
|
||||||
|
* @todo Do something with the numbering style introduced in 0.9.2
|
||||||
*/
|
*/
|
||||||
class Styles extends Base
|
class Styles extends Base
|
||||||
{
|
{
|
||||||
|
|
@ -38,37 +41,32 @@ class Styles extends Base
|
||||||
// XML header
|
// XML header
|
||||||
$xmlWriter->startDocument('1.0', 'UTF-8', 'yes');
|
$xmlWriter->startDocument('1.0', 'UTF-8', 'yes');
|
||||||
$xmlWriter->startElement('w:styles');
|
$xmlWriter->startElement('w:styles');
|
||||||
$xmlWriter->writeAttribute(
|
$xmlWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships');
|
||||||
'xmlns:r',
|
$xmlWriter->writeAttribute('xmlns:w', 'http://schemas.openxmlformats.org/wordprocessingml/2006/main');
|
||||||
'http://schemas.openxmlformats.org/officeDocument/2006/relationships'
|
|
||||||
);
|
|
||||||
$xmlWriter->writeAttribute(
|
|
||||||
'xmlns:w',
|
|
||||||
'http://schemas.openxmlformats.org/wordprocessingml/2006/main'
|
|
||||||
);
|
|
||||||
// Write default styles
|
// Write default styles
|
||||||
$styles = Style::getStyles();
|
$styles = Style::getStyles();
|
||||||
$this->writeDefaultStyles($xmlWriter, $phpWord, $styles);
|
$this->writeDefaultStyles($xmlWriter, $phpWord, $styles);
|
||||||
// Write other styles
|
|
||||||
|
// Write styles
|
||||||
if (count($styles) > 0) {
|
if (count($styles) > 0) {
|
||||||
foreach ($styles as $styleName => $style) {
|
foreach ($styles as $styleName => $style) {
|
||||||
if ($styleName == 'Normal') {
|
if ($styleName == 'Normal') {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ($style instanceof Font) {
|
$styleClass = str_replace('PhpOffice\\PhpWord\\Style\\', '', get_class($style));
|
||||||
|
|
||||||
|
// Font style
|
||||||
|
if ($style instanceof Font) {
|
||||||
$paragraphStyle = $style->getParagraphStyle();
|
$paragraphStyle = $style->getParagraphStyle();
|
||||||
$styleType = $style->getStyleType();
|
$styleType = $style->getStyleType();
|
||||||
|
|
||||||
$type = ($styleType == 'title') ? 'paragraph' : 'character';
|
$type = ($styleType == 'title') ? 'paragraph' : 'character';
|
||||||
|
|
||||||
if (!is_null($paragraphStyle)) {
|
if (!is_null($paragraphStyle)) {
|
||||||
$type = 'paragraph';
|
$type = 'paragraph';
|
||||||
}
|
}
|
||||||
|
|
||||||
$xmlWriter->startElement('w:style');
|
$xmlWriter->startElement('w:style');
|
||||||
$xmlWriter->writeAttribute('w:type', $type);
|
$xmlWriter->writeAttribute('w:type', $type);
|
||||||
|
|
||||||
if ($styleType == 'title') {
|
if ($styleType == 'title') {
|
||||||
$arrStyle = explode('_', $styleName);
|
$arrStyle = explode('_', $styleName);
|
||||||
$styleId = 'Heading' . $arrStyle[1];
|
$styleId = 'Heading' . $arrStyle[1];
|
||||||
|
|
@ -80,11 +78,9 @@ class Styles extends Base
|
||||||
$xmlWriter->writeAttribute('w:val', $styleLink);
|
$xmlWriter->writeAttribute('w:val', $styleLink);
|
||||||
$xmlWriter->endElement();
|
$xmlWriter->endElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
$xmlWriter->startElement('w:name');
|
$xmlWriter->startElement('w:name');
|
||||||
$xmlWriter->writeAttribute('w:val', $styleName);
|
$xmlWriter->writeAttribute('w:val', $styleName);
|
||||||
$xmlWriter->endElement();
|
$xmlWriter->endElement();
|
||||||
|
|
||||||
if (!is_null($paragraphStyle)) {
|
if (!is_null($paragraphStyle)) {
|
||||||
// Point parent style to Normal
|
// Point parent style to Normal
|
||||||
$xmlWriter->startElement('w:basedOn');
|
$xmlWriter->startElement('w:basedOn');
|
||||||
|
|
@ -94,19 +90,17 @@ class Styles extends Base
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->writeFontStyle($xmlWriter, $style);
|
$this->writeFontStyle($xmlWriter, $style);
|
||||||
|
|
||||||
$xmlWriter->endElement();
|
$xmlWriter->endElement();
|
||||||
|
|
||||||
|
// Paragraph style
|
||||||
} elseif ($style instanceof Paragraph) {
|
} elseif ($style instanceof Paragraph) {
|
||||||
$xmlWriter->startElement('w:style');
|
$xmlWriter->startElement('w:style');
|
||||||
$xmlWriter->writeAttribute('w:type', 'paragraph');
|
$xmlWriter->writeAttribute('w:type', 'paragraph');
|
||||||
$xmlWriter->writeAttribute('w:customStyle', '1');
|
$xmlWriter->writeAttribute('w:customStyle', '1');
|
||||||
$xmlWriter->writeAttribute('w:styleId', $styleName);
|
$xmlWriter->writeAttribute('w:styleId', $styleName);
|
||||||
|
|
||||||
$xmlWriter->startElement('w:name');
|
$xmlWriter->startElement('w:name');
|
||||||
$xmlWriter->writeAttribute('w:val', $styleName);
|
$xmlWriter->writeAttribute('w:val', $styleName);
|
||||||
$xmlWriter->endElement();
|
$xmlWriter->endElement();
|
||||||
|
|
||||||
// Parent style
|
// Parent style
|
||||||
$basedOn = $style->getBasedOn();
|
$basedOn = $style->getBasedOn();
|
||||||
if (!is_null($basedOn)) {
|
if (!is_null($basedOn)) {
|
||||||
|
|
@ -114,7 +108,6 @@ class Styles extends Base
|
||||||
$xmlWriter->writeAttribute('w:val', $basedOn);
|
$xmlWriter->writeAttribute('w:val', $basedOn);
|
||||||
$xmlWriter->endElement();
|
$xmlWriter->endElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Next paragraph style
|
// Next paragraph style
|
||||||
$next = $style->getNext();
|
$next = $style->getNext();
|
||||||
if (!is_null($next)) {
|
if (!is_null($next)) {
|
||||||
|
|
@ -126,22 +119,20 @@ class Styles extends Base
|
||||||
$this->writeParagraphStyle($xmlWriter, $style);
|
$this->writeParagraphStyle($xmlWriter, $style);
|
||||||
$xmlWriter->endElement();
|
$xmlWriter->endElement();
|
||||||
|
|
||||||
|
// Table style
|
||||||
} elseif ($style instanceof Table) {
|
} elseif ($style instanceof Table) {
|
||||||
$xmlWriter->startElement('w:style');
|
$xmlWriter->startElement('w:style');
|
||||||
$xmlWriter->writeAttribute('w:type', 'table');
|
$xmlWriter->writeAttribute('w:type', 'table');
|
||||||
$xmlWriter->writeAttribute('w:customStyle', '1');
|
$xmlWriter->writeAttribute('w:customStyle', '1');
|
||||||
$xmlWriter->writeAttribute('w:styleId', $styleName);
|
$xmlWriter->writeAttribute('w:styleId', $styleName);
|
||||||
|
|
||||||
$xmlWriter->startElement('w:name');
|
$xmlWriter->startElement('w:name');
|
||||||
$xmlWriter->writeAttribute('w:val', $styleName);
|
$xmlWriter->writeAttribute('w:val', $styleName);
|
||||||
$xmlWriter->endElement();
|
$xmlWriter->endElement();
|
||||||
|
|
||||||
$xmlWriter->startElement('w:uiPriority');
|
$xmlWriter->startElement('w:uiPriority');
|
||||||
$xmlWriter->writeAttribute('w:val', '99');
|
$xmlWriter->writeAttribute('w:val', '99');
|
||||||
$xmlWriter->endElement();
|
$xmlWriter->endElement();
|
||||||
|
|
||||||
$this->writeTableStyle($xmlWriter, $style);
|
$this->writeTableStyle($xmlWriter, $style);
|
||||||
|
|
||||||
$xmlWriter->endElement(); // w:style
|
$xmlWriter->endElement(); // w:style
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -149,7 +140,6 @@ class Styles extends Base
|
||||||
|
|
||||||
$xmlWriter->endElement(); // w:styles
|
$xmlWriter->endElement(); // w:styles
|
||||||
|
|
||||||
// Return
|
|
||||||
return $xmlWriter->getData();
|
return $xmlWriter->getData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -99,12 +99,12 @@ class DocumentTest extends \PHPUnit_Framework_TestCase
|
||||||
$objectSrc = __DIR__ . "/../../_files/documents/sheet.xls";
|
$objectSrc = __DIR__ . "/../../_files/documents/sheet.xls";
|
||||||
|
|
||||||
$phpWord = new PhpWord();
|
$phpWord = new PhpWord();
|
||||||
$phpWord->addParagraphStyle('pStyle', array('align' => 'center'));
|
$phpWord->addParagraphStyle('pStyle', array('align' => 'center')); // Style #1
|
||||||
$phpWord->addFontStyle('fStyle', array('size' => '20'));
|
$phpWord->addFontStyle('fStyle', array('size' => '20')); // Style #2
|
||||||
$phpWord->addTitleStyle(1, array('color' => '333333', 'bold' => true));
|
$phpWord->addTitleStyle(1, array('color' => '333333', 'bold' => true)); // Style #3
|
||||||
$fontStyle = new Font('text', array('align' => 'center'));
|
$fontStyle = new Font('text', array('align' => 'center'));
|
||||||
$section = $phpWord->addSection();
|
$section = $phpWord->addSection();
|
||||||
$section->addListItem('List Item', 0, null, null, 'pStyle');
|
$section->addListItem('List Item', 0, null, null, 'pStyle'); // Style #4
|
||||||
$section->addObject($objectSrc, array('align' => 'center'));
|
$section->addObject($objectSrc, array('align' => 'center'));
|
||||||
$section->addTOC($fontStyle);
|
$section->addTOC($fontStyle);
|
||||||
$section->addTitle('Title 1', 1);
|
$section->addTitle('Title 1', 1);
|
||||||
|
|
@ -113,7 +113,7 @@ class DocumentTest extends \PHPUnit_Framework_TestCase
|
||||||
|
|
||||||
// List item
|
// List item
|
||||||
$element = $doc->getElement('/w:document/w:body/w:p[1]/w:pPr/w:numPr/w:numId');
|
$element = $doc->getElement('/w:document/w:body/w:p[1]/w:pPr/w:numPr/w:numId');
|
||||||
$this->assertEquals(3, $element->getAttribute('w:val'));
|
$this->assertEquals(4, $element->getAttribute('w:val'));
|
||||||
|
|
||||||
// Object
|
// Object
|
||||||
$element = $doc->getElement('/w:document/w:body/w:p[2]/w:r/w:object/o:OLEObject');
|
$element = $doc->getElement('/w:document/w:body/w:p[2]/w:r/w:object/o:OLEObject');
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue