From 5c2c687efdd0548a6b6dd0a91dffae51c094578c Mon Sep 17 00:00:00 2001 From: Ivan Lanin Date: Thu, 29 May 2014 22:37:10 +0700 Subject: [PATCH] #193: Heading numbering --- docs/recipes.rst | 24 ++++++++ docs/src/documentation.md | 23 +++++++ samples/Sample_14_ListItem.php | 21 ++++++- src/PhpWord/Style/NumberingLevel.php | 30 ++++++++++ src/PhpWord/Style/Paragraph.php | 60 +++++++++++++++++++ .../Writer/Word2007/Part/Numbering.php | 7 ++- .../Writer/Word2007/Style/Paragraph.php | 19 ++++++ 7 files changed, 180 insertions(+), 4 deletions(-) diff --git a/docs/recipes.rst b/docs/recipes.rst index eef31527..d5678a52 100644 --- a/docs/recipes.rst +++ b/docs/recipes.rst @@ -41,3 +41,27 @@ Use ``php://output`` as the filename. header('Expires: 0'); $xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, 'Word2007'); $xmlWriter->save("php://output"); + +Create numbered headings +------------------------ + +Define a numbering style and title styles, and match the two styles (with ``pStyle`` and ``numStyle``) like below. + +.. code-block:: php + + $phpWord->addNumberingStyle( + 'hNum', + array('type' => 'multilevel', 'levels' => array( + array('pStyle' => 'Heading1', 'format' => 'decimal', 'text' => '%1'), + array('pStyle' => 'Heading2', 'format' => 'decimal', 'text' => '%1.%2'), + array('pStyle' => 'Heading3', 'format' => 'decimal', 'text' => '%1.%2.%3'), + ) + ) + ); + $phpWord->addTitleStyle(1, array('size' => 16), array('numStyle' => 'hNum', 'numLevel' => 0)); + $phpWord->addTitleStyle(2, array('size' => 14), array('numStyle' => 'hNum', 'numLevel' => 1)); + $phpWord->addTitleStyle(3, array('size' => 12), array('numStyle' => 'hNum', 'numLevel' => 2)); + + $section->addTitle('Heading 1', 1); + $section->addTitle('Heading 2', 2); + $section->addTitle('Heading 3', 3); diff --git a/docs/src/documentation.md b/docs/src/documentation.md index 0259dd8b..3d2b4b16 100644 --- a/docs/src/documentation.md +++ b/docs/src/documentation.md @@ -980,6 +980,29 @@ $xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, 'Word2007'); $xmlWriter->save("php://output"); ``` +## Create numbered headings + +Define a numbering style and title styles, and match the two styles (with `pStyle` and `numStyle`) like below. + +```php +$phpWord->addNumberingStyle( + 'hNum', + array('type' => 'multilevel', 'levels' => array( + array('pStyle' => 'Heading1', 'format' => 'decimal', 'text' => '%1'), + array('pStyle' => 'Heading2', 'format' => 'decimal', 'text' => '%1.%2'), + array('pStyle' => 'Heading3', 'format' => 'decimal', 'text' => '%1.%2.%3'), + ) + ) +); +$phpWord->addTitleStyle(1, array('size' => 16), array('numStyle' => 'hNum', 'numLevel' => 0)); +$phpWord->addTitleStyle(2, array('size' => 14), array('numStyle' => 'hNum', 'numLevel' => 1)); +$phpWord->addTitleStyle(3, array('size' => 12), array('numStyle' => 'hNum', 'numLevel' => 2)); + +$section->addTitle('Heading 1', 1); +$section->addTitle('Heading 2', 2); +$section->addTitle('Heading 3', 3); +``` + # Frequently asked questions ## Is this the same with PHPWord that I found in CodePlex? diff --git a/samples/Sample_14_ListItem.php b/samples/Sample_14_ListItem.php index 892771bc..3a3d34ab 100644 --- a/samples/Sample_14_ListItem.php +++ b/samples/Sample_14_ListItem.php @@ -18,7 +18,7 @@ $phpWord->addNumberingStyle( array('format' => 'decimal', 'text' => '%1.', 'left' => 360, 'hanging' => 360, 'tabPos' => 360), array('format' => 'upperLetter', 'text' => '%2.', 'left' => 720, 'hanging' => 360, 'tabPos' => 720), ) - ) + ) ); $predefinedMultilevel = array('listType' => \PhpOffice\PhpWord\Style\ListItem::TYPE_NUMBER_NESTED); @@ -66,6 +66,25 @@ $listItemRun->addText('List item 3'); $listItemRun->addText(' underlined', array('underline'=>'dash')); $section->addTextBreak(2); +// Numbered heading + +$phpWord->addNumberingStyle( + 'headingNumbering', + array('type' => 'multilevel', 'levels' => array( + array('pStyle' => 'Heading1', 'format' => 'decimal', 'text' => '%1'), + array('pStyle' => 'Heading2', 'format' => 'decimal', 'text' => '%1.%2'), + array('pStyle' => 'Heading3', 'format' => 'decimal', 'text' => '%1.%2.%3'), + ) + ) +); +$phpWord->addTitleStyle(1, array('size' => 16), array('numStyle' => 'headingNumbering', 'numLevel' => 0)); +$phpWord->addTitleStyle(2, array('size' => 14), array('numStyle' => 'headingNumbering', 'numLevel' => 1)); +$phpWord->addTitleStyle(3, array('size' => 12), array('numStyle' => 'headingNumbering', 'numLevel' => 2)); + +$section->addTitle('Heading 1', 1); +$section->addTitle('Heading 2', 2); +$section->addTitle('Heading 3', 3); + // Save file echo write($phpWord, basename(__FILE__, '.php'), $writers); if (!CLI) { diff --git a/src/PhpWord/Style/NumberingLevel.php b/src/PhpWord/Style/NumberingLevel.php index 465231a7..32e61c89 100644 --- a/src/PhpWord/Style/NumberingLevel.php +++ b/src/PhpWord/Style/NumberingLevel.php @@ -56,6 +56,14 @@ class NumberingLevel extends AbstractStyle */ private $restart; + /** + * Related paragraph style + * + * @var string + * @link http://www.schemacentral.com/sc/ooxml/e-w_pStyle-2.html + */ + private $pStyle; + /** * Content between numbering symbol and paragraph text * @@ -205,6 +213,28 @@ class NumberingLevel extends AbstractStyle return $this; } + /** + * Get related paragraph style + * + * @return string + */ + public function getPStyle() + { + return $this->pStyle; + } + + /** + * Set related paragraph style + * + * @param string $value + * @return self + */ + public function setPStyle($value) + { + $this->pStyle = $value; + return $this; + } + /** * Get suffix * diff --git a/src/PhpWord/Style/Paragraph.php b/src/PhpWord/Style/Paragraph.php index e70833ca..c504e653 100644 --- a/src/PhpWord/Style/Paragraph.php +++ b/src/PhpWord/Style/Paragraph.php @@ -114,6 +114,20 @@ class Paragraph extends AbstractStyle */ private $alignment; + /** + * Numbering style name + * + * @var string + */ + private $numStyle; + + /** + * Numbering level + * + * @var int + */ + private $numLevel = 0; + /** * Create new instance */ @@ -532,6 +546,52 @@ class Paragraph extends AbstractStyle return $this; } + /** + * Get numbering style name + * + * @return string + */ + public function getNumStyle() + { + return $this->numStyle; + } + + /** + * Set numbering style name + * + * @param string $value + * @return self + */ + public function setNumStyle($value) + { + $this->numStyle = $value; + + return $this; + } + + /** + * Get numbering level + * + * @return int + */ + public function getNumLevel() + { + return $this->numLevel; + } + + /** + * Set numbering level + * + * @param int $value + * @return self + */ + public function setNumLevel($value = 0) + { + $this->numLevel = $this->setIntVal($value, $this->numLevel); + + return $this; + } + /** * Get allow first/last line to display on a separate page setting * diff --git a/src/PhpWord/Writer/Word2007/Part/Numbering.php b/src/PhpWord/Writer/Word2007/Part/Numbering.php index 05cbf7b9..8f735dd3 100644 --- a/src/PhpWord/Writer/Word2007/Part/Numbering.php +++ b/src/PhpWord/Writer/Word2007/Part/Numbering.php @@ -58,7 +58,7 @@ class Numbering extends AbstractPart $levels = $style->getLevels(); $xmlWriter->startElement('w:abstractNum'); - $xmlWriter->writeAttribute('w:abstractNumId', $style->getNumId()); + $xmlWriter->writeAttribute('w:abstractNumId', $style->getIndex()); $xmlWriter->startElement('w:nsid'); $xmlWriter->writeAttribute('w:val', $this->getRandomHexNumber()); @@ -81,9 +81,9 @@ class Numbering extends AbstractPart foreach ($styles as $style) { if ($style instanceof NumberingStyle) { $xmlWriter->startElement('w:num'); - $xmlWriter->writeAttribute('w:numId', $style->getNumId()); + $xmlWriter->writeAttribute('w:numId', $style->getIndex()); $xmlWriter->startElement('w:abstractNumId'); - $xmlWriter->writeAttribute('w:val', $style->getNumId()); + $xmlWriter->writeAttribute('w:val', $style->getIndex()); $xmlWriter->endElement(); // w:abstractNumId $xmlWriter->endElement(); // w:num } @@ -107,6 +107,7 @@ class Numbering extends AbstractPart 'start' => 'start', 'format' => 'numFmt', 'restart' => 'lvlRestart', + 'pStyle' => 'pStyle', 'suffix' => 'suff', 'text' => 'lvlText', 'align' => 'lvlJc' diff --git a/src/PhpWord/Writer/Word2007/Style/Paragraph.php b/src/PhpWord/Writer/Word2007/Style/Paragraph.php index 7322fd91..8741c177 100644 --- a/src/PhpWord/Writer/Word2007/Style/Paragraph.php +++ b/src/PhpWord/Writer/Word2007/Style/Paragraph.php @@ -17,6 +17,7 @@ namespace PhpOffice\PhpWord\Writer\Word2007\Style; +use PhpOffice\PhpWord\Style; use PhpOffice\PhpWord\Style\Alignment as AlignmentStyle; /** @@ -117,6 +118,24 @@ class Paragraph extends AbstractStyle $xmlWriter->endElement(); } + // Numbering + $numStyleName = $style->getNumStyle(); + $numStyleObject = Style::getStyle($numStyleName); + if ($numStyleName !== null && $numStyleObject !== null) { + $xmlWriter->startElement('w:numPr'); + $xmlWriter->startElement('w:numId'); + $xmlWriter->writeAttribute('w:val', $numStyleObject->getIndex()); + $xmlWriter->endElement(); // w:numId + $xmlWriter->startElement('w:ilvl'); + $xmlWriter->writeAttribute('w:val', $style->getNumLevel()); + $xmlWriter->endElement(); // w:ilvl + $xmlWriter->endElement(); // w:numPr + + $xmlWriter->startElement('w:outlineLvl'); + $xmlWriter->writeAttribute('w:val', $style->getNumLevel()); + $xmlWriter->endElement(); // w:outlineLvl + } + if (!$this->withoutPPR) { $xmlWriter->endElement(); // w:pPr }