Merge branch 'develop' into parse_drawings
This commit is contained in:
commit
de83da2bbf
|
|
@ -0,0 +1,21 @@
|
||||||
|
# build config
|
||||||
|
/.scrutinizer.yml export-ignore
|
||||||
|
/.travis.yml export-ignore
|
||||||
|
/php_cs.dist export-ignore
|
||||||
|
/phpmd.xml.dist export-ignore
|
||||||
|
/phpstan.neon export-ignore
|
||||||
|
|
||||||
|
/composer.lock export-ignore
|
||||||
|
|
||||||
|
# git files
|
||||||
|
/.gitignore export-ignore
|
||||||
|
/.gitattributes export-ignore
|
||||||
|
|
||||||
|
# project directories
|
||||||
|
/build export-ignore
|
||||||
|
/docs export-ignore
|
||||||
|
/samples export-ignore
|
||||||
|
|
||||||
|
# tests
|
||||||
|
/phpunit.xml.dist export-ignore
|
||||||
|
/tests export-ignore
|
||||||
|
|
@ -19,7 +19,7 @@ tools:
|
||||||
config:
|
config:
|
||||||
ruleset: phpmd.xml.dist
|
ruleset: phpmd.xml.dist
|
||||||
external_code_coverage:
|
external_code_coverage:
|
||||||
enabled: true
|
enabled: false
|
||||||
timeout: 1200
|
timeout: 1200
|
||||||
php_cpd: true
|
php_cpd: true
|
||||||
# php_sim: # Temporarily disabled to allow focus on things other than duplicates
|
# php_sim: # Temporarily disabled to allow focus on things other than duplicates
|
||||||
|
|
|
||||||
12
.travis.yml
12
.travis.yml
|
|
@ -37,7 +37,7 @@ before_script:
|
||||||
- composer self-update
|
- composer self-update
|
||||||
- travis_wait composer install --prefer-source
|
- travis_wait composer install --prefer-source
|
||||||
## PHPDocumentor
|
## PHPDocumentor
|
||||||
- mkdir -p build/docs
|
##- mkdir -p build/docs
|
||||||
- mkdir -p build/coverage
|
- mkdir -p build/coverage
|
||||||
|
|
||||||
script:
|
script:
|
||||||
|
|
@ -52,10 +52,8 @@ script:
|
||||||
## PHPLOC
|
## PHPLOC
|
||||||
- if [ -z "$COVERAGE" ]; then ./vendor/bin/phploc src/ ; fi
|
- if [ -z "$COVERAGE" ]; then ./vendor/bin/phploc src/ ; fi
|
||||||
## PHPDocumentor
|
## PHPDocumentor
|
||||||
- if [ -z "$COVERAGE" ]; then ./vendor/bin/phpdoc -q -d ./src -t ./build/docs --ignore "*/src/PhpWord/Shared/*/*" --template="responsive-twig" ; fi
|
##- if [ -z "$COVERAGE" ]; then ./vendor/bin/phpdoc -q -d ./src -t ./build/docs --ignore "*/src/PhpWord/Shared/*/*" --template="responsive-twig" ; fi
|
||||||
|
|
||||||
after_script:
|
after_success:
|
||||||
## PHPDocumentor
|
## Coveralls
|
||||||
- bash .travis_shell_after_success.sh
|
- if [ -n "$COVERAGE" ]; then travis_retry php vendor/bin/php-coveralls -v ; fi
|
||||||
## Scrutinizer
|
|
||||||
- if [ -n "$COVERAGE" ]; then wget https://scrutinizer-ci.com/ocular.phar && php ocular.phar code-coverage:upload --format=php-clover build/logs/clover.xml ; fi
|
|
||||||
|
|
|
||||||
|
|
@ -1,39 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
echo "--DEBUG--"
|
|
||||||
echo "TRAVIS_REPO_SLUG: $TRAVIS_REPO_SLUG"
|
|
||||||
echo "TRAVIS_PHP_VERSION: $TRAVIS_PHP_VERSION"
|
|
||||||
echo "TRAVIS_PULL_REQUEST: $TRAVIS_PULL_REQUEST"
|
|
||||||
|
|
||||||
if [ "$TRAVIS_REPO_SLUG" == "PHPOffice/PHPWord" ] && [ "$TRAVIS_PULL_REQUEST" == "false" ] && [ "$TRAVIS_PHP_VERSION" == "5.6" ]; then
|
|
||||||
|
|
||||||
echo -e "Publishing PHPDoc...\n"
|
|
||||||
|
|
||||||
cp -R build/docs $HOME/docs-latest
|
|
||||||
cp -R build/coverage $HOME/coverage-latest
|
|
||||||
|
|
||||||
cd $HOME
|
|
||||||
git config --global user.email "travis@travis-ci.org"
|
|
||||||
git config --global user.name "travis-ci"
|
|
||||||
git clone --quiet --branch=gh-pages https://${GH_TOKEN}@github.com/PHPOffice/PHPWord gh-pages > /dev/null
|
|
||||||
|
|
||||||
cd gh-pages
|
|
||||||
echo "--DEBUG : Suppression"
|
|
||||||
git rm -rf ./docs/$TRAVIS_BRANCH
|
|
||||||
|
|
||||||
echo "--DEBUG : Dossier"
|
|
||||||
mkdir -p docs/$TRAVIS_BRANCH
|
|
||||||
mkdir -p coverage/$TRAVIS_BRANCH
|
|
||||||
|
|
||||||
echo "--DEBUG : Copie"
|
|
||||||
cp -Rf $HOME/docs-latest/* ./docs/$TRAVIS_BRANCH/
|
|
||||||
cp -Rf $HOME/coverage-latest/* ./coverage/$TRAVIS_BRANCH/
|
|
||||||
|
|
||||||
echo "--DEBUG : Git"
|
|
||||||
git add -f .
|
|
||||||
git commit -m "PHPDocumentor (Travis Build: $TRAVIS_BUILD_NUMBER - Branch: $TRAVIS_BRANCH)"
|
|
||||||
git push -fq origin gh-pages > /dev/null
|
|
||||||
|
|
||||||
echo -e "Published PHPDoc to gh-pages.\n"
|
|
||||||
|
|
||||||
fi
|
|
||||||
10
CHANGELOG.md
10
CHANGELOG.md
|
|
@ -20,6 +20,11 @@ v0.15.0 (?? ??? 2018)
|
||||||
- Added support for Image text wrapping distance @troosan #1310
|
- Added support for Image text wrapping distance @troosan #1310
|
||||||
- Added parsing of CSS line-height and text-indent in HTML reader @troosan #1316
|
- Added parsing of CSS line-height and text-indent in HTML reader @troosan #1316
|
||||||
- Added the ability to enable gridlines and axislabels on charts @FrankMeyer #576
|
- Added the ability to enable gridlines and axislabels on charts @FrankMeyer #576
|
||||||
|
- Add support for table indent (tblInd) @Trainmaster #1343
|
||||||
|
- Added parsing of internal links in HTML reader @lalop #1336
|
||||||
|
- Several improvements to charts @JAEK-S #1332
|
||||||
|
- Add parsing of html image in base64 format @jgpATs2w #1382
|
||||||
|
- Added Support for Indentation & Tabs on RTF Writer. @smaug1985 #1405
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
- Fix reading of docx default style - @troosan #1238
|
- Fix reading of docx default style - @troosan #1238
|
||||||
|
|
@ -33,10 +38,15 @@ v0.15.0 (?? ??? 2018)
|
||||||
- Fix parsing of Heading and Title formating @troosan @gthomas2 #465
|
- Fix parsing of Heading and Title formating @troosan @gthomas2 #465
|
||||||
- Fix Dateformat typo, fix hours casing, add Month-Day-Year formats @ComputerTinker #591
|
- Fix Dateformat typo, fix hours casing, add Month-Day-Year formats @ComputerTinker #591
|
||||||
- Support reading of w:drawing for documents produced by word 2011+ @gthomas2 #464 #1324
|
- Support reading of w:drawing for documents produced by word 2011+ @gthomas2 #464 #1324
|
||||||
|
- Fix missing column width in ODText writer @potofcoffee #413
|
||||||
|
- Disable entity loader before parsing XML to avoid XXE injection @Tom4t0 #1427
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
- Remove zend-stdlib dependency @Trainmaster #1284
|
- Remove zend-stdlib dependency @Trainmaster #1284
|
||||||
|
- The default unit for `\PhpOffice\PhpWord\Style\Image` changed from `px` to `pt`.
|
||||||
|
|
||||||
|
### Miscelaneous
|
||||||
|
- Drop GitHub pages, switch to coveralls for code coverage analysis @czosel #1360
|
||||||
|
|
||||||
v0.14.0 (29 Dec 2017)
|
v0.14.0 (29 Dec 2017)
|
||||||
----------------------
|
----------------------
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
[](https://packagist.org/packages/phpoffice/phpword)
|
[](https://packagist.org/packages/phpoffice/phpword)
|
||||||
[](https://travis-ci.org/PHPOffice/PHPWord)
|
[](https://travis-ci.org/PHPOffice/PHPWord)
|
||||||
[](https://scrutinizer-ci.com/g/PHPOffice/PHPWord/)
|
[](https://scrutinizer-ci.com/g/PHPOffice/PHPWord/)
|
||||||
[](https://scrutinizer-ci.com/g/PHPOffice/PHPWord/)
|
[](https://coveralls.io/github/PHPOffice/PHPWord?branch=develop)
|
||||||
[](https://packagist.org/packages/phpoffice/phpword)
|
[](https://packagist.org/packages/phpoffice/phpword)
|
||||||
[](https://packagist.org/packages/phpoffice/phpword)
|
[](https://packagist.org/packages/phpoffice/phpword)
|
||||||
[](https://gitter.im/PHPOffice/PHPWord)
|
[](https://gitter.im/PHPOffice/PHPWord)
|
||||||
|
|
|
||||||
|
|
@ -64,15 +64,17 @@
|
||||||
"phpoffice/common": "^0.2.9"
|
"phpoffice/common": "^0.2.9"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpunit/phpunit": "^4.8.36 || ^5.0",
|
"ext-zip": "*",
|
||||||
"phpdocumentor/phpdocumentor":"2.*",
|
"ext-gd": "*",
|
||||||
"squizlabs/php_codesniffer": "^2.7",
|
"phpunit/phpunit": "^4.8.36 || ^7.0",
|
||||||
"friendsofphp/php-cs-fixer": "^2.0",
|
"squizlabs/php_codesniffer": "^2.9",
|
||||||
|
"friendsofphp/php-cs-fixer": "^2.2",
|
||||||
"phpmd/phpmd": "2.*",
|
"phpmd/phpmd": "2.*",
|
||||||
"phploc/phploc": "2.* || 3.* || 4.*",
|
"phploc/phploc": "2.* || 3.* || 4.*",
|
||||||
"dompdf/dompdf":"0.8.*",
|
"dompdf/dompdf":"0.8.*",
|
||||||
"tecnickcom/tcpdf": "6.*",
|
"tecnickcom/tcpdf": "6.*",
|
||||||
"mpdf/mpdf": "5.* || 6.* || 7.*"
|
"mpdf/mpdf": "5.7.4 || 6.* || 7.*",
|
||||||
|
"php-coveralls/php-coveralls": "1.1.0 || ^2.0"
|
||||||
},
|
},
|
||||||
"suggest": {
|
"suggest": {
|
||||||
"ext-zip": "Allows writing OOXML and ODF",
|
"ext-zip": "Allows writing OOXML and ODF",
|
||||||
|
|
|
||||||
|
|
@ -242,7 +242,7 @@ To add an image, use the ``addImage`` method to sections, headers, footers, text
|
||||||
|
|
||||||
$section->addImage($src, [$style]);
|
$section->addImage($src, [$style]);
|
||||||
|
|
||||||
- ``$src``. String path to a local image, URL of a remote image or the image data, as a string.
|
- ``$src``. String path to a local image, URL of a remote image or the image data, as a string. Warning: Do not pass user-generated strings here, as that would allow an attacker to read arbitrary files or perform server-side request forgery by passing file paths or URLs instead of image data.
|
||||||
- ``$style``. See :ref:`image-style`.
|
- ``$style``. See :ref:`image-style`.
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
|
|
@ -435,8 +435,8 @@ Available line style attributes:
|
||||||
- ``dash``. Line types: dash, rounddot, squaredot, dashdot, longdash, longdashdot, longdashdotdot.
|
- ``dash``. Line types: dash, rounddot, squaredot, dashdot, longdash, longdashdot, longdashdotdot.
|
||||||
- ``beginArrow``. Start type of arrow: block, open, classic, diamond, oval.
|
- ``beginArrow``. Start type of arrow: block, open, classic, diamond, oval.
|
||||||
- ``endArrow``. End type of arrow: block, open, classic, diamond, oval.
|
- ``endArrow``. End type of arrow: block, open, classic, diamond, oval.
|
||||||
- ``width``. Line-object width in pt.
|
- ``width``. Line-object width in *pt*.
|
||||||
- ``height``. Line-object height in pt.
|
- ``height``. Line-object height in *pt*.
|
||||||
- ``flip``. Flip the line element: true, false.
|
- ``flip``. Flip the line element: true, false.
|
||||||
|
|
||||||
Chart
|
Chart
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,5 @@ Example:
|
||||||
Using samples
|
Using samples
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
After installation, you can browse and use the samples that we've
|
More examples are provided in the ``samples`` directory.
|
||||||
provided, either by command line or using browser. If you can access
|
For an easy access to those samples launch ``php -S localhost:8000`` in the samples directory then browse to http://localhost:8000 to view the samples.
|
||||||
your PHPWord library folder using browser, point your browser to the
|
|
||||||
``samples`` folder, e.g. ``http://localhost/PhpWord/samples/``.
|
|
||||||
|
|
|
||||||
|
|
@ -104,6 +104,7 @@ Available Table style options:
|
||||||
- ``border(Top|Right|Bottom|Left)Color``. Border color, e.g. '9966CC'.
|
- ``border(Top|Right|Bottom|Left)Color``. Border color, e.g. '9966CC'.
|
||||||
- ``border(Top|Right|Bottom|Left)Size``. Border size in *twip*.
|
- ``border(Top|Right|Bottom|Left)Size``. Border size in *twip*.
|
||||||
- ``cellMargin(Top|Right|Bottom|Left)``. Cell margin in *twip*.
|
- ``cellMargin(Top|Right|Bottom|Left)``. Cell margin in *twip*.
|
||||||
|
- ``indent``. Table indent from leading margin. Must be an instance of ``\PhpOffice\PhpWord\ComplexType\TblWidth``.
|
||||||
- ``width``. Table width in percent.
|
- ``width``. Table width in percent.
|
||||||
- ``unit``. The unit to use for the width. One of ``\PhpOffice\PhpWord\SimpleType\TblWidth``. Defaults to *auto*.
|
- ``unit``. The unit to use for the width. One of ``\PhpOffice\PhpWord\SimpleType\TblWidth``. Defaults to *auto*.
|
||||||
- ``layout``. Table layout, either *fixed* or *autofit* See ``\PhpOffice\PhpWord\Style\Table`` for constants.
|
- ``layout``. Table layout, either *fixed* or *autofit* See ``\PhpOffice\PhpWord\Style\Table`` for constants.
|
||||||
|
|
@ -149,10 +150,10 @@ Image
|
||||||
Available Image style options:
|
Available Image style options:
|
||||||
|
|
||||||
- ``alignment``. See ``\PhpOffice\PhpWord\SimpleType\Jc`` class for the details.
|
- ``alignment``. See ``\PhpOffice\PhpWord\SimpleType\Jc`` class for the details.
|
||||||
- ``height``. Height in pixels.
|
- ``height``. Height in *pt*.
|
||||||
- ``marginLeft``. Left margin in inches, can be negative.
|
- ``marginLeft``. Left margin in inches, can be negative.
|
||||||
- ``marginTop``. Top margin in inches, can be negative.
|
- ``marginTop``. Top margin in inches, can be negative.
|
||||||
- ``width``. Width in pixels.
|
- ``width``. Width in *pt*.
|
||||||
- ``wrappingStyle``. Wrapping style, *inline*, *square*, *tight*, *behind*, or *infront*.
|
- ``wrappingStyle``. Wrapping style, *inline*, *square*, *tight*, *behind*, or *infront*.
|
||||||
- ``wrapDistanceTop``. Top text wrapping in pixels.
|
- ``wrapDistanceTop``. Top text wrapping in pixels.
|
||||||
- ``wrapDistanceBottom``. Bottom text wrapping in pixels.
|
- ``wrapDistanceBottom``. Bottom text wrapping in pixels.
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
includes:
|
includes:
|
||||||
- vendor/phpstan/phpstan/conf/config.level1.neon
|
- vendor/phpstan/phpstan/conf/config.level1.neon
|
||||||
parameters:
|
parameters:
|
||||||
memory-limit: 200000
|
memory-limit: 20000000
|
||||||
autoload_directories:
|
autoload_directories:
|
||||||
- tests
|
- tests
|
||||||
autoload_files:
|
autoload_files:
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,7 @@
|
||||||
convertNoticesToExceptions="true"
|
convertNoticesToExceptions="true"
|
||||||
convertWarningsToExceptions="true"
|
convertWarningsToExceptions="true"
|
||||||
processIsolation="false"
|
processIsolation="false"
|
||||||
stopOnFailure="false"
|
stopOnFailure="false">
|
||||||
syntaxCheck="false">
|
|
||||||
<testsuites>
|
<testsuites>
|
||||||
<testsuite name="PhpWord Test Suite">
|
<testsuite name="PhpWord Test Suite">
|
||||||
<directory>./tests/PhpWord</directory>
|
<directory>./tests/PhpWord</directory>
|
||||||
|
|
@ -22,7 +21,7 @@
|
||||||
</whitelist>
|
</whitelist>
|
||||||
</filter>
|
</filter>
|
||||||
<logging>
|
<logging>
|
||||||
<log type="coverage-html" target="./build/coverage" charset="UTF-8" highlight="true" />
|
<log type="coverage-html" target="./build/coverage" />
|
||||||
<log type="coverage-clover" target="./build/logs/clover.xml" />
|
<log type="coverage-clover" target="./build/logs/clover.xml" />
|
||||||
</logging>
|
</logging>
|
||||||
</phpunit>
|
</phpunit>
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
<?php
|
<?php
|
||||||
use PhpOffice\PhpWord\Style\Font;
|
use PhpOffice\PhpWord\Style\Font;
|
||||||
use PhpOffice\PhpWord\Style\Paragraph;
|
|
||||||
|
|
||||||
include_once 'Sample_Header.php';
|
include_once 'Sample_Header.php';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ $templateProcessor->setValue('userPhone#3', '+1 428 889 775');
|
||||||
echo date('H:i:s'), ' Saving the result document...', EOL;
|
echo date('H:i:s'), ' Saving the result document...', EOL;
|
||||||
$templateProcessor->saveAs('results/Sample_07_TemplateCloneRow.docx');
|
$templateProcessor->saveAs('results/Sample_07_TemplateCloneRow.docx');
|
||||||
|
|
||||||
echo getEndingNotes(array('Word2007' => 'docx'));
|
echo getEndingNotes(array('Word2007' => 'docx'), 'results/Sample_07_TemplateCloneRow.docx');
|
||||||
if (!CLI) {
|
if (!CLI) {
|
||||||
include_once 'Sample_Footer.php';
|
include_once 'Sample_Footer.php';
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ $templateProcessor->deleteBlock('DELETEME');
|
||||||
echo date('H:i:s'), ' Saving the result document...', EOL;
|
echo date('H:i:s'), ' Saving the result document...', EOL;
|
||||||
$templateProcessor->saveAs('results/Sample_23_TemplateBlock.docx');
|
$templateProcessor->saveAs('results/Sample_23_TemplateBlock.docx');
|
||||||
|
|
||||||
echo getEndingNotes(array('Word2007' => 'docx'));
|
echo getEndingNotes(array('Word2007' => 'docx'), 'results/Sample_23_TemplateBlock.docx');
|
||||||
if (!CLI) {
|
if (!CLI) {
|
||||||
include_once 'Sample_Footer.php';
|
include_once 'Sample_Footer.php';
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ $html = '<h1>Adding element via HTML</h1>';
|
||||||
$html .= '<p>Some well-formed HTML snippet needs to be used</p>';
|
$html .= '<p>Some well-formed HTML snippet needs to be used</p>';
|
||||||
$html .= '<p>With for example <strong>some<sup>1</sup> <em>inline</em> formatting</strong><sub>1</sub></p>';
|
$html .= '<p>With for example <strong>some<sup>1</sup> <em>inline</em> formatting</strong><sub>1</sub></p>';
|
||||||
|
|
||||||
$html .= '<p>A link to <a href="http://phpword.readthedocs.io/">Read the docs</a></p>';
|
$html .= '<p>A link to <a href="http://phpword.readthedocs.io/" style="text-decoration: underline">Read the docs</a></p>';
|
||||||
|
|
||||||
$html .= '<p lang="he-IL" style="text-align: right; direction: rtl">היי, זה פסקה מימין לשמאל</p>';
|
$html .= '<p lang="he-IL" style="text-align: right; direction: rtl">היי, זה פסקה מימין לשמאל</p>';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,15 +6,20 @@ include_once 'Sample_Header.php';
|
||||||
// New Word document
|
// New Word document
|
||||||
echo date('H:i:s'), ' Create new PhpWord object', EOL;
|
echo date('H:i:s'), ' Create new PhpWord object', EOL;
|
||||||
$phpWord = new \PhpOffice\PhpWord\PhpWord();
|
$phpWord = new \PhpOffice\PhpWord\PhpWord();
|
||||||
|
PhpOffice\PhpWord\Style::addTitleStyle(1, array('size' => 14));
|
||||||
|
|
||||||
// New section
|
// New section
|
||||||
$section = $phpWord->addSection();
|
$section = $phpWord->addSection();
|
||||||
|
$section->addTitle('This page demos fields');
|
||||||
|
|
||||||
// Add Field elements
|
// Add Field elements
|
||||||
// See Element/Field.php for all options
|
// See Element/Field.php for all options
|
||||||
$section->addText('Date field:');
|
$section->addText('Date field:');
|
||||||
$section->addField('DATE', array('dateformat' => 'dddd d MMMM yyyy H:mm:ss'), array('PreserveFormat'));
|
$section->addField('DATE', array('dateformat' => 'dddd d MMMM yyyy H:mm:ss'), array('PreserveFormat'));
|
||||||
|
|
||||||
|
$section->addText('Style Ref field:');
|
||||||
|
$section->addField('STYLEREF', array('StyleIdentifier' => 'Heading 1'));
|
||||||
|
|
||||||
$section->addText('Page field:');
|
$section->addText('Page field:');
|
||||||
$section->addField('PAGE', array('format' => 'Arabic'));
|
$section->addField('PAGE', array('format' => 'Arabic'));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,8 +16,8 @@ $section = $phpWord->addSection();
|
||||||
$section->addTitle('2D charts', 1);
|
$section->addTitle('2D charts', 1);
|
||||||
$section = $phpWord->addSection(array('colsNum' => 2, 'breakType' => 'continuous'));
|
$section = $phpWord->addSection(array('colsNum' => 2, 'breakType' => 'continuous'));
|
||||||
|
|
||||||
$chartTypes = array('pie', 'doughnut', 'bar', 'column', 'line', 'area', 'scatter', 'radar');
|
$chartTypes = array('pie', 'doughnut', 'bar', 'column', 'line', 'area', 'scatter', 'radar', 'stacked_bar', 'percent_stacked_bar', 'stacked_column', 'percent_stacked_column');
|
||||||
$twoSeries = array('bar', 'column', 'line', 'area', 'scatter', 'radar');
|
$twoSeries = array('bar', 'column', 'line', 'area', 'scatter', 'radar', 'stacked_bar', 'percent_stacked_bar', 'stacked_column', 'percent_stacked_column');
|
||||||
$threeSeries = array('bar', 'line');
|
$threeSeries = array('bar', 'line');
|
||||||
$categories = array('A', 'B', 'C', 'D', 'E');
|
$categories = array('A', 'B', 'C', 'D', 'E');
|
||||||
$series1 = array(1, 3, 2, 5, 4);
|
$series1 = array(1, 3, 2, 5, 4);
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,7 @@ function write($phpWord, $filename, $writers)
|
||||||
$result .= EOL;
|
$result .= EOL;
|
||||||
}
|
}
|
||||||
|
|
||||||
$result .= getEndingNotes($writers);
|
$result .= getEndingNotes($writers, $filename);
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
@ -92,10 +92,10 @@ function write($phpWord, $filename, $writers)
|
||||||
* Get ending notes
|
* Get ending notes
|
||||||
*
|
*
|
||||||
* @param array $writers
|
* @param array $writers
|
||||||
*
|
* @param mixed $filename
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
function getEndingNotes($writers)
|
function getEndingNotes($writers, $filename)
|
||||||
{
|
{
|
||||||
$result = '';
|
$result = '';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,5 +11,15 @@
|
||||||
<ul><li>Item 1</li><li>Item 2</li><ul><li>Item 2.1</li><li>Item 2.1</li></ul></ul>
|
<ul><li>Item 1</li><li>Item 2</li><ul><li>Item 2.1</li><li>Item 2.1</li></ul></ul>
|
||||||
<p>Ordered (numbered) list:</p>
|
<p>Ordered (numbered) list:</p>
|
||||||
<ol><li>Item 1</li><li>Item 2</li></ol>
|
<ol><li>Item 1</li><li>Item 2</li></ol>
|
||||||
|
|
||||||
|
<p style="line-height:2">Double height</p>
|
||||||
|
|
||||||
|
<h2>Includes images</h2>
|
||||||
|
<img src="https://phpword.readthedocs.io/en/latest/_images/phpword.png" alt=""/>
|
||||||
|
|
||||||
|
<img src="https://localhost/gev/desarrollo/actividades/pruebas_14/5b064503587f7.jpeg" name="Imagen 12" align="bottom" width="208" height="183" border="0"/>
|
||||||
|
<img src="http://localhost/gev/desarrollo/actividades/pruebas_14/5b064503589db.png" name="Imagen 13" align="bottom" width="143" height="202" border="0"/>
|
||||||
|
<img src="http://localhost/gev/desarrollo/actividades/pruebas_14/5b0645035aac8.jpeg" name="Imagen 14" align="bottom" width="194" height="188" border="0"/>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,59 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is part of PHPWord - A pure PHP library for reading and writing
|
||||||
|
* word processing documents.
|
||||||
|
*
|
||||||
|
* PHPWord is free software distributed under the terms of the GNU Lesser
|
||||||
|
* General Public License version 3 as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please read the LICENSE
|
||||||
|
* file that was distributed with this source code. For the full list of
|
||||||
|
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
|
||||||
|
*
|
||||||
|
* @see https://github.com/PHPOffice/PHPWord
|
||||||
|
* @copyright 2010-2018 PHPWord contributors
|
||||||
|
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace PhpOffice\PhpWord\ComplexType;
|
||||||
|
|
||||||
|
use PhpOffice\PhpWord\SimpleType\TblWidth as TblWidthSimpleType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see http://www.datypic.com/sc/ooxml/t-w_CT_TblWidth.html
|
||||||
|
*/
|
||||||
|
final class TblWidth
|
||||||
|
{
|
||||||
|
/** @var string */
|
||||||
|
private $type;
|
||||||
|
|
||||||
|
/** @var int */
|
||||||
|
private $value;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $value If omitted, then its value shall be assumed to be 0
|
||||||
|
* @param string $type If omitted, then its value shall be assumed to be dxa
|
||||||
|
*/
|
||||||
|
public function __construct($value = 0, $type = TblWidthSimpleType::TWIP)
|
||||||
|
{
|
||||||
|
$this->value = $value;
|
||||||
|
TblWidthSimpleType::validate($type);
|
||||||
|
$this->type = $type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getType()
|
||||||
|
{
|
||||||
|
return $this->type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getValue()
|
||||||
|
{
|
||||||
|
return $this->value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -347,7 +347,7 @@ abstract class AbstractElement
|
||||||
*
|
*
|
||||||
* @param \PhpOffice\PhpWord\Element\AbstractElement $container
|
* @param \PhpOffice\PhpWord\Element\AbstractElement $container
|
||||||
*/
|
*/
|
||||||
public function setParentContainer(AbstractElement $container)
|
public function setParentContainer(self $container)
|
||||||
{
|
{
|
||||||
$this->parentContainer = substr(get_class($container), strrpos(get_class($container), '\\') + 1);
|
$this->parentContainer = substr(get_class($container), strrpos(get_class($container), '\\') + 1);
|
||||||
$this->parent = $container;
|
$this->parent = $container;
|
||||||
|
|
|
||||||
|
|
@ -61,11 +61,12 @@ class Chart extends AbstractElement
|
||||||
* @param array $categories
|
* @param array $categories
|
||||||
* @param array $values
|
* @param array $values
|
||||||
* @param array $style
|
* @param array $style
|
||||||
|
* @param null|mixed $seriesName
|
||||||
*/
|
*/
|
||||||
public function __construct($type, $categories, $values, $style = null)
|
public function __construct($type, $categories, $values, $style = null, $seriesName = null)
|
||||||
{
|
{
|
||||||
$this->setType($type);
|
$this->setType($type);
|
||||||
$this->addSeries($categories, $values);
|
$this->addSeries($categories, $values, $seriesName);
|
||||||
$this->style = $this->setNewStyle(new ChartStyle(), $style, true);
|
$this->style = $this->setNewStyle(new ChartStyle(), $style, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -86,7 +87,7 @@ class Chart extends AbstractElement
|
||||||
*/
|
*/
|
||||||
public function setType($value)
|
public function setType($value)
|
||||||
{
|
{
|
||||||
$enum = array('pie', 'doughnut', 'line', 'bar', 'column', 'area', 'radar', 'scatter');
|
$enum = array('pie', 'doughnut', 'line', 'bar', 'stacked_bar', 'percent_stacked_bar', 'column', 'stacked_column', 'percent_stacked_column', 'area', 'radar', 'scatter');
|
||||||
$this->type = $this->setEnumVal($value, $enum, 'pie');
|
$this->type = $this->setEnumVal($value, $enum, 'pie');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -95,10 +96,15 @@ class Chart extends AbstractElement
|
||||||
*
|
*
|
||||||
* @param array $categories
|
* @param array $categories
|
||||||
* @param array $values
|
* @param array $values
|
||||||
|
* @param null|mixed $name
|
||||||
*/
|
*/
|
||||||
public function addSeries($categories, $values)
|
public function addSeries($categories, $values, $name = null)
|
||||||
{
|
{
|
||||||
$this->series[] = array('categories' => $categories, 'values' => $values);
|
$this->series[] = array(
|
||||||
|
'categories' => $categories,
|
||||||
|
'values' => $values,
|
||||||
|
'name' => $name,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,10 @@ class Field extends AbstractElement
|
||||||
'properties' => array(),
|
'properties' => array(),
|
||||||
'options' => array('PreserveFormat'),
|
'options' => array('PreserveFormat'),
|
||||||
),
|
),
|
||||||
|
'STYLEREF' => array(
|
||||||
|
'properties' => array('StyleIdentifier' => ''),
|
||||||
|
'options' => array('PreserveFormat'),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,7 @@ class OLEObject extends AbstractElement
|
||||||
$this->style = $this->setNewStyle(new ImageStyle(), $style, true);
|
$this->style = $this->setNewStyle(new ImageStyle(), $style, true);
|
||||||
$this->icon = realpath(__DIR__ . "/../resources/{$ext}.png");
|
$this->icon = realpath(__DIR__ . "/../resources/{$ext}.png");
|
||||||
|
|
||||||
return $this;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new InvalidObjectException();
|
throw new InvalidObjectException();
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ class PreserveText extends AbstractElement
|
||||||
/**
|
/**
|
||||||
* Text content
|
* Text content
|
||||||
*
|
*
|
||||||
* @var string
|
* @var string|array
|
||||||
*/
|
*/
|
||||||
private $text;
|
private $text;
|
||||||
|
|
||||||
|
|
@ -64,8 +64,6 @@ class PreserveText extends AbstractElement
|
||||||
if (isset($matches[0])) {
|
if (isset($matches[0])) {
|
||||||
$this->text = $matches;
|
$this->text = $matches;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -91,7 +89,7 @@ class PreserveText extends AbstractElement
|
||||||
/**
|
/**
|
||||||
* Get Text content
|
* Get Text content
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string|array
|
||||||
*/
|
*/
|
||||||
public function getText()
|
public function getText()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -135,7 +135,7 @@ class Table extends AbstractElement
|
||||||
public function countColumns()
|
public function countColumns()
|
||||||
{
|
{
|
||||||
$columnCount = 0;
|
$columnCount = 0;
|
||||||
if (is_array($this->rows)) {
|
|
||||||
$rowCount = count($this->rows);
|
$rowCount = count($this->rows);
|
||||||
for ($i = 0; $i < $rowCount; $i++) {
|
for ($i = 0; $i < $rowCount; $i++) {
|
||||||
/** @var \PhpOffice\PhpWord\Element\Row $row Type hint */
|
/** @var \PhpOffice\PhpWord\Element\Row $row Type hint */
|
||||||
|
|
@ -145,8 +145,30 @@ class Table extends AbstractElement
|
||||||
$columnCount = $cellCount;
|
$columnCount = $cellCount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return $columnCount;
|
return $columnCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The first declared cell width for each column
|
||||||
|
*
|
||||||
|
* @return int[]
|
||||||
|
*/
|
||||||
|
public function findFirstDefinedCellWidths()
|
||||||
|
{
|
||||||
|
$cellWidths = array();
|
||||||
|
|
||||||
|
foreach ($this->rows as $row) {
|
||||||
|
$cells = $row->getCells();
|
||||||
|
if (count($cells) <= count($cellWidths)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$cellWidths = array();
|
||||||
|
foreach ($cells as $cell) {
|
||||||
|
$cellWidths[] = $cell->getWidth();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $cellWidths;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,6 @@ class Title extends AbstractElement
|
||||||
*/
|
*/
|
||||||
public function __construct($text, $depth = 1)
|
public function __construct($text, $depth = 1)
|
||||||
{
|
{
|
||||||
if (isset($text)) {
|
|
||||||
if (is_string($text)) {
|
if (is_string($text)) {
|
||||||
$this->text = CommonText::toUTF8($text);
|
$this->text = CommonText::toUTF8($text);
|
||||||
} elseif ($text instanceof TextRun) {
|
} elseif ($text instanceof TextRun) {
|
||||||
|
|
@ -69,15 +68,12 @@ class Title extends AbstractElement
|
||||||
} else {
|
} else {
|
||||||
throw new \InvalidArgumentException('Invalid text, should be a string or a TextRun');
|
throw new \InvalidArgumentException('Invalid text, should be a string or a TextRun');
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
$this->depth = $depth;
|
$this->depth = $depth;
|
||||||
$styleName = $depth === 0 ? 'Title' : "Heading_{$this->depth}";
|
$styleName = $depth === 0 ? 'Title' : "Heading_{$this->depth}";
|
||||||
if (array_key_exists($styleName, Style::getStyles())) {
|
if (array_key_exists($styleName, Style::getStyles())) {
|
||||||
$this->style = str_replace('_', '', $styleName);
|
$this->style = str_replace('_', '', $styleName);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
namespace PhpOffice\PhpWord\Metadata;
|
namespace PhpOffice\PhpWord\Metadata;
|
||||||
|
|
||||||
use PhpOffice\PhpWord\Shared\Microsoft\PasswordEncoder;
|
use PhpOffice\Common\Microsoft\PasswordEncoder;
|
||||||
use PhpOffice\PhpWord\SimpleType\DocProtect;
|
use PhpOffice\PhpWord\SimpleType\DocProtect;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -113,7 +113,7 @@ class Protection
|
||||||
/**
|
/**
|
||||||
* Set password
|
* Set password
|
||||||
*
|
*
|
||||||
* @param $password
|
* @param string $password
|
||||||
* @return self
|
* @return self
|
||||||
*/
|
*/
|
||||||
public function setPassword($password)
|
public function setPassword($password)
|
||||||
|
|
@ -136,7 +136,7 @@ class Protection
|
||||||
/**
|
/**
|
||||||
* Set count for hash iterations
|
* Set count for hash iterations
|
||||||
*
|
*
|
||||||
* @param $spinCount
|
* @param int $spinCount
|
||||||
* @return self
|
* @return self
|
||||||
*/
|
*/
|
||||||
public function setSpinCount($spinCount)
|
public function setSpinCount($spinCount)
|
||||||
|
|
@ -159,7 +159,7 @@ class Protection
|
||||||
/**
|
/**
|
||||||
* Set algorithm
|
* Set algorithm
|
||||||
*
|
*
|
||||||
* @param $algorithm
|
* @param string $algorithm
|
||||||
* @return self
|
* @return self
|
||||||
*/
|
*/
|
||||||
public function setAlgorithm($algorithm)
|
public function setAlgorithm($algorithm)
|
||||||
|
|
|
||||||
|
|
@ -35,10 +35,10 @@ use PhpOffice\PhpWord\Exception\Exception;
|
||||||
* @method int addChart(Element\Chart $chart)
|
* @method int addChart(Element\Chart $chart)
|
||||||
* @method int addComment(Element\Comment $comment)
|
* @method int addComment(Element\Comment $comment)
|
||||||
*
|
*
|
||||||
* @method Style\Paragraph addParagraphStyle(string $styleName, array $styles)
|
* @method Style\Paragraph addParagraphStyle(string $styleName, mixed $styles)
|
||||||
* @method Style\Font addFontStyle(string $styleName, mixed $fontStyle, mixed $paragraphStyle = null)
|
* @method Style\Font addFontStyle(string $styleName, mixed $fontStyle, mixed $paragraphStyle = null)
|
||||||
* @method Style\Font addLinkStyle(string $styleName, mixed $styles)
|
* @method Style\Font addLinkStyle(string $styleName, mixed $styles)
|
||||||
* @method Style\Font addTitleStyle(int $depth, mixed $fontStyle, mixed $paragraphStyle = null)
|
* @method Style\Font addTitleStyle(mixed $depth, mixed $fontStyle, mixed $paragraphStyle = null)
|
||||||
* @method Style\Table addTableStyle(string $styleName, mixed $styleTable, mixed $styleFirstRow = null)
|
* @method Style\Table addTableStyle(string $styleName, mixed $styleTable, mixed $styleFirstRow = null)
|
||||||
* @method Style\Numbering addNumberingStyle(string $styleName, mixed $styles)
|
* @method Style\Numbering addNumberingStyle(string $styleName, mixed $styles)
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@
|
||||||
namespace PhpOffice\PhpWord\Reader\Word2007;
|
namespace PhpOffice\PhpWord\Reader\Word2007;
|
||||||
|
|
||||||
use PhpOffice\Common\XMLReader;
|
use PhpOffice\Common\XMLReader;
|
||||||
|
use PhpOffice\PhpWord\ComplexType\TblWidth as TblWidthComplexType;
|
||||||
use PhpOffice\PhpWord\Element\AbstractContainer;
|
use PhpOffice\PhpWord\Element\AbstractContainer;
|
||||||
use PhpOffice\PhpWord\Element\TextRun;
|
use PhpOffice\PhpWord\Element\TextRun;
|
||||||
use PhpOffice\PhpWord\Element\TrackChange;
|
use PhpOffice\PhpWord\Element\TrackChange;
|
||||||
|
|
@ -486,6 +487,11 @@ abstract class AbstractPart
|
||||||
if ($tablePositionNode !== null) {
|
if ($tablePositionNode !== null) {
|
||||||
$style['position'] = $this->readTablePosition($xmlReader, $tablePositionNode);
|
$style['position'] = $this->readTablePosition($xmlReader, $tablePositionNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$indentNode = $xmlReader->getElement('w:tblInd', $styleNode);
|
||||||
|
if ($indentNode !== null) {
|
||||||
|
$style['indent'] = $this->readTableIndent($xmlReader, $indentNode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -517,6 +523,24 @@ abstract class AbstractPart
|
||||||
return $this->readStyleDefs($xmlReader, $domNode, $styleDefs);
|
return $this->readStyleDefs($xmlReader, $domNode, $styleDefs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read w:tblInd
|
||||||
|
*
|
||||||
|
* @param \PhpOffice\Common\XMLReader $xmlReader
|
||||||
|
* @param \DOMElement $domNode
|
||||||
|
* @return TblWidthComplexType
|
||||||
|
*/
|
||||||
|
private function readTableIndent(XMLReader $xmlReader, \DOMElement $domNode)
|
||||||
|
{
|
||||||
|
$styleDefs = array(
|
||||||
|
'value' => array(self::READ_VALUE, '.', 'w:w'),
|
||||||
|
'type' => array(self::READ_VALUE, '.', 'w:type'),
|
||||||
|
);
|
||||||
|
$styleDefs = $this->readStyleDefs($xmlReader, $domNode, $styleDefs);
|
||||||
|
|
||||||
|
return new TblWidthComplexType((int) $styleDefs['value'], $styleDefs['type']);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read w:tcPr
|
* Read w:tcPr
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,7 @@ class Settings extends AbstractPart
|
||||||
*
|
*
|
||||||
* @param XMLReader $xmlReader
|
* @param XMLReader $xmlReader
|
||||||
* @param PhpWord $phpWord
|
* @param PhpWord $phpWord
|
||||||
* @param \DOMNode $node
|
* @param \DOMElement $node
|
||||||
*/
|
*/
|
||||||
protected function setThemeFontLang(XMLReader $xmlReader, PhpWord $phpWord, \DOMElement $node)
|
protected function setThemeFontLang(XMLReader $xmlReader, PhpWord $phpWord, \DOMElement $node)
|
||||||
{
|
{
|
||||||
|
|
@ -102,22 +102,24 @@ class Settings extends AbstractPart
|
||||||
*
|
*
|
||||||
* @param XMLReader $xmlReader
|
* @param XMLReader $xmlReader
|
||||||
* @param PhpWord $phpWord
|
* @param PhpWord $phpWord
|
||||||
* @param \DOMNode $node
|
* @param \DOMElement $node
|
||||||
*/
|
*/
|
||||||
protected function setDocumentProtection(XMLReader $xmlReader, PhpWord $phpWord, \DOMElement $node)
|
protected function setDocumentProtection(XMLReader $xmlReader, PhpWord $phpWord, \DOMElement $node)
|
||||||
{
|
{
|
||||||
$documentProtection = $phpWord->getSettings()->getDocumentProtection();
|
$documentProtection = $phpWord->getSettings()->getDocumentProtection();
|
||||||
|
|
||||||
$edit = $xmlReader->getAttribute('w:edit', $node);
|
$edit = $xmlReader->getAttribute('w:edit', $node);
|
||||||
|
if ($edit !== null) {
|
||||||
$documentProtection->setEditing($edit);
|
$documentProtection->setEditing($edit);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the proof state
|
* Sets the proof state
|
||||||
*
|
*
|
||||||
* @param XMLReader $xmlReader
|
* @param XMLReader $xmlReader
|
||||||
* @param PhpWord $phpWord
|
* @param PhpWord $phpWord
|
||||||
* @param \DOMNode $node
|
* @param \DOMElement $node
|
||||||
*/
|
*/
|
||||||
protected function setProofState(XMLReader $xmlReader, PhpWord $phpWord, \DOMElement $node)
|
protected function setProofState(XMLReader $xmlReader, PhpWord $phpWord, \DOMElement $node)
|
||||||
{
|
{
|
||||||
|
|
@ -139,7 +141,7 @@ class Settings extends AbstractPart
|
||||||
*
|
*
|
||||||
* @param XMLReader $xmlReader
|
* @param XMLReader $xmlReader
|
||||||
* @param PhpWord $phpWord
|
* @param PhpWord $phpWord
|
||||||
* @param \DOMNode $node
|
* @param \DOMElement $node
|
||||||
*/
|
*/
|
||||||
protected function setZoom(XMLReader $xmlReader, PhpWord $phpWord, \DOMElement $node)
|
protected function setZoom(XMLReader $xmlReader, PhpWord $phpWord, \DOMElement $node)
|
||||||
{
|
{
|
||||||
|
|
@ -156,7 +158,7 @@ class Settings extends AbstractPart
|
||||||
*
|
*
|
||||||
* @param XMLReader $xmlReader
|
* @param XMLReader $xmlReader
|
||||||
* @param PhpWord $phpWord
|
* @param PhpWord $phpWord
|
||||||
* @param \DOMNode $node
|
* @param \DOMElement $node
|
||||||
*/
|
*/
|
||||||
protected function setRevisionView(XMLReader $xmlReader, PhpWord $phpWord, \DOMElement $node)
|
protected function setRevisionView(XMLReader $xmlReader, PhpWord $phpWord, \DOMElement $node)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ namespace PhpOffice\PhpWord\Shared;
|
||||||
use PhpOffice\PhpWord\Element\AbstractContainer;
|
use PhpOffice\PhpWord\Element\AbstractContainer;
|
||||||
use PhpOffice\PhpWord\Element\Row;
|
use PhpOffice\PhpWord\Element\Row;
|
||||||
use PhpOffice\PhpWord\Element\Table;
|
use PhpOffice\PhpWord\Element\Table;
|
||||||
|
use PhpOffice\PhpWord\Settings;
|
||||||
use PhpOffice\PhpWord\SimpleType\Jc;
|
use PhpOffice\PhpWord\SimpleType\Jc;
|
||||||
use PhpOffice\PhpWord\SimpleType\NumberFormat;
|
use PhpOffice\PhpWord\SimpleType\NumberFormat;
|
||||||
|
|
||||||
|
|
@ -32,23 +33,30 @@ class Html
|
||||||
{
|
{
|
||||||
private static $listIndex = 0;
|
private static $listIndex = 0;
|
||||||
private static $xpath;
|
private static $xpath;
|
||||||
|
private static $options;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add HTML parts.
|
* Add HTML parts.
|
||||||
*
|
*
|
||||||
* Note: $stylesheet parameter is removed to avoid PHPMD error for unused parameter
|
* Note: $stylesheet parameter is removed to avoid PHPMD error for unused parameter
|
||||||
|
* Warning: Do not pass user-generated HTML here, as that would allow an attacker to read arbitrary
|
||||||
|
* files or perform server-side request forgery by passing local file paths or URLs in <img>.
|
||||||
*
|
*
|
||||||
* @param \PhpOffice\PhpWord\Element\AbstractContainer $element Where the parts need to be added
|
* @param \PhpOffice\PhpWord\Element\AbstractContainer $element Where the parts need to be added
|
||||||
* @param string $html The code to parse
|
* @param string $html The code to parse
|
||||||
* @param bool $fullHTML If it's a full HTML, no need to add 'body' tag
|
* @param bool $fullHTML If it's a full HTML, no need to add 'body' tag
|
||||||
* @param bool $preserveWhiteSpace If false, the whitespaces between nodes will be removed
|
* @param bool $preserveWhiteSpace If false, the whitespaces between nodes will be removed
|
||||||
|
* @param array $options:
|
||||||
|
* + IMG_SRC_SEARCH: optional to speed up images loading from remote url when files can be found locally
|
||||||
|
* + IMG_SRC_REPLACE: optional to speed up images loading from remote url when files can be found locally
|
||||||
*/
|
*/
|
||||||
public static function addHtml($element, $html, $fullHTML = false, $preserveWhiteSpace = true)
|
public static function addHtml($element, $html, $fullHTML = false, $preserveWhiteSpace = true, $options = null)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* @todo parse $stylesheet for default styles. Should result in an array based on id, class and element,
|
* @todo parse $stylesheet for default styles. Should result in an array based on id, class and element,
|
||||||
* which could be applied when such an element occurs in the parseNode function.
|
* which could be applied when such an element occurs in the parseNode function.
|
||||||
*/
|
*/
|
||||||
|
self::$options = $options;
|
||||||
|
|
||||||
// Preprocess: remove all line ends, decode HTML entity,
|
// Preprocess: remove all line ends, decode HTML entity,
|
||||||
// fix ampersand and angle brackets and add body tag for HTML fragments
|
// fix ampersand and angle brackets and add body tag for HTML fragments
|
||||||
|
|
@ -63,10 +71,11 @@ class Html
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load DOM
|
// Load DOM
|
||||||
|
libxml_disable_entity_loader(true);
|
||||||
$dom = new \DOMDocument();
|
$dom = new \DOMDocument();
|
||||||
$dom->preserveWhiteSpace = $preserveWhiteSpace;
|
$dom->preserveWhiteSpace = $preserveWhiteSpace;
|
||||||
$dom->loadXML($html);
|
$dom->loadXML($html);
|
||||||
self::$xpath = new \DOMXpath($dom);
|
self::$xpath = new \DOMXPath($dom);
|
||||||
$node = $dom->getElementsByTagName('body');
|
$node = $dom->getElementsByTagName('body');
|
||||||
|
|
||||||
self::parseNode($node->item(0), $element);
|
self::parseNode($node->item(0), $element);
|
||||||
|
|
@ -139,6 +148,7 @@ class Html
|
||||||
'sup' => array('Property', null, null, $styles, null, 'superScript', true),
|
'sup' => array('Property', null, null, $styles, null, 'superScript', true),
|
||||||
'sub' => array('Property', null, null, $styles, null, 'subScript', true),
|
'sub' => array('Property', null, null, $styles, null, 'subScript', true),
|
||||||
'span' => array('Span', $node, null, $styles, null, null, null),
|
'span' => array('Span', $node, null, $styles, null, null, null),
|
||||||
|
'font' => array('Span', $node, null, $styles, null, null, null),
|
||||||
'table' => array('Table', $node, $element, $styles, null, null, null),
|
'table' => array('Table', $node, $element, $styles, null, null, null),
|
||||||
'tr' => array('Row', $node, $element, $styles, null, null, null),
|
'tr' => array('Row', $node, $element, $styles, null, null, null),
|
||||||
'td' => array('Cell', $node, $element, $styles, null, null, null),
|
'td' => array('Cell', $node, $element, $styles, null, null, null),
|
||||||
|
|
@ -646,7 +656,52 @@ class Html
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
$originSrc = $src;
|
||||||
|
if (strpos($src, 'data:image') !== false) {
|
||||||
|
$tmpDir = Settings::getTempDir() . '/';
|
||||||
|
|
||||||
|
$match = array();
|
||||||
|
preg_match('/data:image\/(\w+);base64,(.+)/', $src, $match);
|
||||||
|
|
||||||
|
$src = $imgFile = $tmpDir . uniqid() . '.' . $match[1];
|
||||||
|
|
||||||
|
$ifp = fopen($imgFile, 'wb');
|
||||||
|
|
||||||
|
if ($ifp !== false) {
|
||||||
|
fwrite($ifp, base64_decode($match[2]));
|
||||||
|
fclose($ifp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$src = urldecode($src);
|
||||||
|
|
||||||
|
if (!is_file($src)
|
||||||
|
&& !is_null(self::$options)
|
||||||
|
&& isset(self::$options['IMG_SRC_SEARCH'])
|
||||||
|
&& isset(self::$options['IMG_SRC_REPLACE'])) {
|
||||||
|
$src = str_replace(self::$options['IMG_SRC_SEARCH'], self::$options['IMG_SRC_REPLACE'], $src);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_file($src)) {
|
||||||
|
if ($imgBlob = @file_get_contents($src)) {
|
||||||
|
$tmpDir = Settings::getTempDir() . '/';
|
||||||
|
$match = array();
|
||||||
|
preg_match('/.+\.(\w+)$/', $src, $match);
|
||||||
|
$src = $tmpDir . uniqid() . '.' . $match[1];
|
||||||
|
|
||||||
|
$ifp = fopen($src, 'wb');
|
||||||
|
|
||||||
|
if ($ifp !== false) {
|
||||||
|
fwrite($ifp, $imgBlob);
|
||||||
|
fclose($ifp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_file($src)) {
|
||||||
$newElement = $element->addImage($src, $style);
|
$newElement = $element->addImage($src, $style);
|
||||||
|
} else {
|
||||||
|
throw new \Exception("Could not load image $originSrc");
|
||||||
|
}
|
||||||
|
|
||||||
return $newElement;
|
return $newElement;
|
||||||
}
|
}
|
||||||
|
|
@ -719,7 +774,11 @@ class Html
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self::parseInlineStyle($node, $styles['font']);
|
$styles['font'] = self::parseInlineStyle($node, $styles['font']);
|
||||||
|
|
||||||
|
if (strpos($target, '#') === 0) {
|
||||||
|
return $element->addLink(substr($target, 1), $node->textContent, $styles['font'], $styles['paragraph'], true);
|
||||||
|
}
|
||||||
|
|
||||||
return $element->addLink($target, $node->textContent, $styles['font'], $styles['paragraph']);
|
return $element->addLink($target, $node->textContent, $styles['font'], $styles['paragraph']);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,235 +0,0 @@
|
||||||
<?php
|
|
||||||
/**
|
|
||||||
* This file is part of PHPWord - A pure PHP library for reading and writing
|
|
||||||
* word processing documents.
|
|
||||||
*
|
|
||||||
* PHPWord is free software distributed under the terms of the GNU Lesser
|
|
||||||
* General Public License version 3 as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* For the full copyright and license information, please read the LICENSE
|
|
||||||
* file that was distributed with this source code. For the full list of
|
|
||||||
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
|
|
||||||
*
|
|
||||||
* @see https://github.com/PHPOffice/PHPWord
|
|
||||||
* @copyright 2010-2018 PHPWord contributors
|
|
||||||
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace PhpOffice\PhpWord\Shared\Microsoft;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Password encoder for microsoft office applications
|
|
||||||
*/
|
|
||||||
class PasswordEncoder
|
|
||||||
{
|
|
||||||
const ALGORITHM_MD2 = 'MD2';
|
|
||||||
const ALGORITHM_MD4 = 'MD4';
|
|
||||||
const ALGORITHM_MD5 = 'MD5';
|
|
||||||
const ALGORITHM_SHA_1 = 'SHA-1';
|
|
||||||
const ALGORITHM_SHA_256 = 'SHA-256';
|
|
||||||
const ALGORITHM_SHA_384 = 'SHA-384';
|
|
||||||
const ALGORITHM_SHA_512 = 'SHA-512';
|
|
||||||
const ALGORITHM_RIPEMD = 'RIPEMD';
|
|
||||||
const ALGORITHM_RIPEMD_160 = 'RIPEMD-160';
|
|
||||||
const ALGORITHM_MAC = 'MAC';
|
|
||||||
const ALGORITHM_HMAC = 'HMAC';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Mapping between algorithm name and algorithm ID
|
|
||||||
*
|
|
||||||
* @var array
|
|
||||||
* @see https://msdn.microsoft.com/en-us/library/documentformat.openxml.wordprocessing.writeprotection.cryptographicalgorithmsid(v=office.14).aspx
|
|
||||||
*/
|
|
||||||
private static $algorithmMapping = array(
|
|
||||||
self::ALGORITHM_MD2 => array(1, 'md2'),
|
|
||||||
self::ALGORITHM_MD4 => array(2, 'md4'),
|
|
||||||
self::ALGORITHM_MD5 => array(3, 'md5'),
|
|
||||||
self::ALGORITHM_SHA_1 => array(4, 'sha1'),
|
|
||||||
self::ALGORITHM_MAC => array(5, ''), // 'mac' -> not possible with hash()
|
|
||||||
self::ALGORITHM_RIPEMD => array(6, 'ripemd'),
|
|
||||||
self::ALGORITHM_RIPEMD_160 => array(7, 'ripemd160'),
|
|
||||||
self::ALGORITHM_HMAC => array(9, ''), //'hmac' -> not possible with hash()
|
|
||||||
self::ALGORITHM_SHA_256 => array(12, 'sha256'),
|
|
||||||
self::ALGORITHM_SHA_384 => array(13, 'sha384'),
|
|
||||||
self::ALGORITHM_SHA_512 => array(14, 'sha512'),
|
|
||||||
);
|
|
||||||
|
|
||||||
private static $initialCodeArray = array(
|
|
||||||
0xE1F0,
|
|
||||||
0x1D0F,
|
|
||||||
0xCC9C,
|
|
||||||
0x84C0,
|
|
||||||
0x110C,
|
|
||||||
0x0E10,
|
|
||||||
0xF1CE,
|
|
||||||
0x313E,
|
|
||||||
0x1872,
|
|
||||||
0xE139,
|
|
||||||
0xD40F,
|
|
||||||
0x84F9,
|
|
||||||
0x280C,
|
|
||||||
0xA96A,
|
|
||||||
0x4EC3,
|
|
||||||
);
|
|
||||||
|
|
||||||
private static $encryptionMatrix = array(
|
|
||||||
array(0xAEFC, 0x4DD9, 0x9BB2, 0x2745, 0x4E8A, 0x9D14, 0x2A09),
|
|
||||||
array(0x7B61, 0xF6C2, 0xFDA5, 0xEB6B, 0xC6F7, 0x9DCF, 0x2BBF),
|
|
||||||
array(0x4563, 0x8AC6, 0x05AD, 0x0B5A, 0x16B4, 0x2D68, 0x5AD0),
|
|
||||||
array(0x0375, 0x06EA, 0x0DD4, 0x1BA8, 0x3750, 0x6EA0, 0xDD40),
|
|
||||||
array(0xD849, 0xA0B3, 0x5147, 0xA28E, 0x553D, 0xAA7A, 0x44D5),
|
|
||||||
array(0x6F45, 0xDE8A, 0xAD35, 0x4A4B, 0x9496, 0x390D, 0x721A),
|
|
||||||
array(0xEB23, 0xC667, 0x9CEF, 0x29FF, 0x53FE, 0xA7FC, 0x5FD9),
|
|
||||||
array(0x47D3, 0x8FA6, 0x0F6D, 0x1EDA, 0x3DB4, 0x7B68, 0xF6D0),
|
|
||||||
array(0xB861, 0x60E3, 0xC1C6, 0x93AD, 0x377B, 0x6EF6, 0xDDEC),
|
|
||||||
array(0x45A0, 0x8B40, 0x06A1, 0x0D42, 0x1A84, 0x3508, 0x6A10),
|
|
||||||
array(0xAA51, 0x4483, 0x8906, 0x022D, 0x045A, 0x08B4, 0x1168),
|
|
||||||
array(0x76B4, 0xED68, 0xCAF1, 0x85C3, 0x1BA7, 0x374E, 0x6E9C),
|
|
||||||
array(0x3730, 0x6E60, 0xDCC0, 0xA9A1, 0x4363, 0x86C6, 0x1DAD),
|
|
||||||
array(0x3331, 0x6662, 0xCCC4, 0x89A9, 0x0373, 0x06E6, 0x0DCC),
|
|
||||||
array(0x1021, 0x2042, 0x4084, 0x8108, 0x1231, 0x2462, 0x48C4),
|
|
||||||
);
|
|
||||||
|
|
||||||
private static $passwordMaxLength = 15;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a hashed password that MS Word will be able to work with
|
|
||||||
* @see https://blogs.msdn.microsoft.com/vsod/2010/04/05/how-to-set-the-editing-restrictions-in-word-using-open-xml-sdk-2-0/
|
|
||||||
*
|
|
||||||
* @param string $password
|
|
||||||
* @param string $algorithmName
|
|
||||||
* @param string $salt
|
|
||||||
* @param int $spinCount
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public static function hashPassword($password, $algorithmName = self::ALGORITHM_SHA_1, $salt = null, $spinCount = 10000)
|
|
||||||
{
|
|
||||||
$origEncoding = mb_internal_encoding();
|
|
||||||
mb_internal_encoding('UTF-8');
|
|
||||||
|
|
||||||
$password = mb_substr($password, 0, min(self::$passwordMaxLength, mb_strlen($password)));
|
|
||||||
|
|
||||||
// Get the single-byte values by iterating through the Unicode characters of the truncated password.
|
|
||||||
// For each character, if the low byte is not equal to 0, take it. Otherwise, take the high byte.
|
|
||||||
$passUtf8 = mb_convert_encoding($password, 'UCS-2LE', 'UTF-8');
|
|
||||||
$byteChars = array();
|
|
||||||
|
|
||||||
for ($i = 0; $i < mb_strlen($password); $i++) {
|
|
||||||
$byteChars[$i] = ord(substr($passUtf8, $i * 2, 1));
|
|
||||||
|
|
||||||
if ($byteChars[$i] == 0) {
|
|
||||||
$byteChars[$i] = ord(substr($passUtf8, $i * 2 + 1, 1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// build low-order word and hig-order word and combine them
|
|
||||||
$combinedKey = self::buildCombinedKey($byteChars);
|
|
||||||
// build reversed hexadecimal string
|
|
||||||
$hex = str_pad(strtoupper(dechex($combinedKey & 0xFFFFFFFF)), 8, '0', \STR_PAD_LEFT);
|
|
||||||
$reversedHex = $hex[6] . $hex[7] . $hex[4] . $hex[5] . $hex[2] . $hex[3] . $hex[0] . $hex[1];
|
|
||||||
|
|
||||||
$generatedKey = mb_convert_encoding($reversedHex, 'UCS-2LE', 'UTF-8');
|
|
||||||
|
|
||||||
// Implementation Notes List:
|
|
||||||
// Word requires that the initial hash of the password with the salt not be considered in the count.
|
|
||||||
// The initial hash of salt + key is not included in the iteration count.
|
|
||||||
$algorithm = self::getAlgorithm($algorithmName);
|
|
||||||
$generatedKey = hash($algorithm, $salt . $generatedKey, true);
|
|
||||||
|
|
||||||
for ($i = 0; $i < $spinCount; $i++) {
|
|
||||||
$generatedKey = hash($algorithm, $generatedKey . pack('CCCC', $i, $i >> 8, $i >> 16, $i >> 24), true);
|
|
||||||
}
|
|
||||||
$generatedKey = base64_encode($generatedKey);
|
|
||||||
|
|
||||||
mb_internal_encoding($origEncoding);
|
|
||||||
|
|
||||||
return $generatedKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get algorithm from self::$algorithmMapping
|
|
||||||
*
|
|
||||||
* @param string $algorithmName
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
private static function getAlgorithm($algorithmName)
|
|
||||||
{
|
|
||||||
$algorithm = self::$algorithmMapping[$algorithmName][1];
|
|
||||||
if ($algorithm == '') {
|
|
||||||
$algorithm = 'sha1';
|
|
||||||
}
|
|
||||||
|
|
||||||
return $algorithm;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the algorithm ID
|
|
||||||
*
|
|
||||||
* @param string $algorithmName
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public static function getAlgorithmId($algorithmName)
|
|
||||||
{
|
|
||||||
return self::$algorithmMapping[$algorithmName][0];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Build combined key from low-order word and high-order word
|
|
||||||
*
|
|
||||||
* @param array $byteChars byte array representation of password
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
private static function buildCombinedKey($byteChars)
|
|
||||||
{
|
|
||||||
$byteCharsLength = count($byteChars);
|
|
||||||
// Compute the high-order word
|
|
||||||
// Initialize from the initial code array (see above), depending on the passwords length.
|
|
||||||
$highOrderWord = self::$initialCodeArray[$byteCharsLength - 1];
|
|
||||||
|
|
||||||
// For each character in the password:
|
|
||||||
// For every bit in the character, starting with the least significant and progressing to (but excluding)
|
|
||||||
// the most significant, if the bit is set, XOR the key’s high-order word with the corresponding word from
|
|
||||||
// the Encryption Matrix
|
|
||||||
for ($i = 0; $i < $byteCharsLength; $i++) {
|
|
||||||
$tmp = self::$passwordMaxLength - $byteCharsLength + $i;
|
|
||||||
$matrixRow = self::$encryptionMatrix[$tmp];
|
|
||||||
for ($intBit = 0; $intBit < 7; $intBit++) {
|
|
||||||
if (($byteChars[$i] & (0x0001 << $intBit)) != 0) {
|
|
||||||
$highOrderWord = ($highOrderWord ^ $matrixRow[$intBit]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compute low-order word
|
|
||||||
// Initialize with 0
|
|
||||||
$lowOrderWord = 0;
|
|
||||||
// For each character in the password, going backwards
|
|
||||||
for ($i = $byteCharsLength - 1; $i >= 0; $i--) {
|
|
||||||
// low-order word = (((low-order word SHR 14) AND 0x0001) OR (low-order word SHL 1) AND 0x7FFF)) XOR character
|
|
||||||
$lowOrderWord = (((($lowOrderWord >> 14) & 0x0001) | (($lowOrderWord << 1) & 0x7FFF)) ^ $byteChars[$i]);
|
|
||||||
}
|
|
||||||
// Lastly, low-order word = (((low-order word SHR 14) AND 0x0001) OR (low-order word SHL 1) AND 0x7FFF)) XOR strPassword length XOR 0xCE4B.
|
|
||||||
$lowOrderWord = (((($lowOrderWord >> 14) & 0x0001) | (($lowOrderWord << 1) & 0x7FFF)) ^ $byteCharsLength ^ 0xCE4B);
|
|
||||||
|
|
||||||
// Combine the Low and High Order Word
|
|
||||||
return self::int32(($highOrderWord << 16) + $lowOrderWord);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Simulate behaviour of (signed) int32
|
|
||||||
*
|
|
||||||
* @codeCoverageIgnore
|
|
||||||
* @param int $value
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
private static function int32($value)
|
|
||||||
{
|
|
||||||
$value = ($value & 0xFFFFFFFF);
|
|
||||||
|
|
||||||
if ($value & 0x80000000) {
|
|
||||||
$value = -((~$value & 0xFFFFFFFF) + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -39,7 +39,7 @@ class Style
|
||||||
* Add paragraph style
|
* Add paragraph style
|
||||||
*
|
*
|
||||||
* @param string $styleName
|
* @param string $styleName
|
||||||
* @param array $styles
|
* @param array|\PhpOffice\PhpWord\Style\AbstractStyle $styles
|
||||||
* @return \PhpOffice\PhpWord\Style\Paragraph
|
* @return \PhpOffice\PhpWord\Style\Paragraph
|
||||||
*/
|
*/
|
||||||
public static function addParagraphStyle($styleName, $styles)
|
public static function addParagraphStyle($styleName, $styles)
|
||||||
|
|
@ -51,8 +51,8 @@ class Style
|
||||||
* Add font style
|
* Add font style
|
||||||
*
|
*
|
||||||
* @param string $styleName
|
* @param string $styleName
|
||||||
* @param array $fontStyle
|
* @param array|\PhpOffice\PhpWord\Style\AbstractStyle $fontStyle
|
||||||
* @param array $paragraphStyle
|
* @param array|\PhpOffice\PhpWord\Style\AbstractStyle $paragraphStyle
|
||||||
* @return \PhpOffice\PhpWord\Style\Font
|
* @return \PhpOffice\PhpWord\Style\Font
|
||||||
*/
|
*/
|
||||||
public static function addFontStyle($styleName, $fontStyle, $paragraphStyle = null)
|
public static function addFontStyle($styleName, $fontStyle, $paragraphStyle = null)
|
||||||
|
|
@ -64,7 +64,7 @@ class Style
|
||||||
* Add link style
|
* Add link style
|
||||||
*
|
*
|
||||||
* @param string $styleName
|
* @param string $styleName
|
||||||
* @param array $styles
|
* @param array|\PhpOffice\PhpWord\Style\AbstractStyle $styles
|
||||||
* @return \PhpOffice\PhpWord\Style\Font
|
* @return \PhpOffice\PhpWord\Style\Font
|
||||||
*/
|
*/
|
||||||
public static function addLinkStyle($styleName, $styles)
|
public static function addLinkStyle($styleName, $styles)
|
||||||
|
|
@ -76,7 +76,7 @@ class Style
|
||||||
* Add numbering style
|
* Add numbering style
|
||||||
*
|
*
|
||||||
* @param string $styleName
|
* @param string $styleName
|
||||||
* @param array $styleValues
|
* @param array|\PhpOffice\PhpWord\Style\AbstractStyle $styleValues
|
||||||
* @return \PhpOffice\PhpWord\Style\Numbering
|
* @return \PhpOffice\PhpWord\Style\Numbering
|
||||||
* @since 0.10.0
|
* @since 0.10.0
|
||||||
*/
|
*/
|
||||||
|
|
@ -88,14 +88,14 @@ class Style
|
||||||
/**
|
/**
|
||||||
* Add title style
|
* Add title style
|
||||||
*
|
*
|
||||||
* @param int $depth
|
* @param int|null $depth Provide null to set title font
|
||||||
* @param array $fontStyle
|
* @param array|\PhpOffice\PhpWord\Style\AbstractStyle $fontStyle
|
||||||
* @param array $paragraphStyle
|
* @param array|\PhpOffice\PhpWord\Style\AbstractStyle $paragraphStyle
|
||||||
* @return \PhpOffice\PhpWord\Style\Font
|
* @return \PhpOffice\PhpWord\Style\Font
|
||||||
*/
|
*/
|
||||||
public static function addTitleStyle($depth, $fontStyle, $paragraphStyle = null)
|
public static function addTitleStyle($depth, $fontStyle, $paragraphStyle = null)
|
||||||
{
|
{
|
||||||
if ($depth == null) {
|
if (empty($depth)) {
|
||||||
$styleName = 'Title';
|
$styleName = 'Title';
|
||||||
} else {
|
} else {
|
||||||
$styleName = "Heading_{$depth}";
|
$styleName = "Heading_{$depth}";
|
||||||
|
|
@ -141,7 +141,7 @@ class Style
|
||||||
/**
|
/**
|
||||||
* Set default paragraph style
|
* Set default paragraph style
|
||||||
*
|
*
|
||||||
* @param array $styles Paragraph style definition
|
* @param array|\PhpOffice\PhpWord\Style\AbstractStyle $styles Paragraph style definition
|
||||||
* @return \PhpOffice\PhpWord\Style\Paragraph
|
* @return \PhpOffice\PhpWord\Style\Paragraph
|
||||||
*/
|
*/
|
||||||
public static function setDefaultParagraphStyle($styles)
|
public static function setDefaultParagraphStyle($styles)
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,60 @@ class Chart extends AbstractStyle
|
||||||
private $is3d = false;
|
private $is3d = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* A list of colors to use in the chart
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
private $colors = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A list of display options for data labels
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
private $dataLabelOptions = array(
|
||||||
|
'showVal' => true, // value
|
||||||
|
'showCatName' => true, // category name
|
||||||
|
'showLegendKey' => false, //show the cart legend
|
||||||
|
'showSerName' => false, // series name
|
||||||
|
'showPercent' => false,
|
||||||
|
'showLeaderLines' => false,
|
||||||
|
'showBubbleSize' => false,
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A string that tells the writer where to write chart labels or to skip
|
||||||
|
* "nextTo" - sets labels next to the axis (bar graphs on the left) (default)
|
||||||
|
* "low" - labels on the left side of the graph
|
||||||
|
* "high" - labels on the right side of the graph
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $categoryLabelPosition = 'nextTo';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A string that tells the writer where to write chart labels or to skip
|
||||||
|
* "nextTo" - sets labels next to the axis (bar graphs on the bottom) (default)
|
||||||
|
* "low" - labels are below the graph
|
||||||
|
* "high" - labels above the graph
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $valueLabelPosition = 'nextTo';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $categoryAxisTitle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $valueAxisTitle;
|
||||||
|
|
||||||
|
private $majorTickMarkPos = 'none';
|
||||||
|
|
||||||
|
/*
|
||||||
* Show labels for axis
|
* Show labels for axis
|
||||||
*
|
*
|
||||||
* @var bool
|
* @var bool
|
||||||
|
|
@ -146,6 +200,28 @@ class Chart extends AbstractStyle
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Get the list of colors to use in a chart.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getColors()
|
||||||
|
{
|
||||||
|
return $this->colors;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the colors to use in a chart.
|
||||||
|
*
|
||||||
|
* @param array $value a list of colors to use in the chart
|
||||||
|
*/
|
||||||
|
public function setColors($value = array())
|
||||||
|
{
|
||||||
|
$this->colors = $value;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
* Show labels for axis
|
* Show labels for axis
|
||||||
*
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
|
|
@ -169,6 +245,31 @@ class Chart extends AbstractStyle
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* get the list of options for data labels
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getDataLabelOptions()
|
||||||
|
{
|
||||||
|
return $this->dataLabelOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set values for data label options.
|
||||||
|
* This will only change values for options defined in $this->dataLabelOptions, and cannot create new ones.
|
||||||
|
*
|
||||||
|
* @param array $values [description]
|
||||||
|
*/
|
||||||
|
public function setDataLabelOptions($values = array())
|
||||||
|
{
|
||||||
|
foreach (array_keys($this->dataLabelOptions) as $option) {
|
||||||
|
if (isset($values[$option])) {
|
||||||
|
$this->dataLabelOptions[$option] = $this->setBoolVal($values[$option], $this->dataLabelOptions[$option]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
* Show Gridlines for Y-Axis
|
* Show Gridlines for Y-Axis
|
||||||
*
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
|
|
@ -192,6 +293,117 @@ class Chart extends AbstractStyle
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Get the categoryLabelPosition setting
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getCategoryLabelPosition()
|
||||||
|
{
|
||||||
|
return $this->categoryLabelPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the categoryLabelPosition setting
|
||||||
|
* "none" - skips writing labels
|
||||||
|
* "nextTo" - sets labels next to the (bar graphs on the left)
|
||||||
|
* "low" - labels on the left side of the graph
|
||||||
|
* "high" - labels on the right side of the graph
|
||||||
|
*
|
||||||
|
* @param mixed $labelPosition
|
||||||
|
* @return self
|
||||||
|
*/
|
||||||
|
public function setCategoryLabelPosition($labelPosition)
|
||||||
|
{
|
||||||
|
$enum = array('nextTo', 'low', 'high');
|
||||||
|
$this->categoryLabelPosition = $this->setEnumVal($labelPosition, $enum, $this->categoryLabelPosition);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the valueAxisLabelPosition setting
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getValueLabelPosition()
|
||||||
|
{
|
||||||
|
return $this->valueLabelPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the valueLabelPosition setting
|
||||||
|
* "none" - skips writing labels
|
||||||
|
* "nextTo" - sets labels next to the value
|
||||||
|
* "low" - sets labels are below the graph
|
||||||
|
* "high" - sets labels above the graph
|
||||||
|
*
|
||||||
|
* @param string
|
||||||
|
* @param mixed $labelPosition
|
||||||
|
*/
|
||||||
|
public function setValueLabelPosition($labelPosition)
|
||||||
|
{
|
||||||
|
$enum = array('nextTo', 'low', 'high');
|
||||||
|
$this->valueLabelPosition = $this->setEnumVal($labelPosition, $enum, $this->valueLabelPosition);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the categoryAxisTitle
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getCategoryAxisTitle()
|
||||||
|
{
|
||||||
|
return $this->categoryAxisTitle;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the title that appears on the category side of the chart
|
||||||
|
* @param string $axisTitle
|
||||||
|
*/
|
||||||
|
public function setCategoryAxisTitle($axisTitle)
|
||||||
|
{
|
||||||
|
$this->categoryAxisTitle = $axisTitle;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the valueAxisTitle
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getValueAxisTitle()
|
||||||
|
{
|
||||||
|
return $this->valueAxisTitle;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the title that appears on the value side of the chart
|
||||||
|
* @param string $axisTitle
|
||||||
|
*/
|
||||||
|
public function setValueAxisTitle($axisTitle)
|
||||||
|
{
|
||||||
|
$this->valueAxisTitle = $axisTitle;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getMajorTickPosition()
|
||||||
|
{
|
||||||
|
return $this->majorTickMarkPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* set the position for major tick marks
|
||||||
|
* @param string $position [description]
|
||||||
|
*/
|
||||||
|
public function setMajorTickPosition($position)
|
||||||
|
{
|
||||||
|
$enum = array('in', 'out', 'cross', 'none');
|
||||||
|
$this->majorTickMarkPos = $this->setEnumVal($position, $enum, $this->majorTickMarkPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
* Show Gridlines for X-Axis
|
* Show Gridlines for X-Axis
|
||||||
*
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
|
|
|
||||||
|
|
@ -264,7 +264,7 @@ class Font extends AbstractStyle
|
||||||
* Create new font style
|
* Create new font style
|
||||||
*
|
*
|
||||||
* @param string $type Type of font
|
* @param string $type Type of font
|
||||||
* @param array $paragraph Paragraph styles definition
|
* @param array|string|\PhpOffice\PhpWord\Style\AbstractStyle $paragraph Paragraph styles definition
|
||||||
*/
|
*/
|
||||||
public function __construct($type = 'text', $paragraph = null)
|
public function __construct($type = 'text', $paragraph = null)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,9 @@ final class Language extends AbstractStyle
|
||||||
const HE_IL = 'he-IL';
|
const HE_IL = 'he-IL';
|
||||||
const HE_IL_ID = 1037;
|
const HE_IL_ID = 1037;
|
||||||
|
|
||||||
|
const IT_IT = 'it-IT';
|
||||||
|
const IT_IT_ID = 1040;
|
||||||
|
|
||||||
const JA_JP = 'ja-JP';
|
const JA_JP = 'ja-JP';
|
||||||
const JA_JP_ID = 1041;
|
const JA_JP_ID = 1041;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
namespace PhpOffice\PhpWord\Style;
|
namespace PhpOffice\PhpWord\Style;
|
||||||
|
|
||||||
|
use PhpOffice\PhpWord\ComplexType\TblWidth as TblWidthComplexType;
|
||||||
use PhpOffice\PhpWord\SimpleType\Jc;
|
use PhpOffice\PhpWord\SimpleType\Jc;
|
||||||
use PhpOffice\PhpWord\SimpleType\JcTable;
|
use PhpOffice\PhpWord\SimpleType\JcTable;
|
||||||
use PhpOffice\PhpWord\SimpleType\TblWidth;
|
use PhpOffice\PhpWord\SimpleType\TblWidth;
|
||||||
|
|
@ -159,6 +160,16 @@ class Table extends Border
|
||||||
*/
|
*/
|
||||||
private $position;
|
private $position;
|
||||||
|
|
||||||
|
/** @var TblWidthComplexType|null */
|
||||||
|
private $indent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The width of each column, computed based on the max cell width of each column
|
||||||
|
*
|
||||||
|
* @var int[]
|
||||||
|
*/
|
||||||
|
private $columnWidths;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create new table style
|
* Create new table style
|
||||||
*
|
*
|
||||||
|
|
@ -724,4 +735,44 @@ class Table extends Border
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return TblWidthComplexType
|
||||||
|
*/
|
||||||
|
public function getIndent()
|
||||||
|
{
|
||||||
|
return $this->indent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param TblWidthComplexType $indent
|
||||||
|
* @return self
|
||||||
|
* @see http://www.datypic.com/sc/ooxml/e-w_tblInd-1.html
|
||||||
|
*/
|
||||||
|
public function setIndent(TblWidthComplexType $indent)
|
||||||
|
{
|
||||||
|
$this->indent = $indent;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the columnWidths
|
||||||
|
*
|
||||||
|
* @return number[]
|
||||||
|
*/
|
||||||
|
public function getColumnWidths()
|
||||||
|
{
|
||||||
|
return $this->columnWidths;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The column widths
|
||||||
|
*
|
||||||
|
* @param int[] $value
|
||||||
|
*/
|
||||||
|
public function setColumnWidths(array $value = null)
|
||||||
|
{
|
||||||
|
$this->columnWidths = $value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -113,6 +113,7 @@ class TemplateProcessor
|
||||||
*/
|
*/
|
||||||
protected function transformSingleXml($xml, $xsltProcessor)
|
protected function transformSingleXml($xml, $xsltProcessor)
|
||||||
{
|
{
|
||||||
|
libxml_disable_entity_loader(true);
|
||||||
$domDocument = new \DOMDocument();
|
$domDocument = new \DOMDocument();
|
||||||
if (false === $domDocument->loadXML($xml)) {
|
if (false === $domDocument->loadXML($xml)) {
|
||||||
throw new Exception('Could not load the given XML document.');
|
throw new Exception('Could not load the given XML document.');
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,10 @@
|
||||||
|
|
||||||
namespace PhpOffice\PhpWord\Writer\ODText\Element;
|
namespace PhpOffice\PhpWord\Writer\ODText\Element;
|
||||||
|
|
||||||
|
use PhpOffice\Common\XMLWriter;
|
||||||
|
use PhpOffice\PhpWord\Element\Row as RowElement;
|
||||||
|
use PhpOffice\PhpWord\Element\Table as TableElement;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Table element writer
|
* Table element writer
|
||||||
*
|
*
|
||||||
|
|
@ -36,18 +40,48 @@ class Table extends AbstractElement
|
||||||
}
|
}
|
||||||
$rows = $element->getRows();
|
$rows = $element->getRows();
|
||||||
$rowCount = count($rows);
|
$rowCount = count($rows);
|
||||||
$colCount = $element->countColumns();
|
|
||||||
|
|
||||||
if ($rowCount > 0) {
|
if ($rowCount > 0) {
|
||||||
$xmlWriter->startElement('table:table');
|
$xmlWriter->startElement('table:table');
|
||||||
$xmlWriter->writeAttribute('table:name', $element->getElementId());
|
$xmlWriter->writeAttribute('table:name', $element->getElementId());
|
||||||
$xmlWriter->writeAttribute('table:style', $element->getElementId());
|
$xmlWriter->writeAttribute('table:style', $element->getElementId());
|
||||||
|
|
||||||
$xmlWriter->startElement('table:table-column');
|
// Write columns
|
||||||
$xmlWriter->writeAttribute('table:number-columns-repeated', $colCount);
|
$this->writeColumns($xmlWriter, $element);
|
||||||
$xmlWriter->endElement(); // table:table-column
|
|
||||||
|
|
||||||
|
// Write rows
|
||||||
foreach ($rows as $row) {
|
foreach ($rows as $row) {
|
||||||
|
$this->writeRow($xmlWriter, $row);
|
||||||
|
}
|
||||||
|
$xmlWriter->endElement(); // table:table
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write column.
|
||||||
|
*
|
||||||
|
* @param \PhpOffice\Common\XMLWriter $xmlWriter
|
||||||
|
* @param \PhpOffice\PhpWord\Element\Table $element
|
||||||
|
*/
|
||||||
|
private function writeColumns(XMLWriter $xmlWriter, TableElement $element)
|
||||||
|
{
|
||||||
|
$colCount = $element->countColumns();
|
||||||
|
|
||||||
|
for ($i = 0; $i < $colCount; $i++) {
|
||||||
|
$xmlWriter->startElement('table:table-column');
|
||||||
|
$xmlWriter->writeAttribute('table:style-name', $element->getElementId() . '.' . $i);
|
||||||
|
$xmlWriter->endElement();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write row.
|
||||||
|
*
|
||||||
|
* @param \PhpOffice\Common\XMLWriter $xmlWriter
|
||||||
|
* @param \PhpOffice\PhpWord\Element\Row $row
|
||||||
|
*/
|
||||||
|
private function writeRow(XMLWriter $xmlWriter, RowElement $row)
|
||||||
|
{
|
||||||
$xmlWriter->startElement('table:table-row');
|
$xmlWriter->startElement('table:table-row');
|
||||||
/** @var $row \PhpOffice\PhpWord\Element\Row Type hint */
|
/** @var $row \PhpOffice\PhpWord\Element\Row Type hint */
|
||||||
foreach ($row->getCells() as $cell) {
|
foreach ($row->getCells() as $cell) {
|
||||||
|
|
@ -61,7 +95,4 @@ class Table extends AbstractElement
|
||||||
}
|
}
|
||||||
$xmlWriter->endElement(); // table:table-row
|
$xmlWriter->endElement(); // table:table-row
|
||||||
}
|
}
|
||||||
$xmlWriter->endElement(); // table:table
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -239,6 +239,7 @@ class Content extends AbstractPart
|
||||||
$style->setStyleName('fr' . $element->getMediaIndex());
|
$style->setStyleName('fr' . $element->getMediaIndex());
|
||||||
$this->autoStyles['Image'][] = $style;
|
$this->autoStyles['Image'][] = $style;
|
||||||
} elseif ($element instanceof Table) {
|
} elseif ($element instanceof Table) {
|
||||||
|
/** @var \PhpOffice\PhpWord\Style\Table $style */
|
||||||
$style = $element->getStyle();
|
$style = $element->getStyle();
|
||||||
if ($style === null) {
|
if ($style === null) {
|
||||||
$style = new TableStyle();
|
$style = new TableStyle();
|
||||||
|
|
@ -246,6 +247,7 @@ class Content extends AbstractPart
|
||||||
$style = Style::getStyle($style);
|
$style = Style::getStyle($style);
|
||||||
}
|
}
|
||||||
$style->setStyleName($element->getElementId());
|
$style->setStyleName($element->getElementId());
|
||||||
|
$style->setColumnWidths($element->findFirstDefinedCellWidths());
|
||||||
$this->autoStyles['Table'][] = $style;
|
$this->autoStyles['Table'][] = $style;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -45,5 +45,19 @@ class Table extends AbstractStyle
|
||||||
$xmlWriter->writeAttribute('table:align', 'center');
|
$xmlWriter->writeAttribute('table:align', 'center');
|
||||||
$xmlWriter->endElement(); // style:table-properties
|
$xmlWriter->endElement(); // style:table-properties
|
||||||
$xmlWriter->endElement(); // style:style
|
$xmlWriter->endElement(); // style:style
|
||||||
|
|
||||||
|
$cellWidths = $style->getColumnWidths();
|
||||||
|
$countCellWidths = count($cellWidths);
|
||||||
|
|
||||||
|
for ($i = 0; $i < $countCellWidths; $i++) {
|
||||||
|
$width = $cellWidths[$i];
|
||||||
|
$xmlWriter->startElement('style:style');
|
||||||
|
$xmlWriter->writeAttribute('style:name', $style->getStyleName() . '.' . $i);
|
||||||
|
$xmlWriter->writeAttribute('style:family', 'table-column');
|
||||||
|
$xmlWriter->startElement('style:table-column-properties');
|
||||||
|
$xmlWriter->writeAttribute('style:column-width', number_format($width * 0.0017638889, 2, '.', '') . 'cm');
|
||||||
|
$xmlWriter->endElement(); // style:table-column-properties
|
||||||
|
$xmlWriter->endElement(); // style:style
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is part of PHPWord - A pure PHP library for reading and writing
|
||||||
|
* word processing documents.
|
||||||
|
*
|
||||||
|
* PHPWord is free software distributed under the terms of the GNU Lesser
|
||||||
|
* General Public License version 3 as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please read the LICENSE
|
||||||
|
* file that was distributed with this source code. For the full list of
|
||||||
|
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
|
||||||
|
*
|
||||||
|
* @see https://github.com/PHPOffice/PHPWord
|
||||||
|
* @copyright 2010-2018 PHPWord contributors
|
||||||
|
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace PhpOffice\PhpWord\Writer\RTF\Style;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RTF indentation style writer
|
||||||
|
*
|
||||||
|
* @since 0.11.0
|
||||||
|
*/
|
||||||
|
class Indentation extends AbstractStyle
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Write style
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function write()
|
||||||
|
{
|
||||||
|
$style = $this->getStyle();
|
||||||
|
if (!$style instanceof \PhpOffice\PhpWord\Style\Indentation) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
$content = '\fi' . $style->getFirstLine();
|
||||||
|
$content .= '\li' . $style->getLeft();
|
||||||
|
$content .= '\ri' . $style->getRight();
|
||||||
|
|
||||||
|
return $content . ' ';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -64,9 +64,49 @@ class Paragraph extends AbstractStyle
|
||||||
if (isset($alignments[$style->getAlignment()])) {
|
if (isset($alignments[$style->getAlignment()])) {
|
||||||
$content .= $alignments[$style->getAlignment()];
|
$content .= $alignments[$style->getAlignment()];
|
||||||
}
|
}
|
||||||
|
$content .= $this->writeIndentation($style->getIndentation());
|
||||||
$content .= $this->getValueIf($spaceBefore !== null, '\sb' . $spaceBefore);
|
$content .= $this->getValueIf($spaceBefore !== null, '\sb' . $spaceBefore);
|
||||||
$content .= $this->getValueIf($spaceAfter !== null, '\sa' . $spaceAfter);
|
$content .= $this->getValueIf($spaceAfter !== null, '\sa' . $spaceAfter);
|
||||||
|
|
||||||
|
$styles = $style->getStyleValues();
|
||||||
|
$content .= $this->writeTabs($styles['tabs']);
|
||||||
|
|
||||||
|
return $content;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes an \PhpOffice\PhpWord\Style\Indentation
|
||||||
|
*
|
||||||
|
* @param null|\PhpOffice\PhpWord\Style\Indentation $indent
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private function writeIndentation($indent = null)
|
||||||
|
{
|
||||||
|
if (isset($indent) && $indent instanceof \PhpOffice\PhpWord\Style\Indentation) {
|
||||||
|
$writer = new Indentation($indent);
|
||||||
|
|
||||||
|
return $writer->write();
|
||||||
|
}
|
||||||
|
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes tabs
|
||||||
|
*
|
||||||
|
* @param \PhpOffice\PhpWord\Style\Tab[] $tabs
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private function writeTabs($tabs = null)
|
||||||
|
{
|
||||||
|
$content = '';
|
||||||
|
if (!empty($tabs)) {
|
||||||
|
foreach ($tabs as $tab) {
|
||||||
|
$styleWriter = new Tab($tab);
|
||||||
|
$content .= $styleWriter->write();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return $content;
|
return $content;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is part of PHPWord - A pure PHP library for reading and writing
|
||||||
|
* word processing documents.
|
||||||
|
*
|
||||||
|
* PHPWord is free software distributed under the terms of the GNU Lesser
|
||||||
|
* General Public License version 3 as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please read the LICENSE
|
||||||
|
* file that was distributed with this source code. For the full list of
|
||||||
|
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
|
||||||
|
*
|
||||||
|
* @see https://github.com/PHPOffice/PHPWord
|
||||||
|
* @copyright 2010-2018 PHPWord contributors
|
||||||
|
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace PhpOffice\PhpWord\Writer\RTF\Style;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Line numbering style writer
|
||||||
|
*
|
||||||
|
* @since 0.10.0
|
||||||
|
*/
|
||||||
|
class Tab extends AbstractStyle
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Write style.
|
||||||
|
*/
|
||||||
|
public function write()
|
||||||
|
{
|
||||||
|
$style = $this->getStyle();
|
||||||
|
if (!$style instanceof \PhpOffice\PhpWord\Style\Tab) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$tabs = array(
|
||||||
|
\PhpOffice\PhpWord\Style\Tab::TAB_STOP_RIGHT => '\tqr',
|
||||||
|
\PhpOffice\PhpWord\Style\Tab::TAB_STOP_CENTER => '\tqc',
|
||||||
|
\PhpOffice\PhpWord\Style\Tab::TAB_STOP_DECIMAL => '\tqdec',
|
||||||
|
);
|
||||||
|
$content = '';
|
||||||
|
if (isset($tabs[$style->getType()])) {
|
||||||
|
$content .= $tabs[$style->getType()];
|
||||||
|
}
|
||||||
|
$content .= '\tx' . $style->getPosition();
|
||||||
|
|
||||||
|
return $content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -177,6 +177,9 @@ class Field extends Text
|
||||||
case 'macroname':
|
case 'macroname':
|
||||||
$propertiesAndOptions .= $propval . ' ';
|
$propertiesAndOptions .= $propval . ' ';
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
$propertiesAndOptions .= '"' . $propval . '" ';
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -76,21 +76,7 @@ class Table extends AbstractElement
|
||||||
*/
|
*/
|
||||||
private function writeColumns(XMLWriter $xmlWriter, TableElement $element)
|
private function writeColumns(XMLWriter $xmlWriter, TableElement $element)
|
||||||
{
|
{
|
||||||
$rows = $element->getRows();
|
$cellWidths = $element->findFirstDefinedCellWidths();
|
||||||
$rowCount = count($rows);
|
|
||||||
|
|
||||||
$cellWidths = array();
|
|
||||||
for ($i = 0; $i < $rowCount; $i++) {
|
|
||||||
$row = $rows[$i];
|
|
||||||
$cells = $row->getCells();
|
|
||||||
if (count($cells) <= count($cellWidths)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
$cellWidths = array();
|
|
||||||
foreach ($cells as $cell) {
|
|
||||||
$cellWidths[] = $cell->getWidth();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$xmlWriter->startElement('w:tblGrid');
|
$xmlWriter->startElement('w:tblGrid');
|
||||||
foreach ($cellWidths as $width) {
|
foreach ($cellWidths as $width) {
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,7 @@ class Title extends AbstractElement
|
||||||
$xmlWriter->endElement();
|
$xmlWriter->endElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$bookmarkRId = null;
|
||||||
if ($element->getDepth() !== 0) {
|
if ($element->getDepth() !== 0) {
|
||||||
$rId = $element->getRelationId();
|
$rId = $element->getRelationId();
|
||||||
$bookmarkRId = $element->getPhpWord()->addBookmark();
|
$bookmarkRId = $element->getPhpWord()->addBookmark();
|
||||||
|
|
|
||||||
|
|
@ -43,8 +43,12 @@ class Chart extends AbstractPart
|
||||||
private $types = array(
|
private $types = array(
|
||||||
'pie' => array('type' => 'pie', 'colors' => 1),
|
'pie' => array('type' => 'pie', 'colors' => 1),
|
||||||
'doughnut' => array('type' => 'doughnut', 'colors' => 1, 'hole' => 75, 'no3d' => true),
|
'doughnut' => array('type' => 'doughnut', 'colors' => 1, 'hole' => 75, 'no3d' => true),
|
||||||
'bar' => array('type' => 'bar', 'colors' => 0, 'axes' => true, 'bar' => 'bar'),
|
'bar' => array('type' => 'bar', 'colors' => 0, 'axes' => true, 'bar' => 'bar', 'grouping' => 'clustered'),
|
||||||
'column' => array('type' => 'bar', 'colors' => 0, 'axes' => true, 'bar' => 'col'),
|
'stacked_bar' => array('type' => 'bar', 'colors' => 0, 'axes' => true, 'bar' => 'bar', 'grouping' => 'stacked'),
|
||||||
|
'percent_stacked_bar' => array('type' => 'bar', 'colors' => 0, 'axes' => true, 'bar' => 'bar', 'grouping' => 'percentStacked'),
|
||||||
|
'column' => array('type' => 'bar', 'colors' => 0, 'axes' => true, 'bar' => 'col', 'grouping' => 'clustered'),
|
||||||
|
'stacked_column' => array('type' => 'bar', 'colors' => 0, 'axes' => true, 'bar' => 'col', 'grouping' => 'stacked'),
|
||||||
|
'percent_stacked_column' => array('type' => 'bar', 'colors' => 0, 'axes' => true, 'bar' => 'col', 'grouping' => 'percentStacked'),
|
||||||
'line' => array('type' => 'line', 'colors' => 0, 'axes' => true),
|
'line' => array('type' => 'line', 'colors' => 0, 'axes' => true),
|
||||||
'area' => array('type' => 'area', 'colors' => 0, 'axes' => true),
|
'area' => array('type' => 'area', 'colors' => 0, 'axes' => true),
|
||||||
'radar' => array('type' => 'radar', 'colors' => 0, 'axes' => true, 'radar' => 'standard', 'no3d' => true),
|
'radar' => array('type' => 'radar', 'colors' => 0, 'axes' => true, 'radar' => 'standard', 'no3d' => true),
|
||||||
|
|
@ -145,7 +149,7 @@ class Chart extends AbstractPart
|
||||||
}
|
}
|
||||||
if (isset($this->options['bar'])) {
|
if (isset($this->options['bar'])) {
|
||||||
$xmlWriter->writeElementBlock('c:barDir', 'val', $this->options['bar']); // bar|col
|
$xmlWriter->writeElementBlock('c:barDir', 'val', $this->options['bar']); // bar|col
|
||||||
$xmlWriter->writeElementBlock('c:grouping', 'val', 'clustered'); // 3d; standard = percentStacked
|
$xmlWriter->writeElementBlock('c:grouping', 'val', $this->options['grouping']); // 3d; standard = percentStacked
|
||||||
}
|
}
|
||||||
if (isset($this->options['radar'])) {
|
if (isset($this->options['radar'])) {
|
||||||
$xmlWriter->writeElementBlock('c:radarStyle', 'val', $this->options['radar']);
|
$xmlWriter->writeElementBlock('c:radarStyle', 'val', $this->options['radar']);
|
||||||
|
|
@ -157,6 +161,8 @@ class Chart extends AbstractPart
|
||||||
// Series
|
// Series
|
||||||
$this->writeSeries($xmlWriter, isset($this->options['scatter']));
|
$this->writeSeries($xmlWriter, isset($this->options['scatter']));
|
||||||
|
|
||||||
|
$xmlWriter->writeElementBlock('c:overlap', 'val', '100');
|
||||||
|
|
||||||
// Axes
|
// Axes
|
||||||
if (isset($this->options['axes'])) {
|
if (isset($this->options['axes'])) {
|
||||||
$xmlWriter->writeElementBlock('c:axId', 'val', 1);
|
$xmlWriter->writeElementBlock('c:axId', 'val', 1);
|
||||||
|
|
@ -183,6 +189,8 @@ class Chart extends AbstractPart
|
||||||
private function writeSeries(XMLWriter $xmlWriter, $scatter = false)
|
private function writeSeries(XMLWriter $xmlWriter, $scatter = false)
|
||||||
{
|
{
|
||||||
$series = $this->element->getSeries();
|
$series = $this->element->getSeries();
|
||||||
|
$style = $this->element->getStyle();
|
||||||
|
$colors = $style->getColors();
|
||||||
|
|
||||||
$index = 0;
|
$index = 0;
|
||||||
foreach ($series as $seriesItem) {
|
foreach ($series as $seriesItem) {
|
||||||
|
|
@ -194,6 +202,32 @@ class Chart extends AbstractPart
|
||||||
$xmlWriter->writeElementBlock('c:idx', 'val', $index);
|
$xmlWriter->writeElementBlock('c:idx', 'val', $index);
|
||||||
$xmlWriter->writeElementBlock('c:order', 'val', $index);
|
$xmlWriter->writeElementBlock('c:order', 'val', $index);
|
||||||
|
|
||||||
|
if (!is_null($seriesItem['name']) && $seriesItem['name'] != '') {
|
||||||
|
$xmlWriter->startElement('c:tx');
|
||||||
|
$xmlWriter->startElement('c:strRef');
|
||||||
|
$xmlWriter->startElement('c:strCache');
|
||||||
|
$xmlWriter->writeElementBlock('c:ptCount', 'val', 1);
|
||||||
|
$xmlWriter->startElement('c:pt');
|
||||||
|
$xmlWriter->writeAttribute('idx', 0);
|
||||||
|
$xmlWriter->startElement('c:v');
|
||||||
|
$xmlWriter->writeRaw($seriesItem['name']);
|
||||||
|
$xmlWriter->endElement(); // c:v
|
||||||
|
$xmlWriter->endElement(); // c:pt
|
||||||
|
$xmlWriter->endElement(); // c:strCache
|
||||||
|
$xmlWriter->endElement(); // c:strRef
|
||||||
|
$xmlWriter->endElement(); // c:tx
|
||||||
|
}
|
||||||
|
|
||||||
|
// The c:dLbls was added to make word charts look more like the reports in SurveyGizmo
|
||||||
|
// This section needs to be made configurable before a pull request is made
|
||||||
|
$xmlWriter->startElement('c:dLbls');
|
||||||
|
|
||||||
|
foreach ($style->getDataLabelOptions() as $option => $val) {
|
||||||
|
$xmlWriter->writeElementBlock("c:{$option}", 'val', (int) $val);
|
||||||
|
}
|
||||||
|
|
||||||
|
$xmlWriter->endElement(); // c:dLbls
|
||||||
|
|
||||||
if (isset($this->options['scatter'])) {
|
if (isset($this->options['scatter'])) {
|
||||||
$this->writeShape($xmlWriter);
|
$this->writeShape($xmlWriter);
|
||||||
}
|
}
|
||||||
|
|
@ -204,6 +238,26 @@ class Chart extends AbstractPart
|
||||||
} else {
|
} else {
|
||||||
$this->writeSeriesItem($xmlWriter, 'cat', $categories);
|
$this->writeSeriesItem($xmlWriter, 'cat', $categories);
|
||||||
$this->writeSeriesItem($xmlWriter, 'val', $values);
|
$this->writeSeriesItem($xmlWriter, 'val', $values);
|
||||||
|
|
||||||
|
// setting the chart colors was taken from https://github.com/PHPOffice/PHPWord/issues/494
|
||||||
|
if (is_array($colors) && count($colors)) {
|
||||||
|
// This is a workaround to make each series in a stack chart use a different color
|
||||||
|
if ($this->options['type'] == 'bar' && stristr($this->options['grouping'], 'stacked')) {
|
||||||
|
array_shift($colors);
|
||||||
|
}
|
||||||
|
$colorIndex = 0;
|
||||||
|
foreach ($colors as $color) {
|
||||||
|
$xmlWriter->startElement('c:dPt');
|
||||||
|
$xmlWriter->writeElementBlock('c:idx', 'val', $colorIndex);
|
||||||
|
$xmlWriter->startElement('c:spPr');
|
||||||
|
$xmlWriter->startElement('a:solidFill');
|
||||||
|
$xmlWriter->writeElementBlock('a:srgbClr', 'val', $color);
|
||||||
|
$xmlWriter->endElement(); // a:solidFill
|
||||||
|
$xmlWriter->endElement(); // c:spPr
|
||||||
|
$xmlWriter->endElement(); // c:dPt
|
||||||
|
$colorIndex++;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$xmlWriter->endElement(); // c:ser
|
$xmlWriter->endElement(); // c:ser
|
||||||
|
|
@ -230,14 +284,19 @@ class Chart extends AbstractPart
|
||||||
|
|
||||||
$xmlWriter->startElement($itemType);
|
$xmlWriter->startElement($itemType);
|
||||||
$xmlWriter->startElement($itemLit);
|
$xmlWriter->startElement($itemLit);
|
||||||
|
$xmlWriter->writeElementBlock('c:ptCount', 'val', count($values));
|
||||||
|
|
||||||
$index = 0;
|
$index = 0;
|
||||||
foreach ($values as $value) {
|
foreach ($values as $value) {
|
||||||
$xmlWriter->startElement('c:pt');
|
$xmlWriter->startElement('c:pt');
|
||||||
$xmlWriter->writeAttribute('idx', $index);
|
$xmlWriter->writeAttribute('idx', $index);
|
||||||
|
if (\PhpOffice\PhpWord\Settings::isOutputEscapingEnabled()) {
|
||||||
|
$xmlWriter->writeElement('c:v', $value);
|
||||||
|
} else {
|
||||||
$xmlWriter->startElement('c:v');
|
$xmlWriter->startElement('c:v');
|
||||||
$xmlWriter->text($value);
|
$xmlWriter->writeRaw($value);
|
||||||
$xmlWriter->endElement(); // c:v
|
$xmlWriter->endElement(); // c:v
|
||||||
|
}
|
||||||
$xmlWriter->endElement(); // c:pt
|
$xmlWriter->endElement(); // c:pt
|
||||||
$index++;
|
$index++;
|
||||||
}
|
}
|
||||||
|
|
@ -266,15 +325,33 @@ class Chart extends AbstractPart
|
||||||
|
|
||||||
$xmlWriter->writeElementBlock('c:axId', 'val', $axisId);
|
$xmlWriter->writeElementBlock('c:axId', 'val', $axisId);
|
||||||
$xmlWriter->writeElementBlock('c:axPos', 'val', $axisPos);
|
$xmlWriter->writeElementBlock('c:axPos', 'val', $axisPos);
|
||||||
|
|
||||||
|
$categoryAxisTitle = $style->getCategoryAxisTitle();
|
||||||
|
$valueAxisTitle = $style->getValueAxisTitle();
|
||||||
|
|
||||||
|
if ($axisType == 'c:catAx') {
|
||||||
|
if (!is_null($categoryAxisTitle)) {
|
||||||
|
$this->writeAxisTitle($xmlWriter, $categoryAxisTitle);
|
||||||
|
}
|
||||||
|
} elseif ($axisType == 'c:valAx') {
|
||||||
|
if (!is_null($valueAxisTitle)) {
|
||||||
|
$this->writeAxisTitle($xmlWriter, $valueAxisTitle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$xmlWriter->writeElementBlock('c:crossAx', 'val', $axisCross);
|
$xmlWriter->writeElementBlock('c:crossAx', 'val', $axisCross);
|
||||||
$xmlWriter->writeElementBlock('c:auto', 'val', 1);
|
$xmlWriter->writeElementBlock('c:auto', 'val', 1);
|
||||||
|
|
||||||
if (isset($this->options['axes'])) {
|
if (isset($this->options['axes'])) {
|
||||||
$xmlWriter->writeElementBlock('c:delete', 'val', 0);
|
$xmlWriter->writeElementBlock('c:delete', 'val', 0);
|
||||||
$xmlWriter->writeElementBlock('c:majorTickMark', 'val', 'none');
|
$xmlWriter->writeElementBlock('c:majorTickMark', 'val', $style->getMajorTickPosition());
|
||||||
$xmlWriter->writeElementBlock('c:minorTickMark', 'val', 'none');
|
$xmlWriter->writeElementBlock('c:minorTickMark', 'val', 'none');
|
||||||
if ($style->showAxisLabels()) {
|
if ($style->showAxisLabels()) {
|
||||||
$xmlWriter->writeElementBlock('c:tickLblPos', 'val', 'nextTo');
|
if ($axisType == 'c:catAx') {
|
||||||
|
$xmlWriter->writeElementBlock('c:tickLblPos', 'val', $style->getCategoryLabelPosition());
|
||||||
|
} else {
|
||||||
|
$xmlWriter->writeElementBlock('c:tickLblPos', 'val', $style->getValueLabelPosition());
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
$xmlWriter->writeElementBlock('c:tickLblPos', 'val', 'none');
|
$xmlWriter->writeElementBlock('c:tickLblPos', 'val', 'none');
|
||||||
}
|
}
|
||||||
|
|
@ -312,4 +389,30 @@ class Chart extends AbstractPart
|
||||||
$xmlWriter->endElement(); // a:ln
|
$xmlWriter->endElement(); // a:ln
|
||||||
$xmlWriter->endElement(); // c:spPr
|
$xmlWriter->endElement(); // c:spPr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function writeAxisTitle(XMLWriter $xmlWriter, $title)
|
||||||
|
{
|
||||||
|
$xmlWriter->startElement('c:title'); //start c:title
|
||||||
|
$xmlWriter->startElement('c:tx'); //start c:tx
|
||||||
|
$xmlWriter->startElement('c:rich'); // start c:rich
|
||||||
|
$xmlWriter->writeElement('a:bodyPr');
|
||||||
|
$xmlWriter->writeElement('a:lstStyle');
|
||||||
|
$xmlWriter->startElement('a:p');
|
||||||
|
$xmlWriter->startElement('a:pPr');
|
||||||
|
$xmlWriter->writeElement('a:defRPr');
|
||||||
|
$xmlWriter->endElement(); // end a:pPr
|
||||||
|
$xmlWriter->startElement('a:r');
|
||||||
|
$xmlWriter->writeElementBlock('a:rPr', 'lang', 'en-US');
|
||||||
|
|
||||||
|
$xmlWriter->startElement('a:t');
|
||||||
|
$xmlWriter->writeRaw($title);
|
||||||
|
$xmlWriter->endElement(); //end a:t
|
||||||
|
|
||||||
|
$xmlWriter->endElement(); // end a:r
|
||||||
|
$xmlWriter->endElement(); //end a:p
|
||||||
|
$xmlWriter->endElement(); //end c:rich
|
||||||
|
$xmlWriter->endElement(); // end c:tx
|
||||||
|
$xmlWriter->writeElementBlock('c:overlay', 'val', '0');
|
||||||
|
$xmlWriter->endElement(); // end c:title
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,9 +17,9 @@
|
||||||
|
|
||||||
namespace PhpOffice\PhpWord\Writer\Word2007\Part;
|
namespace PhpOffice\PhpWord\Writer\Word2007\Part;
|
||||||
|
|
||||||
|
use PhpOffice\Common\Microsoft\PasswordEncoder;
|
||||||
use PhpOffice\PhpWord\ComplexType\ProofState;
|
use PhpOffice\PhpWord\ComplexType\ProofState;
|
||||||
use PhpOffice\PhpWord\ComplexType\TrackChangesView;
|
use PhpOffice\PhpWord\ComplexType\TrackChangesView;
|
||||||
use PhpOffice\PhpWord\Shared\Microsoft\PasswordEncoder;
|
|
||||||
use PhpOffice\PhpWord\Style\Language;
|
use PhpOffice\PhpWord\Style\Language;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -79,6 +79,7 @@ class Table extends AbstractStyle
|
||||||
|
|
||||||
$this->writeTblWidth($xmlWriter, 'w:tblW', $style->getUnit(), $style->getWidth());
|
$this->writeTblWidth($xmlWriter, 'w:tblW', $style->getUnit(), $style->getWidth());
|
||||||
$this->writeTblWidth($xmlWriter, 'w:tblCellSpacing', TblWidth::TWIP, $style->getCellSpacing());
|
$this->writeTblWidth($xmlWriter, 'w:tblCellSpacing', TblWidth::TWIP, $style->getCellSpacing());
|
||||||
|
$this->writeIndent($xmlWriter, $style);
|
||||||
$this->writeLayout($xmlWriter, $style->getLayout());
|
$this->writeLayout($xmlWriter, $style->getLayout());
|
||||||
|
|
||||||
// Position
|
// Position
|
||||||
|
|
@ -216,4 +217,19 @@ class Table extends AbstractStyle
|
||||||
{
|
{
|
||||||
$this->width = $value;
|
$this->width = $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param XMLWriter $xmlWriter
|
||||||
|
* @param TableStyle $style
|
||||||
|
*/
|
||||||
|
private function writeIndent(XMLWriter $xmlWriter, TableStyle $style)
|
||||||
|
{
|
||||||
|
$indent = $style->getIndent();
|
||||||
|
|
||||||
|
if ($indent === null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->writeTblWidth($xmlWriter, 'w:tblInd', $indent->getType(), $indent->getValue());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -126,4 +126,23 @@ class StyleTest extends AbstractTestReader
|
||||||
$fontStyle = $textRun->getElement(0)->getFontStyle();
|
$fontStyle = $textRun->getElement(0)->getFontStyle();
|
||||||
$this->assertEquals(15, $fontStyle->getPosition());
|
$this->assertEquals(15, $fontStyle->getPosition());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testReadIndent()
|
||||||
|
{
|
||||||
|
$documentXml = '<w:tbl>
|
||||||
|
<w:tblPr>
|
||||||
|
<w:tblInd w:w="2160" w:type="dxa"/>
|
||||||
|
</w:tblPr>
|
||||||
|
</w:tbl>';
|
||||||
|
|
||||||
|
$phpWord = $this->getDocumentFromString(array('document' => $documentXml));
|
||||||
|
|
||||||
|
$elements = $phpWord->getSection(0)->getElements();
|
||||||
|
$this->assertInstanceOf('PhpOffice\PhpWord\Element\Table', $elements[0]);
|
||||||
|
$this->assertInstanceOf('PhpOffice\PhpWord\Style\Table', $elements[0]->getStyle());
|
||||||
|
/** @var \PhpOffice\PhpWord\Style\Table $tableStyle */
|
||||||
|
$tableStyle = $elements[0]->getStyle();
|
||||||
|
$this->assertSame(TblWidth::TWIP, $tableStyle->getIndent()->getType());
|
||||||
|
$this->assertSame(2160, $tableStyle->getIndent()->getValue());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -1,91 +0,0 @@
|
||||||
<?php
|
|
||||||
/**
|
|
||||||
* This file is part of PHPWord - A pure PHP library for reading and writing
|
|
||||||
* word processing documents.
|
|
||||||
*
|
|
||||||
* PHPWord is free software distributed under the terms of the GNU Lesser
|
|
||||||
* General Public License version 3 as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* For the full copyright and license information, please read the LICENSE
|
|
||||||
* file that was distributed with this source code. For the full list of
|
|
||||||
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
|
|
||||||
*
|
|
||||||
* @see https://github.com/PHPOffice/PHPWord
|
|
||||||
* @copyright 2010-2018 PHPWord contributors
|
|
||||||
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace PhpOffice\PhpWord\Shared;
|
|
||||||
|
|
||||||
use PhpOffice\PhpWord\Shared\Microsoft\PasswordEncoder;
|
|
||||||
use PHPUnit\Framework\TestCase;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test class for PhpOffice\PhpWord\Shared\Html
|
|
||||||
* @coversDefaultClass \PhpOffice\PhpWord\Shared\Html
|
|
||||||
*/
|
|
||||||
class PasswordEncoderTest extends \PHPUnit\Framework\TestCase
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Test that a password can be hashed without specifying any additional parameters
|
|
||||||
*/
|
|
||||||
public function testEncodePassword()
|
|
||||||
{
|
|
||||||
//given
|
|
||||||
$password = 'test';
|
|
||||||
|
|
||||||
//when
|
|
||||||
$hashPassword = PasswordEncoder::hashPassword($password);
|
|
||||||
|
|
||||||
//then
|
|
||||||
TestCase::assertEquals('M795/MAlmGU8RIsY9Q9uDLHC7bk=', $hashPassword);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test that a password can be hashed with a custom salt
|
|
||||||
*/
|
|
||||||
public function testEncodePasswordWithSalt()
|
|
||||||
{
|
|
||||||
//given
|
|
||||||
$password = 'test';
|
|
||||||
$salt = base64_decode('uq81pJRRGFIY5U+E9gt8tA==');
|
|
||||||
|
|
||||||
//when
|
|
||||||
$hashPassword = PasswordEncoder::hashPassword($password, PasswordEncoder::ALGORITHM_SHA_1, $salt);
|
|
||||||
|
|
||||||
//then
|
|
||||||
TestCase::assertEquals('QiDOcpia1YzSVJPiKPwWebl9p/0=', $hashPassword);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test that the encoder falls back on SHA-1 if a non supported algorithm is given
|
|
||||||
*/
|
|
||||||
public function testDafaultsToSha1IfUnsupportedAlgorithm()
|
|
||||||
{
|
|
||||||
//given
|
|
||||||
$password = 'test';
|
|
||||||
$salt = base64_decode('uq81pJRRGFIY5U+E9gt8tA==');
|
|
||||||
|
|
||||||
//when
|
|
||||||
$hashPassword = PasswordEncoder::hashPassword($password, PasswordEncoder::ALGORITHM_MAC, $salt);
|
|
||||||
|
|
||||||
//then
|
|
||||||
TestCase::assertEquals('QiDOcpia1YzSVJPiKPwWebl9p/0=', $hashPassword);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test that the encoder falls back on SHA-1 if a non supported algorithm is given
|
|
||||||
*/
|
|
||||||
public function testEncodePasswordWithNullAsciiCodeInPassword()
|
|
||||||
{
|
|
||||||
//given
|
|
||||||
$password = 'test' . chr(0);
|
|
||||||
$salt = base64_decode('uq81pJRRGFIY5U+E9gt8tA==');
|
|
||||||
|
|
||||||
//when
|
|
||||||
$hashPassword = PasswordEncoder::hashPassword($password, PasswordEncoder::ALGORITHM_MAC, $salt, 1);
|
|
||||||
|
|
||||||
//then
|
|
||||||
TestCase::assertEquals('rDV9sgdDsztoCQlvRCb1lF2wxNg=', $hashPassword);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,188 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is part of PHPWord - A pure PHP library for reading and writing
|
||||||
|
* word processing documents.
|
||||||
|
*
|
||||||
|
* PHPWord is free software distributed under the terms of the GNU Lesser
|
||||||
|
* General Public License version 3 as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please read the LICENSE
|
||||||
|
* file that was distributed with this source code. For the full list of
|
||||||
|
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
|
||||||
|
*
|
||||||
|
* @see https://github.com/PHPOffice/PHPWord
|
||||||
|
* @copyright 2010-2017 PHPWord contributors
|
||||||
|
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace PhpOffice\PhpWord\Style;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test class for PhpOffice\PhpWord\Style\Chart
|
||||||
|
*
|
||||||
|
* @coversDefaultClass \PhpOffice\PhpWord\Style\Chart
|
||||||
|
* @runTestsInSeparateProcesses
|
||||||
|
*/
|
||||||
|
class ChartTest extends \PHPUnit\Framework\TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Testing getter and setter for chart width
|
||||||
|
*/
|
||||||
|
public function testSetGetWidth()
|
||||||
|
{
|
||||||
|
$chart = new Chart();
|
||||||
|
|
||||||
|
$this->assertEquals($chart->getWidth(), 1000000);
|
||||||
|
|
||||||
|
$chart->setWidth(200);
|
||||||
|
|
||||||
|
$this->assertEquals($chart->getWidth(), 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Testing getter and setter for chart height
|
||||||
|
*/
|
||||||
|
public function testSetGetHeight()
|
||||||
|
{
|
||||||
|
$chart = new Chart();
|
||||||
|
|
||||||
|
$this->assertEquals($chart->getHeight(), 1000000);
|
||||||
|
|
||||||
|
$chart->setHeight(200);
|
||||||
|
|
||||||
|
$this->assertEquals($chart->getHeight(), 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Testing getter and setter for is3d
|
||||||
|
*/
|
||||||
|
public function testSetIs3d()
|
||||||
|
{
|
||||||
|
$chart = new Chart();
|
||||||
|
|
||||||
|
$this->assertEquals($chart->is3d(), false);
|
||||||
|
|
||||||
|
$chart->set3d(true);
|
||||||
|
|
||||||
|
$this->assertEquals($chart->is3d(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Testing getter and setter for chart colors
|
||||||
|
*/
|
||||||
|
public function testSetGetColors()
|
||||||
|
{
|
||||||
|
$chart = new Chart();
|
||||||
|
|
||||||
|
$this->assertInternalType('array', $chart->getColors());
|
||||||
|
|
||||||
|
$this->assertEquals(count($chart->getColors()), 0);
|
||||||
|
|
||||||
|
$chart->setColors(array('FFFFFFFF', 'FF000000', 'FFFF0000'));
|
||||||
|
|
||||||
|
$this->assertEquals($chart->getColors(), array('FFFFFFFF', 'FF000000', 'FFFF0000'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Testing getter and setter for dataLabelOptions
|
||||||
|
*/
|
||||||
|
public function testSetGetDataLabelOptions()
|
||||||
|
{
|
||||||
|
$chart = new Chart();
|
||||||
|
|
||||||
|
$originalDataLabelOptions = array(
|
||||||
|
'showVal' => true,
|
||||||
|
'showCatName' => true,
|
||||||
|
'showLegendKey' => false,
|
||||||
|
'showSerName' => false,
|
||||||
|
'showPercent' => false,
|
||||||
|
'showLeaderLines' => false,
|
||||||
|
'showBubbleSize' => false,
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertEquals($chart->getDataLabelOptions(), $originalDataLabelOptions);
|
||||||
|
|
||||||
|
$changedDataLabelOptions = array(
|
||||||
|
'showVal' => false,
|
||||||
|
'showCatName' => false,
|
||||||
|
'showLegendKey' => true,
|
||||||
|
'showSerName' => true,
|
||||||
|
'showPercent' => true,
|
||||||
|
'showLeaderLines' => true,
|
||||||
|
'showBubbleSize' => true,
|
||||||
|
);
|
||||||
|
|
||||||
|
$chart->setDataLabelOptions(
|
||||||
|
array(
|
||||||
|
'showVal' => false,
|
||||||
|
'showCatName' => false,
|
||||||
|
'showLegendKey' => true,
|
||||||
|
'showSerName' => true,
|
||||||
|
'showPercent' => true,
|
||||||
|
'showLeaderLines' => true,
|
||||||
|
'showBubbleSize' => true,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$this->assertEquals($chart->getDataLabelOptions(), $changedDataLabelOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Testing categoryLabelPosition getter and setter
|
||||||
|
*/
|
||||||
|
public function testSetGetCategoryLabelPosition()
|
||||||
|
{
|
||||||
|
$chart = new Chart();
|
||||||
|
|
||||||
|
$this->assertEquals($chart->getCategoryLabelPosition(), 'nextTo');
|
||||||
|
|
||||||
|
$chart->setCategoryLabelPosition('high');
|
||||||
|
|
||||||
|
$this->assertEquals($chart->getCategoryLabelPosition(), 'high');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Testing valueLabelPosition getter and setter
|
||||||
|
*/
|
||||||
|
public function testSetGetValueLabelPosition()
|
||||||
|
{
|
||||||
|
$chart = new Chart();
|
||||||
|
|
||||||
|
$this->assertEquals($chart->getValueLabelPosition(), 'nextTo');
|
||||||
|
|
||||||
|
$chart->setValueLabelPosition('low');
|
||||||
|
|
||||||
|
$this->assertEquals($chart->getValueLabelPosition(), 'low');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Testing categoryAxisTitle getter and setter
|
||||||
|
*/
|
||||||
|
public function testSetGetCategoryAxisTitle()
|
||||||
|
{
|
||||||
|
$chart = new Chart();
|
||||||
|
|
||||||
|
$chart->getCategoryAxisTitle();
|
||||||
|
|
||||||
|
$this->assertEquals($chart->getCategoryAxisTitle(), null);
|
||||||
|
|
||||||
|
$chart->setCategoryAxisTitle('Test Category Axis Title');
|
||||||
|
|
||||||
|
$this->assertEquals($chart->getCategoryAxisTitle(), 'Test Category Axis Title');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Testing valueAxisTitle getter and setter
|
||||||
|
*/
|
||||||
|
public function testSetGetValueAxisTitle()
|
||||||
|
{
|
||||||
|
$chart = new Chart();
|
||||||
|
|
||||||
|
$chart->getValueAxisTitle();
|
||||||
|
|
||||||
|
$this->assertEquals($chart->getValueAxisTitle(), null);
|
||||||
|
|
||||||
|
$chart->setValueAxisTitle('Test Value Axis Title');
|
||||||
|
|
||||||
|
$this->assertEquals($chart->getValueAxisTitle(), 'Test Value Axis Title');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -17,7 +17,6 @@
|
||||||
|
|
||||||
namespace PhpOffice\PhpWord\Style;
|
namespace PhpOffice\PhpWord\Style;
|
||||||
|
|
||||||
use PhpOffice\PhpWord\PhpWord;
|
|
||||||
use PhpOffice\PhpWord\TestHelperDOCX;
|
use PhpOffice\PhpWord\TestHelperDOCX;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
namespace PhpOffice\PhpWord\Style;
|
namespace PhpOffice\PhpWord\Style;
|
||||||
|
|
||||||
|
use PhpOffice\PhpWord\ComplexType\TblWidth as TblWidthComplexType;
|
||||||
use PhpOffice\PhpWord\SimpleType\JcTable;
|
use PhpOffice\PhpWord\SimpleType\JcTable;
|
||||||
use PhpOffice\PhpWord\SimpleType\TblWidth;
|
use PhpOffice\PhpWord\SimpleType\TblWidth;
|
||||||
|
|
||||||
|
|
@ -57,6 +58,7 @@ class TableTest extends \PHPUnit\Framework\TestCase
|
||||||
$this->assertNull($object->getBgColor());
|
$this->assertNull($object->getBgColor());
|
||||||
$this->assertEquals(Table::LAYOUT_AUTO, $object->getLayout());
|
$this->assertEquals(Table::LAYOUT_AUTO, $object->getLayout());
|
||||||
$this->assertEquals(TblWidth::AUTO, $object->getUnit());
|
$this->assertEquals(TblWidth::AUTO, $object->getUnit());
|
||||||
|
$this->assertNull($object->getIndent());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -208,4 +210,13 @@ class TableTest extends \PHPUnit\Framework\TestCase
|
||||||
$this->assertNotNull($object->getPosition());
|
$this->assertNotNull($object->getPosition());
|
||||||
$this->assertEquals(TablePosition::VANCHOR_PAGE, $object->getPosition()->getVertAnchor());
|
$this->assertEquals(TablePosition::VANCHOR_PAGE, $object->getPosition()->getVertAnchor());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testIndent()
|
||||||
|
{
|
||||||
|
$indent = new TblWidthComplexType(100, TblWidth::TWIP);
|
||||||
|
|
||||||
|
$table = new Table(array('indent' => $indent));
|
||||||
|
|
||||||
|
$this->assertSame($indent, $table->getIndent());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,7 @@ class ElementTest extends \PHPUnit\Framework\TestCase
|
||||||
$text2->setTrackChange(new TrackChange(TrackChange::DELETED, 'another author', new \DateTime()));
|
$text2->setTrackChange(new TrackChange(TrackChange::DELETED, 'another author', new \DateTime()));
|
||||||
|
|
||||||
$dom = $this->getAsHTML($phpWord);
|
$dom = $this->getAsHTML($phpWord);
|
||||||
$xpath = new \DOMXpath($dom);
|
$xpath = new \DOMXPath($dom);
|
||||||
|
|
||||||
$this->assertTrue($xpath->query('/html/body/p[1]/ins')->length == 1);
|
$this->assertTrue($xpath->query('/html/body/p[1]/ins')->length == 1);
|
||||||
$this->assertTrue($xpath->query('/html/body/p[2]/del')->length == 1);
|
$this->assertTrue($xpath->query('/html/body/p[2]/del')->length == 1);
|
||||||
|
|
@ -94,7 +94,7 @@ class ElementTest extends \PHPUnit\Framework\TestCase
|
||||||
$cell22->addText('second cell');
|
$cell22->addText('second cell');
|
||||||
|
|
||||||
$dom = $this->getAsHTML($phpWord);
|
$dom = $this->getAsHTML($phpWord);
|
||||||
$xpath = new \DOMXpath($dom);
|
$xpath = new \DOMXPath($dom);
|
||||||
|
|
||||||
$this->assertTrue($xpath->query('/html/body/table/tr[1]/td')->length == 1);
|
$this->assertTrue($xpath->query('/html/body/table/tr[1]/td')->length == 1);
|
||||||
$this->assertEquals('2', $xpath->query('/html/body/table/tr/td[1]')->item(0)->attributes->getNamedItem('colspan')->textContent);
|
$this->assertEquals('2', $xpath->query('/html/body/table/tr/td[1]')->item(0)->attributes->getNamedItem('colspan')->textContent);
|
||||||
|
|
@ -123,7 +123,7 @@ class ElementTest extends \PHPUnit\Framework\TestCase
|
||||||
$row3->addCell(500)->addText('third cell being spanned');
|
$row3->addCell(500)->addText('third cell being spanned');
|
||||||
|
|
||||||
$dom = $this->getAsHTML($phpWord);
|
$dom = $this->getAsHTML($phpWord);
|
||||||
$xpath = new \DOMXpath($dom);
|
$xpath = new \DOMXPath($dom);
|
||||||
|
|
||||||
$this->assertTrue($xpath->query('/html/body/table/tr[1]/td')->length == 2);
|
$this->assertTrue($xpath->query('/html/body/table/tr[1]/td')->length == 2);
|
||||||
$this->assertEquals('3', $xpath->query('/html/body/table/tr[1]/td[1]')->item(0)->attributes->getNamedItem('rowspan')->textContent);
|
$this->assertEquals('3', $xpath->query('/html/body/table/tr[1]/td[1]')->item(0)->attributes->getNamedItem('rowspan')->textContent);
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,9 @@
|
||||||
|
|
||||||
namespace PhpOffice\PhpWord\Writer\RTF;
|
namespace PhpOffice\PhpWord\Writer\RTF;
|
||||||
|
|
||||||
|
use PhpOffice\PhpWord\Writer\RTF;
|
||||||
use PhpOffice\PhpWord\Writer\RTF\Style\Border;
|
use PhpOffice\PhpWord\Writer\RTF\Style\Border;
|
||||||
|
use PHPUnit\Framework\Assert;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test class for PhpOffice\PhpWord\Writer\RTF\Style subnamespace
|
* Test class for PhpOffice\PhpWord\Writer\RTF\Style subnamespace
|
||||||
|
|
@ -29,7 +31,7 @@ class StyleTest extends \PHPUnit\Framework\TestCase
|
||||||
*/
|
*/
|
||||||
public function testEmptyStyles()
|
public function testEmptyStyles()
|
||||||
{
|
{
|
||||||
$styles = array('Font', 'Paragraph', 'Section');
|
$styles = array('Font', 'Paragraph', 'Section', 'Tab', 'Indentation');
|
||||||
foreach ($styles as $style) {
|
foreach ($styles as $style) {
|
||||||
$objectClass = 'PhpOffice\\PhpWord\\Writer\\RTF\\Style\\' . $style;
|
$objectClass = 'PhpOffice\\PhpWord\\Writer\\RTF\\Style\\' . $style;
|
||||||
$object = new $objectClass();
|
$object = new $objectClass();
|
||||||
|
|
@ -55,4 +57,55 @@ class StyleTest extends \PHPUnit\Framework\TestCase
|
||||||
|
|
||||||
$this->assertEquals($expected, $content);
|
$this->assertEquals($expected, $content);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testIndentation()
|
||||||
|
{
|
||||||
|
$indentation = new \PhpOffice\PhpWord\Style\Indentation();
|
||||||
|
$indentation->setLeft(1);
|
||||||
|
$indentation->setRight(2);
|
||||||
|
$indentation->setFirstLine(3);
|
||||||
|
|
||||||
|
$indentWriter = new \PhpOffice\PhpWord\Writer\RTF\Style\Indentation($indentation);
|
||||||
|
$indentWriter->setParentWriter(new RTF());
|
||||||
|
$result = $indentWriter->write();
|
||||||
|
|
||||||
|
Assert::assertEquals('\fi3\li1\ri2 ', $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testRightTab()
|
||||||
|
{
|
||||||
|
$tabRight = new \PhpOffice\PhpWord\Style\Tab();
|
||||||
|
$tabRight->setType(\PhpOffice\PhpWord\Style\Tab::TAB_STOP_RIGHT);
|
||||||
|
$tabRight->setPosition(5);
|
||||||
|
|
||||||
|
$tabWriter = new \PhpOffice\PhpWord\Writer\RTF\Style\Tab($tabRight);
|
||||||
|
$tabWriter->setParentWriter(new RTF());
|
||||||
|
$result = $tabWriter->write();
|
||||||
|
|
||||||
|
Assert::assertEquals('\tqr\tx5', $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testCenterTab()
|
||||||
|
{
|
||||||
|
$tabRight = new \PhpOffice\PhpWord\Style\Tab();
|
||||||
|
$tabRight->setType(\PhpOffice\PhpWord\Style\Tab::TAB_STOP_CENTER);
|
||||||
|
|
||||||
|
$tabWriter = new \PhpOffice\PhpWord\Writer\RTF\Style\Tab($tabRight);
|
||||||
|
$tabWriter->setParentWriter(new RTF());
|
||||||
|
$result = $tabWriter->write();
|
||||||
|
|
||||||
|
Assert::assertEquals('\tqc\tx0', $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testDecimalTab()
|
||||||
|
{
|
||||||
|
$tabRight = new \PhpOffice\PhpWord\Style\Tab();
|
||||||
|
$tabRight->setType(\PhpOffice\PhpWord\Style\Tab::TAB_STOP_DECIMAL);
|
||||||
|
|
||||||
|
$tabWriter = new \PhpOffice\PhpWord\Writer\RTF\Style\Tab($tabRight);
|
||||||
|
$tabWriter->setParentWriter(new RTF());
|
||||||
|
$result = $tabWriter->write();
|
||||||
|
|
||||||
|
Assert::assertEquals('\tqdec\tx0', $result);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -256,7 +256,7 @@ class ElementTest extends \PHPUnit\Framework\TestCase
|
||||||
{
|
{
|
||||||
$phpWord = new PhpWord();
|
$phpWord = new PhpWord();
|
||||||
$section = $phpWord->addSection();
|
$section = $phpWord->addSection();
|
||||||
$style = array('width' => 1000000, 'height' => 1000000);
|
$style = array('width' => 1000000, 'height' => 1000000, 'showAxisLabels' => true, 'showGridX' => true, 'showGridY' => true);
|
||||||
|
|
||||||
$chartTypes = array('pie', 'doughnut', 'bar', 'line', 'area', 'scatter', 'radar');
|
$chartTypes = array('pie', 'doughnut', 'bar', 'line', 'area', 'scatter', 'radar');
|
||||||
$categories = array('A', 'B', 'C', 'D', 'E');
|
$categories = array('A', 'B', 'C', 'D', 'E');
|
||||||
|
|
@ -288,6 +288,7 @@ class ElementTest extends \PHPUnit\Framework\TestCase
|
||||||
$section->addField('DATE', array(), array('LunarCalendar'));
|
$section->addField('DATE', array(), array('LunarCalendar'));
|
||||||
$section->addField('DATE', array(), array('SakaEraCalendar'));
|
$section->addField('DATE', array(), array('SakaEraCalendar'));
|
||||||
$section->addField('NUMPAGES', array('format' => 'roman', 'numformat' => '0,00'), array('SakaEraCalendar'));
|
$section->addField('NUMPAGES', array('format' => 'roman', 'numformat' => '0,00'), array('SakaEraCalendar'));
|
||||||
|
$section->addField('STYLEREF', array('StyleIdentifier' => 'Heading 1'));
|
||||||
$doc = TestHelperDOCX::getDocument($phpWord);
|
$doc = TestHelperDOCX::getDocument($phpWord);
|
||||||
|
|
||||||
$element = '/w:document/w:body/w:p/w:r/w:instrText';
|
$element = '/w:document/w:body/w:p/w:r/w:instrText';
|
||||||
|
|
|
||||||
|
|
@ -17,11 +17,10 @@
|
||||||
|
|
||||||
namespace PhpOffice\PhpWord\Writer\Word2007\Part;
|
namespace PhpOffice\PhpWord\Writer\Word2007\Part;
|
||||||
|
|
||||||
|
use PhpOffice\Common\Microsoft\PasswordEncoder;
|
||||||
use PhpOffice\PhpWord\ComplexType\ProofState;
|
use PhpOffice\PhpWord\ComplexType\ProofState;
|
||||||
use PhpOffice\PhpWord\ComplexType\TrackChangesView;
|
use PhpOffice\PhpWord\ComplexType\TrackChangesView;
|
||||||
use PhpOffice\PhpWord\PhpWord;
|
use PhpOffice\PhpWord\PhpWord;
|
||||||
use PhpOffice\PhpWord\Settings;
|
|
||||||
use PhpOffice\PhpWord\Shared\Microsoft\PasswordEncoder;
|
|
||||||
use PhpOffice\PhpWord\SimpleType\Zoom;
|
use PhpOffice\PhpWord\SimpleType\Zoom;
|
||||||
use PhpOffice\PhpWord\Style\Language;
|
use PhpOffice\PhpWord\Style\Language;
|
||||||
use PhpOffice\PhpWord\TestHelperDOCX;
|
use PhpOffice\PhpWord\TestHelperDOCX;
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ class FontTest extends \PHPUnit\Framework\TestCase
|
||||||
$phpWord = new \PhpOffice\PhpWord\PhpWord();
|
$phpWord = new \PhpOffice\PhpWord\PhpWord();
|
||||||
$section = $phpWord->addSection();
|
$section = $phpWord->addSection();
|
||||||
$textrun = $section->addTextRun();
|
$textrun = $section->addTextRun();
|
||||||
$textrun->addText('سلام این یک پاراگراف راست به چپ است', array('rtl' => true));
|
$textrun->addText('سلام این یک پاراگراف راست به چپ است', array('rtl' => true, 'lang' => 'ar-DZ'));
|
||||||
$doc = TestHelperDOCX::getDocument($phpWord, 'Word2007');
|
$doc = TestHelperDOCX::getDocument($phpWord, 'Word2007');
|
||||||
|
|
||||||
$file = 'word/document.xml';
|
$file = 'word/document.xml';
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,8 @@
|
||||||
|
|
||||||
namespace PhpOffice\PhpWord\Writer\Word2007\Style;
|
namespace PhpOffice\PhpWord\Writer\Word2007\Style;
|
||||||
|
|
||||||
|
use PhpOffice\PhpWord\ComplexType\TblWidth as TblWidthComplexType;
|
||||||
|
use PhpOffice\PhpWord\SimpleType\TblWidth;
|
||||||
use PhpOffice\PhpWord\Style\Table;
|
use PhpOffice\PhpWord\Style\Table;
|
||||||
use PhpOffice\PhpWord\Style\TablePosition;
|
use PhpOffice\PhpWord\Style\TablePosition;
|
||||||
use PhpOffice\PhpWord\TestHelperDOCX;
|
use PhpOffice\PhpWord\TestHelperDOCX;
|
||||||
|
|
@ -75,7 +77,7 @@ class TableTest extends \PHPUnit\Framework\TestCase
|
||||||
$path = '/w:document/w:body/w:tbl/w:tblPr/w:tblCellSpacing';
|
$path = '/w:document/w:body/w:tbl/w:tblPr/w:tblCellSpacing';
|
||||||
$this->assertTrue($doc->elementExists($path));
|
$this->assertTrue($doc->elementExists($path));
|
||||||
$this->assertEquals(10.3, $doc->getElementAttribute($path, 'w:w'));
|
$this->assertEquals(10.3, $doc->getElementAttribute($path, 'w:w'));
|
||||||
$this->assertEquals(\PhpOffice\PhpWord\SimpleType\TblWidth::TWIP, $doc->getElementAttribute($path, 'w:type'));
|
$this->assertEquals(TblWidth::TWIP, $doc->getElementAttribute($path, 'w:type'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -118,4 +120,25 @@ class TableTest extends \PHPUnit\Framework\TestCase
|
||||||
$this->assertEquals(TablePosition::YALIGN_TOP, $doc->getElementAttribute($path, 'w:tblpYSpec'));
|
$this->assertEquals(TablePosition::YALIGN_TOP, $doc->getElementAttribute($path, 'w:tblpYSpec'));
|
||||||
$this->assertEquals(60, $doc->getElementAttribute($path, 'w:tblpY'));
|
$this->assertEquals(60, $doc->getElementAttribute($path, 'w:tblpY'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testIndent()
|
||||||
|
{
|
||||||
|
$value = 100;
|
||||||
|
$type = TblWidth::TWIP;
|
||||||
|
|
||||||
|
$tableStyle = new Table();
|
||||||
|
$tableStyle->setIndent(new TblWidthComplexType($value, $type));
|
||||||
|
|
||||||
|
$phpWord = new \PhpOffice\PhpWord\PhpWord();
|
||||||
|
$section = $phpWord->addSection();
|
||||||
|
$table = $section->addTable($tableStyle);
|
||||||
|
$table->addRow();
|
||||||
|
|
||||||
|
$doc = TestHelperDOCX::getDocument($phpWord, 'Word2007');
|
||||||
|
|
||||||
|
$path = '/w:document/w:body/w:tbl/w:tblPr/w:tblInd';
|
||||||
|
$this->assertTrue($doc->elementExists($path));
|
||||||
|
$this->assertSame($value, (int) $doc->getElementAttribute($path, 'w:w'));
|
||||||
|
$this->assertSame($type, $doc->getElementAttribute($path, 'w:type'));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,9 +37,9 @@ class XmlDocument
|
||||||
private $dom;
|
private $dom;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DOMXpath object
|
* DOMXPath object
|
||||||
*
|
*
|
||||||
* @var \DOMXpath
|
* @var \DOMXPath
|
||||||
*/
|
*/
|
||||||
private $xpath;
|
private $xpath;
|
||||||
|
|
||||||
|
|
@ -76,8 +76,10 @@ class XmlDocument
|
||||||
$this->file = $file;
|
$this->file = $file;
|
||||||
|
|
||||||
$file = $this->path . '/' . $file;
|
$file = $this->path . '/' . $file;
|
||||||
|
libxml_disable_entity_loader(false);
|
||||||
$this->dom = new \DOMDocument();
|
$this->dom = new \DOMDocument();
|
||||||
$this->dom->load($file);
|
$this->dom->load($file);
|
||||||
|
libxml_disable_entity_loader(true);
|
||||||
|
|
||||||
return $this->dom;
|
return $this->dom;
|
||||||
}
|
}
|
||||||
|
|
@ -96,7 +98,7 @@ class XmlDocument
|
||||||
}
|
}
|
||||||
|
|
||||||
if (null === $this->xpath) {
|
if (null === $this->xpath) {
|
||||||
$this->xpath = new \DOMXpath($this->dom);
|
$this->xpath = new \DOMXPath($this->dom);
|
||||||
$this->xpath->registerNamespace('w14', 'http://schemas.microsoft.com/office/word/2010/wordml');
|
$this->xpath->registerNamespace('w14', 'http://schemas.microsoft.com/office/word/2010/wordml');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue