Merge remote-tracking branch 'origin/develop' into develop

Conflicts:
	src/PhpWord/Element/Section.php
	src/PhpWord/Endnotes.php
	src/PhpWord/Footnotes.php
	src/PhpWord/Media.php
	src/PhpWord/PhpWord.php
	src/PhpWord/Reader/Word2007.php
	src/PhpWord/Writer/AbstractWriter.php
	src/PhpWord/Writer/ODText/Content.php
	src/PhpWord/Writer/Word2007.php
	src/PhpWord/Writer/Word2007/Notes.php
This commit is contained in:
Roman Syroeshko 2014-04-16 17:39:26 +04:00
commit db1d89ab23
97 changed files with 4195 additions and 1116 deletions

View File

@ -18,8 +18,9 @@ before_script:
## Composer
# - curl -s http://getcomposer.org/installer | php
# - php composer.phar install --prefer-source
- composer self-update
- composer require dompdf/dompdf:0.6.*
- composer install --prefer-source
- composer selfupdate --quiet
## PHP_CodeSniffer
- pyrus install pear/PHP_CodeSniffer
- phpenv rehash

View File

@ -2,9 +2,9 @@
This is the changelog between releases of PHPWord. Releases are listed in reverse chronological order with the latest version listed on top, while additions/changes in each release are listed in chronological order. Changes in each release are divided into three parts: added or change features, bugfixes, and miscellaneous improvements. Each line contains short information about the change made, the person who made it, and the related issue number(s) in GitHub.
## 0.9.2 - Not yet released
## 0.10.0 - 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. Basic HTML and PDF writing support is enabled.
### Features
@ -27,12 +27,18 @@ 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
- Media: Add `Media::resetElements()` to reset all media data - @juzi GH-19
- 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
- DOCX Reader: Ability to read header, footer, footnotes, link, preservetext, textbreak, pagebreak, table, list, image - @ivanlanin
- Endnote: Ability to add endnotes - @ivanlanin
- ListItem: Ability to create custom list and reset list number - @ivanlanin GH-10 GH-198
- ODT Writer: Basic table writing support - @ivanlanin
- Image: Keep image aspect ratio if only 1 dimension styled - @japonicus GH-194
- HTML Writer: Basic HTML writer: text, textrun, link, title, textbreak, table, image (as Base64), footnote, endnote - @ivanlanin GH-203 GH-67 GH-147
- PDF Writer: Basic PDF writer using DomPDF: All HTML element except image - @ivanlanin GH-68
### Bugfixes
- Footnote: Footnote content doesn't show footnote reference number - @ivanlanin GH-170
- Documentation : Error in a fonction - @theBeerNut GH-195
### Deprecated
@ -61,6 +67,8 @@ This release marked heavy refactorings on internal code structure with the creat
- Style: New `Style\AbstractStyle` abstract class - @ivanlanin GH-187
- Writer: New 'ODText\Base` class - @ivanlanin GH-187
- General: Rename `Footnote` to `Footnotes` to reflect the nature of collection - @ivanlanin
- General: Add some unit tests for Shared & Element (100%!) - @Progi1984
- Test: Add some samples and tests for image wrapping style - @brunocasado GH-59
## 0.9.1 - 27 Mar 2014

View File

@ -40,9 +40,10 @@
"phpunit/phpunit": "3.7.*"
},
"suggest": {
"ext-gd2": "*",
"ext-xmlwriter": "*",
"ext-xsl": "*"
"ext-gd2": "Required to add images",
"ext-xmlwriter": "Required to write DOCX and ODT",
"ext-xsl": "Required to apply XSL style sheet to template part",
"dompdf/dompdf": "Required to write PDF"
},
"autoload": {
"psr-4": {

View File

@ -207,10 +207,14 @@ Lists
To add a list item use the function ``addListItem``.
Basic usage:
.. code-block:: php
$section->addListItem($text, [$depth], [$fontStyle], [$listStyle], [$paragraphStyle]);
Parameters:
- ``$text`` Text that appears in the document.
- ``$depth`` Depth of list item.
- ``$fontStyle`` See "Font style" section.
@ -219,6 +223,40 @@ To add a list item use the function ``addListItem``.
PHPWord\_Style\_ListItem.
- ``$paragraphStyle`` See "Paragraph style" section.
Advanced usage:
You can also create your own numbering style by changing the ``$listStyle`` parameter
with the name of your numbering style.
.. code-block:: php
$phpWord->addNumberingStyle(
'multilevel',
array('type' => 'multilevel', 'levels' => array(
array('format' => 'decimal', 'text' => '%1.', 'left' => 360, 'hanging' => 360, 'tabPos' => 360),
array('format' => 'upperLetter', 'text' => '%2.', 'left' => 720, 'hanging' => 360, 'tabPos' => 720),
)
)
);
$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');
Level styles:
- ``start`` Starting value
- ``format`` Numbering format bullet|decimal|upperRoman|lowerRoman|upperLetter|lowerLetter
- ``restart`` Restart numbering level symbol
- ``suffix`` Content between numbering symbol and paragraph text tab|space|nothing
- ``text`` Numbering level text e.g. %1 for nonbullet or bullet character
- ``align`` Numbering symbol align left|center|right|both
- ``left`` See paragraph style
- ``hanging`` See paragraph style
- ``tabPos`` See paragraph style
- ``font`` Font name
- ``hint`` See font style
Tables
------

View File

@ -63,9 +63,9 @@ XML Writer compatibility
~~~~~~~~~~~~~~~~~~~~~~~~
This option sets
```XMLWriter::setIndent`` <http://www.php.net/manual/en/function.xmlwriter-set-indent.php>`__
`XMLWriter::setIndent <http://www.php.net/manual/en/function.xmlwriter-set-indent.php>`__
and
```XMLWriter::setIndentString`` <http://www.php.net/manual/en/function.xmlwriter-set-indent-string.php>`__.
`XMLWriter::setIndentString <http://www.php.net/manual/en/function.xmlwriter-set-indent-string.php>`__.
The default value of this option is ``true`` (compatible), which is
`required for OpenOffice <https://github.com/PHPOffice/PHPWord/issues/103>`__ to
render OOXML document correctly. You can set this option to ``false``
@ -108,7 +108,7 @@ name. Use the following functions:
.. code-block:: php
$properties = $phpWord->getProperties();
$properties = $phpWord->getDocumentProperties();
$properties->setCreator('My name');
$properties->setCompany('My factory');
$properties->setTitle('My title');

View File

@ -62,63 +62,63 @@ Below are the supported features for each file formats.
Writers
~~~~~~~
+-------------------------------------------------+--------+-------+-------+
| Features | DOCX | ODT | RTF |
+=========================+=======================+========+=======+=======+
| **Document Properties** | Standard | | | |
+ +-----------------------+--------+-------+-------+
| | Extended | | | |
+ +-----------------------+--------+-------+-------+
| | UserDefined | | | |
+-------------------------+-----------------------+--------+-------+-------+
| **Element Type** | Text | ✓ | ✓ | ✓ |
+ +-----------------------+--------+-------+-------+
| | Text Run | ✓ | ✓ | ✓ |
+ +-----------------------+--------+-------+-------+
| | Title | ✓ | | |
+ +-----------------------+--------+-------+-------+
| | Link | ✓ | | |
+ +-----------------------+--------+-------+-------+
| | Preserve Text | ✓ | | |
+ +-----------------------+--------+-------+-------+
| | Text Break | ✓ | ✓ | ✓ |
+ +-----------------------+--------+-------+-------+
| | Page Break | ✓ | | |
+ +-----------------------+--------+-------+-------+
| | List | ✓ | | |
+ +-----------------------+--------+-------+-------+
| | Table | ✓ | | |
+ +-----------------------+--------+-------+-------+
| | Image | ✓ | | |
+ +-----------------------+--------+-------+-------+
| | Object | ✓ | | |
+ +-----------------------+--------+-------+-------+
| | Watermark | ✓ | | |
+ +-----------------------+--------+-------+-------+
| | Table of Contents | ✓ | | |
+ +-----------------------+--------+-------+-------+
| | Header | ✓ | | |
+ +-----------------------+--------+-------+-------+
| | Footer | ✓ | | |
+ +-----------------------+--------+-------+-------+
| | Footnote | ✓ | | |
+ +-----------------------+--------+-------+-------+
| | Endnote | ✓ | | |
+-------------------------+-----------------------+--------+-------+-------+
| **Graphs** | 2D basic graphs | | | |
+ +-----------------------+--------+-------+-------+
| | 2D advanced graphs | | | |
+ +-----------------------+--------+-------+-------+
| | 3D graphs | | | |
+-------------------------+-----------------------+--------+-------+-------+
| **Math** | OMML support | | | |
+ +-----------------------+--------+-------+-------+
| | MathML support | | | |
+-------------------------+-----------------------+--------+-------+-------+
| **Bonus** | Encryption | | | |
+ +-----------------------+--------+-------+-------+
| | Protection | | | |
+-------------------------+-----------------------+--------+-------+-------+
+-------------------------------------------------+--------+-------+-------+-------+-------+
| Features | DOCX | ODT | RTF | HTML | PDF |
+=========================+=======================+========+=======+=======+=======+=======+
| **Document Properties** | Standard | ✓ | | | | |
+ +-----------------------+--------+-------+-------+-------+-------+
| | Extended | ✓ | | | | |
+ +-----------------------+--------+-------+-------+-------+-------+
| | UserDefined | ✓ | | | | |
+-------------------------+-----------------------+--------+-------+-------+-------+-------+
| **Element Type** | Text | ✓ | ✓ | ✓ | ✓ | ✓ |
+ +-----------------------+--------+-------+-------+-------+-------+
| | Text Run | ✓ | ✓ | ✓ | ✓ | ✓ |
+ +-----------------------+--------+-------+-------+-------+-------+
| | Title | ✓ | | | ✓ | ✓ |
+ +-----------------------+--------+-------+-------+-------+-------+
| | Link | ✓ | | | ✓ | ✓ |
+ +-----------------------+--------+-------+-------+-------+-------+
| | Preserve Text | ✓ | | | | |
+ +-----------------------+--------+-------+-------+-------+-------+
| | Text Break | ✓ | ✓ | ✓ | ✓ | ✓ |
+ +-----------------------+--------+-------+-------+-------+-------+
| | Page Break | ✓ | | | | |
+ +-----------------------+--------+-------+-------+-------+-------+
| | List | ✓ | | | | |
+ +-----------------------+--------+-------+-------+-------+-------+
| | Table | ✓ | ✓ | | | ✓ |
+ +-----------------------+--------+-------+-------+-------+-------+
| | Image | ✓ | | | ✓ | |
+ +-----------------------+--------+-------+-------+-------+-------+
| | Object | ✓ | | | | |
+ +-----------------------+--------+-------+-------+-------+-------+
| | Watermark | ✓ | | | | |
+ +-----------------------+--------+-------+-------+-------+-------+
| | Table of Contents | ✓ | | | | |
+ +-----------------------+--------+-------+-------+-------+-------+
| | Header | ✓ | | | | |
+ +-----------------------+--------+-------+-------+-------+-------+
| | Footer | ✓ | | | | |
+ +-----------------------+--------+-------+-------+-------+-------+
| | Footnote | ✓ | | | ✓ | |
+ +-----------------------+--------+-------+-------+-------+-------+
| | Endnote | ✓ | | | ✓ | |
+-------------------------+-----------------------+--------+-------+-------+-------+-------+
| **Graphs** | 2D basic graphs | | | | | |
+ +-----------------------+--------+-------+-------+-------+-------+
| | 2D advanced graphs | | | | | |
+ +-----------------------+--------+-------+-------+-------+-------+
| | 3D graphs | | | | | |
+-------------------------+-----------------------+--------+-------+-------+-------+-------+
| **Math** | OMML support | | | | | |
+ +-----------------------+--------+-------+-------+-------+-------+
| | MathML support | | | | | |
+-------------------------+-----------------------+--------+-------+-------+-------+-------+
| **Bonus** | Encryption | | | | | |
+ +-----------------------+--------+-------+-------+-------+-------+
| | Protection | | | | | |
+-------------------------+-----------------------+--------+-------+-------+-------+-------+
Readers

View File

@ -45,13 +45,7 @@ $section->addTextBreak();
$section->addImage('resources/_earth.jpg', array('width'=>18, 'height'=>18));
// Save file
$name = basename(__FILE__, '.php');
$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf');
foreach ($writers as $writer => $extension) {
echo date('H:i:s'), " Write to {$writer} format", EOL;
$xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer);
$xmlWriter->save("{$name}.{$extension}");
rename("{$name}.{$extension}", "results/{$name}.{$extension}");
echo write($phpWord, basename(__FILE__, '.php'), $writers);
if (!CLI) {
include_once 'Sample_Footer.php';
}
include_once 'Sample_Footer.php';

View File

@ -33,13 +33,7 @@ $section->addText("Left Aligned\tRight Aligned", null, 'rightTab');
$section->addText("\tCenter Aligned", null, 'centerTab');
// Save file
$name = basename(__FILE__, '.php');
$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf');
foreach ($writers as $writer => $extension) {
echo date('H:i:s'), " Write to {$writer} format", EOL;
$xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer);
$xmlWriter->save("{$name}.{$extension}");
rename("{$name}.{$extension}", "results/{$name}.{$extension}");
echo write($phpWord, basename(__FILE__, '.php'), $writers);
if (!CLI) {
include_once 'Sample_Footer.php';
}
include_once 'Sample_Footer.php';

View File

@ -26,13 +26,7 @@ $section->addHeader()->addText('Header');
$section->addFooter()->addText('Footer');
// Save file
$name = basename(__FILE__, '.php');
$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf');
foreach ($writers as $writer => $extension) {
echo date('H:i:s'), " Write to {$writer} format", EOL;
$xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer);
$xmlWriter->save("{$name}.{$extension}");
rename("{$name}.{$extension}", "results/{$name}.{$extension}");
echo write($phpWord, basename(__FILE__, '.php'), $writers);
if (!CLI) {
include_once 'Sample_Footer.php';
}
include_once 'Sample_Footer.php';

View File

@ -34,13 +34,7 @@ $textrun->addObject('resources/_sheet.xls');
$textrun->addText(' Here is some more text. ');
// Save file
$name = basename(__FILE__, '.php');
$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf');
foreach ($writers as $writer => $extension) {
echo date('H:i:s'), " Write to {$writer} format", EOL;
$xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer);
$xmlWriter->save("{$name}.{$extension}");
rename("{$name}.{$extension}", "results/{$name}.{$extension}");
echo write($phpWord, basename(__FILE__, '.php'), $writers);
if (!CLI) {
include_once 'Sample_Footer.php';
}
include_once 'Sample_Footer.php';

View File

@ -36,13 +36,7 @@ $section = $phpWord->addSection(array('breakType' => 'continuous'));
$section->addText('Normal paragraph again.');
// Save file
$name = basename(__FILE__, '.php');
$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf');
foreach ($writers as $writer => $extension) {
echo date('H:i:s'), " Write to {$writer} format", EOL;
$xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer);
$xmlWriter->save("{$name}.{$extension}");
rename("{$name}.{$extension}", "results/{$name}.{$extension}");
echo write($phpWord, basename(__FILE__, '.php'), $writers);
if (!CLI) {
include_once 'Sample_Footer.php';
}
include_once 'Sample_Footer.php';

View File

@ -38,13 +38,7 @@ $footnote = $section->addFootnote();
$footnote->addText('The reference for this is wrapped in its own line');
// Save file
$name = basename(__FILE__, '.php');
$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf');
foreach ($writers as $writer => $extension) {
echo date('H:i:s'), " Write to {$writer} format", EOL;
$xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer);
$xmlWriter->save("{$name}.{$extension}");
rename("{$name}.{$extension}", "results/{$name}.{$extension}");
echo write($phpWord, basename(__FILE__, '.php'), $writers);
if (!CLI) {
include_once 'Sample_Footer.php';
}
include_once 'Sample_Footer.php';

View File

@ -60,4 +60,8 @@ echo date('H:i:s'), " Write to Word2007 format", EOL;
$document->saveAs($name);
rename($name, "results/{$name}");
include_once 'Sample_Footer.php';
$writers = array('Word2007' => 'docx');
echo getEndingNotes($writers);
if (!CLI) {
include_once 'Sample_Footer.php';
}

View File

@ -46,13 +46,7 @@ $section->addText('Paragraph with pageBreakBefore = true (default: false). ' .
null, array('pageBreakBefore' => true));
// Save file
$name = basename(__FILE__, '.php');
$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf');
foreach ($writers as $writer => $extension) {
echo date('H:i:s'), " Write to {$writer} format", EOL;
$xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer);
$xmlWriter->save("{$name}.{$extension}");
rename("{$name}.{$extension}", "results/{$name}.{$extension}");
echo write($phpWord, basename(__FILE__, '.php'), $writers);
if (!CLI) {
include_once 'Sample_Footer.php';
}
include_once 'Sample_Footer.php';

View File

@ -85,13 +85,7 @@ $table->addCell(2000, $cellVCentered)->addText('D', null, $cellHCentered);
$table->addCell(null, $cellRowContinue);
// Save file
$name = basename(__FILE__, '.php');
$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf');
foreach ($writers as $writer => $extension) {
echo date('H:i:s'), " Write to {$writer} format", EOL;
$xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer);
$xmlWriter->save("{$name}.{$extension}");
rename("{$name}.{$extension}", "results/{$name}.{$extension}");
echo write($phpWord, basename(__FILE__, '.php'), $writers);
if (!CLI) {
include_once 'Sample_Footer.php';
}
include_once 'Sample_Footer.php';

View File

@ -10,13 +10,7 @@ $header = array('size' => 16, 'bold' => true);
$section->addText('中文楷体样式测试',array('name' => '楷体', 'size' => 16, 'color' => '1B2232'));
// Save file
$name = basename(__FILE__, '.php');
$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf');
foreach ($writers as $writer => $extension) {
echo date('H:i:s'), " Write to {$writer} format", EOL;
$xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer);
$xmlWriter->save("{$name}.{$extension}");
rename("{$name}.{$extension}", "results/{$name}.{$extension}");
echo write($phpWord, basename(__FILE__, '.php'), $writers);
if (!CLI) {
include_once 'Sample_Footer.php';
}
include_once 'Sample_Footer.php';

View File

@ -7,13 +7,8 @@ $source = "resources/{$name}.docx";
echo date('H:i:s'), " Reading contents from `{$source}`", EOL;
$phpWord = \PhpOffice\PhpWord\IOFactory::load($source);
// (Re)write contents
$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf');
foreach ($writers as $writer => $extension) {
echo date('H:i:s'), " Write to {$writer} format", EOL;
$xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer);
$xmlWriter->save("{$name}.{$extension}");
rename("{$name}.{$extension}", "results/{$name}.{$extension}");
// Save file
echo write($phpWord, basename(__FILE__, '.php'), $writers);
if (!CLI) {
include_once 'Sample_Footer.php';
}
include_once 'Sample_Footer.php';

View File

@ -59,15 +59,8 @@ $sec2Header->addText("All pages in Section 2 will Have this!");
$section2->addTextBreak();
$section2->addText('Some text...');
// Save file
$name = basename(__FILE__, '.php');
$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf');
foreach ($writers as $writer => $extension) {
echo date('H:i:s'), " Write to {$writer} format", EOL;
$xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer);
$xmlWriter->save("{$name}.{$extension}");
rename("{$name}.{$extension}", "results/{$name}.{$extension}");
echo write($phpWord, basename(__FILE__, '.php'), $writers);
if (!CLI) {
include_once 'Sample_Footer.php';
}
include_once 'Sample_Footer.php';

View File

@ -10,24 +10,29 @@ $section = $phpWord->addSection();
$section->addText('Local image without any styles:');
$section->addImage('resources/_mars.jpg');
$section->addTextBreak(2);
//
$section->addText('Local image with styles:');
$section->addImage('resources/_earth.jpg', array('width' => 210, 'height' => 210, 'align' => 'center'));
$section->addTextBreak(2);
// Remote image
$source = 'http://php.net/images/logos/php-med-trans-light.gif';
$section->addText("Remote image from: {$source}");
$section->addImage($source);
// End code
// Save file
$name = basename(__FILE__, '.php');
$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf');
foreach ($writers as $writer => $extension) {
echo date('H:i:s'), " Write to {$writer} format", EOL;
$xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer);
$xmlWriter->save("{$name}.{$extension}");
rename("{$name}.{$extension}", "results/{$name}.{$extension}");
//Wrapping style
$text = str_repeat('Hello World! ', 15);
$wrappingStyles = array('inline', 'behind', 'infront', 'square', 'tight');
foreach ($wrappingStyles as $wrappingStyle) {
$section->addTextBreak(5);
$section->addText('Wrapping style ' . $wrappingStyle);
$section->addImage('resources/_earth.jpg', array('marginTop' => -1, 'marginLeft' => 1,
'width' => 80, 'height' => 80, 'wrappingStyle' => $wrappingStyle));
$section->addText($text);
}
include_once 'Sample_Footer.php';
// Save file
echo write($phpWord, basename(__FILE__, '.php'), $writers);
if (!CLI) {
include_once 'Sample_Footer.php';
}

View File

@ -8,50 +8,54 @@ $phpWord = new \PhpOffice\PhpWord\PhpWord();
// Begin code
$section = $phpWord->addSection();
// Add listitem elements
$section->addListItem('List Item 1', 0);
$section->addListItem('List Item 2', 0);
$section->addListItem('List Item 3', 0);
$section->addTextBreak(2);
// Style definition
// 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->addParagraphStyle('P-Style', array('spaceAfter'=>95));
$listStyle = array('listType' => \PhpOffice\PhpWord\Style\ListItem::TYPE_NUMBER_NESTED);
$section->addListItem('List Item 1', 0, 'myOwnStyle', $listStyle, 'P-Style');
$section->addListItem('List Item 2', 0, 'myOwnStyle', $listStyle, 'P-Style');
$section->addListItem('List Item 3', 1, 'myOwnStyle', $listStyle, 'P-Style');
$section->addListItem('List Item 4', 1, 'myOwnStyle', $listStyle, 'P-Style');
$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');
$phpWord->addNumberingStyle(
'multilevel',
array('type' => 'multilevel', 'levels' => array(
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);
// End code
// 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);
// Save file
$name = basename(__FILE__, '.php');
$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf');
foreach ($writers as $writer => $extension) {
echo date('H:i:s'), " Write to {$writer} format", EOL;
$xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer);
$xmlWriter->save("{$name}.{$extension}");
rename("{$name}.{$extension}", "results/{$name}.{$extension}");
echo write($phpWord, basename(__FILE__, '.php'), $writers);
if (!CLI) {
include_once 'Sample_Footer.php';
}
include_once 'Sample_Footer.php';

View File

@ -16,16 +16,8 @@ $phpWord->addLinkStyle('myOwnLinkStyle', array('bold'=>true, 'color'=>'808000'))
$section->addLink('http://www.bing.com', null, 'myOwnLinkStyle');
$section->addLink('http://www.yahoo.com', null, 'myOwnLinkStyle');
// End code
// Save file
$name = basename(__FILE__, '.php');
$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf');
foreach ($writers as $writer => $extension) {
echo date('H:i:s'), " Write to {$writer} format", EOL;
$xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer);
$xmlWriter->save("{$name}.{$extension}");
rename("{$name}.{$extension}", "results/{$name}.{$extension}");
echo write($phpWord, basename(__FILE__, '.php'), $writers);
if (!CLI) {
include_once 'Sample_Footer.php';
}
include_once 'Sample_Footer.php';

View File

@ -11,16 +11,8 @@ $section->addText('You can open this OLE object by double clicking on the icon:'
$section->addTextBreak(2);
$section->addObject('resources/_sheet.xls');
// End code
// Save file
$name = basename(__FILE__, '.php');
$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf');
foreach ($writers as $writer => $extension) {
echo date('H:i:s'), " Write to {$writer} format", EOL;
$xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer);
$xmlWriter->save("{$name}.{$extension}");
rename("{$name}.{$extension}", "results/{$name}.{$extension}");
echo write($phpWord, basename(__FILE__, '.php'), $writers);
if (!CLI) {
include_once 'Sample_Footer.php';
}
include_once 'Sample_Footer.php';

View File

@ -67,16 +67,9 @@ $section->addTitle('Subtitle 3.1.2', 3);
$section->addText('Text');
echo date('H:i:s'), " Note: Please refresh TOC manually.", EOL;
// End code
// Save file
$name = basename(__FILE__, '.php');
$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf');
foreach ($writers as $writer => $extension) {
echo date('H:i:s'), " Write to {$writer} format", EOL;
$xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer);
$xmlWriter->save("{$name}.{$extension}");
rename("{$name}.{$extension}", "results/{$name}.{$extension}");
echo write($phpWord, basename(__FILE__, '.php'), $writers);
if (!CLI) {
include_once 'Sample_Footer.php';
}
include_once 'Sample_Footer.php';

View File

@ -12,16 +12,8 @@ $header = $section->addHeader();
$header->addWatermark('resources/_earth.jpg', array('marginTop' => 200, 'marginLeft' => 55));
$section->addText('The header reference to the current section includes a watermark image.');
// End code
// Save file
$name = basename(__FILE__, '.php');
$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf');
foreach ($writers as $writer => $extension) {
echo date('H:i:s'), " Write to {$writer} format", EOL;
$xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer);
$xmlWriter->save("{$name}.{$extension}");
rename("{$name}.{$extension}", "results/{$name}.{$extension}");
echo write($phpWord, basename(__FILE__, '.php'), $writers);
if (!CLI) {
include_once 'Sample_Footer.php';
}
include_once 'Sample_Footer.php';

View File

@ -25,16 +25,8 @@ $section->addText('Text break with inline paragraph style:');
$section->addTextBreak(1, null, $paragraphStyle);
$section->addText('Done.');
// End code
// Save file
$name = basename(__FILE__, '.php');
$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf');
foreach ($writers as $writer => $extension) {
echo date('H:i:s'), " Write to {$writer} format", EOL;
$xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer);
$xmlWriter->save("{$name}.{$extension}");
rename("{$name}.{$extension}", "results/{$name}.{$extension}");
echo write($phpWord, basename(__FILE__, '.php'), $writers);
if (!CLI) {
include_once 'Sample_Footer.php';
}
include_once 'Sample_Footer.php';

View File

@ -11,13 +11,7 @@ $section->addText("This one uses bgColor and is using hex value (0xfbbb10)", arr
$section->addText("Compatible with font colors", array("color"=>"0000ff", "bgColor" => "fbbb10"));
// Save file
$name = basename(__FILE__, '.php');
$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf');
foreach ($writers as $writer => $extension) {
echo date('H:i:s'), " Write to {$writer} format", EOL;
$xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer);
$xmlWriter->save("{$name}.{$extension}");
rename("{$name}.{$extension}", "results/{$name}.{$extension}");
echo write($phpWord, basename(__FILE__, '.php'), $writers);
if (!CLI) {
include_once 'Sample_Footer.php';
}
include_once 'Sample_Footer.php';

View File

@ -28,13 +28,7 @@ $section->addText("In this example, image is 250px height. Rows are calculated i
$section->addText("So: $"."table2->addRow(3750, array('exactHeight'=>true));");
// Save file
$name = basename(__FILE__, '.php');
$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf');
foreach ($writers as $writer => $extension) {
echo date('H:i:s'), " Write to {$writer} format", EOL;
$xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer);
$xmlWriter->save("{$name}.{$extension}");
rename("{$name}.{$extension}", "results/{$name}.{$extension}");
echo write($phpWord, basename(__FILE__, '.php'), $writers);
if (!CLI) {
include_once 'Sample_Footer.php';
}
include_once 'Sample_Footer.php';

View File

@ -15,13 +15,7 @@ $cell = $table->addCell();
$cell->addCheckBox('chkBox2', 'Checkbox 2');
// Save file
$name = basename(__FILE__, '.php');
$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf');
foreach ($writers as $writer => $extension) {
echo date('H:i:s'), " Write to {$writer} format", EOL;
$xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer);
$xmlWriter->save("{$name}.{$extension}");
rename("{$name}.{$extension}", "results/{$name}.{$extension}");
echo write($phpWord, basename(__FILE__, '.php'), $writers);
if (!CLI) {
include_once 'Sample_Footer.php';
}
include_once 'Sample_Footer.php';

View File

@ -18,4 +18,8 @@ echo date('H:i:s'), " Write to Word2007 format", EOL;
$document->saveAs($name);
rename($name, "results/{$name}");
include_once 'Sample_Footer.php';
$writers = array('Word2007' => 'docx');
echo getEndingNotes($writers);
if (!CLI) {
include_once 'Sample_Footer.php';
}

View File

@ -2,33 +2,10 @@
/**
* Footer file
*/
// Do not show execution time for index
if (!IS_INDEX) {
echo date('H:i:s'), " Done writing file(s)", EOL;
echo date('H:i:s'), " Peak memory usage: ", (memory_get_peak_usage(true) / 1024 / 1024), " MB", EOL;
}
// Show message when executed with CLI, show links when using browsers
if (CLI) {
echo 'The results are stored in the "results" subdirectory.', EOL;
} else {
if (!IS_INDEX) {
$types = array('docx', 'odt', 'rtf');
echo '<p>&nbsp;</p>';
echo '<p>Results: ';
foreach ($types as $type) {
$result = 'results/' . SCRIPT_FILENAME . '.' . $type;
if (file_exists($result)) {
echo "<a href='{$result}' class='btn btn-primary'>{$type}</a> ";
}
}
echo '</p>';
}
?>
</div>
<script src="bootstrap/js/jquery.min.js"></script>
<script src="bootstrap/js/bootstrap.min.js"></script>
</body>
</html>
<?php
} // if (CLI)

View File

@ -11,6 +11,17 @@ define('IS_INDEX', SCRIPT_FILENAME == 'index');
require_once '../src/PhpWord/Autoloader.php';
\PhpOffice\PhpWord\Autoloader::register();
// Set writers
$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf', 'HTML' => 'html', 'PDF' => 'pdf');
// Set PDF renderer
$rendererName = \PhpOffice\PhpWord\Settings::PDF_RENDERER_DOMPDF;
$rendererLibraryPath = ''; // DomPDF library path
if (!\PhpOffice\PhpWord\Settings::setPdfRenderer($rendererName, $rendererLibraryPath)) {
$writers['PDF'] = null;
}
// Return to the caller script when runs by CLI
if (CLI) {
return;
@ -21,6 +32,7 @@ $pageHeading = str_replace('_', ' ', SCRIPT_FILENAME);
$pageTitle = IS_INDEX ? 'Welcome to ' : "{$pageHeading} - ";
$pageTitle .= 'PHPWord';
$pageHeading = IS_INDEX ? '' : "<h1>{$pageHeading}</h1>";
// Populate samples
$files = '';
if ($handle = opendir('.')) {
@ -32,6 +44,73 @@ if ($handle = opendir('.')) {
}
closedir($handle);
}
/**
* Write documents
*
* @param \PhpOffice\PhpWord\PhpWord $phpWord
* @param string $filename
* @param array $writers
*/
function write($phpWord, $filename, $writers)
{
$result = '';
// Write documents
foreach ($writers as $writer => $extension) {
$result .= date('H:i:s') . " Write to {$writer} format";
if (!is_null($extension)) {
$xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer);
$xmlWriter->save("{$filename}.{$extension}");
rename("{$filename}.{$extension}", "results/{$filename}.{$extension}");
} else {
$result .= ' ... NOT DONE!';
}
$result .= EOL;
}
$result .= getEndingNotes($writers);
return $result;
}
/**
* Get ending notes
*
* @param array $writers
*/
function getEndingNotes($writers)
{
$result = '';
// Do not show execution time for index
if (!IS_INDEX) {
$result .= date('H:i:s') . " Done writing file(s)" . EOL;
$result .= date('H:i:s') . " Peak memory usage: " . (memory_get_peak_usage(true) / 1024 / 1024) . " MB" . EOL;
}
// Return
if (CLI) {
$result .= 'The results are stored in the "results" subdirectory.' . EOL;
} else {
if (!IS_INDEX) {
$types = array_values($writers);
$result .= '<p>&nbsp;</p>';
$result .= '<p>Results: ';
foreach ($types as $type) {
if (!is_null($type)) {
$resultFile = 'results/' . SCRIPT_FILENAME . '.' . $type;
if (file_exists($resultFile)) {
$result .= "<a href='{$resultFile}' class='btn btn-primary'>{$type}</a> ";
}
}
}
$result .= '</p>';
}
}
return $result;
}
?>
<title><?php echo $pageTitle; ?></title>
<meta charset="utf-8">

View File

@ -24,5 +24,7 @@ foreach ($requirements as $key => $value) {
echo "<li>{$value[0]} ... <span class='{$status}'>{$status}</span></li>";
}
echo "</ul>";
} // if (!CLI)
include_once 'Sample_Footer.php';
}
if (!CLI) {
include_once 'Sample_Footer.php';
}

View File

@ -22,7 +22,7 @@ use PhpOffice\PhpWord\TOC;
/**
* Container abstract class
*
* @since 0.9.2
* @since 0.10.0
*/
abstract class AbstractElement
{
@ -69,6 +69,20 @@ abstract class AbstractElement
*/
protected $elements = array();
/**
* Index of element in the elements collection (start with 1)
*
* @var integer
*/
protected $elementIndex = 1;
/**
* Unique Id for element
*
* @var integer
*/
protected $elementId;
/**
* Relation Id
*
@ -96,7 +110,7 @@ abstract class AbstractElement
$text = String::toUTF8($text);
$textObject = new Text($text, $fontStyle, $paragraphStyle);
$textObject->setDocPart($this->getDocPart(), $this->getDocPartId());
$this->elements[] = $textObject;
$this->addElement($textObject);
return $textObject;
}
@ -113,7 +127,7 @@ abstract class AbstractElement
$textRun = new TextRun($paragraphStyle);
$textRun->setDocPart($this->getDocPart(), $this->getDocPartId());
$this->elements[] = $textRun;
$this->addElement($textRun);
return $textRun;
}
@ -136,7 +150,7 @@ abstract class AbstractElement
$link->setDocPart($this->getDocPart(), $this->getDocPartId());
$rId = Media::addElement($elementDocPart, 'link', $linkSrc);
$link->setRelationId($rId);
$this->elements[] = $link;
$this->addElement($link);
return $link;
}
@ -167,7 +181,7 @@ abstract class AbstractElement
$bookmarkId = $data[1];
$title->setAnchor($anchor);
$title->setBookmarkId($bookmarkId);
$this->elements[] = $title;
$this->addElement($title);
return $title;
}
@ -186,7 +200,7 @@ abstract class AbstractElement
$preserveText = new PreserveText(String::toUTF8($text), $fontStyle, $paragraphStyle);
$preserveText->setDocPart($this->getDocPart(), $this->getDocPartId());
$this->elements[] = $preserveText;
$this->addElement($preserveText);
return $preserveText;
}
@ -205,7 +219,7 @@ abstract class AbstractElement
for ($i = 1; $i <= $count; $i++) {
$textBreak = new TextBreak($fontStyle, $paragraphStyle);
$textBreak->setDocPart($this->getDocPart(), $this->getDocPartId());
$this->elements[] = $textBreak;
$this->addElement($textBreak);
}
}
@ -225,7 +239,7 @@ abstract class AbstractElement
$listItem = new ListItem(String::toUTF8($text), $depth, $fontStyle, $styleList, $paragraphStyle);
$listItem->setDocPart($this->getDocPart(), $this->getDocPartId());
$this->elements[] = $listItem;
$this->addElement($listItem);
return $listItem;
}
@ -241,7 +255,7 @@ abstract class AbstractElement
$this->checkValidity('table');
$table = new Table($this->getDocPart(), $this->getDocPartId(), $style);
$this->elements[] = $table;
$this->addElement($table);
return $table;
}
@ -263,7 +277,8 @@ abstract class AbstractElement
$image->setDocPart($this->getDocPart(), $this->getDocPartId());
$rId = Media::addElement($elementDocPart, 'image', $src, $image);
$image->setRelationId($rId);
$this->elements[] = $image;
$this->addElement($image);
return $image;
}
@ -296,7 +311,8 @@ abstract class AbstractElement
$object->setRelationId($rId);
$rIdimg = Media::addElement($elementDocPart, 'image', $icon, new Image($icon));
$object->setImageRelationId($rIdimg);
$this->elements[] = $object;
$this->addElement($object);
return $object;
} else {
throw new InvalidObjectException();
@ -318,7 +334,7 @@ abstract class AbstractElement
$footnote->setDocPart('footnote', $this->getDocPartId());
$footnote->setRelationId($rId);
$this->elements[] = $footnote;
$this->addElement($footnote);
return $footnote;
}
@ -338,7 +354,7 @@ abstract class AbstractElement
$endnote->setDocPart('endnote', $this->getDocPartId());
$endnote->setRelationId($rId);
$this->elements[] = $endnote;
$this->addElement($endnote);
return $endnote;
}
@ -358,7 +374,7 @@ abstract class AbstractElement
$checkBox = new CheckBox(String::toUTF8($name), String::toUTF8($text), $fontStyle, $paragraphStyle);
$checkBox->setDocPart($this->getDocPart(), $this->getDocPartId());
$this->elements[] = $checkBox;
$this->addElement($checkBox);
return $checkBox;
}
@ -405,6 +421,16 @@ abstract class AbstractElement
return $this->docPartId;
}
/**
* Set element index and unique id, and add element into elements collection
*/
protected function addElement(AbstractElement $element)
{
$element->setElementIndex($this->countElements() + 1);
$element->setElementId();
$this->elements[] = $element;
}
/**
* Get all elements
*
@ -415,6 +441,54 @@ abstract class AbstractElement
return $this->elements;
}
/**
* Count elements
*
* @return integer
*/
public function countElements()
{
return count($this->elements);
}
/**
* Get element index
*
* @return int
*/
public function getElementIndex()
{
return $this->elementIndex;
}
/**
* Set element index
*
* @param int $value
*/
public function setElementIndex($value)
{
$this->elementIndex = $value;
}
/**
* Get element unique ID
*
* @return string
*/
public function getElementId()
{
return $this->elementId;
}
/**
* Set element unique ID from 6 first digit of md5
*/
public function setElementId()
{
$this->elementId = substr(md5(rand()), 0, 6);
}
/**
* Get relation Id
*
@ -458,9 +532,6 @@ abstract class AbstractElement
{
if (!is_null($styleValue) && is_array($styleValue)) {
foreach ($styleValue as $key => $value) {
if (substr($key, 0, 1) == '_') {
$key = substr($key, 1);
}
$styleObject->setStyleValue($key, $value);
}
$style = $styleObject;
@ -555,7 +626,7 @@ abstract class AbstractElement
* Create textrun element
*
* @param mixed $paragraphStyle
* @deprecated 0.9.2
* @deprecated 0.10.0
* @codeCoverageIgnore
*/
public function createTextRun($paragraphStyle = null)
@ -567,7 +638,7 @@ abstract class AbstractElement
* Create footnote element
*
* @param mixed $paragraphStyle
* @deprecated 0.9.2
* @deprecated 0.10.0
* @codeCoverageIgnore
*/
public function createFootnote($paragraphStyle = null)

View File

@ -14,7 +14,7 @@ use PhpOffice\PhpWord\Style\Paragraph;
/**
* Endnote element
*
* @since 0.9.2
* @since 0.10.0
*/
class Endnote extends Footnote
{

View File

@ -44,7 +44,7 @@ class Footer extends AbstractElement
* Set type
*
* @param string $value
* @since 0.9.2
* @since 0.10.0
*/
public function setType($value = self::AUTO)
{
@ -55,7 +55,7 @@ class Footer extends AbstractElement
* Get type
*
* @return string
* @since 0.9.2
* @since 0.10.0
*/
public function getType()
{

View File

@ -48,7 +48,7 @@ class Footnote extends AbstractElement
* Get Footnote Reference ID
*
* @return int
* @deprecated 0.9.2
* @deprecated 0.10.0
* @codeCoverageIgnore
*/
public function getReferenceId()
@ -60,7 +60,7 @@ class Footnote extends AbstractElement
* Set Footnote Reference ID
*
* @param int $rId
* @deprecated 0.9.2
* @deprecated 0.10.0
* @codeCoverageIgnore
*/
public function setReferenceId($rId)

View File

@ -64,7 +64,7 @@ class Header extends AbstractElement
* Set header type
*
* @param string $value
* @since 0.9.2
* @since 0.10.0
*/
public function setType($value = self::AUTO)
{

View File

@ -18,6 +18,13 @@ use PhpOffice\PhpWord\Style\Image as ImageStyle;
*/
class Image extends AbstractElement
{
/**
* Image source type constants
*/
const SOURCE_LOCAL = 'local'; // Local images
const SOURCE_GD = 'gd'; // Generated using GD
const SOURCE_ARCHIVE = 'archive'; // Image in archives zip://$archive#$image
/**
* Image source
*
@ -25,6 +32,13 @@ class Image extends AbstractElement
*/
private $source;
/**
* Source type: local|gd|archive
*
* @var string
*/
private $sourceType;
/**
* Image style
*
@ -85,57 +99,11 @@ class Image extends AbstractElement
*/
public function __construct($source, $style = null, $isWatermark = false)
{
// Detect if it's a memory image, by .php ext or by URL
if (stripos(strrev($source), strrev('.php')) === 0) {
$this->isMemImage = true;
} else {
$this->isMemImage = (filter_var($source, FILTER_VALIDATE_URL) !== false);
}
// Check supported types
if ($this->isMemImage) {
$supportedTypes = array('image/jpeg', 'image/gif', 'image/png');
$imgData = @getimagesize($source);
if (!is_array($imgData)) {
throw new InvalidImageException();
}
$this->imageType = $imgData['mime']; // string
if (!in_array($this->imageType, $supportedTypes)) {
throw new UnsupportedImageTypeException();
}
} else {
$supportedTypes = array(
IMAGETYPE_JPEG, IMAGETYPE_GIF,
IMAGETYPE_PNG, IMAGETYPE_BMP,
IMAGETYPE_TIFF_II, IMAGETYPE_TIFF_MM
);
if (!file_exists($source)) {
throw new InvalidImageException();
}
$imgData = getimagesize($source);
if (function_exists('exif_imagetype')) {
$this->imageType = exif_imagetype($source);
} else {
// @codeCoverageIgnoreStart
$tmp = getimagesize($source);
$this->imageType = $tmp[2];
// @codeCoverageIgnoreEnd
}
if (!in_array($this->imageType, $supportedTypes)) {
throw new UnsupportedImageTypeException();
}
$this->imageType = image_type_to_mime_type($this->imageType);
}
// Set private properties
$this->source = $source;
$this->isWatermark = $isWatermark;
$this->setIsWatermark($isWatermark);
$this->style = $this->setStyle(new ImageStyle(), $style, true);
if ($this->style->getWidth() == null && $this->style->getHeight() == null) {
$this->style->setWidth($imgData[0]);
$this->style->setHeight($imgData[1]);
}
$this->setImageFunctions();
$this->checkImage($source);
}
/**
@ -158,6 +126,16 @@ class Image extends AbstractElement
return $this->source;
}
/**
* Get image source type
*
* @return string
*/
public function getSourceType()
{
return $this->sourceType;
}
/**
* Get image media ID
*
@ -239,9 +217,92 @@ class Image extends AbstractElement
}
/**
* Set image functions
* Check memory image, supported type, image functions, and proportional width/height
*
* @param string $source
*/
private function setImageFunctions()
private function checkImage($source)
{
$this->setSourceType($source);
// Check image data
if ($this->sourceType == self::SOURCE_ARCHIVE) {
$imageData = $this->getArchiveImageSize($source);
} else {
$imageData = @getimagesize($source);
}
if (!is_array($imageData)) {
throw new InvalidImageException();
}
list($actualWidth, $actualHeight, $imageType) = $imageData;
// Check image type support
$supportedTypes = array(IMAGETYPE_JPEG, IMAGETYPE_GIF, IMAGETYPE_PNG);
if ($this->sourceType != self::SOURCE_GD) {
$supportedTypes = array_merge($supportedTypes, array(IMAGETYPE_BMP, IMAGETYPE_TIFF_II, IMAGETYPE_TIFF_MM));
}
if (!in_array($imageType, $supportedTypes)) {
throw new UnsupportedImageTypeException();
}
// Define image functions
$this->imageType = image_type_to_mime_type($imageType);
$this->setFunctions();
$this->setProportionalSize($actualWidth, $actualHeight);
}
/**
* Set source type
*
* @param string $source
*/
private function setSourceType($source)
{
if (stripos(strrev($source), strrev('.php')) === 0) {
$this->isMemImage = true;
$this->sourceType = self::SOURCE_GD;
} elseif (strpos($source, 'zip://') !== false) {
$this->isMemImage = false;
$this->sourceType = self::SOURCE_ARCHIVE;
} else {
$this->isMemImage = (filter_var($source, FILTER_VALIDATE_URL) !== false);
$this->sourceType = $this->isMemImage ? self::SOURCE_GD : self::SOURCE_LOCAL;
}
}
/**
* Get image size from archive
*
* @param string $source
* @return array|null
*/
private function getArchiveImageSize($source)
{
$imageData = null;
$source = substr($source, 6);
list($zipFilename, $imageFilename) = explode('#', $source);
$tempFilename = tempnam(sys_get_temp_dir(), 'PHPWordImage');
$zip = new \ZipArchive();
if ($zip->open($zipFilename) !== false) {
if ($zip->locateName($imageFilename)) {
$imageContent = $zip->getFromName($imageFilename);
if ($imageContent !== false) {
file_put_contents($tempFilename, $imageContent);
$imageData = @getimagesize($tempFilename);
unlink($tempFilename);
}
}
$zip->close();
}
return $imageData;
}
/**
* Set image functions and extensions
*/
private function setFunctions()
{
switch ($this->imageType) {
case 'image/png':
@ -260,8 +321,8 @@ class Image extends AbstractElement
$this->imageFunc = 'imagejpeg';
$this->imageExtension = 'jpg';
break;
case 'image/x-ms-bmp':
case 'image/bmp':
case 'image/x-ms-bmp':
$this->imageType = 'image/bmp';
$this->imageExtension = 'bmp';
break;
@ -270,4 +331,26 @@ class Image extends AbstractElement
break;
}
}
/**
* Set proportional width/height if one dimension not available
*
* @param integer $actualWidth
* @param integer $actualHeight
*/
private function setProportionalSize($actualWidth, $actualHeight)
{
$styleWidth = $this->style->getWidth();
$styleHeight = $this->style->getHeight();
if (!($styleWidth && $styleHeight)) {
if ($styleWidth == null && $styleHeight == null) {
$this->style->setWidth($actualWidth);
$this->style->setHeight($actualHeight);
} elseif ($styleWidth) {
$this->style->setHeight($actualHeight * ($styleWidth / $actualWidth));
} else {
$this->style->setWidth($actualWidth * ($styleHeight / $actualHeight));
}
}
}
}

View File

@ -43,15 +43,21 @@ class ListItem extends AbstractElement
*
* @param string $text
* @param int $depth
* @param mixed $styleFont
* @param mixed $styleList
* @param mixed $styleParagraph
* @param mixed $fontStyle
* @param array|string|null $listStyle
* @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->style = $this->setStyle(new ListItemStyle(), $styleList, true);
// Version >= 0.10.0 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);
}
}
/**

View File

@ -101,7 +101,7 @@ class Object extends AbstractElement
* Get Object ID
*
* @return int
* @deprecated 0.9.2
* @deprecated 0.10.0
* @codeCoverageIgnore
*/
public function getObjectId()
@ -113,7 +113,7 @@ class Object extends AbstractElement
* Set Object ID
*
* @param int $objId
* @deprecated 0.9.2
* @deprecated 0.10.0
* @codeCoverageIgnore
*/
public function setObjectId($objId)

View File

@ -66,9 +66,6 @@ class Section extends AbstractElement
if (is_null($value)) {
continue;
}
if (substr($key, 0, 1) == '_') {
$key = substr($key, 1);
}
$this->settings->setSettingValue($key, $value);
}
}
@ -113,7 +110,7 @@ class Section extends AbstractElement
*
* @param string $type
* @return Header
* @since 0.9.2
* @since 0.10.0
*/
public function addHeader($type = Header::AUTO)
{
@ -125,7 +122,7 @@ class Section extends AbstractElement
*
* @param string $type
* @return Footer
* @since 0.9.2
* @since 0.10.0
*/
public function addFooter($type = Header::AUTO)
{
@ -177,7 +174,7 @@ class Section extends AbstractElement
* @param boolean $header
* @return Header|Footer
* @throws \PhpOffice\PhpWord\Exception\Exception
* @since 0.9.2
* @since 0.10.0
*/
private function addHeaderFooter($type = Header::AUTO, $header = true)
{
@ -201,7 +198,7 @@ class Section extends AbstractElement
* Create header
*
* @return Header
* @deprecated 0.9.2
* @deprecated 0.10.0
* @codeCoverageIgnore
*/
public function createHeader()
@ -213,7 +210,7 @@ class Section extends AbstractElement
* Create footer
*
* @return Footer
* @deprecated 0.9.2
* @deprecated 0.10.0
* @codeCoverageIgnore
*/
public function createFooter()
@ -225,7 +222,7 @@ class Section extends AbstractElement
* Get footer
*
* @return Footer
* @deprecated 0.9.2
* @deprecated 0.10.0
* @codeCoverageIgnore
*/
public function getFooter()

View File

@ -33,7 +33,7 @@ class Table extends AbstractElement
/**
* Table width
*
* @var int
* @var integer
*/
private $width = null;
@ -42,7 +42,7 @@ class Table extends AbstractElement
* Create a new table
*
* @param string $docPart
* @param int $docPartId
* @param integer $docPartId
* @param mixed $style
*/
public function __construct($docPart, $docPartId, $style = null)
@ -54,7 +54,7 @@ class Table extends AbstractElement
/**
* Add a row
*
* @param int $height
* @param integer $height
* @param mixed $style
*/
public function addRow($height = null, $style = null)
@ -67,7 +67,7 @@ class Table extends AbstractElement
/**
* Add a cell
*
* @param int $width
* @param integer $width
* @param mixed $style
* @return Cell
*/
@ -101,7 +101,7 @@ class Table extends AbstractElement
/**
* Set table width
*
* @param int $width
* @param integer $width
*/
public function setWidth($width)
{
@ -111,10 +111,31 @@ class Table extends AbstractElement
/**
* Get table width
*
* @return int
* @return integer
*/
public function getWidth()
{
return $this->width;
}
/**
* Get column count
*
* @return integer
*/
public function countColumns()
{
$columnCount = 0;
if (is_array($this->rows)) {
$rowCount = count($this->rows);
for ($i = 0; $i < $rowCount; $i++) {
$cellCount = count($this->rows[$i]->getCells());
if ($columnCount < $cellCount) {
$columnCount = $cellCount;
}
}
}
return $columnCount;
}
}

View File

@ -119,6 +119,16 @@ class Title extends AbstractElement
return $this->text;
}
/**
* Get depth
*
* @return integer
*/
public function getDepth()
{
return $this->depth;
}
/**
* Get Title style
*

View File

@ -12,7 +12,7 @@ namespace PhpOffice\PhpWord;
/**
* Endnote collection
*
* @since 0.9.2
* @since 0.10.0
*/
class Endnotes
{

View File

@ -26,7 +26,7 @@ class Footnotes
*
* @param \PhpOffice\PhpWord\Element\Footnote $element
* @return integer Reference ID
* @since 0.9.2
* @since 0.10.0
*/
public static function addElement($element)
{
@ -41,7 +41,7 @@ class Footnotes
*
* @param integer $index
* @param \PhpOffice\PhpWord\Element\Footnote $element
* @since 0.9.2
* @since 0.10.0
*/
public static function setElement($index, $element)
{
@ -55,7 +55,7 @@ class Footnotes
*
* @param integer $index
* @return \PhpOffice\PhpWord\Element\Footnote
* @since 0.9.2
* @since 0.10.0
*/
public static function getElement($index)
{
@ -70,7 +70,7 @@ class Footnotes
* Get elements
*
* @return array
* @since 0.9.2
* @since 0.10.0
*/
public static function getElements()
{
@ -81,7 +81,7 @@ class Footnotes
* Get element count
*
* @return integer
* @since 0.9.2
* @since 0.10.0
*/
public static function countElements()
{
@ -91,7 +91,7 @@ class Footnotes
/**
* Reset elements
*
* @since 0.9.2
* @since 0.10.0
*/
public static function resetElements()
{
@ -103,7 +103,7 @@ class Footnotes
*
* @param \PhpOffice\PhpWord\Element\Footnote $element
* @return integer Reference ID
* @deprecated 0.9.2
* @deprecated 0.10.0
* @codeCoverageIgnore
*/
public static function addFootnoteElement($element)
@ -115,7 +115,7 @@ class Footnotes
* Get Footnote Elements
*
* @return array
* @deprecated 0.9.2
* @deprecated 0.10.0
* @codeCoverageIgnore
*/
public static function getFootnoteElements()
@ -127,7 +127,7 @@ class Footnotes
* Get Footnote Elements Count
*
* @return integer
* @deprecated 0.9.2
* @deprecated 0.10.0
* @codeCoverageIgnore
*/
public static function countFootnoteElements()
@ -140,7 +140,7 @@ class Footnotes
*
* @param string $linkSrc
* @return integer Reference ID
* @deprecated 0.9.2
* @deprecated 0.10.0
* @codeCoverageIgnore
*/
public static function addFootnoteLinkElement($linkSrc)
@ -152,7 +152,7 @@ class Footnotes
* Get Footnote Link Elements
*
* @return array
* @deprecated 0.9.2
* @deprecated 0.10.0
* @codeCoverageIgnore
*/
public static function getFootnoteLinkElements()

View File

@ -26,7 +26,7 @@ abstract class IOFactory
*/
public static function createWriter(PhpWord $phpWord, $name = 'Word2007')
{
if ($name !== 'WriterInterface' && $name !== 'ODText' && $name !== 'RTF' && $name !== 'Word2007') {
if (!in_array($name, array('WriterInterface', 'Word2007', 'ODText', 'RTF', 'HTML', 'PDF'))) {
throw new Exception("\"{$name}\" is not a valid writer.");
}
@ -43,7 +43,7 @@ abstract class IOFactory
*/
public static function createReader($name = 'Word2007')
{
if ($name !== 'ReaderInterface' && $name !== 'Word2007') {
if (!in_array($name, array('ReaderInterface', 'Word2007'))) {
throw new Exception("\"{$name}\" is not a valid reader.");
}

View File

@ -34,6 +34,7 @@ class Media
* @return integer
* @throws \PhpOffice\PhpWord\Exception\Exception
* @since 0.9.2
* @since 0.10.0
*/
public static function addElement($container, $mediaType, $source, Image $image = null)
{
@ -98,7 +99,7 @@ class Media
* @param string $container section|headerx|footerx|footnote|endnote
* @param string $mediaType image|object|link
* @return integer
* @since 0.9.2
* @since 0.10.0
*/
public static function countElements($container, $mediaType = null)
{
@ -125,7 +126,7 @@ class Media
* @param string $container section|headerx|footerx|footnote|endnote
* @param string $mediaType image|object|link
* @return array
* @since 0.9.2
* @since 0.10.0
*/
public static function getElements($container, $mediaType = null)
{
@ -171,7 +172,7 @@ class Media
* @param string $type
* @param \PhpOffice\PhpWord\Element\Image $image
* @return integer
* @deprecated 0.9.2
* @deprecated 0.10.0
* @codeCoverageIgnore
*/
public static function addSectionMediaElement($src, $type, Image $image = null)
@ -184,7 +185,7 @@ class Media
*
* @param string $linkSrc
* @return integer
* @deprecated 0.9.2
* @deprecated 0.10.0
* @codeCoverageIgnore
*/
public static function addSectionLinkElement($linkSrc)
@ -197,7 +198,7 @@ class Media
*
* @param string $key
* @return array
* @deprecated 0.9.2
* @deprecated 0.10.0
* @codeCoverageIgnore
*/
public static function getSectionMediaElements($key = null)
@ -210,7 +211,7 @@ class Media
*
* @param string $key
* @return integer
* @deprecated 0.9.2
* @deprecated 0.10.0
* @codeCoverageIgnore
*/
public static function countSectionMediaElements($key = null)
@ -225,7 +226,7 @@ class Media
* @param string $src
* @param \PhpOffice\PhpWord\Element\Image $image
* @return integer
* @deprecated 0.9.2
* @deprecated 0.10.0
* @codeCoverageIgnore
*/
public static function addHeaderMediaElement($headerCount, $src, Image $image = null)
@ -238,7 +239,7 @@ class Media
*
* @param string $key
* @return integer
* @deprecated 0.9.2
* @deprecated 0.10.0
* @codeCoverageIgnore
*/
public static function countHeaderMediaElements($key)
@ -250,7 +251,7 @@ class Media
* Get Header Media Elements
*
* @return array
* @deprecated 0.9.2
* @deprecated 0.10.0
* @codeCoverageIgnore
*/
public static function getHeaderMediaElements()
@ -265,7 +266,7 @@ class Media
* @param string $src
* @param \PhpOffice\PhpWord\Element\Image $image
* @return integer
* @deprecated 0.9.2
* @deprecated 0.10.0
* @codeCoverageIgnore
*/
public static function addFooterMediaElement($footerCount, $src, Image $image = null)
@ -278,7 +279,7 @@ class Media
*
* @param string $key
* @return integer
* @deprecated 0.9.2
* @deprecated 0.10.0
* @codeCoverageIgnore
*/
public static function countFooterMediaElements($key)
@ -290,7 +291,7 @@ class Media
* Get Footer Media Elements
*
* @return array
* @deprecated 0.9.2
* @deprecated 0.10.0
* @codeCoverageIgnore
*/
public static function getFooterMediaElements()

View File

@ -9,9 +9,11 @@
namespace PhpOffice\PhpWord;
use PhpOffice\PhpWord\Element\Section;
use PhpOffice\PhpWord\DocumentProperties;
use PhpOffice\PhpWord\Exception\Exception;
use PhpOffice\PhpWord\Element\Section;
use PhpOffice\PhpWord\Style;
use PhpOffice\PhpWord\Template;
/**
* PHPWord main class
@ -212,6 +214,17 @@ class PhpWord
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
*
@ -243,7 +256,7 @@ class PhpWord
*
* @param array $settings
* @return \PhpOffice\PhpWord\Element\Section
* @deprecated 0.9.2
* @deprecated 0.10.0
* @codeCoverageIgnore
*/
public function createSection($settings = null)

View File

@ -9,16 +9,18 @@
namespace PhpOffice\PhpWord\Reader;
use PhpOffice\PhpWord\DocumentProperties;
use PhpOffice\PhpWord\Footnote;
use PhpOffice\PhpWord\PhpWord;
use PhpOffice\PhpWord\Settings;
use PhpOffice\PhpWord\Footnote;
use PhpOffice\PhpWord\Endnotes;
use PhpOffice\PhpWord\DocumentProperties;
use PhpOffice\PhpWord\Shared\XMLReader;
use PhpOffice\PhpWord\Element\Section;
/**
* Reader for Word2007
*
* @since 0.9.2
* @since 0.10.0
* @todo title, list, watermark, checkbox, toc
* @todo Partly done: image, object
*/
@ -38,6 +40,13 @@ class Word2007 extends AbstractReader implements ReaderInterface
*/
private $rels = array('main' => array(), 'document' => array());
/**
* Filename
*
* @var string
*/
private $filename;
/**
* Loads PhpWord from file
*
@ -48,14 +57,27 @@ class Word2007 extends AbstractReader implements ReaderInterface
{
$this->phpWord = new PhpWord();
$this->readRelationships($filename);
$this->filename = $filename;
$this->readRelationships();
// Read styles and numbering first
foreach ($this->rels['document'] as $rId => $rel) {
switch ($rel['type']) {
case 'styles':
$this->readStyles($rel['target']);
break;
case 'numbering':
$this->readNumbering($rel['target']);
break;
}
}
// Read main relationship
foreach ($this->rels['main'] as $rId => $rel) {
switch ($rel['type']) {
case 'officeDocument':
$this->readDocument($filename, $rel['target']);
$this->readDocument($rel['target']);
break;
case 'core-properties':
@ -71,31 +93,26 @@ class Word2007 extends AbstractReader implements ReaderInterface
'dcterms:modified' => 'setModified',
);
$callbacks = array('dcterms:created' => 'strtotime', 'dcterms:modified' => 'strtotime');
$this->readDocProps($filename, $rel['target'], $mapping, $callbacks);
$this->readDocProps($rel['target'], $mapping, $callbacks);
break;
case 'extended-properties':
$mapping = array('Company' => 'setCompany', 'Manager' => 'setManager');
$this->readDocProps($filename, $rel['target'], $mapping);
$this->readDocProps($rel['target'], $mapping);
break;
case 'custom-properties':
$this->readDocPropsCustom($filename, $rel['target']);
$this->readDocPropsCustom($rel['target']);
break;
}
}
// Read document relationships
// Read footnotes and endnotes
foreach ($this->rels['document'] as $rId => $rel) {
switch ($rel['type']) {
case 'styles':
$this->readStyles($filename, $rel['target']);
break;
case 'footnotes':
case 'endnotes':
$this->readNotes($filename, $rel['target'], $rel['type']);
$this->readNotes($rel['target'], $rel['type']);
break;
}
}
@ -105,24 +122,22 @@ class Word2007 extends AbstractReader implements ReaderInterface
/**
* Read all relationship files
*
* @param string $filename
*/
private function readRelationships($filename)
private function readRelationships()
{
// _rels/.rels
$this->rels['main'] = $this->getRels($filename, '_rels/.rels');
$this->rels['main'] = $this->getRels('_rels/.rels');
// word/_rels/*.xml.rels
$wordRelsPath = 'word/_rels/';
$zipClass = Settings::getZipClass();
$zip = new $zipClass();
if ($zip->open($filename) === true) {
if ($zip->open($this->filename) === true) {
for ($i = 0; $i < $zip->numFiles; $i++) {
$xmlFile = $zip->getNameIndex($i);
if ((substr($xmlFile, 0, strlen($wordRelsPath))) == $wordRelsPath) {
if ((substr($xmlFile, 0, strlen($wordRelsPath))) == $wordRelsPath && (substr($xmlFile, -1)) != '/') {
$docPart = str_replace('.xml.rels', '', str_replace($wordRelsPath, '', $xmlFile));
$this->rels[$docPart] = $this->getRels($filename, $xmlFile, 'word/');
$this->rels[$docPart] = $this->getRels($xmlFile, 'word/');
}
}
$zip->close();
@ -132,15 +147,14 @@ class Word2007 extends AbstractReader implements ReaderInterface
/**
* Read core and extended document properties
*
* @param string $filename
* @param string $xmlFile
* @param array $mapping
* @param array $callbacks
*/
private function readDocProps($filename, $xmlFile, $mapping, $callbacks = array())
private function readDocProps($xmlFile, $mapping, $callbacks = array())
{
$xmlReader = new XMLReader();
$xmlReader->getDomFromZip($filename, $xmlFile);
$xmlReader->getDomFromZip($this->filename, $xmlFile);
$docProps = $this->phpWord->getDocumentProperties();
$nodes = $xmlReader->getElements('*');
@ -164,19 +178,17 @@ class Word2007 extends AbstractReader implements ReaderInterface
/**
* Read custom document properties
*
* @param string $filename
* @param string $xmlFile
*/
private function readDocPropsCustom($filename, $xmlFile)
private function readDocPropsCustom($xmlFile)
{
$xmlReader = new XMLReader();
$xmlReader->getDomFromZip($filename, $xmlFile);
$xmlReader->getDomFromZip($this->filename, $xmlFile);
$docProps = $this->phpWord->getDocumentProperties();
$nodes = $xmlReader->getElements('*');
if ($nodes->length > 0) {
foreach ($nodes as $node) {
$nodeName = $node->nodeName;
$propertyName = $xmlReader->getAttribute('name', $node);
$attributeNode = $xmlReader->getElement('*', $node);
$attributeType = $attributeNode->nodeName;
@ -191,19 +203,19 @@ class Word2007 extends AbstractReader implements ReaderInterface
/**
* Read document.xml
*
* @param string $filename
* @param string $xmlFile
*/
private function readDocument($filename, $xmlFile)
private function readDocument($xmlFile)
{
$xmlReader = new XMLReader();
$xmlReader->getDomFromZip($filename, $xmlFile);
$xmlReader->getDomFromZip($this->filename, $xmlFile);
$nodes = $xmlReader->getElements('w:body/*');
if ($nodes->length > 0) {
$section = $this->phpWord->addSection();
foreach ($nodes as $node) {
switch ($node->nodeName) {
case 'w:p': // Paragraph
if ($xmlReader->getAttribute('w:type', $node, 'w:r/w:br') == 'page') {
$section->addPageBreak(); // PageBreak
@ -213,19 +225,27 @@ class Word2007 extends AbstractReader implements ReaderInterface
// Section properties
if ($xmlReader->elementExists('w:pPr/w:sectPr', $node)) {
$settingsNode = $xmlReader->getElement('w:pPr/w:sectPr', $node);
$settings = $this->readSectionStyle($xmlReader, $settingsNode);
$section->setSettings($settings);
$this->readHeaderFooter($filename, $settings, $section);
if (!is_null($settingsNode)) {
$settings = $this->readSectionStyle($xmlReader, $settingsNode);
$section->setSettings($settings);
if (!is_null($settings)) {
$this->readHeaderFooter($settings, $section);
}
}
$section = $this->phpWord->addSection();
}
break;
case 'w:tbl': // Table
$this->readTable($xmlReader, $node, $section, 'document');
break;
case 'w:sectPr': // Last section
$settings = $this->readSectionStyle($xmlReader, $node);
$section->setSettings($settings);
$this->readHeaderFooter($filename, $settings, $section);
if (!is_null($settings)) {
$this->readHeaderFooter($settings, $section);
}
break;
}
}
@ -235,13 +255,12 @@ class Word2007 extends AbstractReader implements ReaderInterface
/**
* Read styles.xml
*
* @param string $filename
* @param string $xmlFile
*/
private function readStyles($filename, $xmlFile)
private function readStyles($xmlFile)
{
$xmlReader = new XMLReader();
$xmlReader->getDomFromZip($filename, $xmlFile);
$xmlReader->getDomFromZip($this->filename, $xmlFile);
$nodes = $xmlReader->getElements('w:style');
if ($nodes->length > 0) {
@ -253,21 +272,26 @@ class Word2007 extends AbstractReader implements ReaderInterface
}
// $default = ($xmlReader->getAttribute('w:default', $node) == 1);
switch ($type) {
case 'paragraph':
$pStyle = $this->readParagraphStyle($xmlReader, $node);
$fStyle = $this->readFontStyle($xmlReader, $node);
if (empty($fStyle)) {
$this->phpWord->addParagraphStyle($name, $pStyle);
if (is_array($pStyle)) {
$this->phpWord->addParagraphStyle($name, $pStyle);
}
} else {
$this->phpWord->addFontStyle($name, $fStyle, $pStyle);
}
break;
case 'character':
$fStyle = $this->readFontStyle($xmlReader, $node);
if (!empty($fStyle)) {
$this->phpWord->addFontStyle($name, $fStyle);
}
break;
case 'table':
$tStyle = $this->readTableStyle($xmlReader, $node);
if (!empty($tStyle)) {
@ -279,14 +303,104 @@ class Word2007 extends AbstractReader implements ReaderInterface
}
}
/**
* Read numbering.xml
*
* @param string $xmlFile
*/
private function readNumbering($xmlFile)
{
$abstracts = array();
$numberings = array();
$xmlReader = new XMLReader();
$xmlReader->getDomFromZip($this->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
*
* @param string $filename
* @param array $settings
* @param \PhpOffice\PhpWord\Element\Section $section
*/
private function readHeaderFooter($filename, $settings, &$section)
private function readHeaderFooter($settings, &$section)
{
if (is_array($settings) && array_key_exists('hf', $settings)) {
foreach ($settings['hf'] as $rId => $hfSetting) {
@ -297,7 +411,7 @@ class Word2007 extends AbstractReader implements ReaderInterface
// Read header/footer content
$xmlReader = new XMLReader();
$xmlReader->getDomFromZip($filename, $xmlFile);
$xmlReader->getDomFromZip($this->filename, $xmlFile);
$nodes = $xmlReader->getElements('*');
if ($nodes->length > 0) {
foreach ($nodes as $node) {
@ -321,17 +435,17 @@ class Word2007 extends AbstractReader implements ReaderInterface
/**
* Read (footnotes|endnotes).xml
*
* @param string $filename
* @param string $xmlFile
* @param string $notesType
*/
private function readNotes($filename, $xmlFile, $notesType = 'footnotes')
private function readNotes($xmlFile, $notesType = 'footnotes')
{
$notesType = ($notesType == 'endnotes') ? 'endnotes' : 'footnotes';
$collectionClass = 'PhpOffice\\PhpWord\\' . ucfirst($notesType);
$collection = $collectionClass::getElements();
$xmlReader = new XMLReader();
$xmlReader->getDomFromZip($filename, $xmlFile);
$xmlReader->getDomFromZip($this->filename, $xmlFile);
$nodes = $xmlReader->getElements('*');
if ($nodes->length > 0) {
foreach ($nodes as $node) {
@ -360,7 +474,7 @@ class Word2007 extends AbstractReader implements ReaderInterface
*
* @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
$pStyle = null;
@ -394,6 +508,17 @@ class Word2007 extends AbstractReader implements ReaderInterface
}
$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
} else {
$runCount = $xmlReader->countElements('w:r', $domNode);
@ -419,13 +544,15 @@ class Word2007 extends AbstractReader implements ReaderInterface
/**
* Read w:r
*
* @param \PhpOffice\PhpWord\Shared\XMLReader $xmlReader
* @param \DOMElement $domNode
* @param mixed $parent
* @param string $docPart
* @param mixed $pStyle
*
* @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'))) {
return;
@ -454,8 +581,8 @@ class Word2007 extends AbstractReader implements ReaderInterface
$rId = $xmlReader->getAttribute('r:id', $domNode, 'w:pict/v:shape/v:imagedata');
$target = $this->getMediaTarget($docPart, $rId);
if (!is_null($target)) {
$textContent = "<Image: {$target}>";
$parent->addText($textContent, $fStyle, $pStyle);
$imageSource = "zip://{$this->filename}#{$target}";
$parent->addImage($imageSource);
}
// Object
@ -482,7 +609,7 @@ class Word2007 extends AbstractReader implements ReaderInterface
* @param mixed $parent
* @param string $docPart
*/
private function readTable(XMLReader $xmlReader, \DOMNode $domNode, &$parent, $docPart)
private function readTable(XMLReader $xmlReader, \DOMElement $domNode, &$parent, $docPart)
{
// Table style
$tblStyle = null;
@ -515,8 +642,9 @@ class Word2007 extends AbstractReader implements ReaderInterface
} elseif ($rowNode->nodeName == 'w:tc') { // Cell
$cellWidth = $xmlReader->getAttribute('w:w', $rowNode, 'w:tcPr/w:tcW');
$cellStyle = null;
if ($xmlReader->elementExists('w:tcPr', $rowNode)) {
$cellStyle = $this->readCellStyle($xmlReader, $xmlReader->getElement('w:tcPr', $rowNode));
$cellStyleNode = $xmlReader->getElement('w:tcPr', $rowNode);
if (!is_null($cellStyleNode)) {
$cellStyle = $this->readCellStyle($xmlReader, $cellStyleNode);
}
$cell = $row->addCell($cellWidth, $cellStyle);
@ -537,7 +665,7 @@ class Word2007 extends AbstractReader implements ReaderInterface
*
* @return array|null
*/
private function readSectionStyle(XMLReader $xmlReader, \DOMNode $domNode)
private function readSectionStyle(XMLReader $xmlReader, \DOMElement $domNode)
{
$ret = null;
$mapping = array(
@ -552,6 +680,7 @@ class Word2007 extends AbstractReader implements ReaderInterface
}
$property = $mapping[$node->nodeName];
switch ($node->nodeName) {
case 'w:type':
$ret['breakType'] = $xmlReader->getAttribute('w:val', $node);
break;
@ -596,7 +725,7 @@ class Word2007 extends AbstractReader implements ReaderInterface
*
* @return string|array|null
*/
private function readParagraphStyle(XMLReader $xmlReader, \DOMNode $domNode)
private function readParagraphStyle(XMLReader $xmlReader, \DOMElement $domNode)
{
$style = null;
if ($xmlReader->elementExists('w:pPr', $domNode)) {
@ -618,6 +747,7 @@ class Word2007 extends AbstractReader implements ReaderInterface
}
$property = $mapping[$node->nodeName];
switch ($node->nodeName) {
case 'w:ind':
$style['indent'] = $xmlReader->getAttribute('w:left', $node);
$style['hanging'] = $xmlReader->getAttribute('w:hanging', $node);
@ -658,13 +788,16 @@ class Word2007 extends AbstractReader implements ReaderInterface
*
* @return string|array|null
*/
private function readFontStyle(XMLReader $xmlReader, \DOMNode $domNode)
private function readFontStyle(XMLReader $xmlReader, \DOMElement $domNode)
{
$style = null;
// Hyperlink has an extra w:r child
if ($domNode->nodeName == 'w:hyperlink') {
$domNode = $xmlReader->getElement('w:r', $domNode);
}
if (is_null($domNode)) {
return $style;
}
if ($xmlReader->elementExists('w:rPr', $domNode)) {
if ($xmlReader->elementExists('w:rPr/w:rStyle', $domNode)) {
$style = $xmlReader->getAttribute('w:val', $domNode, 'w:rPr/w:rStyle');
@ -684,6 +817,7 @@ class Word2007 extends AbstractReader implements ReaderInterface
}
$property = $mapping[$node->nodeName];
switch ($node->nodeName) {
case 'w:rFonts':
$style['name'] = $xmlReader->getAttribute('w:ascii', $node);
$style['hint'] = $xmlReader->getAttribute('w:hint', $node);
@ -728,7 +862,7 @@ class Word2007 extends AbstractReader implements ReaderInterface
* @return string|array|null
* @todo Capture w:tblStylePr w:type="firstRow"
*/
private function readTableStyle(XMLReader $xmlReader, \DOMNode $domNode)
private function readTableStyle(XMLReader $xmlReader, \DOMElement $domNode)
{
$style = null;
$margins = array('top', 'left', 'bottom', 'right');
@ -751,6 +885,7 @@ class Word2007 extends AbstractReader implements ReaderInterface
}
// $property = $mapping[$node->nodeName];
switch ($node->nodeName) {
case 'w:tblCellMar':
foreach ($margins as $side) {
$ucfSide = ucfirst($side);
@ -778,7 +913,7 @@ class Word2007 extends AbstractReader implements ReaderInterface
*
* @return array|null
*/
private function readCellStyle(XMLReader $xmlReader, \DOMNode $domNode)
private function readCellStyle(XMLReader $xmlReader, \DOMElement $domNode)
{
$style = null;
$mapping = array(
@ -809,12 +944,11 @@ class Word2007 extends AbstractReader implements ReaderInterface
/**
* Get relationship array
*
* @param string $filename
* @param string $xmlFile
* @param string $targetPrefix
* @return array
*/
private function getRels($filename, $xmlFile, $targetPrefix = '')
private function getRels($xmlFile, $targetPrefix = '')
{
$metaPrefix = 'http://schemas.openxmlformats.org/package/2006/relationships/metadata/';
$officePrefix = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/';
@ -822,7 +956,7 @@ class Word2007 extends AbstractReader implements ReaderInterface
$rels = array();
$xmlReader = new XMLReader();
$xmlReader->getDomFromZip($filename, $xmlFile);
$xmlReader->getDomFromZip($this->filename, $xmlFile);
$nodes = $xmlReader->getElements('*');
foreach ($nodes as $node) {
$rId = $xmlReader->getAttribute('Id', $node);

View File

@ -14,10 +14,13 @@ namespace PhpOffice\PhpWord;
*/
class Settings
{
/** Available Zip library classes */
/** Available Zip library classes */
const PCLZIP = 'PhpOffice\\PhpWord\\Shared\\ZipArchive';
const ZIPARCHIVE = 'ZipArchive';
/** Optional PDF Rendering libraries */
const PDF_RENDERER_DOMPDF = 'DomPDF';
/**
* Compatibility option for XMLWriter
*
@ -27,13 +30,32 @@ class Settings
/**
* Name of the class used for Zip file management
* e.g.
* ZipArchive
*
* @var string
*/
private static $zipClass = self::ZIPARCHIVE;
/**
* Name of the classes used for PDF renderer
*
* @var array
*/
private static $pdfRenderers = array(self::PDF_RENDERER_DOMPDF);
/**
* Name of the external Library used for rendering PDF files
*
* @var string
*/
private static $pdfRendererName = null;
/**
* Directory Path to the external Library used for rendering PDF files
*
* @var string
*/
private static $pdfRendererPath = null;
/**
* Set the compatibility option used by the XMLWriter
*
@ -74,7 +96,7 @@ class Settings
return true;
}
return false;
} // function setZipClass()
}
/**
* Return the name of the Zip handler Class that PHPWord is configured to use (PCLZip or ZipArchive)
@ -87,5 +109,71 @@ class Settings
public static function getZipClass()
{
return self::$zipClass;
} // function getZipClass()
}
/**
* Set details of the external library for rendering PDF files
*
* @param string $libraryName
* @param string $libraryBaseDir
* @return boolean Success or failure
*/
public static function setPdfRenderer($libraryName, $libraryBaseDir)
{
if (!self::setPdfRendererName($libraryName)) {
return false;
}
return self::setPdfRendererPath($libraryBaseDir);
}
/**
* Return the PDF Rendering Library
*/
public static function getPdfRendererName()
{
return self::$pdfRendererName;
}
/**
* Identify the external library to use for rendering PDF files
*
* @param string $libraryName
* @return boolean Success or failure
*/
public static function setPdfRendererName($libraryName)
{
if (!in_array($libraryName, self::$pdfRenderers)) {
return false;
}
self::$pdfRendererName = $libraryName;
return true;
}
/**
* Return the directory path to the PDF Rendering Library
*/
public static function getPdfRendererPath()
{
return self::$pdfRendererPath;
}
/**
* Location of external library to use for rendering PDF files
*
* @param string $libraryBaseDir Directory path to the library's base folder
* @return boolean Success or failure
*/
public static function setPdfRendererPath($libraryBaseDir)
{
if ((file_exists($libraryBaseDir) === false) || (is_readable($libraryBaseDir) === false)) {
return false;
}
self::$pdfRendererPath = $libraryBaseDir;
return true;
}
}

View File

@ -77,6 +77,23 @@ class String
return $value;
}
/**
* Return name without underscore for < 0.10.0 variable name compatibility
*
* @param string $value
* @return string
*/
public static function removeUnderscorePrefix($value)
{
if (!is_null($value)) {
if (substr($value, 0, 1) == '_') {
$value = substr($value, 1);
}
}
return $value;
}
/**
* Build control characters array
*/

View File

@ -15,7 +15,7 @@ use PhpOffice\PhpWord\Settings;
/**
* XML Reader wrapper
*
* @since 0.9.2
* @since 0.10.0
*/
class XMLReader
{
@ -70,7 +70,7 @@ class XMLReader
* @param string $path
* @return \DOMNodeList
*/
public function getElements($path, \DOMNode $contextNode = null)
public function getElements($path, \DOMElement $contextNode = null)
{
if ($this->dom === null) {
return array();
@ -86,9 +86,9 @@ class XMLReader
* Get element
*
* @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);
if ($elements->length > 0) {
@ -105,7 +105,7 @@ class XMLReader
* @param string $path
* @return string|null
*/
public function getAttribute($attribute, \DOMNode $contextNode, $path = null)
public function getAttribute($attribute, \DOMElement $contextNode, $path = null)
{
if (is_null($path)) {
$return = $contextNode->getAttribute($attribute);
@ -127,7 +127,7 @@ class XMLReader
* @param string $path
* @return string|null
*/
public function getValue($path, \DOMNode $contextNode)
public function getValue($path, \DOMElement $contextNode)
{
$elements = $this->getElements($path, $contextNode);
if ($elements->length > 0) {
@ -143,7 +143,7 @@ class XMLReader
* @param string $path
* @return integer
*/
public function countElements($path, \DOMNode $contextNode)
public function countElements($path, \DOMElement $contextNode)
{
$elements = $this->getElements($path, $contextNode);
@ -156,7 +156,7 @@ class XMLReader
* @param string $path
* @return boolean
*/
public function elementExists($path, \DOMNode $contextNode)
public function elementExists($path, \DOMElement $contextNode)
{
return $this->getElements($path, $contextNode)->length > 0;
}

View File

@ -22,7 +22,7 @@ require_once 'PCLZip/pclzip.lib.php';
/**
* PCLZip wrapper
*
* @since 0.9.2
* @since 0.10.0
*/
class ZipArchive
{
@ -217,8 +217,7 @@ class ZipArchive
public function getNameIndex($index)
{
$list = $this->zip->listContent();
$listCount = count($list);
if ($index <= $listCount) {
if (isset($list[$index])) {
return $list[$index]['filename'];
} else {
return false;

View File

@ -12,6 +12,7 @@ namespace PhpOffice\PhpWord;
use PhpOffice\PhpWord\Style\Font;
use PhpOffice\PhpWord\Style\Paragraph;
use PhpOffice\PhpWord\Style\Table;
use PhpOffice\PhpWord\Style\Numbering;
/**
* Style collection
@ -33,7 +34,7 @@ class Style
*/
public static function addParagraphStyle($styleName, $styles)
{
self::setStyleValues($styleName, $styles, new Paragraph());
self::setStyleValues($styleName, new Paragraph(), $styles);
}
/**
@ -45,7 +46,7 @@ class Style
*/
public static function addFontStyle($styleName, $styleFont, $styleParagraph = null)
{
self::setStyleValues($styleName, $styleFont, new Font('text', $styleParagraph));
self::setStyleValues($styleName, new Font('text', $styleParagraph), $styleFont);
}
/**
@ -56,7 +57,7 @@ class Style
*/
public static function addLinkStyle($styleName, $styles)
{
self::setStyleValues($styleName, $styles, new Font('link'));
self::setStyleValues($styleName, new Font('link'), $styles);
}
/**
@ -64,15 +65,11 @@ class Style
*
* @param string $styleName
* @param array $styleTable
* @param array $styleFirstRow
* @param array|null $styleFirstRow
*/
public static function addTableStyle($styleName, $styleTable, $styleFirstRow = null)
{
if (!array_key_exists($styleName, self::$styles)) {
$style = new Table($styleTable, $styleFirstRow);
self::$styles[$styleName] = $style;
}
self::setStyleValues($styleName, new Table($styleTable, $styleFirstRow), null);
}
/**
@ -84,12 +81,36 @@ class Style
*/
public static function addTitleStyle($titleCount, $styleFont, $styleParagraph = null)
{
$styleName = 'Heading_' . $titleCount;
self::setStyleValues("Heading_{$titleCount}", $styleFont, new Font('title', $styleParagraph));
self::setStyleValues("Heading_{$titleCount}", new Font('title', $styleParagraph), $styleFont);
}
/**
* Add numbering style
*
* @param string $styleName
* @param array $styleValues
* @return Numbering
* @since 0.10.0
*/
public static function addNumberingStyle($styleName, $styleValues)
{
self::setStyleValues($styleName, new Numbering(), $styleValues);
}
/**
* Count styles
*
* @return integer
* @since 0.10.0
*/
public static function countStyles()
{
return count(self::$styles);
}
/**
* Reset styles
* @since 0.10.0
*/
public static function resetStyles()
{
@ -120,6 +141,7 @@ class Style
* Get style by name
*
* @param string $styleName
* @return Paragraph|Font|Table|Numbering|null
*/
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 array $styleValues
* @param mixed $styleObject
* @param Paragraph|Font|Table|Numbering $styleObject
* @param array|null $styleValues
*/
private static function setStyleValues($styleName, $styleValues, $styleObject)
private static function setStyleValues($styleName, $styleObject, $styleValues = null)
{
if (!array_key_exists($styleName, self::$styles)) {
if (is_array($styleValues)) {
if (!is_null($styleValues) && is_array($styleValues)) {
foreach ($styleValues as $key => $value) {
if (substr($key, 0, 1) == '_') {
$key = substr($key, 1);
}
$styleObject->setStyleValue($key, $value);
}
}
$styleObject->setIndex(self::countStyles() + 1); // One based index
self::$styles[$styleName] = $styleObject;
}
}

View File

@ -9,35 +9,144 @@
namespace PhpOffice\PhpWord\Style;
use PhpOffice\PhpWord\Shared\String;
/**
* Abstract style class
*
* @since 0.9.2
* @since 0.10.0
*/
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
*
* Some child classes have their own specific overrides
* Some child classes have their own specific overrides.
* Backward compability check for versions < 0.10.0 which use underscore
* prefix for their private properties.
* Check if the set method is exists. Throws an exception?
*
* @param string $key
* @param string $value
*
* @todo Implement type check mechanism, e.g. boolean, integer, enum, defaults
* @return self
*/
public function setStyleValue($key, $value)
{
// Backward compability check for versions < 0.9.2 which use underscore
// prefix for their private properties
if (substr($key, 0, 1) == '_') {
$key = substr($key, 1);
}
// Check if the set method is exists. Throws an exception?
$method = 'set' . $key;
$method = 'set' . String::removeUnderscorePrefix($key);
if (method_exists($this, $method)) {
$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)
{
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)
{
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;
}
}

View File

@ -9,6 +9,8 @@
namespace PhpOffice\PhpWord\Style;
use PhpOffice\PhpWord\Shared\String;
/**
* Table cell style
*/
@ -145,9 +147,7 @@ class Cell extends AbstractStyle
*/
public function setStyleValue($key, $value)
{
if (substr($key, 0, 1) == '_') {
$key = substr($key, 1);
}
$key = String::removeUnderscorePrefix($key);
if ($key == 'borderSize') {
$this->setBorderSize($value);
} elseif ($key == 'borderColor') {

View File

@ -193,8 +193,6 @@ class Font extends AbstractStyle
if ($key === 'line-height') {
$this->setLineHeight($value);
null;
} elseif (substr($key, 0, 1) == '_') {
$key = substr($key, 1);
}
$this->setStyleValue($key, $value);
}

View File

@ -9,46 +9,239 @@
namespace PhpOffice\PhpWord\Style;
use PhpOffice\PhpWord\Style;
/**
* List item style
*
* Before version 0.10.0, numbering style is defined statically with $listType.
* After version 0.10.0, numbering style is defined by using Numbering and
* recorded by $numStyle. $listStyle is maintained for backward compatility
*/
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_NESTED = 8;
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;
/**
* Create a new ListItem Style
* Numbering style name
*
* @var string
* @since 0.10.0
*/
public function __construct()
{
$this->listType = self::TYPE_BULLET_FILLED;
}
private $numStyle;
/**
* Set List Type
* Numbering definition instance ID
*
* @param int $pValue
* @var integer
* @since 0.10.0
*/
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
*
* @return integer
*/
public function getListType()
{
return $this->listType;
}
/**
* Set legacy list type for version < 0.10.0
*
* @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 string
*/
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 ($numStyleObject instanceof Numbering) {
$this->numId = $numStyleObject->getIndex();
$numStyleObject->setNumId($this->numId);
}
}
/**
* Get numbering Id
*
* @return integer
*/
public function getNumId()
{
return $this->numId;
}
/**
* Get legacy numbering definition
*
* @return array
* @since 0.10.0
*/
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) {
$level = array();
$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);
}
}

View File

@ -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.10.0
*/
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;
}
}

View File

@ -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.10.0
*/
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 $this->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;
}
}

View File

@ -10,6 +10,7 @@
namespace PhpOffice\PhpWord\Style;
use PhpOffice\PhpWord\Exception\InvalidStyleException;
use PhpOffice\PhpWord\Shared\String;
/**
* Paragraph style
@ -127,8 +128,6 @@ class Paragraph extends AbstractStyle
foreach ($style as $key => $value) {
if ($key === 'line-height') {
null;
} elseif (substr($key, 0, 1) == '_') {
$key = substr($key, 1);
}
$this->setStyleValue($key, $value);
}
@ -144,9 +143,7 @@ class Paragraph extends AbstractStyle
*/
public function setStyleValue($key, $value)
{
if (substr($key, 0, 1) == '_') {
$key = substr($key, 1);
}
$key = String::removeUnderscorePrefix($key);
if ($key == 'indent' || $key == 'hanging') {
$value = $value * 720;
} elseif ($key == 'spacing') {

View File

@ -45,16 +45,12 @@ class Row extends AbstractStyle
/**
* Set tblHeader
*
* @param boolean $pValue
* @return $this
* @param boolean $value
* @return self
*/
public function setTblHeader($pValue = false)
public function setTblHeader($value = false)
{
if (!is_bool($pValue)) {
$pValue = false;
}
$this->tblHeader = $pValue;
return $this;
$this->tblHeader = $this->setBoolVal($value, $this->tblHeader);
}
/**
@ -70,16 +66,12 @@ class Row extends AbstractStyle
/**
* Set cantSplit
*
* @param boolean $pValue
* @return $this
* @param boolean $value
* @return self
*/
public function setCantSplit($pValue = false)
public function setCantSplit($value = false)
{
if (!is_bool($pValue)) {
$pValue = false;
}
$this->cantSplit = $pValue;
return $this;
$this->cantSplit = $this->setBoolVal($value, $this->cantSplit);
}
/**
@ -95,15 +87,12 @@ class Row extends AbstractStyle
/**
* Set exactHeight
*
* @param bool $pValue
* @return $this
* @param bool $value
* @return self
*/
public function setExactHeight($pValue = false)
public function setExactHeight($value = false)
{
if (!is_bool($pValue)) {
$pValue = false;
}
$this->exactHeight = $pValue;
$this->exactHeight = $this->setBoolVal($value, $this->exactHeight);
return $this;
}

View File

@ -9,6 +9,8 @@
namespace PhpOffice\PhpWord\Style;
use PhpOffice\PhpWord\Shared\String;
/**
* Section settings
*/
@ -217,9 +219,7 @@ class Section extends AbstractStyle
*/
public function setSettingValue($key, $value)
{
if (substr($key, 0, 1) == '_') {
$key = substr($key, 1);
}
$key = String::removeUnderscorePrefix($key);
if ($key == 'orientation' && $value == 'landscape') {
$this->setLandscape();
} elseif ($key == 'orientation' && is_null($value)) {

View File

@ -110,15 +110,4 @@ class TOC extends AbstractStyle
{
$this->indent = $pValue;
}
/**
* Set style value
*
* @param string $key
* @param string $value
*/
public function setStyleValue($key, $value)
{
$this->$key = $value;
}
}

View File

@ -9,6 +9,8 @@
namespace PhpOffice\PhpWord\Style;
use PhpOffice\PhpWord\Shared\String;
/**
* Table style
*/
@ -161,18 +163,12 @@ class Table extends AbstractStyle
unset($this->firstRow->borderInsideHColor);
unset($this->firstRow->borderInsideHSize);
foreach ($styleFirstRow as $key => $value) {
if (substr($key, 0, 1) == '_') {
$key = substr($key, 1);
}
$this->firstRow->setStyleValue($key, $value);
}
}
if (!is_null($styleTable) && is_array($styleTable)) {
foreach ($styleTable as $key => $value) {
if (substr($key, 0, 1) == '_') {
$key = substr($key, 1);
}
$this->setStyleValue($key, $value);
}
}
@ -186,9 +182,7 @@ class Table extends AbstractStyle
*/
public function setStyleValue($key, $value)
{
if (substr($key, 0, 1) == '_') {
$key = substr($key, 1);
}
$key = String::removeUnderscorePrefix($key);
if ($key == 'borderSize') {
$this->setBorderSize($value);
} elseif ($key == 'borderColor') {

View File

@ -82,9 +82,6 @@ class TOC
if (!is_null($styleTOC) && is_array($styleTOC)) {
foreach ($styleTOC as $key => $value) {
if (substr($key, 0, 1) == '_') {
$key = substr($key, 1);
}
self::$TOCStyle->setStyleValue($key, $value);
}
}
@ -93,9 +90,6 @@ class TOC
if (is_array($styleFont)) {
self::$fontStyle = new Font();
foreach ($styleFont as $key => $value) {
if (substr($key, 0, 1) == '_') {
$key = substr($key, 1);
}
self::$fontStyle->setStyleValue($key, $value);
}
} else {

View File

@ -420,17 +420,4 @@ class Template
}
return substr($this->documentXML, $startPosition, ($endPosition - $startPosition));
}
/**
* Delete a block of text
*
* @param string $blockname
* @param string $replacement
* @deprecated
* @codeCoverageIgnore
*/
public function deleteTemplateBlock($blockname, $replacement = '')
{
$this->deleteBlock($blockname, $replacement);
}
}

View File

@ -16,7 +16,7 @@ use PhpOffice\PhpWord\Settings;
/**
* Abstract writer class
*
* @since 0.9.2
* @since 0.10.0
*/
abstract class AbstractWriter implements WriterInterface
{
@ -48,6 +48,13 @@ abstract class AbstractWriter implements WriterInterface
*/
private $diskCachingDirectory = './';
/**
* Temporary directory
*
* @var string
*/
private $tempDir = '';
/**
* Original file name
*
@ -81,7 +88,7 @@ abstract class AbstractWriter implements WriterInterface
* Set PhpWord object
*
* @param \PhpOffice\PhpWord\PhpWord
* @return $this
* @return self
*/
public function setPhpWord(PhpWord $phpWord = null)
{
@ -119,7 +126,7 @@ abstract class AbstractWriter implements WriterInterface
*
* @param boolean $pValue
* @param string $pDirectory
* @return $this
* @return self
*/
public function setUseDiskCaching($pValue = false, $pDirectory = null)
{
@ -146,6 +153,32 @@ abstract class AbstractWriter implements WriterInterface
return $this->diskCachingDirectory;
}
/**
* Get temporary directory
*
* @return string
*/
public function getTempDir()
{
return $this->tempDir;
}
/**
* Set temporary directory
*
* @param string $value
* @return self
*/
public function setTempDir($value)
{
if (!is_dir($value)) {
mkdir($value);
}
$this->tempDir = $value;
return $this;
}
/**
* Get temporary file name
*
@ -156,6 +189,10 @@ abstract class AbstractWriter implements WriterInterface
*/
protected function getTempFile($filename)
{
// Temporary directory
$this->setTempDir(sys_get_temp_dir() . '/PHPWordWriter/');
// Temporary file
$this->originalFilename = $filename;
if (strtolower($filename) == 'php://output' || strtolower($filename) == 'php://stdout') {
$filename = @tempnam(sys_get_temp_dir(), 'phpword_');
@ -170,8 +207,6 @@ abstract class AbstractWriter implements WriterInterface
/**
* Cleanup temporary file
*
* If a temporary file was used, copy it to the correct file stream
*/
protected function cleanupTempFile()
{
@ -181,6 +216,18 @@ abstract class AbstractWriter implements WriterInterface
}
@unlink($this->tempFilename);
}
$this->clearTempDir();
}
/**
* Clear temporary directory
*/
protected function clearTempDir()
{
if (is_dir($this->tempDir)) {
$this->deleteDir($this->tempDir);
}
}
/**
@ -215,4 +262,24 @@ abstract class AbstractWriter implements WriterInterface
return $objZip;
}
/**
* Delete directory
*
* @param string $dir
*/
private function deleteDir($dir)
{
foreach (scandir($dir) as $file) {
if ($file === '.' || $file === '..') {
continue;
} elseif (is_file($dir . "/" . $file)) {
unlink($dir . "/" . $file);
} elseif (is_dir($dir . "/" . $file)) {
$this->deleteDir($dir . "/" . $file);
}
}
rmdir($dir);
}
}

746
src/PhpWord/Writer/HTML.php Normal file
View File

@ -0,0 +1,746 @@
<?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;
use PhpOffice\PhpWord\Element\Endnote;
use PhpOffice\PhpWord\Element\Footnote;
use PhpOffice\PhpWord\Element\Image;
use PhpOffice\PhpWord\Element\Link;
use PhpOffice\PhpWord\Element\ListItem;
use PhpOffice\PhpWord\Element\Object;
use PhpOffice\PhpWord\Element\PageBreak;
use PhpOffice\PhpWord\Element\PreserveText;
use PhpOffice\PhpWord\Element\Table;
use PhpOffice\PhpWord\Element\Text;
use PhpOffice\PhpWord\Element\TextBreak;
use PhpOffice\PhpWord\Element\TextRun;
use PhpOffice\PhpWord\Element\Title;
use PhpOffice\PhpWord\Endnotes;
use PhpOffice\PhpWord\Exception\Exception;
use PhpOffice\PhpWord\Footnotes;
use PhpOffice\PhpWord\PhpWord;
use PhpOffice\PhpWord\Style;
use PhpOffice\PhpWord\Style\Font;
use PhpOffice\PhpWord\Style\Paragraph;
/**
* HTML writer
*
* @since 0.10.0
*/
class HTML extends AbstractWriter implements WriterInterface
{
/**
* Is the current writer creating PDF?
*
* @var boolean
*/
protected $isPdf = false;
/**
* Footnotes and endnotes collection
*
* @var array
*/
protected $notes = array();
/**
* Create new instance
*/
public function __construct(PhpWord $phpWord = null)
{
$this->setPhpWord($phpWord);
}
/**
* Save PhpWord to file
*
* @param string $filename
* @throws Exception
*/
public function save($filename = null)
{
if (!is_null($this->getPhpWord())) {
$this->setTempDir(sys_get_temp_dir() . '/PHPWordWriter/');
$hFile = fopen($filename, 'w') or die("can't open file");
fwrite($hFile, $this->writeDocument());
fclose($hFile);
$this->clearTempDir();
} else {
throw new Exception("No PHPWord assigned.");
}
}
/**
* Get phpWord data
*
* @return string
*/
public function writeDocument()
{
$html = '';
$html .= '<!DOCTYPE html>' . PHP_EOL;
$html .= '<!-- Generated by PHPWord -->' . PHP_EOL;
$html .= '<html>' . PHP_EOL;
$html .= '<head>' . PHP_EOL;
$html .= $this->writeHTMLHead();
$html .= '</head>' . PHP_EOL;
$html .= '<body>' . PHP_EOL;
$html .= $this->writeHTMLBody();
$html .= $this->writeNotes();
$html .= '</body>' . PHP_EOL;
$html .= '</html>' . PHP_EOL;
return $html;
}
/**
* Generate HTML header
*
* @return string
*/
private function writeHTMLHead()
{
$properties = $this->getPhpWord()->getDocumentProperties();
$propertiesMapping = array(
'creator' => 'author',
'title' => '',
'description' => '',
'subject' => '',
'keywords' => '',
'category' => '',
'company' => '',
'manager' => ''
);
$title = $properties->getTitle();
$title = ($title != '') ? $title : 'PHPWord';
$html = '';
$html .= '<meta charset="UTF-8" />' . PHP_EOL;
$html .= '<title>' . htmlspecialchars($title) . '</title>' . PHP_EOL;
foreach ($propertiesMapping as $key => $value) {
$value = ($value == '') ? $key : $value;
$method = "get" . $key;
if ($properties->$method() != '') {
$html .= '<meta name="' . $value . '" content="' .
htmlspecialchars($properties->$method()) . '" />' . PHP_EOL;
}
}
$html .= $this->writeStyles();
return $html;
}
/**
* Get content
*
* @return string
*/
private function writeHTMLBody()
{
$phpWord = $this->getPhpWord();
$html = '';
$sections = $phpWord->getSections();
$countSections = count($sections);
$pSection = 0;
if ($countSections > 0) {
foreach ($sections as $section) {
$pSection++;
$contents = $section->getElements();
foreach ($contents as $element) {
if ($element instanceof Text) {
$html .= $this->writeText($element);
} elseif ($element instanceof TextRun) {
$html .= $this->writeTextRun($element);
} elseif ($element instanceof Link) {
$html .= $this->writeLink($element);
} elseif ($element instanceof Title) {
$html .= $this->writeTitle($element);
} elseif ($element instanceof PreserveText) {
$html .= $this->writePreserveText($element);
} elseif ($element instanceof TextBreak) {
$html .= $this->writeTextBreak($element);
} elseif ($element instanceof PageBreak) {
$html .= $this->writePageBreak($element);
} elseif ($element instanceof Table) {
$html .= $this->writeTable($element);
} elseif ($element instanceof ListItem) {
$html .= $this->writeListItem($element);
} elseif ($element instanceof Image) {
$html .= $this->writeImage($element);
} elseif ($element instanceof Object) {
$html .= $this->writeObject($element);
} elseif ($element instanceof Endnote) {
$html .= $this->writeEndnote($element);
} elseif ($element instanceof Footnote) {
$html .= $this->writeFootnote($element);
}
}
}
}
return $html;
}
/**
* Write footnote/endnote contents
*/
private function writeNotes()
{
$footnote = Footnotes::getElements();
$endnote = Endnotes::getElements();
$html = '';
if (count($this->notes) > 0) {
$html .= "<hr />";
foreach ($this->notes as $noteId => $noteMark) {
$noteAnchor = "note-{$noteId}";
list($noteType, $noteTypeId) = explode('-', $noteMark);
$collection = $$noteType;
if (array_key_exists($noteTypeId, $collection)) {
$element = $collection[$noteTypeId];
$content = "<a href=\"#{$noteMark}\" class=\"NoteRef\"><sup>{$noteId}</sup></a>" . $this->writeTextRun($element, true);
$html .= "<p><a name=\"{$noteAnchor}\" />{$content}</p>" . PHP_EOL;
}
}
}
return $html;
}
/**
* Get text
*
* @param Text $text
* @param boolean $withoutP
* @return string
*/
private function writeText($text, $withoutP = false)
{
$html = '';
$paragraphStyle = $text->getParagraphStyle();
$spIsObject = ($paragraphStyle instanceof Paragraph);
$fontStyle = $text->getFontStyle();
$sfIsObject = ($fontStyle instanceof Font);
if ($paragraphStyle && !$withoutP) {
$html .= '<p';
if (!$spIsObject) {
$html .= ' class="' . $paragraphStyle . '"';
} else {
$html .= ' style="' . $this->writeParagraphStyle($paragraphStyle) . '"';
}
$html .= '>';
}
if ($fontStyle) {
$html .= '<span';
if (!$sfIsObject) {
$html .= ' class="' . $fontStyle . '"';
} else {
$html .= ' style="' . $this->writeFontStyle($fontStyle) . '"';
}
$html .= '>';
}
$html .= htmlspecialchars($text->getText());
if ($fontStyle) {
$html .= '</span>';
}
if ($paragraphStyle && !$withoutP) {
$html .= '</p>' . PHP_EOL;
}
return $html;
}
/**
* Write text run content
*
* @param TextRun|Footnote|Endnote $textrun
* @return string
*/
private function writeTextRun($textrun, $withoutP = false)
{
$html = '';
$elements = $textrun->getElements();
if (count($elements) > 0) {
$paragraphStyle = $textrun->getParagraphStyle();
$spIsObject = ($paragraphStyle instanceof Paragraph);
$html .= $withoutP ? '<span' : '<p';
if ($paragraphStyle) {
if (!$spIsObject) {
$html .= ' class="' . $paragraphStyle . '"';
} else {
$html .= ' style="' . $this->writeParagraphStyle($paragraphStyle) . '"';
}
}
$html .= '>';
foreach ($elements as $element) {
if ($element instanceof Text) {
$html .= $this->writeText($element, true);
} elseif ($element instanceof Link) {
$html .= $this->writeLink($element, true);
} elseif ($element instanceof TextBreak) {
$html .= $this->writeTextBreak($element, true);
} elseif ($element instanceof Image) {
$html .= $this->writeImage($element, true);
} elseif ($element instanceof Endnote) {
$html .= $this->writeEndnote($element);
} elseif ($element instanceof Footnote) {
$html .= $this->writeFootnote($element);
}
}
$html .= $withoutP ? '</span>' : '</p>';
$html .= PHP_EOL;
}
return $html;
}
/**
* Write link
*
* @param Link $element
* @param boolean $withoutP
* @return string
*/
private function writeLink($element, $withoutP = false)
{
$url = $element->getLinkSrc();
$text = $element->getLinkName();
if ($text == '') {
$text = $url;
}
$html = '';
if (!$withoutP) {
$html .= "<p>" . PHP_EOL;
}
$html .= "<a href=\"{$url}\">{$text}</a>" . PHP_EOL;
if (!$withoutP) {
$html .= "</p>" . PHP_EOL;
}
return $html;
}
/**
* Write heading
*
* @param Title $element
* @return string
*/
private function writeTitle($element)
{
$tag = 'h' . $element->getDepth();
$text = htmlspecialchars($element->getText());
$html = "<{$tag}>{$text}</{$tag}>" . PHP_EOL;
return $html;
}
/**
* Write preserve text
*
* @param PreserveText $element
* @param boolean $withoutP
* @return string
*/
private function writePreserveText($element, $withoutP = false)
{
return $this->writeUnsupportedElement($element, $withoutP);
}
/**
* Get text break
*
* @param TextBreak $element
* @param boolean $withoutP
* @return string
*/
private function writeTextBreak($element, $withoutP = false)
{
if ($withoutP) {
$html = '<br />' . PHP_EOL;
} else {
$html = '<p>&nbsp;</p>' . PHP_EOL;
}
return $html;
}
/**
* Write page break
*
* @param PageBreak $element
* @return string
*/
private function writePageBreak($element)
{
return $this->writeUnsupportedElement($element, false);
}
/**
* Write list item
*
* @param ListItem $element
* @return string
*/
private function writeListItem($element)
{
$text = htmlspecialchars($element->getTextObject()->getText());
$html = '<p>' . $text . '</{$p}>' . PHP_EOL;
return $html;
}
/**
* Write table
*
* @param Table $element
* @return string
*/
private function writeTable($element)
{
$html = '';
$rows = $element->getRows();
$cRows = count($rows);
if ($cRows > 0) {
$html .= "<table>" . PHP_EOL;
foreach ($rows as $row) {
// $height = $row->getHeight();
$rowStyle = $row->getStyle();
$tblHeader = $rowStyle->getTblHeader();
$html .= "<tr>" . PHP_EOL;
foreach ($row->getCells() as $cell) {
$cellTag = $tblHeader ? 'th' : 'td';
$cellContents = $cell->getElements();
$html .= "<{$cellTag}>" . PHP_EOL;
if (count($cellContents) > 0) {
foreach ($cellContents as $content) {
if ($content instanceof Text) {
$html .= $this->writeText($content);
} elseif ($content instanceof TextRun) {
$html .= $this->writeTextRun($content);
} elseif ($content instanceof Link) {
$html .= $this->writeLink($content);
} elseif ($content instanceof PreserveText) {
$html .= $this->writePreserveText($content);
} elseif ($content instanceof TextBreak) {
$html .= $this->writeTextBreak($content);
} elseif ($content instanceof ListItem) {
$html .= $this->writeListItem($content);
} elseif ($content instanceof Image) {
$html .= $this->writeImage($content);
} elseif ($content instanceof Object) {
$html .= $this->writeObject($content);
} elseif ($element instanceof Endnote) {
$html .= $this->writeEndnote($element);
} elseif ($element instanceof Footnote) {
$html .= $this->writeFootnote($element);
}
}
} else {
$html .= $this->writeTextBreak(new TextBreak());
}
$html .= "</td>" . PHP_EOL;
}
$html .= "</tr>" . PHP_EOL;
}
$html .= "</table>" . PHP_EOL;
}
return $html;
}
/**
* Write image
*
* @param Image $element
* @param boolean $withoutP
* @return string
*/
private function writeImage($element, $withoutP = false)
{
$html = $this->writeUnsupportedElement($element, $withoutP);
if (!$this->isPdf) {
$imageData = $this->getBase64ImageData($element);
if (!is_null($imageData)) {
$style = $this->assembleCss(array(
'width' => $element->getStyle()->getWidth() . 'px',
'height' => $element->getStyle()->getHeight() . 'px',
));
$html = "<img border=\"0\" style=\"{$style}\" src=\"{$imageData}\"/>";
if (!$withoutP) {
$html = "<p>{$html}</p>" . PHP_EOL;
}
}
}
return $html;
}
/**
* Write object
*
* @param Object $element
* @param boolean $withoutP
* @return string
*/
private function writeObject($element, $withoutP = false)
{
return $this->writeUnsupportedElement($element, $withoutP);
}
/**
* Write footnote
*
* @param Footnote $element
* @return string
*/
private function writeFootnote($element)
{
return $this->writeNote($element);
}
/**
* Write endnote
*
* @param Endnote $element
* @return string
*/
private function writeEndnote($element)
{
return $this->writeNote($element);
}
/**
* Write footnote/endnote marks
*
* @param Footnote|Endnote $element
* @return string
*/
private function writeNote($element)
{
$index = count($this->notes) + 1;
$prefix = ($element instanceof Endnote) ? 'endnote' : 'footnote';
$noteMark = $prefix . '-' . $element->getRelationId();
$noteAnchor = "note-{$index}";
$this->notes[$index] = $noteMark;
$html = "<a name=\"{$noteMark}\"><a href=\"#{$noteAnchor}\" class=\"NoteRef\"><sup>{$index}</sup></a>";
return $html;
}
/**
* Write unsupported element
*
* @param mixed $element
* @param boolean $withoutP
* @return string
*/
private function writeUnsupportedElement($element, $withoutP = false)
{
$elementClass = get_class($element);
$elementMark = str_replace('PhpOffice\\PhpWord\\Element\\', '', $elementClass);
$elementMark = htmlentities("<{$elementMark}>");
if ($withoutP) {
$html = "<span class=\"other-elm\">{$elementMark}</span>" . PHP_EOL;
} else {
$html = "<p>{$elementMark}</p>" . PHP_EOL;
}
return $html;
}
/**
* Get styles
*
* @return string
*/
private function writeStyles()
{
$css = '<style>' . PHP_EOL;
// Default styles
$defaultStyles = array(
'*' => array(
'font-family' => $this->getPhpWord()->getDefaultFontName(),
'font-size' => $this->getPhpWord()->getDefaultFontSize() . 'pt',
),
'a.NoteRef' => array(
'text-decoration' => 'none',
),
'hr' => array(
'height' => '1px',
'padding' => '0',
'margin' => '1em 0',
'border' => '0',
'border-top' => '1px solid #CCC',
),
);
foreach ($defaultStyles as $selector => $style) {
$css .= $selector . ' ' . $this->assembleCss($style, true) . PHP_EOL;
}
// Custom styles
$customStyles = Style::getStyles();
if (is_array($customStyles)) {
foreach ($customStyles as $name => $style) {
if ($style instanceof Font) {
if ($style->getStyleType() == 'title') {
$name = str_replace('Heading_', 'h', $name);
} else {
$name = '.' . $name;
}
$css .= "{$name} " . $this->writeFontStyle($style, true) . PHP_EOL;
} elseif ($style instanceof Paragraph) {
$name = '.' . $name;
$css .= "{$name} " . $this->writeParagraphStyle($style, true) . PHP_EOL;
}
}
}
$css .= '</style>' . PHP_EOL;
return $css;
}
/**
* Get font style
*
* @param Font $style
* @param boolean $curlyBracket
* @return string
*/
private function writeFontStyle($style, $curlyBracket = false)
{
$css = array();
if (PHPWord::DEFAULT_FONT_NAME != $style->getName()) {
$css['font-family'] = "'" . $style->getName() . "'";
}
if (PHPWord::DEFAULT_FONT_SIZE != $style->getSize()) {
$css['font-size'] = $style->getSize() . 'pt';
}
if (PHPWord::DEFAULT_FONT_COLOR != $style->getColor()) {
$css['color'] = '#' . $style->getColor();
}
$css['background'] = $style->getFgColor();
if ($style->getBold()) {
$css['font-weight'] = 'bold';
}
if ($style->getItalic()) {
$css['font-style'] = 'italic';
}
if ($style->getSuperScript()) {
$css['vertical-align'] = 'super';
} elseif ($style->getSubScript()) {
$css['vertical-align'] = 'sub';
}
$css['text-decoration'] = '';
if ($style->getUnderline() != Font::UNDERLINE_NONE) {
$css['text-decoration'] .= 'underline ';
}
if ($style->getStrikethrough()) {
$css['text-decoration'] .= 'line-through ';
}
return $this->assembleCss($css, $curlyBracket);
}
/**
* Get paragraph style
*
* @param Paragraph $style
* @param boolean $curlyBracket
* @return string
*/
private function writeParagraphStyle($style, $curlyBracket = false)
{
$css = array();
if ($style->getAlign()) {
$css['text-align'] = $style->getAlign();
}
return $this->assembleCss($css, $curlyBracket);
}
/**
* Takes array where of CSS properties / values and converts to CSS string
*
* @param array $css
* @param boolean $curlyBracket
* @return string
*/
private function assembleCss($css, $curlyBracket = false)
{
$pairs = array();
foreach ($css as $key => $value) {
if ($value != '') {
$pairs[] = $key . ': ' . $value;
}
}
$string = implode('; ', $pairs);
if ($curlyBracket) {
$string = '{ ' . $string . ' }';
}
return $string;
}
/**
* Get Base64 image data
*
* @return string|null
*/
private function getBase64ImageData(Image $element)
{
$imageData = null;
$imageBinary = null;
$source = $element->getSource();
$imageType = $element->getImageType();
// Get actual source from archive image
if ($element->getSourceType() == Image::SOURCE_ARCHIVE) {
$source = substr($source, 6);
list($zipFilename, $imageFilename) = explode('#', $source);
$zip = new \ZipArchive();
if ($zip->open($zipFilename) !== false) {
if ($zip->locateName($imageFilename)) {
$zip->extractTo($this->getTempDir(), $imageFilename);
$actualSource = $this->getTempDir() . DIRECTORY_SEPARATOR . $imageFilename;
}
}
$zip->close();
} else {
$actualSource = $source;
}
// Read image binary data and convert into Base64
if ($element->getSourceType() == Image::SOURCE_GD) {
$imageResource = call_user_func($element->getImageCreateFunction(), $actualSource);
ob_start();
call_user_func($element->getImageFunction(), $imageResource);
$imageBinary = ob_get_contents();
ob_end_clean();
} else {
if ($fp = fopen($actualSource, 'rb', false)) {
$imageBinary = fread($fp, filesize($actualSource));
fclose($fp);
}
}
if (!is_null($imageBinary)) {
$base64 = chunk_split(base64_encode($imageBinary));
$imageData = 'data:' . $imageType . ';base64,' . $base64;
}
return $imageData;
}
}

View File

@ -17,7 +17,7 @@ use PhpOffice\PhpWord\Shared\XMLWriter;
/**
* ODT base part writer
*
* @since 0.9.2
* @since 0.10.0
*/
class Base extends AbstractWriterPart
{

View File

@ -24,7 +24,6 @@ use PhpOffice\PhpWord\Shared\XMLWriter;
use PhpOffice\PhpWord\Style\Font;
use PhpOffice\PhpWord\Style\Paragraph;
use PhpOffice\PhpWord\Style;
use PhpOffice\PhpWord\TOC;
/**
* ODText content part writer
@ -95,10 +94,311 @@ class Content extends Base
}
}
// office:font-face-decls
$this->writeFontFaces($xmlWriter);
// office:automatic-styles
$this->writeFontFaces($xmlWriter); // office:font-face-decls
$this->writeAutomaticStyles($xmlWriter); // office:automatic-styles
// Tables
$sections = $phpWord->getSections();
$countSections = count($sections);
if ($countSections > 0) {
$sectionId = 0;
foreach ($sections as $section) {
$sectionId++;
$elements = $section->getElements();
foreach ($elements as $element) {
if ($elements instanceof Table) {
$xmlWriter->startElement('style:style');
$xmlWriter->writeAttribute('style:name', $element->getElementId());
$xmlWriter->writeAttribute('style:family', 'table');
$xmlWriter->startElement('style:table-properties');
//$xmlWriter->writeAttribute('style:width', 'table');
$xmlWriter->writeAttribute('style:rel-width', 100);
$xmlWriter->writeAttribute('table:align', 'center');
$xmlWriter->endElement();
$xmlWriter->endElement();
}
}
}
}
$xmlWriter->endElement();
// office:body
$xmlWriter->startElement('office:body');
// office:text
$xmlWriter->startElement('office:text');
// text:sequence-decls
$xmlWriter->startElement('text:sequence-decls');
// text:sequence-decl
$xmlWriter->startElement('text:sequence-decl');
$xmlWriter->writeAttribute('text:display-outline-level', 0);
$xmlWriter->writeAttribute('text:name', 'Illustration');
$xmlWriter->endElement();
// text:sequence-decl
$xmlWriter->startElement('text:sequence-decl');
$xmlWriter->writeAttribute('text:display-outline-level', 0);
$xmlWriter->writeAttribute('text:name', 'Table');
$xmlWriter->endElement();
// text:sequence-decl
$xmlWriter->startElement('text:sequence-decl');
$xmlWriter->writeAttribute('text:display-outline-level', 0);
$xmlWriter->writeAttribute('text:name', 'Text');
$xmlWriter->endElement();
// text:sequence-decl
$xmlWriter->startElement('text:sequence-decl');
$xmlWriter->writeAttribute('text:display-outline-level', 0);
$xmlWriter->writeAttribute('text:name', 'Drawing');
$xmlWriter->endElement();
$xmlWriter->endElement();
$sections = $phpWord->getSections();
$countSections = count($sections);
if ($countSections > 0) {
foreach ($sections as $section) {
$elements = $section->getElements();
foreach ($elements as $element) {
if ($element instanceof Text) {
$this->writeText($xmlWriter, $element);
} elseif ($element instanceof TextRun) {
$this->writeTextRun($xmlWriter, $element);
} elseif ($element instanceof Link) {
$this->writeLink($xmlWriter, $element);
} elseif ($element instanceof Title) {
$this->writeTitle($xmlWriter, $element);
} elseif ($element instanceof ListItem) {
$this->writeListItem($xmlWriter, $element);
} elseif ($element instanceof TextBreak) {
$this->writeTextBreak($xmlWriter);
} elseif ($element instanceof PageBreak) {
$this->writePageBreak($xmlWriter);
} elseif ($element instanceof Table) {
$this->writeTable($xmlWriter, $element);
} elseif ($element instanceof Image) {
$this->writeImage($xmlWriter, $element);
} elseif ($element instanceof Object) {
$this->writeObject($xmlWriter, $element);
}
}
}
}
$xmlWriter->endElement();
$xmlWriter->endElement();
$xmlWriter->endElement();
// Return
return $xmlWriter->getData();
}
/**
* Write text
*
* @param XMLWriter $xmlWriter
* @param Text $text
* @param bool $withoutP
*/
protected function writeText(XMLWriter $xmlWriter, Text $text, $withoutP = false)
{
$styleFont = $text->getFontStyle();
$styleParagraph = $text->getParagraphStyle();
// @todo Commented for TextRun. Should really checkout this value
// $SfIsObject = ($styleFont instanceof Font) ? true : false;
$SfIsObject = false;
if ($SfIsObject) {
// Don't never be the case, because I browse all sections for cleaning all styles not declared
die('PhpWord : $SfIsObject wouldn\'t be an object');
} else {
if (!$withoutP) {
$xmlWriter->startElement('text:p'); // text:p
}
if (empty($styleFont)) {
if (empty($styleParagraph)) {
$xmlWriter->writeAttribute('text:style-name', 'P1');
} elseif (is_string($styleParagraph)) {
$xmlWriter->writeAttribute('text:style-name', $styleParagraph);
}
$xmlWriter->writeRaw($text->getText());
} else {
if (empty($styleParagraph)) {
$xmlWriter->writeAttribute('text:style-name', 'Standard');
} elseif (is_string($styleParagraph)) {
$xmlWriter->writeAttribute('text:style-name', $styleParagraph);
}
// text:span
$xmlWriter->startElement('text:span');
if (is_string($styleFont)) {
$xmlWriter->writeAttribute('text:style-name', $styleFont);
}
$xmlWriter->writeRaw($text->getText());
$xmlWriter->endElement();
}
if (!$withoutP) {
$xmlWriter->endElement(); // text:p
}
}
}
/**
* Write TextRun section
*
* @param XMLWriter $xmlWriter
* @param TextRun $textrun
* @todo Enable all other section types
*/
protected function writeTextRun(XMLWriter $xmlWriter, TextRun $textrun)
{
$elements = $textrun->getElements();
$xmlWriter->startElement('text:p');
if (count($elements) > 0) {
foreach ($elements as $element) {
if ($element instanceof Text) {
$this->writeText($xmlWriter, $element, true);
}
}
}
$xmlWriter->endElement();
}
/**
* Write link element
*
* @param \PhpOffice\PhpWord\Shared\XMLWriter $xmlWriter
*/
protected function writeLink(XMLWriter $xmlWriter, Link $link)
{
$this->writeUnsupportedElement($xmlWriter, 'Link');
}
/**
* Write title element
*/
protected function writeTitle(XMLWriter $xmlWriter, Title $title)
{
$this->writeUnsupportedElement($xmlWriter, 'Title');
}
/**
* Write preserve text
*/
protected function writePreserveText(XMLWriter $xmlWriter, PreserveText $preservetext)
{
$this->writeUnsupportedElement($xmlWriter, 'PreserveText');
}
/**
* Write list item
*/
protected function writeListItem(XMLWriter $xmlWriter, ListItem $listItem)
{
$this->writeUnsupportedElement($xmlWriter, 'ListItem');
}
/**
* Write text break
*/
protected function writeTextBreak(XMLWriter $xmlWriter)
{
$xmlWriter->startElement('text:p');
$xmlWriter->writeAttribute('text:style-name', 'Standard');
$xmlWriter->endElement();
}
/**
* Write page break
*/
protected function writePageBreak(XMLWriter $xmlWriter)
{
$this->writeUnsupportedElement($xmlWriter, 'PageBreak');
}
/**
* Write table
*/
protected function writeTable(XMLWriter $xmlWriter, Table $table)
{
$rows = $table->getRows();
$rowCount = count($rows);
$colCount = $table->countColumns();
if ($rowCount > 0) {
$xmlWriter->startElement('table:table');
$xmlWriter->writeAttribute('table:name', $table->getElementId());
$xmlWriter->writeAttribute('table:style', $table->getElementId());
$xmlWriter->startElement('table:table-column');
$xmlWriter->writeAttribute('table:number-columns-repeated', $colCount);
$xmlWriter->endElement(); // table:table-column
foreach ($rows as $row) {
$xmlWriter->startElement('table:table-row');
foreach ($row->getCells() as $cell) {
$xmlWriter->startElement('table:table-cell');
$xmlWriter->writeAttribute('office:value-type', 'string');
$elements = $cell->getElements();
if (count($elements) > 0) {
foreach ($elements as $element) {
if ($element instanceof Text) {
$this->writeText($xmlWriter, $element);
} elseif ($element instanceof TextRun) {
$this->writeTextRun($xmlWriter, $element);
} elseif ($element instanceof ListItem) {
$this->writeListItem($xmlWriter, $element);
} elseif ($element instanceof TextBreak) {
$this->writeTextBreak($xmlWriter);
} elseif ($element instanceof Image) {
$this->writeImage($xmlWriter, $element);
} elseif ($element instanceof Object) {
$this->writeObject($xmlWriter, $element);
}
}
} else {
$this->writeTextBreak($xmlWriter);
}
$xmlWriter->endElement(); // table:table-cell
}
$xmlWriter->endElement(); // table:table-row
}
$xmlWriter->endElement(); // table:table
}
}
/**
* Write image
*/
protected function writeImage(XMLWriter $xmlWriter, Image $element)
{
$this->writeUnsupportedElement($xmlWriter, 'Image');
}
/**
* Write object
*/
protected function writeObject(XMLWriter $xmlWriter, Object $element)
{
$this->writeUnsupportedElement($xmlWriter, 'Object');
}
/**
* Write unsupported element
*
* @param \PhpOffice\PhpWord\Shared\XMLWriter $xmlWriter
* @param string $element
*/
private function writeUnsupportedElement(XMLWriter $xmlWriter, $element)
{
$xmlWriter->startElement('text:p');
$xmlWriter->writeRaw($element);
$xmlWriter->endElement();
}
/**
* Write automatic styles
*/
private function writeAutomaticStyles(XMLWriter $xmlWriter)
{
$xmlWriter->startElement('office:automatic-styles');
$styles = Style::getStyles();
$numPStyles = 0;
@ -151,172 +451,5 @@ class Content extends Base
$xmlWriter->endElement();
}
}
$xmlWriter->endElement();
// office:body
$xmlWriter->startElement('office:body');
// office:text
$xmlWriter->startElement('office:text');
// text:sequence-decls
$xmlWriter->startElement('text:sequence-decls');
// text:sequence-decl
$xmlWriter->startElement('text:sequence-decl');
$xmlWriter->writeAttribute('text:display-outline-level', 0);
$xmlWriter->writeAttribute('text:name', 'Illustration');
$xmlWriter->endElement();
// text:sequence-decl
$xmlWriter->startElement('text:sequence-decl');
$xmlWriter->writeAttribute('text:display-outline-level', 0);
$xmlWriter->writeAttribute('text:name', 'Table');
$xmlWriter->endElement();
// text:sequence-decl
$xmlWriter->startElement('text:sequence-decl');
$xmlWriter->writeAttribute('text:display-outline-level', 0);
$xmlWriter->writeAttribute('text:name', 'Text');
$xmlWriter->endElement();
// text:sequence-decl
$xmlWriter->startElement('text:sequence-decl');
$xmlWriter->writeAttribute('text:display-outline-level', 0);
$xmlWriter->writeAttribute('text:name', 'Drawing');
$xmlWriter->endElement();
$xmlWriter->endElement();
$sections = $phpWord->getSections();
$countSections = count($sections);
if ($countSections > 0) {
foreach ($sections as $section) {
$elements = $section->getElements();
foreach ($elements as $element) {
if ($element instanceof Text) {
$this->writeText($xmlWriter, $element);
} elseif ($element instanceof TextRun) {
$this->writeTextRun($xmlWriter, $element);
} elseif ($element instanceof TextBreak) {
$this->writeTextBreak($xmlWriter);
} elseif ($element instanceof Link) {
$this->writeUnsupportedElement($xmlWriter, 'Link');
} elseif ($element instanceof Title) {
$this->writeUnsupportedElement($xmlWriter, 'Title');
} elseif ($element instanceof PageBreak) {
$this->writeUnsupportedElement($xmlWriter, 'Page Break');
} elseif ($element instanceof Table) {
$this->writeUnsupportedElement($xmlWriter, 'Table');
} elseif ($element instanceof ListItem) {
$this->writeUnsupportedElement($xmlWriter, 'List Item');
} elseif ($element instanceof Image) {
$this->writeUnsupportedElement($xmlWriter, 'Image');
} elseif ($element instanceof Object) {
$this->writeUnsupportedElement($xmlWriter, 'Object');
} elseif ($element instanceof TOC) {
$this->writeUnsupportedElement($xmlWriter, 'TOC');
} else {
$this->writeUnsupportedElement($xmlWriter, 'Element');
}
}
}
}
$xmlWriter->endElement();
$xmlWriter->endElement();
$xmlWriter->endElement();
// Return
return $xmlWriter->getData();
}
/**
* Write text
*
* @param \PhpOffice\PhpWord\Shared\XMLWriter $xmlWriter
* @param \PhpOffice\PhpWord\Element\Text $text
* @param bool $withoutP
*/
protected function writeText(XMLWriter $xmlWriter, Text $text, $withoutP = false)
{
$styleFont = $text->getFontStyle();
$styleParagraph = $text->getParagraphStyle();
// @todo Commented for TextRun. Should really checkout this value
// $SfIsObject = ($styleFont instanceof Font) ? true : false;
$SfIsObject = false;
if ($SfIsObject) {
// Don't never be the case, because I browse all sections for cleaning all styles not declared
die('PhpWord : $SfIsObject wouldn\'t be an object');
} else {
if (!$withoutP) {
$xmlWriter->startElement('text:p'); // text:p
}
if (empty($styleFont)) {
if (empty($styleParagraph)) {
$xmlWriter->writeAttribute('text:style-name', 'P1');
} elseif (is_string($styleParagraph)) {
$xmlWriter->writeAttribute('text:style-name', $styleParagraph);
}
$xmlWriter->writeRaw($text->getText());
} else {
if (empty($styleParagraph)) {
$xmlWriter->writeAttribute('text:style-name', 'Standard');
} elseif (is_string($styleParagraph)) {
$xmlWriter->writeAttribute('text:style-name', $styleParagraph);
}
// text:span
$xmlWriter->startElement('text:span');
if (is_string($styleFont)) {
$xmlWriter->writeAttribute('text:style-name', $styleFont);
}
$xmlWriter->writeRaw($text->getText());
$xmlWriter->endElement();
}
if (!$withoutP) {
$xmlWriter->endElement(); // text:p
}
}
}
/**
* Write TextRun section
*
* @param \PhpOffice\PhpWord\Shared\XMLWriter $xmlWriter
* @param \PhpOffice\PhpWord\Element\TextRun $textrun
* @todo Enable all other section types
*/
protected function writeTextRun(XMLWriter $xmlWriter, TextRun $textrun)
{
$elements = $textrun->getElements();
$xmlWriter->startElement('text:p');
if (count($elements) > 0) {
foreach ($elements as $element) {
if ($element instanceof Text) {
$this->writeText($xmlWriter, $element, true);
}
}
}
$xmlWriter->endElement();
}
/**
* Write TextBreak
*
* @param \PhpOffice\PhpWord\Shared\XMLWriter $xmlWriter
*/
protected function writeTextBreak(XMLWriter $xmlWriter)
{
$xmlWriter->startElement('text:p');
$xmlWriter->writeAttribute('text:style-name', 'Standard');
$xmlWriter->endElement();
}
/**
* Write unsupported element
*
* @param \PhpOffice\PhpWord\Shared\XMLWriter $xmlWriter
* @param string $element
*/
private function writeUnsupportedElement($xmlWriter, $element)
{
$xmlWriter->startElement('text:p');
$xmlWriter->writeRaw($element);
$xmlWriter->endElement();
}
}

View File

@ -0,0 +1,66 @@
<?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;
use PhpOffice\PhpWord\Exception\Exception;
use PhpOffice\PhpWord\PhpWord;
use PhpOffice\PhpWord\Settings;
/**
* PDF Writer
*/
class PDF
{
/**
* The wrapper for the requested PDF rendering engine
*
* @var \PhpOffice\PhpWord\Writer\PDF\AbstractRenderer
*/
private $renderer = null;
/**
* Instantiate a new renderer of the configured type within this container class
*
* @param \PhpOffice\PhpWord\PhpWord $phpWord
*/
public function __construct(PhpWord $phpWord)
{
$pdfLibraryName = Settings::getPdfRendererName();
$pdfLibraryPath = Settings::getPdfRendererPath();
if (is_null($pdfLibraryName) || is_null($pdfLibraryPath)) {
throw new Exception("PDF rendering library or library path has not been defined.");
}
$includePath = str_replace('\\', '/', get_include_path());
$rendererPath = str_replace('\\', '/', $pdfLibraryPath);
if (strpos($rendererPath, $includePath) === false) {
set_include_path(get_include_path() . PATH_SEPARATOR . $pdfLibraryPath);
}
$rendererName = 'PhpOffice\\PhpWord\\Writer\\PDF\\' . $pdfLibraryName;
$this->renderer = new $rendererName($phpWord);
}
/**
* Magic method to handle direct calls to the configured PDF renderer wrapper class.
*
* @param string $name Renderer library method name
* @param mixed[] $arguments Array of arguments to pass to the renderer method
* @return mixed Returned data from the PDF renderer wrapper method
*/
public function __call($name, $arguments)
{
if ($this->renderer === null) {
throw new Exception("PDF Rendering library has not been defined.");
}
return call_user_func_array(array($this->renderer, $name), $arguments);
}
}

View File

@ -0,0 +1,170 @@
<?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\PDF;
use PhpOffice\PhpWord\Exception\Exception;
use PhpOffice\PhpWord\PhpWord;
/**
* Abstract PDF renderer
*/
abstract class AbstractRenderer extends \PhpOffice\PhpWord\Writer\HTML
{
/**
* Temporary storage directory
*
* @var string
*/
protected $tempDir = '';
/**
* Font
*
* @var string
*/
protected $font;
/**
* Paper size
*
* @var int
*/
protected $paperSize = null;
/**
* Orientation
*
* @var string
*/
protected $orientation = null;
/**
* Temporary storage for Save Array Return type
*
* @var string
*/
private $saveArrayReturnType;
/**
* Paper Sizes xRef List
*
* @var array
*/
protected static $paperSizes = array(
9 => 'A4', // (210 mm by 297 mm)
);
/**
* Create new instance
*
* @param PhpWord $phpWord PhpWord object
*/
public function __construct(PhpWord $phpWord)
{
parent::__construct($phpWord);
}
/**
* Get Font
*
* @return string
*/
public function getFont()
{
return $this->font;
}
/**
* Set font. Examples:
* 'arialunicid0-chinese-simplified'
* 'arialunicid0-chinese-traditional'
* 'arialunicid0-korean'
* 'arialunicid0-japanese'
*
* @param string $fontName
*/
public function setFont($fontName)
{
$this->font = $fontName;
return $this;
}
/**
* Get Paper Size
*
* @return int
*/
public function getPaperSize()
{
return $this->paperSize;
}
/**
* Set Paper Size
*
* @param string $pValue Paper size = PAPERSIZE_A4
* @return self
*/
public function setPaperSize($pValue = 9)
{
$this->paperSize = $pValue;
return $this;
}
/**
* Get Orientation
*
* @return string
*/
public function getOrientation()
{
return $this->orientation;
}
/**
* Set Orientation
*
* @param string $pValue Page orientation ORIENTATION_DEFAULT
* @return self
*/
public function setOrientation($pValue = 'default')
{
$this->orientation = $pValue;
return $this;
}
/**
* Save PhpWord to PDF file, pre-save
*
* @param string $pFilename Name of the file to save as
* @return resource
*/
protected function prepareForSave($pFilename = null)
{
$fileHandle = fopen($pFilename, 'w');
if ($fileHandle === false) {
throw new Exception("Could not open file $pFilename for writing.");
}
$this->isPdf = true;
return $fileHandle;
}
/**
* Save PhpWord to PDF file, post-save
*
* @param resource $fileHandle
* @throws Exception
*/
protected function restoreStateAfterSave($fileHandle)
{
fclose($fileHandle);
}
}

View File

@ -0,0 +1,70 @@
<?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\PDF;
use PhpOffice\PhpWord\PhpWord;
use PhpOffice\PhpWord\Settings;
use PhpOffice\PhpWord\Exception\Exception;
/**
* DomPDF writer
*/
class DomPDF extends AbstractRenderer implements \PhpOffice\PhpWord\Writer\WriterInterface
{
/**
* Create new instance
*
* @param PhpWord $phpWord PhpWord object
*/
public function __construct(PhpWord $phpWord)
{
parent::__construct($phpWord);
$configFile = Settings::getPdfRendererPath() . '/dompdf_config.inc.php';
if (file_exists($configFile)) {
require_once $configFile;
} else {
throw new Exception('Unable to load PDF Rendering library');
}
}
/**
* Save PhpWord to file
*
* @param string $pFilename Name of the file to save as
* @throws Exception
*/
public function save($pFilename = null)
{
$fileHandle = parent::prepareForSave($pFilename);
// Default PDF paper size
$paperSize = 'A4';
$orientation = 'P';
$printPaperSize = 9;
if (isset(self::$paperSizes[$printPaperSize])) {
$paperSize = self::$paperSizes[$printPaperSize];
}
$orientation = ($orientation == 'L') ? 'landscape' : 'portrait';
// Create PDF
$pdf = new \DOMPDF();
$pdf->set_paper(strtolower($paperSize), $orientation);
$pdf->load_html($this->writeDocument());
$pdf->render();
// Write to file
fwrite($fileHandle, $pdf->output());
parent::restoreStateAfterSave($fileHandle);
}
}

View File

@ -9,17 +9,18 @@
namespace PhpOffice\PhpWord\Writer;
use PhpOffice\PhpWord\Element\Section;
use PhpOffice\PhpWord\Exception\Exception;
use PhpOffice\PhpWord\Media;
use PhpOffice\PhpWord\PhpWord;
use PhpOffice\PhpWord\Media;
use PhpOffice\PhpWord\Element\Section;
use PhpOffice\PhpWord\Writer\Word2007\ContentTypes;
use PhpOffice\PhpWord\Writer\Word2007\Rels;
use PhpOffice\PhpWord\Writer\Word2007\DocProps;
use PhpOffice\PhpWord\Writer\Word2007\Document;
use PhpOffice\PhpWord\Writer\Word2007\Footer;
use PhpOffice\PhpWord\Writer\Word2007\Header;
use PhpOffice\PhpWord\Writer\Word2007\Notes;
use PhpOffice\PhpWord\Writer\Word2007\Rels;
use PhpOffice\PhpWord\Writer\Word2007\Numbering;
use PhpOffice\PhpWord\Writer\Word2007\Header;
use PhpOffice\PhpWord\Writer\Word2007\Styles;
/**
@ -57,6 +58,7 @@ class Word2007 extends AbstractWriter implements WriterInterface
$this->writerParts['docprops'] = new DocProps();
$this->writerParts['document'] = new Document();
$this->writerParts['styles'] = new Styles();
$this->writerParts['numbering'] = new Numbering();
$this->writerParts['header'] = new Header();
$this->writerParts['footer'] = new Footer();
$this->writerParts['footnotes'] = new Notes();
@ -97,7 +99,6 @@ class Word2007 extends AbstractWriter implements WriterInterface
$this->addHeaderFooterMedia($objZip, 'footer');
// Add header/footer contents
$overrides = array();
$rId = Media::countElements('section') + 6; // @see Rels::writeDocRels for 6 first elements
$sections = $this->phpWord->getSections();
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/document.xml', $this->getWriterPart('document')->writeDocument($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
$objZip->addFile(__DIR__ . '/../_staticDocParts/numbering.xml', 'word/numbering.xml');
$objZip->addFile(__DIR__ . '/../_staticDocParts/settings.xml', 'word/settings.xml');
$objZip->addFile(__DIR__ . '/../_staticDocParts/theme1.xml', 'word/theme/theme1.xml');
$objZip->addFile(__DIR__ . '/../_staticDocParts/webSettings.xml', 'word/webSettings.xml');

View File

@ -279,7 +279,7 @@ class Base extends AbstractWriterPart
{
$textObject = $listItem->getTextObject();
$depth = $listItem->getDepth();
$listType = $listItem->getStyle()->getListType();
$numId = $listItem->getStyle()->getNumId();
$styleParagraph = $textObject->getParagraphStyle();
$xmlWriter->startElement('w:p');
@ -290,7 +290,7 @@ class Base extends AbstractWriterPart
$xmlWriter->writeAttribute('w:val', $depth);
$xmlWriter->endElement(); // w:ilvl
$xmlWriter->startElement('w:numId');
$xmlWriter->writeAttribute('w:val', $listType);
$xmlWriter->writeAttribute('w:val', $numId);
$xmlWriter->endElement(); // w:numId
$xmlWriter->endElement(); // w:numPr
$xmlWriter->endElement(); // w:pPr
@ -427,25 +427,22 @@ class Base extends AbstractWriterPart
$marginTop = $style->getMarginTop();
$marginLeft = $style->getMarginLeft();
$wrappingStyle = $style->getWrappingStyle();
$w10wrapType = null;
if (!$withoutP) {
$xmlWriter->startElement('w:p');
if (!is_null($align)) {
$xmlWriter->startElement('w:pPr');
$xmlWriter->startElement('w:jc');
$xmlWriter->writeAttribute('w:val', $align);
$xmlWriter->endElement();
$xmlWriter->endElement();
$xmlWriter->endElement(); // w:jc
$xmlWriter->endElement(); // w:pPr
}
}
$xmlWriter->startElement('w:r');
$xmlWriter->startElement('w:pict');
$xmlWriter->startElement('v:shape');
$xmlWriter->writeAttribute('type', '#_x0000_t75');
$imgStyle = '';
if (null !== $width) {
$imgStyle .= 'width:' . $width . 'px;';
@ -459,33 +456,38 @@ class Base extends AbstractWriterPart
if (null !== $marginLeft) {
$imgStyle .= 'margin-left:' . $marginLeft . 'in;';
}
switch ($wrappingStyle) {
case ImageStyle::WRAPPING_STYLE_BEHIND:
$imgStyle .= 'position:absolute;z-index:-251658752;';
break;
case ImageStyle::WRAPPING_STYLE_SQUARE:
case ImageStyle::WRAPPING_STYLE_INFRONT:
$imgStyle .= 'position:absolute;z-index:251659264;mso-position-horizontal:absolute;mso-position-vertical:absolute;';
break;
case ImageStyle::WRAPPING_STYLE_TIGHT:
$imgStyle .= 'position:absolute;z-index:251659264;mso-wrap-edited:f;mso-position-horizontal:absolute;mso-position-vertical:absolute';
case ImageStyle::WRAPPING_STYLE_SQUARE:
$imgStyle .= 'position:absolute;z-index:251659264;mso-position-horizontal:absolute;mso-position-vertical:absolute;';
$w10wrapType = 'square';
break;
case ImageStyle::WRAPPING_STYLE_INFRONT:
$imgStyle .= 'position:absolute;zz-index:251659264;mso-position-horizontal:absolute;mso-position-vertical:absolute;';
case ImageStyle::WRAPPING_STYLE_TIGHT:
$imgStyle .= 'position:absolute;z-index:251659264;mso-position-horizontal:absolute;mso-position-vertical:absolute;';
$w10wrapType = 'tight';
break;
}
$xmlWriter->writeAttribute('style', $imgStyle);
$xmlWriter->startElement('v:imagedata');
$xmlWriter->writeAttribute('r:id', 'rId' . $rId);
$xmlWriter->writeAttribute('o:title', '');
$xmlWriter->endElement();
$xmlWriter->endElement();
$xmlWriter->endElement(); // v:imagedata
$xmlWriter->endElement();
if (!is_null($w10wrapType)) {
$xmlWriter->startElement('w10:wrap');
$xmlWriter->writeAttribute('type', $w10wrapType);
$xmlWriter->endElement(); // w10:wrap
}
$xmlWriter->endElement();
$xmlWriter->endElement(); // v:shape
$xmlWriter->endElement(); // w:pict
$xmlWriter->endElement(); // w:r
if (!$withoutP) {
$xmlWriter->endElement(); // w:p

View File

@ -9,8 +9,8 @@
namespace PhpOffice\PhpWord\Writer\Word2007;
use PhpOffice\PhpWord\Element\Endnote;
use PhpOffice\PhpWord\Element\Footnote;
use PhpOffice\PhpWord\Element\Endnote;
use PhpOffice\PhpWord\Shared\XMLWriter;
/**
@ -69,7 +69,7 @@ class Notes extends Base
// Content
foreach ($elements as $element) {
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 \PhpOffice\PhpWord\Shared\XMLWriter $xmlWriter
* @param \PhpOffice\PhpWord\Element\Footnote|\PhpOffice\PhpWord\Element\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');
$elementNode = $isFootnote ? 'w:footnote' : 'w:endnote';

View File

@ -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));
}
}

View File

@ -15,7 +15,7 @@ use PhpOffice\PhpWord\Shared\XMLWriter;
/**
* Word2007 relationship writer
*
* @since 0.9.2
* @since 0.10.0
*/
class Rels extends AbstractWriterPart
{

View File

@ -18,6 +18,8 @@ use PhpOffice\PhpWord\Style;
/**
* Word2007 styles part writer
*
* @todo Do something with the numbering style introduced in 0.10.0
*/
class Styles extends Base
{
@ -38,37 +40,31 @@ class Styles extends Base
// XML header
$xmlWriter->startDocument('1.0', 'UTF-8', 'yes');
$xmlWriter->startElement('w:styles');
$xmlWriter->writeAttribute(
'xmlns:r',
'http://schemas.openxmlformats.org/officeDocument/2006/relationships'
);
$xmlWriter->writeAttribute(
'xmlns:w',
'http://schemas.openxmlformats.org/wordprocessingml/2006/main'
);
$xmlWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships');
$xmlWriter->writeAttribute('xmlns:w', 'http://schemas.openxmlformats.org/wordprocessingml/2006/main');
// Write default styles
$styles = Style::getStyles();
$this->writeDefaultStyles($xmlWriter, $phpWord, $styles);
// Write other styles
// Write styles
if (count($styles) > 0) {
foreach ($styles as $styleName => $style) {
if ($styleName == 'Normal') {
continue;
}
if ($style instanceof Font) {
// Font style
if ($style instanceof Font) {
$paragraphStyle = $style->getParagraphStyle();
$styleType = $style->getStyleType();
$type = ($styleType == 'title') ? 'paragraph' : 'character';
if (!is_null($paragraphStyle)) {
$type = 'paragraph';
}
$xmlWriter->startElement('w:style');
$xmlWriter->writeAttribute('w:type', $type);
if ($styleType == 'title') {
$arrStyle = explode('_', $styleName);
$styleId = 'Heading' . $arrStyle[1];
@ -80,11 +76,9 @@ class Styles extends Base
$xmlWriter->writeAttribute('w:val', $styleLink);
$xmlWriter->endElement();
}
$xmlWriter->startElement('w:name');
$xmlWriter->writeAttribute('w:val', $styleName);
$xmlWriter->endElement();
if (!is_null($paragraphStyle)) {
// Point parent style to Normal
$xmlWriter->startElement('w:basedOn');
@ -94,19 +88,17 @@ class Styles extends Base
}
$this->writeFontStyle($xmlWriter, $style);
$xmlWriter->endElement();
// Paragraph style
} elseif ($style instanceof Paragraph) {
$xmlWriter->startElement('w:style');
$xmlWriter->writeAttribute('w:type', 'paragraph');
$xmlWriter->writeAttribute('w:customStyle', '1');
$xmlWriter->writeAttribute('w:styleId', $styleName);
$xmlWriter->startElement('w:name');
$xmlWriter->writeAttribute('w:val', $styleName);
$xmlWriter->endElement();
// Parent style
$basedOn = $style->getBasedOn();
if (!is_null($basedOn)) {
@ -114,7 +106,6 @@ class Styles extends Base
$xmlWriter->writeAttribute('w:val', $basedOn);
$xmlWriter->endElement();
}
// Next paragraph style
$next = $style->getNext();
if (!is_null($next)) {
@ -126,22 +117,20 @@ class Styles extends Base
$this->writeParagraphStyle($xmlWriter, $style);
$xmlWriter->endElement();
// Table style
} elseif ($style instanceof Table) {
$xmlWriter->startElement('w:style');
$xmlWriter->writeAttribute('w:type', 'table');
$xmlWriter->writeAttribute('w:customStyle', '1');
$xmlWriter->writeAttribute('w:styleId', $styleName);
$xmlWriter->startElement('w:name');
$xmlWriter->writeAttribute('w:val', $styleName);
$xmlWriter->endElement();
$xmlWriter->startElement('w:uiPriority');
$xmlWriter->writeAttribute('w:val', '99');
$xmlWriter->endElement();
$this->writeTableStyle($xmlWriter, $style);
$xmlWriter->endElement(); // w:style
}
}
@ -149,7 +138,6 @@ class Styles extends Base
$xmlWriter->endElement(); // w:styles
// Return
return $xmlWriter->getData();
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,39 @@
<?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\Tests\Element;
/**
* Test class for PhpOffice\PhpWord\Element\AbstractElement
*
* @runTestsInSeparateProcesses
*/
class AbstractElementTest extends \PHPUnit_Framework_TestCase
{
/**
* Test set/get element index
*/
public function testElementIndex()
{
$stub = $this->getMockForAbstractClass('\PhpOffice\PhpWord\Element\AbstractElement');
$ival = rand(0, 100);
$stub->setElementIndex($ival);
$this->assertEquals($stub->getElementIndex(), $ival);
}
/**
* Test set/get element unique Id
*/
public function testElementId()
{
$stub = $this->getMockForAbstractClass('\PhpOffice\PhpWord\Element\AbstractElement');
$stub->setElementId();
$this->assertEquals(strlen($stub->getElementId()), 6);
}
}

View File

@ -51,34 +51,29 @@ class ImageTest extends \PHPUnit_Framework_TestCase
/**
* Valid image types
*/
public function testValidImageTypes()
public function testImages()
{
new Image(__DIR__ . "/../_files/images/mars_noext_jpg");
new Image(__DIR__ . "/../_files/images/mars.jpg");
new Image(__DIR__ . "/../_files/images/mario.gif");
new Image(__DIR__ . "/../_files/images/firefox.png");
new Image(__DIR__ . "/../_files/images/duke_nukem.bmp");
new Image(__DIR__ . "/../_files/images/angela_merkel.tif");
}
$images = array(
array('mars.jpg', 'image/jpeg', 'jpg', 'imagecreatefromjpeg', 'imagejpeg'),
array('mario.gif', 'image/gif', 'gif', 'imagecreatefromgif', 'imagegif'),
array('firefox.png', 'image/png', 'png', 'imagecreatefrompng', 'imagepng'),
array('duke_nukem.bmp', 'image/bmp', 'bmp', null, null),
array('angela_merkel.tif', 'image/tiff', 'tif', null, null),
);
/**
* Image not found
*
* @expectedException \PhpOffice\PhpWord\Exception\InvalidImageException
*/
public function testImageNotFound()
{
new Image(__DIR__ . "/../_files/images/thisisnotarealimage");
}
/**
* Invalid image types
*
* @expectedException \PhpOffice\PhpWord\Exception\UnsupportedImageTypeException
*/
public function testInvalidImageTypes()
{
new Image(__DIR__ . "/../_files/images/alexz-johnson.pcx");
foreach ($images as $imageData) {
list($source, $type, $extension, $createFunction, $imageFunction) = $imageData;
$source = __DIR__ . "/../_files/images/" . $source;
$image = new Image($source);
$this->assertInstanceOf('PhpOffice\\PhpWord\\Element\\Image', $image);
$this->assertEquals($image->getSource(), $source);
$this->assertEquals($image->getMediaId(), md5($source));
$this->assertEquals($image->getImageType(), $type);
$this->assertEquals($image->getImageExtension(), $extension);
$this->assertEquals($image->getImageCreateFunction(), $createFunction);
$this->assertEquals($image->getImageFunction(), $imageFunction);
$this->assertFalse($image->getIsMemImage());
}
}
/**
@ -88,118 +83,61 @@ class ImageTest extends \PHPUnit_Framework_TestCase
{
$oImage = new Image(
__DIR__ . "/../_files/images/earth.jpg",
array('width' => 210, 'height' => 210, 'align' => 'center')
array('height' => 210, 'align' => 'center')
);
$this->assertInstanceOf('PhpOffice\\PhpWord\\Style\\Image', $oImage->getStyle());
}
/**
* Test invalid local image
*
* @expectedException \PhpOffice\PhpWord\Exception\InvalidImageException
*/
public function testInvalidImageLocal()
{
new Image(__DIR__ . "/../_files/images/thisisnotarealimage");
}
/**
* Test invalid PHP Image
*
* @expectedException \PhpOffice\PhpWord\Exception\InvalidImageException
*/
public function testInvalidImagePhp()
{
$object = new Image('test.php');
}
/**
* Test unsupported image
*
* @expectedException \PhpOffice\PhpWord\Exception\UnsupportedImageTypeException
*/
public function testUnsupportedImage()
{
$object = new Image('http://samples.libav.org/image-samples/RACECAR.BMP');
}
/**
* Get relation Id
*/
public function testRelationID()
{
$oImage = new Image(__DIR__ . "/../_files/images/earth.jpg");
$oImage = new Image(__DIR__ . "/../_files/images/earth.jpg", array('width' => 100));
$iVal = rand(1, 1000);
$oImage->setRelationId($iVal);
$this->assertEquals($oImage->getRelationId(), $iVal);
}
/**
* Get is watermark
* Test archived image
*/
public function testWatermark()
public function testArchivedImage()
{
$oImage = new Image(__DIR__ . "/../_files/images/earth.jpg");
$oImage->setIsWatermark(true);
$this->assertEquals($oImage->getIsWatermark(), true);
}
/**
* Test PNG
*/
public function testPNG()
{
$src = __DIR__ . "/../_files/images/firefox.png";
$oImage = new Image($src);
$this->assertInstanceOf('PhpOffice\\PhpWord\\Element\\Image', $oImage);
$this->assertEquals($oImage->getSource(), $src);
$this->assertEquals($oImage->getMediaId(), md5($src));
$this->assertEquals($oImage->getImageCreateFunction(), 'imagecreatefrompng');
$this->assertEquals($oImage->getImageFunction(), 'imagepng');
$this->assertEquals($oImage->getImageExtension(), 'png');
$this->assertEquals($oImage->getImageType(), 'image/png');
}
/**
* Test GIF
*/
public function testGIF()
{
$src = __DIR__ . "/../_files/images/mario.gif";
$oImage = new Image($src);
$this->assertInstanceOf('PhpOffice\\PhpWord\\Element\\Image', $oImage);
$this->assertEquals($oImage->getSource(), $src);
$this->assertEquals($oImage->getMediaId(), md5($src));
$this->assertEquals($oImage->getImageCreateFunction(), 'imagecreatefromgif');
$this->assertEquals($oImage->getImageFunction(), 'imagegif');
$this->assertEquals($oImage->getImageExtension(), 'gif');
$this->assertEquals($oImage->getImageType(), 'image/gif');
}
/**
* Test JPG
*/
public function testJPG()
{
$src = __DIR__ . "/../_files/images/earth.jpg";
$oImage = new Image($src);
$this->assertInstanceOf('PhpOffice\\PhpWord\\Element\\Image', $oImage);
$this->assertEquals($oImage->getSource(), $src);
$this->assertEquals($oImage->getMediaId(), md5($src));
$this->assertEquals($oImage->getImageCreateFunction(), 'imagecreatefromjpeg');
$this->assertEquals($oImage->getImageFunction(), 'imagejpeg');
$this->assertEquals($oImage->getImageExtension(), 'jpg');
$this->assertEquals($oImage->getImageType(), 'image/jpeg');
}
/**
* Test BMP
*/
public function testBMP()
{
$oImage = new Image(__DIR__ . "/../_files/images/duke_nukem.bmp");
$this->assertInstanceOf('PhpOffice\\PhpWord\\Element\\Image', $oImage);
$this->assertEquals($oImage->getImageCreateFunction(), null);
$this->assertEquals($oImage->getImageFunction(), null);
$this->assertEquals($oImage->getImageExtension(), 'bmp');
$this->assertEquals($oImage->getImageType(), 'image/bmp');
}
/**
* Test TIFF
*/
public function testTIFF()
{
$oImage = new Image(__DIR__ . "/../_files/images/angela_merkel.tif");
$this->assertInstanceOf('PhpOffice\\PhpWord\\Element\\Image', $oImage);
$this->assertEquals($oImage->getImageCreateFunction(), null);
$this->assertEquals($oImage->getImageFunction(), null);
$this->assertEquals($oImage->getImageType(), 'image/tiff');
}
/**
* Test PHP Image
*
* @expectedException \PhpOffice\PhpWord\Exception\InvalidImageException
*/
public function testPhpImage()
{
$object = new Image('test.php');
$archiveFile = __DIR__ . "/../_files/documents/reader.docx";
$imageFile = 'word/media/image1.jpeg';
$image = new Image("zip://{$archiveFile}#{$imageFile}");
$this->assertEquals('image/jpeg', $image->getImageType());
}
}

View File

@ -48,11 +48,11 @@ class TableTest extends \PHPUnit_Framework_TestCase
*/
public function testStyleArray()
{
$oTable = new Table(
'section',
1,
array('borderSize' => 6, 'borderColor' => '006699', 'cellMargin' => 80)
);
$oTable = new Table('section', 1, array(
'borderSize' => 6,
'borderColor' => '006699',
'cellMargin' => 80
));
$this->assertInstanceOf('PhpOffice\\PhpWord\\Style\\Table', $oTable->getStyle());
}
@ -63,7 +63,7 @@ class TableTest extends \PHPUnit_Framework_TestCase
public function testWidth()
{
$oTable = new Table('section', 1);
$iVal = rand(1, 1000);
$iVal = rand(1, 1000);
$oTable->setWidth($iVal);
$this->assertEquals($oTable->getWidth(), $iVal);
}
@ -73,7 +73,7 @@ class TableTest extends \PHPUnit_Framework_TestCase
*/
public function testRow()
{
$oTable = new Table('section', 1);
$oTable = new Table('section', 1);
$element = $oTable->addRow();
$this->assertInstanceOf('PhpOffice\\PhpWord\\Element\\Row', $element);
$this->assertCount(1, $oTable->getRows());
@ -89,4 +89,18 @@ class TableTest extends \PHPUnit_Framework_TestCase
$element = $oTable->addCell();
$this->assertInstanceOf('PhpOffice\\PhpWord\\Element\\Cell', $element);
}
/**
* Add cell
*/
public function testCountColumns()
{
$oTable = new Table('section', 1);
$oTable->addRow();
$element = $oTable->addCell();
$this->assertEquals($oTable->countColumns(), 1);
$element = $oTable->addCell();
$element = $oTable->addCell();
$this->assertEquals($oTable->countColumns(), 3);
}
}

View File

@ -19,9 +19,9 @@ use PhpOffice\PhpWord\Settings;
class SettingsTest extends \PHPUnit_Framework_TestCase
{
/**
* Get/set compatibity option
* Test set/get compatibity option
*/
public function testGetSetCompatibility()
public function testSetGetCompatibility()
{
$this->assertTrue(Settings::getCompatibility());
$this->assertTrue(Settings::setCompatibility(false));
@ -30,12 +30,26 @@ class SettingsTest extends \PHPUnit_Framework_TestCase
}
/**
* Get/set zip class
* Test set/get zip class
*/
public function testGetSetZipClass()
public function testSetGetZipClass()
{
$this->assertEquals(Settings::ZIPARCHIVE, Settings::getZipClass());
$this->assertTrue(Settings::setZipClass(Settings::PCLZIP));
$this->assertFalse(Settings::setZipClass('foo'));
}
/**
* Test set/get PDF renderer
*/
public function testSetGetPdfRenderer()
{
$domPdfPath = realpath(PHPWORD_TESTS_BASE_DIR . '/../vendor/dompdf/dompdf');
$this->assertFalse(Settings::setPdfRenderer('FOO', 'dummy/path'));
$this->assertTrue(Settings::setPdfRenderer(Settings::PDF_RENDERER_DOMPDF, $domPdfPath));
$this->assertEquals(Settings::PDF_RENDERER_DOMPDF, Settings::getPdfRendererName());
$this->assertEquals($domPdfPath, Settings::getPdfRendererPath());
$this->assertFalse(Settings::setPdfRendererPath('dummy/path'));
}
}

View File

@ -0,0 +1,54 @@
<?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\Tests\Shared;
use PhpOffice\PhpWord\Shared\XMLReader;
/**
* Test class for PhpOffice\PhpWord\Shared\XMLReader
*
* @runTestsInSeparateProcesses
* @since 0.10.0
*/
class XMLReaderTest extends \PHPUnit_Framework_TestCase
{
/**
* Test get DOMDocument from ZipArchive returns false
*/
public function testGetDomFromZipReturnsFalse()
{
$filename = __DIR__ . "/../_files/documents/reader.docx.zip";
$object = new XMLReader();
$this->assertFalse($object->getDomFromZip($filename, 'yadayadaya'));
}
/**
* Test get elements returns empty
*/
public function testGetElementsReturnsEmpty()
{
$object = new XMLReader();
$this->assertEquals(array(), $object->getElements('w:document'));
}
/**
* Test get element returns null
*/
public function testGetElementReturnsNull()
{
$filename = __DIR__ . "/../_files/documents/reader.docx.zip";
$object = new XMLReader();
$object->getDomFromZip($filename, '[Content_Types].xml');
$element = $object->getElements('*')->item(0);
$this->assertNull($object->getElement('yadayadaya', $element));
}
}

View File

@ -24,14 +24,51 @@ class ZipArchiveTest extends \PHPUnit_Framework_TestCase
public function testAdd()
{
$existingFile = __DIR__ . "/../_files/documents/sheet.xls";
$zipFile = __DIR__ . "/../_files/documents/ziptest.zip";
$object = new ZipArchive();
$zipFile = __DIR__ . "/../_files/documents/ziptest.zip";
$object = new ZipArchive();
$object->open($zipFile);
$object->addFile($existingFile, 'xls/new.xls');
$object->addFromString('content/string.txt', 'Test');
$this->assertTrue($object->locateName('xls/new.xls'));
$this->assertEquals('Test', $object->getFromName('content/string.txt'));
$this->assertEquals('Test', $object->getFromName('/content/string.txt'));
unlink($zipFile);
}
/**
* Test find if a given name exists in the archive
*/
public function testLocate()
{
$existingFile = __DIR__ . "/../_files/documents/sheet.xls";
$zipFile = __DIR__ . "/../_files/documents/ziptest.zip";
$object = new ZipArchive();
$object->open($zipFile);
$object->addFile($existingFile, 'xls/new.xls');
$object->addFromString('content/string.txt', 'Test');
$this->assertEquals(1, $object->locateName('content/string.txt'));
$this->assertFalse($object->locateName('blablabla'));
unlink($zipFile);
}
/**
* Test returns the name of an entry using its index
*/
public function testNameIndex()
{
$existingFile = __DIR__ . "/../_files/documents/sheet.xls";
$zipFile = __DIR__ . "/../_files/documents/ziptest.zip";
$object = new ZipArchive();
$object->open($zipFile);
$object->addFile($existingFile, 'xls/new.xls');
$object->addFromString('content/string.txt', 'Test');
$this->assertFalse($object->getNameIndex(-1));
$this->assertEquals('content/string.txt', $object->getNameIndex(1));
unlink($zipFile);
}

View File

@ -0,0 +1,70 @@
<?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\Tests\Style;
/**
* Test class for PhpOffice\PhpWord\Style\AbstractStyle
*
* @runTestsInSeparateProcesses
*/
class AbstractStyleTest extends \PHPUnit_Framework_TestCase
{
/**
* Test set style by array
*/
public function testSetStyleByArray()
{
$stub = $this->getMockForAbstractClass('\PhpOffice\PhpWord\Style\AbstractStyle');
$stub->setStyleByArray(array('index' => 1));
$this->assertEquals(1, $stub->getIndex());
}
/**
* Test setBoolVal, setIntVal, setFloatVal, setEnumVal with normal value
*/
public function testSetValNormal()
{
$stub = $this->getMockForAbstractClass('\PhpOffice\PhpWord\Style\AbstractStyle');
$this->assertEquals(true, self::callProtectedMethod($stub, 'setBoolVal', array(true, false)));
$this->assertEquals(12, self::callProtectedMethod($stub, 'setIntVal', array(12, 200)));
$this->assertEquals(871.1, self::callProtectedMethod($stub, 'setFloatVal', array(871.1, 2.1)));
$this->assertEquals('a', self::callProtectedMethod($stub, 'setEnumVal', array('a', array('a', 'b'), 'b')));
}
/**
* Test setBoolVal, setIntVal, setFloatVal, setEnumVal with default value
*/
public function testSetValDefault()
{
$stub = $this->getMockForAbstractClass('\PhpOffice\PhpWord\Style\AbstractStyle');
$this->assertEquals(false, self::callProtectedMethod($stub, 'setBoolVal', array('a', false)));
$this->assertEquals(200, self::callProtectedMethod($stub, 'setIntVal', array('foo', 200)));
$this->assertEquals(2.1, self::callProtectedMethod($stub, 'setFloatVal', array('foo', 2.1)));
$this->assertEquals('b', self::callProtectedMethod($stub, 'setEnumVal', array('z', array('a', 'b'), 'b')));
}
/**
* Helper function to call protected method
*
* @param mixed $object
* @param string $method
* @param array $args
*/
public static function callProtectedMethod($object, $method, array $args = array())
{
$class = new \ReflectionClass(get_class($object));
$method = $class->getMethod($method);
$method->setAccessible(true);
return $method->invokeArgs($object, $args);
}
}

View File

@ -32,7 +32,7 @@ class ImageTest extends \PHPUnit_Framework_TestCase
'align' => 'left',
'marginTop' => 240,
'marginLeft' => 240,
'wrappingStyle' => 'inline',
'wrappingStyle' => 'inline'
);
foreach ($properties as $key => $value) {
$set = "set{$key}";
@ -54,7 +54,7 @@ class ImageTest extends \PHPUnit_Framework_TestCase
'height' => 200,
'align' => 'left',
'marginTop' => 240,
'marginLeft' => 240,
'marginLeft' => 240
);
foreach ($properties as $key => $value) {
$get = "get{$key}";

View File

@ -53,4 +53,16 @@ class ListItemTest extends \PHPUnit_Framework_TestCase
$object->setListType($value);
$this->assertEquals($value, $object->getListType());
}
/**
* Test set/get numbering style name
*/
public function testSetGetNumStyle()
{
$expected = 'List Name';
$object = new ListItem();
$object->setNumStyle($expected);
$this->assertEquals($expected, $object->getNumStyle());
}
}

View File

@ -0,0 +1,49 @@
<?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\Tests\Style;
use PhpOffice\PhpWord\Style\NumberingLevel;
/**
* Test class for PhpOffice\PhpWord\Style\NumberingLevel
*
* @runTestsInSeparateProcesses
*/
class NumberingLevelTest extends \PHPUnit_Framework_TestCase
{
/**
* Test setting style with normal value
*/
public function testSetGetNormal()
{
$object = new NumberingLevel();
$attributes = array(
'level' => 1,
'start' => 1,
'format' => 'decimal',
'restart' => 1,
'suffix' => 'space',
'text' => '%1.',
'align' => 'left',
'left' => 360,
'hanging' => 360,
'tabPos' => 360,
'font' => 'Arial',
'hint' => 'default',
);
foreach ($attributes as $key => $value) {
$set = "set{$key}";
$get = "get{$key}";
$object->$set($value);
$this->assertEquals($value, $object->$get());
}
}
}

View File

@ -0,0 +1,110 @@
<?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\Tests\Writer;
use PhpOffice\PhpWord\PhpWord;
use PhpOffice\PhpWord\Writer\HTML;
/**
* Test class for PhpOffice\PhpWord\Writer\HTML
*
* @runTestsInSeparateProcesses
*/
class HTMLTest extends \PHPUnit_Framework_TestCase
{
/**
* Construct
*/
public function testConstruct()
{
$object = new HTML(new PhpWord);
$this->assertInstanceOf('PhpOffice\\PhpWord\\PhpWord', $object->getPhpWord());
}
/**
* Construct with null
*
* @expectedException \PhpOffice\PhpWord\Exception\Exception
* @expectedExceptionMessage No PhpWord assigned.
*/
public function testConstructWithNull()
{
$object = new HTML();
$object->getPhpWord();
}
/**
* Save
*/
public function testSave()
{
$localImage = __DIR__ . "/../_files/images/PhpWord.png";
$archiveImage = 'zip://' . __DIR__ . '/../_files/documents/reader.docx#word/media/image1.jpeg';
$gdImage = 'http://php.net/images/logos/php-med-trans-light.gif';
$objectSrc = __DIR__ . "/../_files/documents/sheet.xls";
$file = __DIR__ . "/../_files/temp.html";
$phpWord = new PhpWord();
$docProps = $phpWord->getDocumentProperties();
$docProps->setTitle('HTML Test');
$phpWord->addFontStyle('Font', array('name' => 'Verdana', 'size' => 11, 'color' => 'FF0000', 'fgColor' => 'FF0000'));
$phpWord->addParagraphStyle('Paragraph', array('align' => 'center'));
$section = $phpWord->addSection();
$section->addText('Test 1', 'Font', 'Paragraph');
$section->addTextBreak();
$section->addText('Test 2', array('name' => 'Tahoma', 'bold' => true, 'italic' => true));
$section->addLink('http://test.com');
$section->addTitle('Test', 1);
$section->addPageBreak();
$section->addListItem('Test');
$section->addImage($localImage);
$section->addImage($archiveImage);
$section->addImage($gdImage);
$section->addObject($objectSrc);
$section->addFootnote();
$section->addEndnote();
$section = $phpWord->addSection();
$textrun = $section->addTextRun(array('align' => 'center'));
$textrun->addText('Test 3');
$textrun->addTextBreak();
$textrun = $section->addTextRun('Paragraph');
$textrun->addLink('http://test.com');
$textrun->addImage($localImage);
$textrun->addFootnote();
$textrun->addEndnote();
$section = $phpWord->addSection();
$table = $section->addTable();
$cell = $table->addRow()->addCell();
$cell->addText('Test 1', array('superscript' => true, 'underline' => 'dash', 'strikethrough' => true));
$cell->addTextRun();
$cell->addLink('http://test.com');
$cell->addTextBreak();
$cell->addListItem('Test');
$cell->addImage($localImage);
$cell->addObject($objectSrc);
$cell->addFootnote();
$cell->addEndnote();
$cell = $table->addRow()->addCell();
$writer = new HTML($phpWord);
$writer->save($file);
$this->assertTrue(file_exists($file));
unlink($file);
}
}

View File

@ -0,0 +1,70 @@
<?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\Tests\Writer\PDF;
use PhpOffice\PhpWord\PhpWord;
use PhpOffice\PhpWord\Settings;
use PhpOffice\PhpWord\Writer\PDF;
/**
* Test class for PhpOffice\PhpWord\Writer\PDF\DomPDF
*
* @runTestsInSeparateProcesses
*/
class DomPDFTest extends \PHPUnit_Framework_TestCase
{
/**
* Test construct
*/
public function testConstruct()
{
define('DOMPDF_ENABLE_AUTOLOAD', false);
$file = __DIR__ . "/../../_files/temp.pdf";
$phpWord = new PhpWord();
$section = $phpWord->addSection();
$section->addText('Test 1');
$rendererName = Settings::PDF_RENDERER_DOMPDF;
$rendererLibraryPath = realpath(PHPWORD_TESTS_BASE_DIR . '/../vendor/dompdf/dompdf');
Settings::setPdfRenderer($rendererName, $rendererLibraryPath);
$writer = new PDF($phpWord);
$writer->save($file);
$this->assertTrue(file_exists($file));
unlink($file);
}
/**
* Test set/get abstract renderer properties
*/
public function testSetGetAbstractRendererProperties()
{
define('DOMPDF_ENABLE_AUTOLOAD', false);
$file = __DIR__ . "/../../_files/temp.pdf";
$rendererName = Settings::PDF_RENDERER_DOMPDF;
$rendererLibraryPath = realpath(PHPWORD_TESTS_BASE_DIR . '/../vendor/dompdf/dompdf');
Settings::setPdfRenderer($rendererName, $rendererLibraryPath);
$writer = new PDF(new PhpWord());
$writer->setFont('arial');
$this->assertEquals('arial', $writer->getFont());
$writer->setPaperSize();
$this->assertEquals(9, $writer->getPaperSize());
$writer->setOrientation();
$this->assertEquals('default', $writer->getOrientation());
$writer->setTempDir(sys_get_temp_dir());
$this->assertEquals(sys_get_temp_dir(), $writer->getTempDir());
}
}

View File

@ -0,0 +1,51 @@
<?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\Tests\Writer;
use PhpOffice\PhpWord\PhpWord;
use PhpOffice\PhpWord\Settings;
use PhpOffice\PhpWord\Writer\PDF;
/**
* Test class for PhpOffice\PhpWord\Writer\PDF
*
* @runTestsInSeparateProcesses
*/
class PDFTest extends \PHPUnit_Framework_TestCase
{
/**
* Test normal construct
*/
public function testConstruct()
{
define('DOMPDF_ENABLE_AUTOLOAD', false);
$file = __DIR__ . "/../_files/temp.pdf";
$rendererName = Settings::PDF_RENDERER_DOMPDF;
$rendererLibraryPath = realpath(PHPWORD_TESTS_BASE_DIR . '/../vendor/dompdf/dompdf');
Settings::setPdfRenderer($rendererName, $rendererLibraryPath);
$writer = new PDF(new PhpWord());
$writer->save($file);
$this->assertTrue(file_exists($file));
unlink($file);
}
/**
* Test construct exception
*
* @expectedException \PhpOffice\PhpWord\Exception\Exception
* @expectedExceptionMessage PDF rendering library or library path has not been defined.
*/
public function testConstructException()
{
$writer = new PDF(new PhpWord());
}
}

View File

@ -28,7 +28,7 @@ class BaseTest extends \PHPUnit_Framework_TestCase
}
/**
* covers ::_writeText
* Test write text element
*/
public function testWriteText()
{
@ -49,7 +49,7 @@ class BaseTest extends \PHPUnit_Framework_TestCase
}
/**
* covers ::_writeTextRun
* Test write textrun element
*/
public function testWriteTextRun()
{
@ -74,7 +74,7 @@ class BaseTest extends \PHPUnit_Framework_TestCase
}
/**
* covers ::_writeLink
* Test write link element
*/
public function testWriteLink()
{
@ -97,7 +97,7 @@ class BaseTest extends \PHPUnit_Framework_TestCase
}
/**
* covers ::_writePreserveText
* Test write preserve text element
*/
public function testWritePreserveText()
{
@ -121,7 +121,7 @@ class BaseTest extends \PHPUnit_Framework_TestCase
}
/**
* covers ::_writeTextBreak
* Test write text break
*/
public function testWriteTextBreak()
{
@ -146,30 +146,98 @@ class BaseTest extends \PHPUnit_Framework_TestCase
}
/**
* covers ::_writeParagraphStyle
* covers ::_writeImage
*/
public function testWriteParagraphStyleAlign()
public function testWriteImage()
{
$phpWord = new PhpWord();
$styles = array('align' => 'left', 'width' => 40, 'height' => 40, 'marginTop' => -1, 'marginLeft' => -1);
$wraps = array('inline', 'behind', 'infront', 'square', 'tight');
$section = $phpWord->addSection();
foreach ($wraps as $wrap) {
$styles['wrappingStyle'] = $wrap;
$section->addImage(__DIR__ . "/../../_files/images/earth.jpg", $styles);
}
$section->addText('This is my text', null, array('align' => 'right'));
$archiveFile = realpath(__DIR__ . '/../../_files/documents/reader.docx');
$imageFile = 'word/media/image1.jpeg';
$source = 'zip://' . $archiveFile . '#' . $imageFile;
$section->addImage($source);
$doc = TestHelperDOCX::getDocument($phpWord);
$element = $doc->getElement('/w:document/w:body/w:p/w:pPr/w:jc');
$this->assertEquals('right', $element->getAttribute('w:val'));
// behind
$element = $doc->getElement('/w:document/w:body/w:p[2]/w:r/w:pict/v:shape');
$style = $element->getAttribute('style');
$this->assertRegExp('/z\-index:\-[0-9]*/', $style);
// square
$element = $doc->getElement('/w:document/w:body/w:p[4]/w:r/w:pict/v:shape/w10:wrap');
$this->assertEquals('square', $element->getAttribute('type'));
}
/**
* covers ::_writeWatermark
*/
public function testWriteWatermark()
{
$imageSrc = __DIR__ . "/../../_files/images/earth.jpg";
$phpWord = new PhpWord();
$section = $phpWord->addSection();
$header = $section->addHeader();
$header->addWatermark($imageSrc);
$doc = TestHelperDOCX::getDocument($phpWord);
$element = $doc->getElement("/w:document/w:body/w:sectPr/w:headerReference");
$this->assertStringStartsWith("rId", $element->getAttribute('r:id'));
}
/**
* covers ::_writeTitle
*/
public function testWriteTitle()
{
$phpWord = new PhpWord();
$phpWord->addTitleStyle(1, array('bold' => true), array('spaceAfter' => 240));
$phpWord->addSection()->addTitle('Test', 1);
$doc = TestHelperDOCX::getDocument($phpWord);
$element = "/w:document/w:body/w:p/w:pPr/w:pStyle";
$this->assertEquals('Heading1', $doc->getElementAttribute($element, 'w:val'));
$element = "/w:document/w:body/w:p/w:r/w:fldChar";
$this->assertEquals('end', $doc->getElementAttribute($element, 'w:fldCharType'));
}
/**
* covers ::_writeCheckbox
*/
public function testWriteCheckbox()
{
$rStyle = 'rStyle';
$pStyle = 'pStyle';
$phpWord = new PhpWord();
$phpWord->addFontStyle($rStyle, array('bold' => true));
$phpWord->addParagraphStyle($pStyle, array('hanging' => 120, 'indent' => 120));
$section = $phpWord->addSection();
$section->addCheckbox('Check1', 'Test', $rStyle, $pStyle);
$doc = TestHelperDOCX::getDocument($phpWord);
$element = '/w:document/w:body/w:p/w:r/w:fldChar/w:ffData/w:name';
$this->assertEquals('Check1', $doc->getElementAttribute($element, 'w:val'));
}
/**
* covers ::_writeParagraphStyle
*/
public function testWriteParagraphStylePagination()
public function testWriteParagraphStyle()
{
// Create the doc
$phpWord = new PhpWord();
$section = $phpWord->addSection();
$attributes = array(
'align' => 'right',
'widowControl' => false,
'keepNext' => true,
'keepLines' => true,
@ -184,10 +252,13 @@ class BaseTest extends \PHPUnit_Framework_TestCase
$i = 0;
foreach ($attributes as $key => $value) {
$i++;
$path = "/w:document/w:body/w:p[{$i}]/w:pPr/w:{$key}";
$nodeName = ($key == 'align') ? 'jc' : $key;
$path = "/w:document/w:body/w:p[{$i}]/w:pPr/w:{$nodeName}";
if ($key != 'align') {
$value = $value ? 1 : 0;
}
$element = $doc->getElement($path);
$expected = $value ? 1 : 0;
$this->assertEquals($expected, $element->getAttribute('w:val'));
$this->assertEquals($value, $element->getAttribute('w:val'));
}
}
@ -316,81 +387,4 @@ class BaseTest extends \PHPUnit_Framework_TestCase
$this->assertEquals(5, $element->getAttribute('w:val'));
}
/**
* covers ::_writeImage
*/
public function testWriteImagePosition()
{
$phpWord = new PhpWord();
$section = $phpWord->addSection();
$section->addImage(
__DIR__ . "/../../_files/images/earth.jpg",
array(
'marginTop' => -1,
'marginLeft' => -1,
'wrappingStyle' => 'behind'
)
);
$doc = TestHelperDOCX::getDocument($phpWord);
$element = $doc->getElement('/w:document/w:body/w:p/w:r/w:pict/v:shape');
$style = $element->getAttribute('style');
$this->assertRegExp('/z\-index:\-[0-9]*/', $style);
$this->assertRegExp('/position:absolute;/', $style);
}
/**
* covers ::_writeWatermark
*/
public function testWriteWatermark()
{
$imageSrc = __DIR__ . "/../../_files/images/earth.jpg";
$phpWord = new PhpWord();
$section = $phpWord->addSection();
$header = $section->addHeader();
$header->addWatermark($imageSrc);
$doc = TestHelperDOCX::getDocument($phpWord);
$element = $doc->getElement("/w:document/w:body/w:sectPr/w:headerReference");
$this->assertStringStartsWith("rId", $element->getAttribute('r:id'));
}
/**
* covers ::_writeTitle
*/
public function testWriteTitle()
{
$phpWord = new PhpWord();
$phpWord->addTitleStyle(1, array('bold' => true), array('spaceAfter' => 240));
$phpWord->addSection()->addTitle('Test', 1);
$doc = TestHelperDOCX::getDocument($phpWord);
$element = "/w:document/w:body/w:p/w:pPr/w:pStyle";
$this->assertEquals('Heading1', $doc->getElementAttribute($element, 'w:val'));
$element = "/w:document/w:body/w:p/w:r/w:fldChar";
$this->assertEquals('end', $doc->getElementAttribute($element, 'w:fldCharType'));
}
/**
* covers ::_writeCheckbox
*/
public function testWriteCheckbox()
{
$rStyle = 'rStyle';
$pStyle = 'pStyle';
$phpWord = new PhpWord();
$phpWord->addFontStyle($rStyle, array('bold' => true));
$phpWord->addParagraphStyle($pStyle, array('hanging' => 120, 'indent' => 120));
$section = $phpWord->addSection();
$section->addCheckbox('Check1', 'Test', $rStyle, $pStyle);
$doc = TestHelperDOCX::getDocument($phpWord);
$element = '/w:document/w:body/w:p/w:r/w:fldChar/w:ffData/w:name';
$this->assertEquals('Check1', $doc->getElementAttribute($element, 'w:val'));
}
}

View File

@ -99,12 +99,12 @@ class DocumentTest extends \PHPUnit_Framework_TestCase
$objectSrc = __DIR__ . "/../../_files/documents/sheet.xls";
$phpWord = new PhpWord();
$phpWord->addParagraphStyle('pStyle', array('align' => 'center'));
$phpWord->addFontStyle('fStyle', array('size' => '20'));
$phpWord->addTitleStyle(1, array('color' => '333333', 'bold' => true));
$phpWord->addParagraphStyle('pStyle', array('align' => 'center')); // Style #1
$phpWord->addFontStyle('fStyle', array('size' => '20')); // Style #2
$phpWord->addTitleStyle(1, array('color' => '333333', 'bold' => true)); // Style #3
$fontStyle = new Font('text', array('align' => 'center'));
$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->addTOC($fontStyle);
$section->addTitle('Title 1', 1);
@ -113,7 +113,7 @@ class DocumentTest extends \PHPUnit_Framework_TestCase
// List item
$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
$element = $doc->getElement('/w:document/w:body/w:p[2]/w:r/w:object/o:OLEObject');