Updates to 3rd party libraries
Add Dockerfile and specific docker-php.ini
This commit is contained in:
24
inc/vendor/phpoffice/phpspreadsheet/.sami.php
vendored
Normal file
24
inc/vendor/phpoffice/phpspreadsheet/.sami.php
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
use Sami\RemoteRepository\GitHubRemoteRepository;
|
||||
use Sami\Sami;
|
||||
use Sami\Version\GitVersionCollection;
|
||||
use Symfony\Component\Finder\Finder;
|
||||
|
||||
$iterator = Finder::create()
|
||||
->files()
|
||||
->name('*.php')
|
||||
->in($dir = __DIR__ . '/src');
|
||||
$versions = GitVersionCollection::create($dir)
|
||||
->addFromTags(function ($version) {
|
||||
return preg_match('~^\d+\.\d+\.\d+$~', $version);
|
||||
})
|
||||
->add('master');
|
||||
|
||||
return new Sami($iterator, [
|
||||
'title' => 'PhpSpreadsheet',
|
||||
'versions' => $versions,
|
||||
'build_dir' => __DIR__ . '/build/%version%',
|
||||
'cache_dir' => __DIR__ . '/cache/%version%',
|
||||
'remote_repository' => new GitHubRemoteRepository('PHPOffice/PhpSpreadsheet', dirname($dir)),
|
||||
]);
|
21
inc/vendor/phpoffice/phpspreadsheet/.travis.yml
vendored
21
inc/vendor/phpoffice/phpspreadsheet/.travis.yml
vendored
@ -10,6 +10,7 @@ php:
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- cache
|
||||
- vendor
|
||||
- $HOME/.composer/cache
|
||||
|
||||
@ -28,7 +29,7 @@ jobs:
|
||||
php: 7.1
|
||||
script:
|
||||
- ./vendor/bin/php-cs-fixer fix --diff --verbose --dry-run
|
||||
- ./vendor/bin/phpcs --report-width=200 --report-summary --report-full samples/ src/ tests/ --ignore=samples/Header.php --standard=PSR2 -n
|
||||
- ./vendor/bin/phpcs --report-width=200 samples/ src/ tests/ --ignore=samples/Header.php --standard=PSR2 -n
|
||||
|
||||
- stage: Coverage
|
||||
php: 7.1
|
||||
@ -38,3 +39,21 @@ jobs:
|
||||
after_script:
|
||||
- wget https://scrutinizer-ci.com/ocular.phar
|
||||
- php ocular.phar code-coverage:upload --format=php-clover tests/coverage-clover.xml
|
||||
|
||||
- stage: API documentation
|
||||
php: 7.1
|
||||
before_script:
|
||||
- curl -O http://get.sensiolabs.org/sami.phar
|
||||
script:
|
||||
- git fetch origin master:master
|
||||
- git fetch origin --tags
|
||||
- php sami.phar update .sami.php
|
||||
- echo '<html><head><meta http-equiv="Refresh" content="0; url=master/"></head><body><p>If you are not automatically redirected, please go to <a href="master/">the latest stable API documentation</a>.</p></body></html>' > build/index.html
|
||||
deploy:
|
||||
provider: pages
|
||||
skip-cleanup: true
|
||||
local-dir: build
|
||||
github-token: $GITHUB_TOKEN
|
||||
on:
|
||||
all_branches: true
|
||||
condition: $TRAVIS_BRANCH =~ ^master|develop$
|
||||
|
89
inc/vendor/phpoffice/phpspreadsheet/CHANGELOG.md
vendored
89
inc/vendor/phpoffice/phpspreadsheet/CHANGELOG.md
vendored
@ -5,6 +5,95 @@ All notable changes to this project will be documented in this file.
|
||||
The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
||||
and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
## [1.4.0] - 2018-08-06
|
||||
|
||||
### Added
|
||||
|
||||
- Add excel function EXACT(value1, value2) support - [#595](https://github.com/PHPOffice/PhpSpreadsheet/pull/595)
|
||||
- Support workbook view attributes for Xlsx format - [#523](https://github.com/PHPOffice/PhpSpreadsheet/issues/523)
|
||||
- Read and write hyperlink for drawing image - [#490](https://github.com/PHPOffice/PhpSpreadsheet/pull/490)
|
||||
- Added calculation engine support for the new bitwise functions that were added in MS Excel 2013
|
||||
- BITAND() Returns a Bitwise 'And' of two numbers
|
||||
- BITOR() Returns a Bitwise 'Or' of two number
|
||||
- BITXOR() Returns a Bitwise 'Exclusive Or' of two numbers
|
||||
- BITLSHIFT() Returns a number shifted left by a specified number of bits
|
||||
- BITRSHIFT() Returns a number shifted right by a specified number of bits
|
||||
- Added calculation engine support for other new functions that were added in MS Excel 2013 and MS Excel 2016
|
||||
- Text Functions
|
||||
- CONCAT() Synonym for CONCATENATE()
|
||||
- NUMBERVALUE() Converts text to a number, in a locale-independent way
|
||||
- UNICHAR() Synonym for CHAR() in PHPSpreadsheet, which has always used UTF-8 internally
|
||||
- UNIORD() Synonym for ORD() in PHPSpreadsheet, which has always used UTF-8 internally
|
||||
- TEXTJOIN() Joins together two or more text strings, separated by a delimiter
|
||||
- Logical Functions
|
||||
- XOR() Returns a logical Exclusive Or of all arguments
|
||||
- Date/Time Functions
|
||||
- ISOWEEKNUM() Returns the ISO 8601 week number of the year for a given date
|
||||
- Lookup and Reference Functions
|
||||
- FORMULATEXT() Returns a formula as a string
|
||||
- Financial Functions
|
||||
- PDURATION() Calculates the number of periods required for an investment to reach a specified value
|
||||
- RRI() Calculates the interest rate required for an investment to grow to a specified future value
|
||||
- Engineering Functions
|
||||
- ERF.PRECISE() Returns the error function integrated between 0 and a supplied limit
|
||||
- ERFC.PRECISE() Synonym for ERFC
|
||||
- Math and Trig Functions
|
||||
- SEC() Returns the secant of an angle
|
||||
- SECH() Returns the hyperbolic secant of an angle
|
||||
- CSC() Returns the cosecant of an angle
|
||||
- CSCH() Returns the hyperbolic cosecant of an angle
|
||||
- COT() Returns the cotangent of an angle
|
||||
- COTH() Returns the hyperbolic cotangent of an angle
|
||||
- ACOT() Returns the cotangent of an angle
|
||||
- ACOTH() Returns the hyperbolic cotangent of an angle
|
||||
- Refactored Complex Engineering Functions to use external complex number library
|
||||
- Added calculation engine support for the new complex number functions that were added in MS Excel 2013
|
||||
- IMCOSH() Returns the hyperbolic cosine of a complex number
|
||||
- IMCOT() Returns the cotangent of a complex number
|
||||
- IMCSC() Returns the cosecant of a complex number
|
||||
- IMCSCH() Returns the hyperbolic cosecant of a complex number
|
||||
- IMSEC() Returns the secant of a complex number
|
||||
- IMSECH() Returns the hyperbolic secant of a complex number
|
||||
- IMSINH() Returns the hyperbolic sine of a complex number
|
||||
- IMTAN() Returns the tangent of a complex number
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix ISFORMULA() function to work with a cell reference to another worksheet
|
||||
- Xlsx reader crashed when reading a file with workbook protection - [#553](https://github.com/PHPOffice/PhpSpreadsheet/pull/553)
|
||||
- Cell formats with escaped spaces were causing incorrect date formatting - [#557](https://github.com/PHPOffice/PhpSpreadsheet/issues/557)
|
||||
- Could not open CSV file containing HTML fragment - [#564](https://github.com/PHPOffice/PhpSpreadsheet/issues/564)
|
||||
- Exclude the vendor folder in migration - [#481](https://github.com/PHPOffice/PhpSpreadsheet/issues/481)
|
||||
- Chained operations on cell ranges involving borders operated on last cell only [#428](https://github.com/PHPOffice/PhpSpreadsheet/issues/428)
|
||||
- Avoid memory exhaustion when cloning worksheet with a drawing [#437](https://github.com/PHPOffice/PhpSpreadsheet/issues/437)
|
||||
- Migration tool keep variables containing $PHPExcel untouched [#598](https://github.com/PHPOffice/PhpSpreadsheet/issues/598)
|
||||
- Rowspans/colspans were incorrect when adding worksheet using loadIntoExisting [#619](https://github.com/PHPOffice/PhpSpreadsheet/issues/619)
|
||||
|
||||
## [1.3.1] - 2018-06-12
|
||||
|
||||
### Fixed
|
||||
|
||||
- Ranges across Z and AA columns incorrectly threw an exception - [#545](https://github.com/PHPOffice/PhpSpreadsheet/issues/545)
|
||||
|
||||
## [1.3.0] - 2018-06-10
|
||||
|
||||
### Added
|
||||
|
||||
- Support to read Xlsm templates with form elements, macros, printer settings, protected elements and back compatibility drawing, and save result without losing important elements of document - [#435](https://github.com/PHPOffice/PhpSpreadsheet/issues/435)
|
||||
- Expose sheet title maximum length as `Worksheet::SHEET_TITLE_MAXIMUM_LENGTH` - [#482](https://github.com/PHPOffice/PhpSpreadsheet/issues/482)
|
||||
- Allow escape character to be set in CSV reader – [#492](https://github.com/PHPOffice/PhpSpreadsheet/issues/492)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Subtotal 9 in a group that has other subtotals 9 exclude the totals of the other subtotals in the range - [#332](https://github.com/PHPOffice/PhpSpreadsheet/issues/332)
|
||||
- `Helper\Html` support UTF-8 HTML input - [#444](https://github.com/PHPOffice/PhpSpreadsheet/issues/444)
|
||||
- Xlsx loaded an extra empty comment for each real comment - [#375](https://github.com/PHPOffice/PhpSpreadsheet/issues/375)
|
||||
- Xlsx reader do not read rows and columns filtered out in readFilter at all - [#370](https://github.com/PHPOffice/PhpSpreadsheet/issues/370)
|
||||
- Make newer Excel versions properly recalculate formulas on document open - [#456](https://github.com/PHPOffice/PhpSpreadsheet/issues/456)
|
||||
- `Coordinate::extractAllCellReferencesInRange()` throws an exception for an invalid range – [#519](https://github.com/PHPOffice/PhpSpreadsheet/issues/519)
|
||||
- Fixed parsing of conditionals in COUNTIF functions - [#526](https://github.com/PHPOffice/PhpSpreadsheet/issues/526)
|
||||
- Corruption errors for saved Xlsx docs with frozen panes - [#532](https://github.com/PHPOffice/PhpSpreadsheet/issues/532)
|
||||
|
||||
## [1.2.1] - 2018-04-10
|
||||
|
||||
### Fixed
|
||||
|
@ -18,9 +18,7 @@ PhpSpreadsheet is a library written in pure PHP and providing a set of classes t
|
||||
|
||||
## Documentation
|
||||
|
||||
Read more about it, including install instructions, in the official documentation:
|
||||
|
||||
https://phpspreadsheet.readthedocs.io
|
||||
Read more about it, including install instructions, in the [official documentation](https://phpspreadsheet.readthedocs.io). Or check out the [API documentation](https://phpoffice.github.io/PhpSpreadsheet/master).
|
||||
|
||||
Please ask your support questions on [StackOverflow](http://stackoverflow.com/questions/tagged/phpspreadsheet), or have a quick chat on [Gitter](https://gitter.im/PHPOffice/PhpSpreadsheet).
|
||||
|
||||
|
@ -25,7 +25,7 @@
|
||||
"scripts": {
|
||||
"check": [
|
||||
"php-cs-fixer fix --ansi --dry-run --diff",
|
||||
"phpcs --report-width=200 --report-summary --report-full samples/ src/ tests/ --ignore=samples/Header.php --standard=PSR2 -n",
|
||||
"phpcs --report-width=200 samples/ src/ tests/ --ignore=samples/Header.php --standard=PSR2 -n",
|
||||
"phpunit --color=always"
|
||||
],
|
||||
"fix": [
|
||||
@ -46,16 +46,17 @@
|
||||
"ext-xmlwriter": "*",
|
||||
"ext-zip": "*",
|
||||
"ext-zlib": "*",
|
||||
"psr/simple-cache": "^1.0"
|
||||
"psr/simple-cache": "^1.0",
|
||||
"markbaker/complex": "^1.4.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"tecnickcom/tcpdf": "^6.2",
|
||||
"squizlabs/php_codesniffer": "^2.7",
|
||||
"phpunit/phpunit": "^5.7",
|
||||
"dompdf/dompdf": "^0.8.0",
|
||||
"mpdf/mpdf": "^7.0.0",
|
||||
"jpgraph/jpgraph": "^4.0",
|
||||
"friendsofphp/php-cs-fixer": "@stable"
|
||||
"friendsofphp/php-cs-fixer": "@stable",
|
||||
"squizlabs/php_codesniffer": "^3.3"
|
||||
},
|
||||
"suggest": {
|
||||
"mpdf/mpdf": "Option for rendering PDF with PDF Writer",
|
||||
|
146
inc/vendor/phpoffice/phpspreadsheet/composer.lock
generated
vendored
146
inc/vendor/phpoffice/phpspreadsheet/composer.lock
generated
vendored
@ -1,11 +1,106 @@
|
||||
{
|
||||
"_readme": [
|
||||
"This file locks the dependencies of your project to a known state",
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "e61a906bd83393400add286703f10557",
|
||||
"content-hash": "66067b3ab7afd673a28cf0b31eb9ae20",
|
||||
"packages": [
|
||||
{
|
||||
"name": "markbaker/complex",
|
||||
"version": "1.4.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/MarkBaker/PHPComplex.git",
|
||||
"reference": "615f5443473cf37729666e2354fd8dfa2cb48e91"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/MarkBaker/PHPComplex/zipball/615f5443473cf37729666e2354fd8dfa2cb48e91",
|
||||
"reference": "615f5443473cf37729666e2354fd8dfa2cb48e91",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^5.6.0|^7.0.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"dealerdirect/phpcodesniffer-composer-installer": "^0.4.3",
|
||||
"phpdocumentor/phpdocumentor": "2.*",
|
||||
"phploc/phploc": "2.*",
|
||||
"phpmd/phpmd": "2.*",
|
||||
"phpunit/phpunit": "^4.8.35|^5.4.0",
|
||||
"sebastian/phpcpd": "2.*",
|
||||
"squizlabs/php_codesniffer": "^3.1.1",
|
||||
"wimg/php-compatibility": "^8.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Complex\\": "classes/src/"
|
||||
},
|
||||
"files": [
|
||||
"classes/src/functions/abs.php",
|
||||
"classes/src/functions/acos.php",
|
||||
"classes/src/functions/acosh.php",
|
||||
"classes/src/functions/acot.php",
|
||||
"classes/src/functions/acoth.php",
|
||||
"classes/src/functions/acsc.php",
|
||||
"classes/src/functions/acsch.php",
|
||||
"classes/src/functions/argument.php",
|
||||
"classes/src/functions/asec.php",
|
||||
"classes/src/functions/asech.php",
|
||||
"classes/src/functions/asin.php",
|
||||
"classes/src/functions/asinh.php",
|
||||
"classes/src/functions/atan.php",
|
||||
"classes/src/functions/atanh.php",
|
||||
"classes/src/functions/conjugate.php",
|
||||
"classes/src/functions/cos.php",
|
||||
"classes/src/functions/cosh.php",
|
||||
"classes/src/functions/cot.php",
|
||||
"classes/src/functions/coth.php",
|
||||
"classes/src/functions/csc.php",
|
||||
"classes/src/functions/csch.php",
|
||||
"classes/src/functions/exp.php",
|
||||
"classes/src/functions/inverse.php",
|
||||
"classes/src/functions/ln.php",
|
||||
"classes/src/functions/log2.php",
|
||||
"classes/src/functions/log10.php",
|
||||
"classes/src/functions/negative.php",
|
||||
"classes/src/functions/pow.php",
|
||||
"classes/src/functions/rho.php",
|
||||
"classes/src/functions/sec.php",
|
||||
"classes/src/functions/sech.php",
|
||||
"classes/src/functions/sin.php",
|
||||
"classes/src/functions/sinh.php",
|
||||
"classes/src/functions/sqrt.php",
|
||||
"classes/src/functions/tan.php",
|
||||
"classes/src/functions/tanh.php",
|
||||
"classes/src/functions/theta.php",
|
||||
"classes/src/operations/add.php",
|
||||
"classes/src/operations/subtract.php",
|
||||
"classes/src/operations/multiply.php",
|
||||
"classes/src/operations/divideby.php",
|
||||
"classes/src/operations/divideinto.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Mark Baker",
|
||||
"email": "mark@lange.demon.co.uk"
|
||||
}
|
||||
],
|
||||
"description": "PHP Class for working with complex numbers",
|
||||
"homepage": "https://github.com/MarkBaker/PHPComplex",
|
||||
"keywords": [
|
||||
"complex",
|
||||
"mathematics"
|
||||
],
|
||||
"time": "2018-07-24T19:47:28+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/simple-cache",
|
||||
"version": "1.0.0",
|
||||
@ -2106,64 +2201,37 @@
|
||||
},
|
||||
{
|
||||
"name": "squizlabs/php_codesniffer",
|
||||
"version": "2.8.1",
|
||||
"version": "3.3.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/squizlabs/PHP_CodeSniffer.git",
|
||||
"reference": "d7cf0d894e8aa4c73712ee4a331cc1eaa37cdc7d"
|
||||
"reference": "628a481780561150481a9ec74709092b9759b3ec"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/d7cf0d894e8aa4c73712ee4a331cc1eaa37cdc7d",
|
||||
"reference": "d7cf0d894e8aa4c73712ee4a331cc1eaa37cdc7d",
|
||||
"url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/628a481780561150481a9ec74709092b9759b3ec",
|
||||
"reference": "628a481780561150481a9ec74709092b9759b3ec",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-simplexml": "*",
|
||||
"ext-tokenizer": "*",
|
||||
"ext-xmlwriter": "*",
|
||||
"php": ">=5.1.2"
|
||||
"php": ">=5.4.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "~4.0"
|
||||
"phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0"
|
||||
},
|
||||
"bin": [
|
||||
"scripts/phpcs",
|
||||
"scripts/phpcbf"
|
||||
"bin/phpcs",
|
||||
"bin/phpcbf"
|
||||
],
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.x-dev"
|
||||
"dev-master": "3.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
"CodeSniffer.php",
|
||||
"CodeSniffer/CLI.php",
|
||||
"CodeSniffer/Exception.php",
|
||||
"CodeSniffer/File.php",
|
||||
"CodeSniffer/Fixer.php",
|
||||
"CodeSniffer/Report.php",
|
||||
"CodeSniffer/Reporting.php",
|
||||
"CodeSniffer/Sniff.php",
|
||||
"CodeSniffer/Tokens.php",
|
||||
"CodeSniffer/Reports/",
|
||||
"CodeSniffer/Tokenizers/",
|
||||
"CodeSniffer/DocGenerators/",
|
||||
"CodeSniffer/Standards/AbstractPatternSniff.php",
|
||||
"CodeSniffer/Standards/AbstractScopeSniff.php",
|
||||
"CodeSniffer/Standards/AbstractVariableSniff.php",
|
||||
"CodeSniffer/Standards/IncorrectPatternException.php",
|
||||
"CodeSniffer/Standards/Generic/Sniffs/",
|
||||
"CodeSniffer/Standards/MySource/Sniffs/",
|
||||
"CodeSniffer/Standards/PEAR/Sniffs/",
|
||||
"CodeSniffer/Standards/PSR1/Sniffs/",
|
||||
"CodeSniffer/Standards/PSR2/Sniffs/",
|
||||
"CodeSniffer/Standards/Squiz/Sniffs/",
|
||||
"CodeSniffer/Standards/Zend/Sniffs/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
@ -2180,7 +2248,7 @@
|
||||
"phpcs",
|
||||
"standards"
|
||||
],
|
||||
"time": "2017-03-01T22:17:45+00:00"
|
||||
"time": "2018-07-26T23:47:18+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/console",
|
||||
|
@ -1,57 +0,0 @@
|
||||
var nodemcu = nodemcu || {};
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
$(document).ready(function () {
|
||||
fixSearch();
|
||||
});
|
||||
|
||||
/*
|
||||
* RTD messes up MkDocs' search feature by tinkering with the search box defined in the theme, see
|
||||
* https://github.com/rtfd/readthedocs.org/issues/1088. This function sets up a DOM4 MutationObserver
|
||||
* to react to changes to the search form (triggered by RTD on doc ready). It then reverts everything
|
||||
* the RTD JS code modified.
|
||||
*/
|
||||
function fixSearch() {
|
||||
var target = document.getElementById('rtd-search-form');
|
||||
var config = {attributes: true, childList: true};
|
||||
|
||||
var observer = new MutationObserver(function (mutations) {
|
||||
// if it isn't disconnected it'll loop infinitely because the observed element is modified
|
||||
observer.disconnect();
|
||||
var form = $('#rtd-search-form');
|
||||
form.empty();
|
||||
form.attr('action', 'https://' + window.location.hostname + '/en/' + determineSelectedBranch() + '/search.html');
|
||||
$('<input>').attr({
|
||||
type: "text",
|
||||
name: "q",
|
||||
placeholder: "Search docs"
|
||||
}).appendTo(form);
|
||||
});
|
||||
|
||||
if (window.location.origin.indexOf('readthedocs') > -1) {
|
||||
observer.observe(target, config);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Analyzes the URL of the current page to find out what the selected GitHub branch is. It's usually
|
||||
* part of the location path. The code needs to distinguish between running MkDocs standalone
|
||||
* and docs served from RTD. If no valid branch could be determined 'dev' returned.
|
||||
*
|
||||
* @returns GitHub branch name
|
||||
*/
|
||||
function determineSelectedBranch() {
|
||||
var branch = 'dev', path = window.location.pathname;
|
||||
if (window.location.origin.indexOf('readthedocs') > -1) {
|
||||
// path is like /en/<branch>/<lang>/build/ -> extract 'lang'
|
||||
// split[0] is an '' because the path starts with the separator
|
||||
var thirdPathSegment = path.split('/')[2];
|
||||
// 'latest' is an alias on RTD for the 'dev' branch - which is the default for 'branch' here
|
||||
if (thirdPathSegment !== 'latest') {
|
||||
branch = thirdPathSegment;
|
||||
}
|
||||
}
|
||||
return branch;
|
||||
}
|
||||
}());
|
@ -95,6 +95,8 @@ architecture](./topics/architecture.md),
|
||||
[accessing cells](./topics/accessing-cells.md) and
|
||||
[reading and writing to files](./topics/reading-and-writing-to-file.md).
|
||||
|
||||
Or browse the [API documentation](https://phpoffice.github.io/PhpSpreadsheet/master).
|
||||
|
||||
# Credits
|
||||
|
||||
Please refer to the [contributor
|
||||
|
@ -750,6 +750,24 @@
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding-left: 1em;">Drawing hyperlink</td>
|
||||
<td></td>
|
||||
<td style="text-align: center; color: green;">✔</td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td style="text-align: center; color: green;">✔</td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td>$drawing->getHyperlink()->getUrl()</td>
|
||||
<td>$drawing->setHyperlink()->setUrl($url)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>Cell Formatting</strong></td>
|
||||
<td></td>
|
||||
|
@ -41,6 +41,7 @@ DAYS360 | \PhpOffice\PhpSpreadsheet\Calculation\DateTime::DAYS360
|
||||
EDATE | \PhpOffice\PhpSpreadsheet\Calculation\DateTime::EDATE
|
||||
EOMONTH | \PhpOffice\PhpSpreadsheet\Calculation\DateTime::EOMONTH
|
||||
HOUR | \PhpOffice\PhpSpreadsheet\Calculation\DateTime::HOUROFDAY
|
||||
ISOWEEKNUM | \PhpOffice\PhpSpreadsheet\Calculation\DateTime::ISOWEEKNUM
|
||||
MINUTE | \PhpOffice\PhpSpreadsheet\Calculation\DateTime::MINUTE
|
||||
MONTH | \PhpOffice\PhpSpreadsheet\Calculation\DateTime::MONTHOFYEAR
|
||||
NETWORKDAYS | \PhpOffice\PhpSpreadsheet\Calculation\DateTime::NETWORKDAYS
|
||||
@ -73,7 +74,9 @@ DEC2HEX | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::DECTOHE
|
||||
DEC2OCT | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::DECTOOCT
|
||||
DELTA | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::DELTA
|
||||
ERF | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::ERF
|
||||
ERF.PRECISE | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::ERFPRECISE
|
||||
ERFC | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::ERFC
|
||||
ERFC.PRECISE | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::ERFC
|
||||
GESTEP | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::GESTEP
|
||||
HEX2BIN | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::HEXTOBIN
|
||||
HEX2DEC | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::HEXTODEC
|
||||
@ -83,6 +86,10 @@ IMAGINARY | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMAGINA
|
||||
IMARGUMENT | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMARGUMENT
|
||||
IMCONJUGATE | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMCONJUGATE
|
||||
IMCOS | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMCOS
|
||||
IMCOSH | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMCOSH
|
||||
IMCOT | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMCOT
|
||||
IMCSC | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMCSC
|
||||
IMCSCH | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMCSCH
|
||||
IMDIV | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMDIV
|
||||
IMEXP | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMEXP
|
||||
IMLN | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMLN
|
||||
@ -91,10 +98,14 @@ IMLOG2 | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMLOG2
|
||||
IMPOWER | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMPOWER
|
||||
IMPRODUCT | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMPRODUCT
|
||||
IMREAL | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMREAL
|
||||
IMSEC | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMSEC
|
||||
IMSECH | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMSECH
|
||||
IMSIN | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMSIN
|
||||
IMSINH | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMSINH
|
||||
IMSQRT | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMSQRT
|
||||
IMSUB | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMSUB
|
||||
IMSUM | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMSUM
|
||||
IMTAN | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMTAN
|
||||
OCT2BIN | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::OCTTOBIN
|
||||
OCT2DEC | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::OCTTODEC
|
||||
OCT2HEX | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::OCTTOHEX
|
||||
@ -137,6 +148,7 @@ ODDFPRICE | **Not yet Implemented**
|
||||
ODDFYIELD | **Not yet Implemented**
|
||||
ODDLPRICE | **Not yet Implemented**
|
||||
ODDLYIELD | **Not yet Implemented**
|
||||
PDURATION | \PhpOffice\PhpSpreadsheet\Calculation\Financial::PDURATION
|
||||
PMT | \PhpOffice\PhpSpreadsheet\Calculation\Financial::PMT
|
||||
PPMT | \PhpOffice\PhpSpreadsheet\Calculation\Financial::PPMT
|
||||
PRICE | \PhpOffice\PhpSpreadsheet\Calculation\Financial::PRICE
|
||||
@ -145,6 +157,7 @@ PRICEMAT | \PhpOffice\PhpSpreadsheet\Calculation\Financial::PRICEMAT
|
||||
PV | \PhpOffice\PhpSpreadsheet\Calculation\Financial::PV
|
||||
RATE | \PhpOffice\PhpSpreadsheet\Calculation\Financial::RATE
|
||||
RECEIVED | \PhpOffice\PhpSpreadsheet\Calculation\Financial::RECEIVED
|
||||
RRI | \PhpOffice\PhpSpreadsheet\Calculation\Financial::RRI
|
||||
SLN | \PhpOffice\PhpSpreadsheet\Calculation\Financial::SLN
|
||||
SYD | \PhpOffice\PhpSpreadsheet\Calculation\Financial::SYD
|
||||
TBILLEQ | \PhpOffice\PhpSpreadsheet\Calculation\Financial::TBILLEQ
|
||||
@ -169,6 +182,7 @@ ISBLANK | \PhpOffice\PhpSpreadsheet\Calculation\Functions::IS_BLANK
|
||||
ISERR | \PhpOffice\PhpSpreadsheet\Calculation\Functions::IS_ERR
|
||||
ISERROR | \PhpOffice\PhpSpreadsheet\Calculation\Functions::IS_ERROR
|
||||
ISEVEN | \PhpOffice\PhpSpreadsheet\Calculation\Functions::IS_EVEN
|
||||
ISFORMULA | \PhpOffice\PhpSpreadsheet\Calculation\Functions::ISFORMULA
|
||||
ISLOGICAL | \PhpOffice\PhpSpreadsheet\Calculation\Functions::IS_LOGICAL
|
||||
ISNA | \PhpOffice\PhpSpreadsheet\Calculation\Functions::IS_NA
|
||||
ISNONTEXT | \PhpOffice\PhpSpreadsheet\Calculation\Functions::IS_NONTEXT
|
||||
@ -184,13 +198,14 @@ TYPE | \PhpOffice\PhpSpreadsheet\Calculation\Functions::TYPE
|
||||
|
||||
Excel Function | PhpSpreadsheet Function
|
||||
--------------------|-------------------------------------------
|
||||
AND | \PhpOffice\PhpSpreadsheet\Calculation\Logical::LOGICAL_AND
|
||||
AND | \PhpOffice\PhpSpreadsheet\Calculation\Logical::logicalAnd
|
||||
FALSE | \PhpOffice\PhpSpreadsheet\Calculation\Logical::FALSE
|
||||
IF | \PhpOffice\PhpSpreadsheet\Calculation\Logical::STATEMENT_IF
|
||||
IFERROR | \PhpOffice\PhpSpreadsheet\Calculation\Logical::IFERROR
|
||||
NOT | \PhpOffice\PhpSpreadsheet\Calculation\Logical::NOT
|
||||
OR | \PhpOffice\PhpSpreadsheet\Calculation\Logical::LOGICAL_OR
|
||||
OR | \PhpOffice\PhpSpreadsheet\Calculation\Logical::logicalOr
|
||||
TRUE | \PhpOffice\PhpSpreadsheet\Calculation\Logical::TRUE
|
||||
XOR | \PhpOffice\PhpSpreadsheet\Calculation\Logical::logicalXor
|
||||
|
||||
## CATEGORY_LOOKUP_AND_REFERENCE
|
||||
|
||||
@ -201,8 +216,9 @@ AREAS | **Not yet Implemented**
|
||||
CHOOSE | \PhpOffice\PhpSpreadsheet\Calculation\LookupRef::CHOOSE
|
||||
COLUMN | \PhpOffice\PhpSpreadsheet\Calculation\LookupRef::COLUMN
|
||||
COLUMNS | \PhpOffice\PhpSpreadsheet\Calculation\LookupRef::COLUMNS
|
||||
FORMULATEXT | \PhpOffice\PhpSpreadsheet\Calculation\LookupRef::FORMULATEXT
|
||||
GETPIVOTDATA | **Not yet Implemented**
|
||||
HLOOKUP | **Not yet Implemented**
|
||||
HLOOKUP | \PhpOffice\PhpSpreadsheet\Calculation\LookupRef::HLOOKUP
|
||||
HYPERLINK | \PhpOffice\PhpSpreadsheet\Calculation\LookupRef::HYPERLINK
|
||||
INDEX | \PhpOffice\PhpSpreadsheet\Calculation\LookupRef::INDEX
|
||||
INDIRECT | \PhpOffice\PhpSpreadsheet\Calculation\LookupRef::INDIRECT
|
||||
@ -222,6 +238,8 @@ Excel Function | PhpSpreadsheet Function
|
||||
ABS | abs
|
||||
ACOS | acos
|
||||
ACOSH | acosh
|
||||
ACOT | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::ACOT
|
||||
ACOTH | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::ACOTH
|
||||
ASIN | asin
|
||||
ASINH | asinh
|
||||
ATAN | atan
|
||||
@ -231,6 +249,10 @@ CEILING | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::CEILING
|
||||
COMBIN | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::COMBIN
|
||||
COS | cos
|
||||
COSH | cosh
|
||||
COT | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::COT
|
||||
COTH | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::COTH
|
||||
CSC | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::CSC
|
||||
CSCH | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::CSCH
|
||||
DEGREES | rad2deg
|
||||
EVEN | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::EVEN
|
||||
EXP | exp
|
||||
@ -261,6 +283,8 @@ ROMAN | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::ROMAN
|
||||
ROUND | round
|
||||
ROUNDDOWN | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::ROUNDDOWN
|
||||
ROUNDUP | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::ROUNDUP
|
||||
SEC | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::SEC
|
||||
SECH | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::SECH
|
||||
SERIESSUM | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::SERIESSUM
|
||||
SIGN | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::SIGN
|
||||
SIN | sin
|
||||
@ -270,7 +294,7 @@ SQRTPI | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::SQRTPI
|
||||
SUBTOTAL | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::SUBTOTAL
|
||||
SUM | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::SUM
|
||||
SUMIF | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::SUMIF
|
||||
SUMIFS | **Not yet Implemented**
|
||||
SUMIFS | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::SUMIFS
|
||||
SUMPRODUCT | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::SUMPRODUCT
|
||||
SUMSQ | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::SUMSQ
|
||||
SUMX2MY2 | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::SUMX2MY2
|
||||
@ -336,6 +360,7 @@ MIN | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::MIN
|
||||
MINA | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::MINA
|
||||
MINIF | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::MINIF
|
||||
MODE | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::MODE
|
||||
MODE.SNGL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::MODE
|
||||
NEGBINOMDIST | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::NEGBINOMDIST
|
||||
NORMDIST | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::NORMDIST
|
||||
NORMINV | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::NORMINV
|
||||
@ -355,6 +380,8 @@ SLOPE | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::SLOPE
|
||||
SMALL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::SMALL
|
||||
STANDARDIZE | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::STANDARDIZE
|
||||
STDEV | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::STDEV
|
||||
STDEV.S | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::STDEV
|
||||
STDEV.P | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::STDEVP
|
||||
STDEVA | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::STDEVA
|
||||
STDEVP | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::STDEVP
|
||||
STDEVPA | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::STDEVPA
|
||||
@ -365,6 +392,8 @@ TREND | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::TREND
|
||||
TRIMMEAN | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::TRIMMEAN
|
||||
TTEST | **Not yet Implemented**
|
||||
VAR | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::VARFunc
|
||||
VAR.P | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::VARP
|
||||
VAR.S | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::VARFunc
|
||||
VARA | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::VARA
|
||||
VARP | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::VARP
|
||||
VARPA | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::VARPA
|
||||
@ -380,9 +409,10 @@ BAHTTEXT | **Not yet Implemented**
|
||||
CHAR | \PhpOffice\PhpSpreadsheet\Calculation\TextData::CHARACTER
|
||||
CLEAN | \PhpOffice\PhpSpreadsheet\Calculation\TextData::TRIMNONPRINTABLE
|
||||
CODE | \PhpOffice\PhpSpreadsheet\Calculation\TextData::ASCIICODE
|
||||
CONCAT | \PhpOffice\PhpSpreadsheet\Calculation\TextData::CONCATENATE
|
||||
CONCATENATE | \PhpOffice\PhpSpreadsheet\Calculation\TextData::CONCATENATE
|
||||
DOLLAR | \PhpOffice\PhpSpreadsheet\Calculation\TextData::DOLLAR
|
||||
EXACT | **Not yet Implemented**
|
||||
EXACT | \PhpOffice\PhpSpreadsheet\Calculation\TextData::EXACT
|
||||
FIND | \PhpOffice\PhpSpreadsheet\Calculation\TextData::SEARCHSENSITIVE
|
||||
FINDB | \PhpOffice\PhpSpreadsheet\Calculation\TextData::SEARCHSENSITIVE
|
||||
FIXED | \PhpOffice\PhpSpreadsheet\Calculation\TextData::FIXEDFORMAT
|
||||
@ -394,6 +424,7 @@ LENB | \PhpOffice\PhpSpreadsheet\Calculation\TextData::STRINGLENG
|
||||
LOWER | \PhpOffice\PhpSpreadsheet\Calculation\TextData::LOWERCASE
|
||||
MID | \PhpOffice\PhpSpreadsheet\Calculation\TextData::MID
|
||||
MIDB | \PhpOffice\PhpSpreadsheet\Calculation\TextData::MID
|
||||
NUMBERVALUE | \PhpOffice\PhpSpreadsheet\Calculation\TextData::NUMBERVALUE
|
||||
PHONETIC | **Not yet Implemented**
|
||||
PROPER | \PhpOffice\PhpSpreadsheet\Calculation\TextData::PROPERCASE
|
||||
REPLACE | \PhpOffice\PhpSpreadsheet\Calculation\TextData::REPLACE
|
||||
@ -406,6 +437,9 @@ SEARCHB | \PhpOffice\PhpSpreadsheet\Calculation\TextData::SEARCHINSE
|
||||
SUBSTITUTE | \PhpOffice\PhpSpreadsheet\Calculation\TextData::SUBSTITUTE
|
||||
T | \PhpOffice\PhpSpreadsheet\Calculation\TextData::RETURNSTRING
|
||||
TEXT | \PhpOffice\PhpSpreadsheet\Calculation\TextData::TEXTFORMAT
|
||||
TEXTJOIN | \PhpOffice\PhpSpreadsheet\Calculation\TextData::TEXTJOIN
|
||||
TRIM | \PhpOffice\PhpSpreadsheet\Calculation\TextData::TRIMSPACES
|
||||
UNICHAR | \PhpOffice\PhpSpreadsheet\Calculation\TextData::CHARACTER
|
||||
UNICODE | \PhpOffice\PhpSpreadsheet\Calculation\TextData::ASCIICODE
|
||||
UPPER | \PhpOffice\PhpSpreadsheet\Calculation\TextData::UPPERCASE
|
||||
VALUE | **Not yet Implemented**
|
||||
VALUE | \PhpOffice\PhpSpreadsheet\Calculation\TextData::VALUE
|
||||
|
@ -9,10 +9,12 @@ ACCRINT | CATEGORY_FINANCIAL | \PhpOffice\PhpSpreadsheet
|
||||
ACCRINTM | CATEGORY_FINANCIAL | \PhpOffice\PhpSpreadsheet\Calculation\Financial::ACCRINTM
|
||||
ACOS | CATEGORY_MATH_AND_TRIG | acos
|
||||
ACOSH | CATEGORY_MATH_AND_TRIG | acosh
|
||||
ACOT | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::ACOT
|
||||
ACOTH | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::ACOTH
|
||||
ADDRESS | CATEGORY_LOOKUP_AND_REFERENCE | \PhpOffice\PhpSpreadsheet\Calculation\LookupRef::CELL_ADDRESS
|
||||
AMORDEGRC | CATEGORY_FINANCIAL | \PhpOffice\PhpSpreadsheet\Calculation\Financial::AMORDEGRC
|
||||
AMORLINC | CATEGORY_FINANCIAL | \PhpOffice\PhpSpreadsheet\Calculation\Financial::AMORLINC
|
||||
AND | CATEGORY_LOGICAL | \PhpOffice\PhpSpreadsheet\Calculation\Logical::LOGICAL_AND
|
||||
AND | CATEGORY_LOGICAL | \PhpOffice\PhpSpreadsheet\Calculation\Logical::logicalAnd
|
||||
AREAS | CATEGORY_LOOKUP_AND_REFERENCE | **Not yet Implemented**
|
||||
ASC | CATEGORY_TEXT_AND_DATA | **Not yet Implemented**
|
||||
ASIN | CATEGORY_MATH_AND_TRIG | asin
|
||||
@ -59,12 +61,15 @@ COLUMN | CATEGORY_LOOKUP_AND_REFERENCE | \PhpOffice\PhpSpreadsheet
|
||||
COLUMNS | CATEGORY_LOOKUP_AND_REFERENCE | \PhpOffice\PhpSpreadsheet\Calculation\LookupRef::COLUMNS
|
||||
COMBIN | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::COMBIN
|
||||
COMPLEX | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::COMPLEX
|
||||
CONCAT | CATEGORY_TEXT_AND_DATA | \PhpOffice\PhpSpreadsheet\Calculation\TextData::CONCATENATE
|
||||
CONCATENATE | CATEGORY_TEXT_AND_DATA | \PhpOffice\PhpSpreadsheet\Calculation\TextData::CONCATENATE
|
||||
CONFIDENCE | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::CONFIDENCE
|
||||
CONVERT | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::CONVERTUOM
|
||||
CORREL | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::CORREL
|
||||
COS | CATEGORY_MATH_AND_TRIG | cos
|
||||
COSH | CATEGORY_MATH_AND_TRIG | cosh
|
||||
COT | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::COT
|
||||
COTH | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::COTH
|
||||
COUNT | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::COUNT
|
||||
COUNTA | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::COUNTA
|
||||
COUNTBLANK | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::COUNTBLANK
|
||||
@ -78,6 +83,8 @@ COUPNUM | CATEGORY_FINANCIAL | \PhpOffice\PhpSpreadsheet
|
||||
COUPPCD | CATEGORY_FINANCIAL | \PhpOffice\PhpSpreadsheet\Calculation\Financial::COUPPCD
|
||||
COVAR | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::COVAR
|
||||
CRITBINOM | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::CRITBINOM
|
||||
CSC | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::CSC
|
||||
CSCH | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::CSCH
|
||||
CUBEKPIMEMBER | CATEGORY_CUBE | **Not yet Implemented**
|
||||
CUBEMEMBER | CATEGORY_CUBE | **Not yet Implemented**
|
||||
CUBEMEMBERPROPERTY | CATEGORY_CUBE | **Not yet Implemented**
|
||||
@ -131,10 +138,12 @@ EDATE | CATEGORY_DATE_AND_TIME | \PhpOffice\PhpSpreadsheet
|
||||
EFFECT | CATEGORY_FINANCIAL | \PhpOffice\PhpSpreadsheet\Calculation\Financial::EFFECT
|
||||
EOMONTH | CATEGORY_DATE_AND_TIME | \PhpOffice\PhpSpreadsheet\Calculation\DateTime::EOMONTH
|
||||
ERF | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::ERF
|
||||
ERF.PRECISE | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::ERFPRECISE
|
||||
ERFC | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::ERFC
|
||||
ERFC.PRECISE | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::ERFC
|
||||
ERROR.TYPE | CATEGORY_INFORMATION | \PhpOffice\PhpSpreadsheet\Calculation\Functions::ERROR_TYPE
|
||||
EVEN | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::EVEN
|
||||
EXACT | CATEGORY_TEXT_AND_DATA | **Not yet Implemented**
|
||||
EXACT | CATEGORY_TEXT_AND_DATA | \PhpOffice\PhpSpreadsheet\Calculation\TextData::EXACT
|
||||
EXP | CATEGORY_MATH_AND_TRIG | exp
|
||||
EXPONDIST | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::EXPONDIST
|
||||
|
||||
@ -154,6 +163,7 @@ FISHERINV | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet
|
||||
FIXED | CATEGORY_TEXT_AND_DATA | \PhpOffice\PhpSpreadsheet\Calculation\TextData::FIXEDFORMAT
|
||||
FLOOR | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::FLOOR
|
||||
FORECAST | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::FORECAST
|
||||
FORMULATEXT | CATEGORY_LOOKUP_AND_REFERENCE | \PhpOffice\PhpSpreadsheet\Calculation\LookupRef::FORMULATEXT
|
||||
FREQUENCY | CATEGORY_STATISTICAL | **Not yet Implemented**
|
||||
FTEST | CATEGORY_STATISTICAL | **Not yet Implemented**
|
||||
FV | CATEGORY_FINANCIAL | \PhpOffice\PhpSpreadsheet\Calculation\Financial::FV
|
||||
@ -180,7 +190,7 @@ HARMEAN | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet
|
||||
HEX2BIN | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::HEXTOBIN
|
||||
HEX2DEC | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::HEXTODEC
|
||||
HEX2OCT | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::HEXTOOCT
|
||||
HLOOKUP | CATEGORY_LOOKUP_AND_REFERENCE | **Not yet Implemented**
|
||||
HLOOKUP | CATEGORY_LOOKUP_AND_REFERENCE | \PhpOffice\PhpSpreadsheet\Calculation\LookupRef::HLOOKUP
|
||||
HOUR | CATEGORY_DATE_AND_TIME | \PhpOffice\PhpSpreadsheet\Calculation\DateTime::HOUROFDAY
|
||||
HYPERLINK | CATEGORY_LOOKUP_AND_REFERENCE | \PhpOffice\PhpSpreadsheet\Calculation\LookupRef::HYPERLINK
|
||||
HYPGEOMDIST | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::HYPGEOMDIST
|
||||
@ -196,6 +206,10 @@ IMAGINARY | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet
|
||||
IMARGUMENT | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMARGUMENT
|
||||
IMCONJUGATE | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMCONJUGATE
|
||||
IMCOS | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMCOS
|
||||
IMCOSH | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMCOSH
|
||||
IMCOT | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMCOT
|
||||
IMCSC | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMCSC
|
||||
IMCSCH | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMCSCH
|
||||
IMDIV | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMDIV
|
||||
IMEXP | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMEXP
|
||||
IMLN | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMLN
|
||||
@ -204,10 +218,14 @@ IMLOG2 | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet
|
||||
IMPOWER | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMPOWER
|
||||
IMPRODUCT | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMPRODUCT
|
||||
IMREAL | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMREAL
|
||||
IMSEC | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMSEC
|
||||
IMSECH | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMSECH
|
||||
IMSIN | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMSIN
|
||||
IMSINH | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMSINH
|
||||
IMSQRT | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMSQRT
|
||||
IMSUB | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMSUB
|
||||
IMSUM | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMSUM
|
||||
IMTAN | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMTAN
|
||||
INDEX | CATEGORY_LOOKUP_AND_REFERENCE | \PhpOffice\PhpSpreadsheet\Calculation\LookupRef::INDEX
|
||||
INDIRECT | CATEGORY_LOOKUP_AND_REFERENCE | \PhpOffice\PhpSpreadsheet\Calculation\LookupRef::INDIRECT
|
||||
INFO | CATEGORY_INFORMATION | **Not yet Implemented**
|
||||
@ -220,11 +238,13 @@ ISBLANK | CATEGORY_INFORMATION | \PhpOffice\PhpSpreadsheet
|
||||
ISERR | CATEGORY_INFORMATION | \PhpOffice\PhpSpreadsheet\Calculation\Functions::IS_ERR
|
||||
ISERROR | CATEGORY_INFORMATION | \PhpOffice\PhpSpreadsheet\Calculation\Functions::IS_ERROR
|
||||
ISEVEN | CATEGORY_INFORMATION | \PhpOffice\PhpSpreadsheet\Calculation\Functions::IS_EVEN
|
||||
ISFORMULA | CATEGORY_INFORMATION | \PhpOffice\PhpSpreadsheet\Calculation\Functions::ISFORMULA
|
||||
ISLOGICAL | CATEGORY_INFORMATION | \PhpOffice\PhpSpreadsheet\Calculation\Functions::IS_LOGICAL
|
||||
ISNA | CATEGORY_INFORMATION | \PhpOffice\PhpSpreadsheet\Calculation\Functions::IS_NA
|
||||
ISNONTEXT | CATEGORY_INFORMATION | \PhpOffice\PhpSpreadsheet\Calculation\Functions::IS_NONTEXT
|
||||
ISNUMBER | CATEGORY_INFORMATION | \PhpOffice\PhpSpreadsheet\Calculation\Functions::IS_NUMBER
|
||||
ISODD | CATEGORY_INFORMATION | \PhpOffice\PhpSpreadsheet\Calculation\Functions::IS_ODD
|
||||
ISOWEEKNUM | CATEGORY_DATE_AND_TIME | \PhpOffice\PhpSpreadsheet\Calculation\DateTime::ISOWEEKNUM
|
||||
ISPMT | CATEGORY_FINANCIAL | \PhpOffice\PhpSpreadsheet\Calculation\Financial::ISPMT
|
||||
ISREF | CATEGORY_INFORMATION | **Not yet Implemented**
|
||||
ISTEXT | CATEGORY_INFORMATION | \PhpOffice\PhpSpreadsheet\Calculation\Functions::IS_TEXT
|
||||
@ -284,6 +304,7 @@ MIRR | CATEGORY_FINANCIAL | \PhpOffice\PhpSpreadsheet
|
||||
MMULT | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::MMULT
|
||||
MOD | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::MOD
|
||||
MODE | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::MODE
|
||||
MODE.SNGL | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::MODE
|
||||
MONTH | CATEGORY_DATE_AND_TIME | \PhpOffice\PhpSpreadsheet\Calculation\DateTime::MONTHOFYEAR
|
||||
MROUND | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::MROUND
|
||||
MULTINOMIAL | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::MULTINOMIAL
|
||||
@ -305,6 +326,7 @@ NOT | CATEGORY_LOGICAL | \PhpOffice\PhpSpreadsheet
|
||||
NOW | CATEGORY_DATE_AND_TIME | \PhpOffice\PhpSpreadsheet\Calculation\DateTime::DATETIMENOW
|
||||
NPER | CATEGORY_FINANCIAL | \PhpOffice\PhpSpreadsheet\Calculation\Financial::NPER
|
||||
NPV | CATEGORY_FINANCIAL | \PhpOffice\PhpSpreadsheet\Calculation\Financial::NPV
|
||||
NUMBERVALUE | CATEGORY_TEXT_AND_DATA | \PhpOffice\PhpSpreadsheet\Calculation\TextData::NUMBERVALUE
|
||||
|
||||
## O
|
||||
|
||||
@ -319,12 +341,13 @@ ODDFYIELD | CATEGORY_FINANCIAL | **Not yet Implemented**
|
||||
ODDLPRICE | CATEGORY_FINANCIAL | **Not yet Implemented**
|
||||
ODDLYIELD | CATEGORY_FINANCIAL | **Not yet Implemented**
|
||||
OFFSET | CATEGORY_LOOKUP_AND_REFERENCE | \PhpOffice\PhpSpreadsheet\Calculation\LookupRef::OFFSET
|
||||
OR | CATEGORY_LOGICAL | \PhpOffice\PhpSpreadsheet\Calculation\Logical::LOGICAL_OR
|
||||
OR | CATEGORY_LOGICAL | \PhpOffice\PhpSpreadsheet\Calculation\Logical::logicalOr
|
||||
|
||||
## P
|
||||
|
||||
Excel Function | Category | PhpSpreadsheet Function
|
||||
--------------------|--------------------------------|-------------------------------------------
|
||||
PDURATION | CATEGORY_FINANCIAL | \PhpOffice\PhpSpreadsheet\Calculation\Financial::PDURATION
|
||||
PEARSON | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::CORREL
|
||||
PERCENTILE | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::PERCENTILE
|
||||
PERCENTRANK | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::PERCENTRANK
|
||||
@ -371,6 +394,7 @@ ROUNDDOWN | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet
|
||||
ROUNDUP | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::ROUNDUP
|
||||
ROW | CATEGORY_LOOKUP_AND_REFERENCE | \PhpOffice\PhpSpreadsheet\Calculation\LookupRef::ROW
|
||||
ROWS | CATEGORY_LOOKUP_AND_REFERENCE | \PhpOffice\PhpSpreadsheet\Calculation\LookupRef::ROWS
|
||||
RRI | CATEGORY_FINANCIAL | \PhpOffice\PhpSpreadsheet\Calculation\Financial::RRI
|
||||
RSQ | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::RSQ
|
||||
RTD | CATEGORY_LOOKUP_AND_REFERENCE | **Not yet Implemented**
|
||||
|
||||
@ -380,6 +404,8 @@ Excel Function | Category | PhpSpreadsheet Function
|
||||
--------------------|--------------------------------|-------------------------------------------
|
||||
SEARCH | CATEGORY_TEXT_AND_DATA | \PhpOffice\PhpSpreadsheet\Calculation\TextData::SEARCHINSENSITIVE
|
||||
SEARCHB | CATEGORY_TEXT_AND_DATA | \PhpOffice\PhpSpreadsheet\Calculation\TextData::SEARCHINSENSITIVE
|
||||
SEC | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::SEC
|
||||
SECH | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::SECH
|
||||
SECOND | CATEGORY_DATE_AND_TIME | \PhpOffice\PhpSpreadsheet\Calculation\DateTime::SECOND
|
||||
SERIESSUM | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::SERIESSUM
|
||||
SIGN | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::SIGN
|
||||
@ -393,6 +419,8 @@ SQRT | CATEGORY_MATH_AND_TRIG | sqrt
|
||||
SQRTPI | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::SQRTPI
|
||||
STANDARDIZE | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::STANDARDIZE
|
||||
STDEV | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::STDEV
|
||||
STDEV.S | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::STDEV
|
||||
STDEV.P | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::STDEVP
|
||||
STDEVA | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::STDEVA
|
||||
STDEVP | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::STDEVP
|
||||
STDEVPA | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::STDEVPA
|
||||
@ -401,7 +429,7 @@ SUBSTITUTE | CATEGORY_TEXT_AND_DATA | \PhpOffice\PhpSpreadsheet
|
||||
SUBTOTAL | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::SUBTOTAL
|
||||
SUM | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::SUM
|
||||
SUMIF | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::SUMIF
|
||||
SUMIFS | CATEGORY_MATH_AND_TRIG | **Not yet Implemented**
|
||||
SUMIFS | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::SUMIFS
|
||||
SUMPRODUCT | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::SUMPRODUCT
|
||||
SUMSQ | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::SUMSQ
|
||||
SUMX2MY2 | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::SUMX2MY2
|
||||
@ -421,6 +449,7 @@ TBILLPRICE | CATEGORY_FINANCIAL | \PhpOffice\PhpSpreadsheet
|
||||
TBILLYIELD | CATEGORY_FINANCIAL | \PhpOffice\PhpSpreadsheet\Calculation\Financial::TBILLYIELD
|
||||
TDIST | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::TDIST
|
||||
TEXT | CATEGORY_TEXT_AND_DATA | \PhpOffice\PhpSpreadsheet\Calculation\TextData::TEXTFORMAT
|
||||
TEXTJOIN | CATEGORY_TEXT_AND_DATA | \PhpOffice\PhpSpreadsheet\Calculation\TextData::TEXTJOIN
|
||||
TIME | CATEGORY_DATE_AND_TIME | \PhpOffice\PhpSpreadsheet\Calculation\DateTime::TIME
|
||||
TIMEVALUE | CATEGORY_DATE_AND_TIME | \PhpOffice\PhpSpreadsheet\Calculation\DateTime::TIMEVALUE
|
||||
TINV | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::TINV
|
||||
@ -438,6 +467,8 @@ TYPE | CATEGORY_INFORMATION | \PhpOffice\PhpSpreadsheet
|
||||
|
||||
Excel Function | Category | PhpSpreadsheet Function
|
||||
--------------------|--------------------------------|-------------------------------------------
|
||||
UNICHAR | CATEGORY_TEXT_AND_DATA | \PhpOffice\PhpSpreadsheet\Calculation\TextData::CHARACTER
|
||||
UNICODE | CATEGORY_TEXT_AND_DATA | \PhpOffice\PhpSpreadsheet\Calculation\TextData::ASCIICODE
|
||||
UPPER | CATEGORY_TEXT_AND_DATA | \PhpOffice\PhpSpreadsheet\Calculation\TextData::UPPERCASE
|
||||
USDOLLAR | CATEGORY_FINANCIAL | **Not yet Implemented**
|
||||
|
||||
@ -445,8 +476,10 @@ USDOLLAR | CATEGORY_FINANCIAL | **Not yet Implemented**
|
||||
|
||||
Excel Function | Category | PhpSpreadsheet Function
|
||||
--------------------|--------------------------------|-------------------------------------------
|
||||
VALUE | CATEGORY_TEXT_AND_DATA | **Not yet Implemented**
|
||||
VALUE | CATEGORY_TEXT_AND_DATA | \PhpOffice\PhpSpreadsheet\Calculation\TextData::VALUE
|
||||
VAR | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::VARFunc
|
||||
VAR.P | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::VARP
|
||||
VAR.S | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::VARFunc
|
||||
VARA | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::VARA
|
||||
VARP | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::VARP
|
||||
VARPA | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::VARPA
|
||||
@ -468,6 +501,8 @@ Excel Function | Category | PhpSpreadsheet Function
|
||||
--------------------|--------------------------------|-------------------------------------------
|
||||
XIRR | CATEGORY_FINANCIAL | \PhpOffice\PhpSpreadsheet\Calculation\Financial::XIRR
|
||||
XNPV | CATEGORY_FINANCIAL | \PhpOffice\PhpSpreadsheet\Calculation\Financial::XNPV
|
||||
XOR | CATEGORY_LOGICAL | \PhpOffice\PhpSpreadsheet\Calculation\Logical::logicalXor
|
||||
|
||||
|
||||
## Y
|
||||
|
||||
|
@ -426,9 +426,9 @@ for ($row = 1; $row <= $highestRow; ++$row) {
|
||||
echo '</table>' . PHP_EOL;
|
||||
```
|
||||
|
||||
Note that we can't use a <= comparison here, because 'AA' would match
|
||||
as <= 'B', so we increment the highest column letter and then loop
|
||||
while \$col != the incremented highest column.
|
||||
Note that we can't use a `<=` comparison here, because `'AA'` would match
|
||||
as `<= 'B'`, so we increment the highest column letter and then loop
|
||||
while `$col !=` the incremented highest column.
|
||||
|
||||
## Using value binders to facilitate data entry
|
||||
|
||||
|
@ -285,8 +285,8 @@ $columnFilter->createRule()
|
||||
|
||||
We also set the rule type to CUSTOMFILTER.
|
||||
|
||||
This defined two rules, filtering numbers that are >= -20 OR <=
|
||||
20, so we also need to modify the join condition to reflect AND rather
|
||||
This defined two rules, filtering numbers that are `>= -20` OR `<=
|
||||
20`, so we also need to modify the join condition to reflect AND rather
|
||||
than OR.
|
||||
|
||||
``` php
|
||||
|
@ -634,16 +634,16 @@ $writer->setSheetIndex(0);
|
||||
#### Setting the images root of the HTML file
|
||||
|
||||
There might be situations where you want to explicitly set the included
|
||||
images root. For example, one might want to see
|
||||
images root. For example, instead of:
|
||||
|
||||
``` html
|
||||
<img src="./images/logo.jpg">
|
||||
```
|
||||
|
||||
You might want to see:
|
||||
|
||||
``` html
|
||||
<img style="position: relative; left: 0px; top: 0px; width: 140px; height: 78px;" src="http://www.domain.com/*images/logo.jpg" border="0">
|
||||
```
|
||||
|
||||
instead of
|
||||
|
||||
``` html
|
||||
<img style="position: relative; left: 0px; top: 0px; width: 140px; height: 78px;" src="./images/logo.jpg" border="0">.
|
||||
<img src="http://www.domain.com/images/logo.jpg">
|
||||
```
|
||||
|
||||
You can use the following code to achieve this result:
|
||||
|
@ -3,12 +3,12 @@
|
||||
The following pages offer you some widely-used PhpSpreadsheet recipes.
|
||||
Please note that these do NOT offer complete documentation on specific
|
||||
PhpSpreadsheet API functions, but just a bump to get you started. If you
|
||||
need specific API functions, please refer to the API documentation.
|
||||
need specific API functions, please refer to the [API documentation](https://phpoffice.github.io/PhpSpreadsheet/master).
|
||||
|
||||
For example, [setting a worksheet's page orientation and size
|
||||
](#setting-a-worksheets-page-orientation-and-size) covers setting a page
|
||||
orientation to A4. Other paper formats, like US Letter, are not covered
|
||||
in this document, but in the PhpSpreadsheet API documentation.
|
||||
in this document, but in the PhpSpreadsheet [API documentation](https://phpoffice.github.io/PhpSpreadsheet/master).
|
||||
|
||||
## Setting a spreadsheet's metadata
|
||||
|
||||
@ -132,7 +132,7 @@ will take care of displaying the formula according the applications
|
||||
language. Translation is taken care of by the application!
|
||||
|
||||
The following line of code writes the formula
|
||||
`=IF(C4>500,"profit","loss")` into the cell B8. Note that the
|
||||
`=IF(C4>500,"profit","loss")` into the cell B8. Note that the
|
||||
formula must start with `=` to make PhpSpreadsheet recognise this as a
|
||||
formula.
|
||||
|
||||
@ -301,7 +301,7 @@ $spreadsheet->getActiveSheet()->getPageSetup()
|
||||
```
|
||||
|
||||
Note that there are additional page settings available. Please refer to
|
||||
the API documentation for all possible options.
|
||||
the [API documentation](https://phpoffice.github.io/PhpSpreadsheet/master) for all possible options.
|
||||
|
||||
### Page Setup: Scaling options
|
||||
|
||||
|
@ -31,8 +31,6 @@ index, use the `getSheet()` method.
|
||||
$spreadsheet->getSheet(1);
|
||||
```
|
||||
|
||||
If you don't specify a sheet index, then the first worksheet will be
|
||||
returned.
|
||||
|
||||
Methods also exist allowing you to reorder the worksheets in the
|
||||
workbook.
|
||||
@ -71,7 +69,7 @@ $spreadsheet->createSheet();
|
||||
```
|
||||
|
||||
A new worksheet created using this method will be called
|
||||
"Worksheet<n>" where "<n>" is the lowest number possible to
|
||||
`Worksheet<n>` where `<n>` is the lowest number possible to
|
||||
guarantee that the title is unique.
|
||||
|
||||
Alternatively, you can instantiate a new worksheet (setting the title to
|
||||
|
@ -5,7 +5,3 @@ edit_uri: edit/develop/docs/
|
||||
theme: readthedocs
|
||||
extra_css:
|
||||
- extra/extra.css
|
||||
|
||||
extra_javascript:
|
||||
- extra/extra.js
|
||||
|
@ -125,7 +125,7 @@ $autoFilter->getColumn('C')
|
||||
)
|
||||
->setRuleType(Rule::AUTOFILTER_RULETYPE_CUSTOMFILTER);
|
||||
// Filter the Date column on a filter value of the first day of every period of the current year
|
||||
// We us a dateGroup ruletype for this, although it is still a standard filter
|
||||
// We us a dateGroup ruletype for this, although it is still a standard filter
|
||||
foreach ($periods as $period) {
|
||||
$endDate = date('t', mktime(0, 0, 0, $period, 1, $currentYear));
|
||||
|
||||
|
@ -108,7 +108,7 @@ $spreadsheet->getActiveSheet()->setAutoFilter($spreadsheet->getActiveSheet()->ca
|
||||
$autoFilter = $spreadsheet->getActiveSheet()->getAutoFilter();
|
||||
$helper->log('Set active filters');
|
||||
// Filter the Country column on a filter value of Germany
|
||||
// As it's just a simple value filter, we can use FILTERTYPE_FILTER
|
||||
// As it's just a simple value filter, we can use FILTERTYPE_FILTER
|
||||
$autoFilter->getColumn('C')
|
||||
->setFilterType(Column::AUTOFILTER_FILTERTYPE_FILTER)
|
||||
->createRule()
|
||||
|
@ -125,7 +125,7 @@ $autoFilter->getColumn('C')
|
||||
)
|
||||
->setRuleType(Rule::AUTOFILTER_RULETYPE_CUSTOMFILTER);
|
||||
// Filter the Date column on a filter value of the first day of every period of the current year
|
||||
// We us a dateGroup ruletype for this, although it is still a standard filter
|
||||
// We us a dateGroup ruletype for this, although it is still a standard filter
|
||||
foreach ($periods as $period) {
|
||||
$endDate = date('t', mktime(0, 0, 0, $period, 1, $currentYear));
|
||||
|
||||
|
@ -84,7 +84,7 @@ $conditionalStyles[] = $conditional2;
|
||||
$conditionalStyles[] = $conditional3;
|
||||
$spreadsheet->getActiveSheet()->getStyle('B2')->setConditionalStyles($conditionalStyles);
|
||||
|
||||
// duplicate the conditional styles across a range of cells
|
||||
// duplicate the conditional styles across a range of cells
|
||||
$helper->log('Duplicate the conditional formatting across a range of cells');
|
||||
$spreadsheet->getActiveSheet()->duplicateConditionalStyle(
|
||||
$spreadsheet->getActiveSheet()->getStyle('B2')->getConditionalStyles(),
|
||||
|
@ -59,7 +59,7 @@ $conditionalStyles[] = $conditional1;
|
||||
$conditionalStyles[] = $conditional3;
|
||||
$spreadsheet->getActiveSheet()->getStyle('A1')->setConditionalStyles($conditionalStyles);
|
||||
|
||||
// duplicate the conditional styles across a range of cells
|
||||
// duplicate the conditional styles across a range of cells
|
||||
$helper->log('Duplicate the conditional formatting across a range of cells');
|
||||
$spreadsheet->getActiveSheet()->duplicateConditionalStyle(
|
||||
$spreadsheet->getActiveSheet()->getStyle('A1')->getConditionalStyles(),
|
||||
|
@ -5,7 +5,7 @@ use PhpOffice\PhpSpreadsheet\Settings;
|
||||
|
||||
require __DIR__ . '/../Header.php';
|
||||
|
||||
// Change these values to select the Rendering library that you wish to use
|
||||
// Change these values to select the Rendering library that you wish to use
|
||||
Settings::setChartRenderer(\PhpOffice\PhpSpreadsheet\Chart\Renderer\JpGraph::class);
|
||||
|
||||
$inputFileType = 'Xlsx';
|
||||
|
@ -7,7 +7,7 @@ require __DIR__ . '/../Header.php';
|
||||
|
||||
IOFactory::registerWriter('Pdf', \PhpOffice\PhpSpreadsheet\Writer\Pdf\Mpdf::class);
|
||||
|
||||
// Change these values to select the Rendering library that you wish to use
|
||||
// Change these values to select the Rendering library that you wish to use
|
||||
Settings::setChartRenderer(\PhpOffice\PhpSpreadsheet\Chart\Renderer\JpGraph::class);
|
||||
|
||||
$inputFileType = 'Xlsx';
|
||||
|
@ -23,42 +23,42 @@ $worksheet->fromArray(
|
||||
]
|
||||
);
|
||||
|
||||
// Set the Labels for each data series we want to plot
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
// Set the Labels for each data series we want to plot
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
$dataSeriesLabels = [
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$B$1', null, 1), // 2010
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C$1', null, 1), // 2011
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$D$1', null, 1), // 2012
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$B$1', null, 1), // 2010
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C$1', null, 1), // 2011
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$D$1', null, 1), // 2012
|
||||
];
|
||||
// Set the X-Axis Labels
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
// Set the X-Axis Labels
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
$xAxisTickValues = [
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$A$5', null, 4), // Q1 to Q4
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$A$5', null, 4), // Q1 to Q4
|
||||
];
|
||||
// Set the Data values for each data series we want to plot
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
// Set the Data values for each data series we want to plot
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
$dataSeriesValues = [
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$B$2:$B$5', null, 4),
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$C$2:$C$5', null, 4),
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$D$2:$D$5', null, 4),
|
||||
];
|
||||
|
||||
// Build the dataseries
|
||||
// Build the dataseries
|
||||
$series = new DataSeries(
|
||||
DataSeries::TYPE_AREACHART, // plotType
|
||||
DataSeries::GROUPING_PERCENT_STACKED, // plotGrouping
|
||||
@ -68,15 +68,15 @@ $series = new DataSeries(
|
||||
$dataSeriesValues // plotValues
|
||||
);
|
||||
|
||||
// Set the series in the plot area
|
||||
// Set the series in the plot area
|
||||
$plotArea = new PlotArea(null, [$series]);
|
||||
// Set the chart legend
|
||||
// Set the chart legend
|
||||
$legend = new Legend(Legend::POSITION_TOPRIGHT, null, false);
|
||||
|
||||
$title = new Title('Test %age-Stacked Area Chart');
|
||||
$yAxisLabel = new Title('Value ($k)');
|
||||
|
||||
// Create the chart
|
||||
// Create the chart
|
||||
$chart = new Chart(
|
||||
'chart1', // name
|
||||
$title, // title
|
||||
@ -88,11 +88,11 @@ $chart = new Chart(
|
||||
$yAxisLabel // yAxisLabel
|
||||
);
|
||||
|
||||
// Set the position where the chart should appear in the worksheet
|
||||
// Set the position where the chart should appear in the worksheet
|
||||
$chart->setTopLeftPosition('A7');
|
||||
$chart->setBottomRightPosition('H20');
|
||||
|
||||
// Add the chart to the worksheet
|
||||
// Add the chart to the worksheet
|
||||
$worksheet->addChart($chart);
|
||||
|
||||
// Save Excel 2007 file
|
||||
|
@ -23,42 +23,42 @@ $worksheet->fromArray(
|
||||
]
|
||||
);
|
||||
|
||||
// Set the Labels for each data series we want to plot
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
// Set the Labels for each data series we want to plot
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
$dataSeriesLabels = [
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$B$1', null, 1), // 2010
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C$1', null, 1), // 2011
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$D$1', null, 1), // 2012
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$B$1', null, 1), // 2010
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C$1', null, 1), // 2011
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$D$1', null, 1), // 2012
|
||||
];
|
||||
// Set the X-Axis Labels
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
// Set the X-Axis Labels
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
$xAxisTickValues = [
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$A$5', null, 4), // Q1 to Q4
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$A$5', null, 4), // Q1 to Q4
|
||||
];
|
||||
// Set the Data values for each data series we want to plot
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
// Set the Data values for each data series we want to plot
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
$dataSeriesValues = [
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$B$2:$B$5', null, 4),
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$C$2:$C$5', null, 4),
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$D$2:$D$5', null, 4),
|
||||
];
|
||||
|
||||
// Build the dataseries
|
||||
// Build the dataseries
|
||||
$series = new DataSeries(
|
||||
DataSeries::TYPE_BARCHART, // plotType
|
||||
DataSeries::GROUPING_STACKED, // plotGrouping
|
||||
@ -67,19 +67,19 @@ $series = new DataSeries(
|
||||
$xAxisTickValues, // plotCategory
|
||||
$dataSeriesValues // plotValues
|
||||
);
|
||||
// Set additional dataseries parameters
|
||||
// Make it a horizontal bar rather than a vertical column graph
|
||||
// Set additional dataseries parameters
|
||||
// Make it a horizontal bar rather than a vertical column graph
|
||||
$series->setPlotDirection(DataSeries::DIRECTION_BAR);
|
||||
|
||||
// Set the series in the plot area
|
||||
// Set the series in the plot area
|
||||
$plotArea = new PlotArea(null, [$series]);
|
||||
// Set the chart legend
|
||||
// Set the chart legend
|
||||
$legend = new Legend(Legend::POSITION_RIGHT, null, false);
|
||||
|
||||
$title = new Title('Test Chart');
|
||||
$yAxisLabel = new Title('Value ($k)');
|
||||
|
||||
// Create the chart
|
||||
// Create the chart
|
||||
$chart = new Chart(
|
||||
'chart1', // name
|
||||
$title, // title
|
||||
@ -91,11 +91,11 @@ $chart = new Chart(
|
||||
$yAxisLabel // yAxisLabel
|
||||
);
|
||||
|
||||
// Set the position where the chart should appear in the worksheet
|
||||
// Set the position where the chart should appear in the worksheet
|
||||
$chart->setTopLeftPosition('A7');
|
||||
$chart->setBottomRightPosition('H20');
|
||||
|
||||
// Add the chart to the worksheet
|
||||
// Add the chart to the worksheet
|
||||
$worksheet->addChart($chart);
|
||||
|
||||
// Save Excel 2007 file
|
||||
|
@ -23,42 +23,42 @@ $worksheet->fromArray(
|
||||
]
|
||||
);
|
||||
|
||||
// Set the Labels for each data series we want to plot
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
// Set the Labels for each data series we want to plot
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
$dataSeriesLabels = [
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$B$1', null, 1), // 2010
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C$1', null, 1), // 2011
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$D$1', null, 1), // 2012
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$B$1', null, 1), // 2010
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C$1', null, 1), // 2011
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$D$1', null, 1), // 2012
|
||||
];
|
||||
// Set the X-Axis Labels
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
// Set the X-Axis Labels
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
$xAxisTickValues = [
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$A$5', null, 4), // Q1 to Q4
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$A$5', null, 4), // Q1 to Q4
|
||||
];
|
||||
// Set the Data values for each data series we want to plot
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
// Set the Data values for each data series we want to plot
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
$dataSeriesValues = [
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$B$2:$B$5', null, 4),
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$C$2:$C$5', null, 4),
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$D$2:$D$5', null, 4),
|
||||
];
|
||||
|
||||
// Build the dataseries
|
||||
// Build the dataseries
|
||||
$series = new DataSeries(
|
||||
DataSeries::TYPE_BARCHART, // plotType
|
||||
DataSeries::GROUPING_STANDARD, // plotGrouping
|
||||
@ -67,19 +67,19 @@ $series = new DataSeries(
|
||||
$xAxisTickValues, // plotCategory
|
||||
$dataSeriesValues // plotValues
|
||||
);
|
||||
// Set additional dataseries parameters
|
||||
// Make it a vertical column rather than a horizontal bar graph
|
||||
// Set additional dataseries parameters
|
||||
// Make it a vertical column rather than a horizontal bar graph
|
||||
$series->setPlotDirection(DataSeries::DIRECTION_COL);
|
||||
|
||||
// Set the series in the plot area
|
||||
// Set the series in the plot area
|
||||
$plotArea = new PlotArea(null, [$series]);
|
||||
// Set the chart legend
|
||||
// Set the chart legend
|
||||
$legend = new Legend(Legend::POSITION_RIGHT, null, false);
|
||||
|
||||
$title = new Title('Test Column Chart');
|
||||
$yAxisLabel = new Title('Value ($k)');
|
||||
|
||||
// Create the chart
|
||||
// Create the chart
|
||||
$chart = new Chart(
|
||||
'chart1', // name
|
||||
$title, // title
|
||||
@ -91,11 +91,11 @@ $chart = new Chart(
|
||||
$yAxisLabel // yAxisLabel
|
||||
);
|
||||
|
||||
// Set the position where the chart should appear in the worksheet
|
||||
// Set the position where the chart should appear in the worksheet
|
||||
$chart->setTopLeftPosition('A7');
|
||||
$chart->setBottomRightPosition('H20');
|
||||
|
||||
// Add the chart to the worksheet
|
||||
// Add the chart to the worksheet
|
||||
$worksheet->addChart($chart);
|
||||
|
||||
// Save Excel 2007 file
|
||||
|
@ -31,42 +31,42 @@ $worksheet->fromArray(
|
||||
]
|
||||
);
|
||||
|
||||
// Set the Labels for each data series we want to plot
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
// Set the Labels for each data series we want to plot
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
$dataSeriesLabels = [
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C$1', null, 1), // 'Budget'
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$D$1', null, 1), // 'Forecast'
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$E$1', null, 1), // 'Actual'
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C$1', null, 1), // 'Budget'
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$D$1', null, 1), // 'Forecast'
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$E$1', null, 1), // 'Actual'
|
||||
];
|
||||
// Set the X-Axis Labels
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
// Set the X-Axis Labels
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
$xAxisTickValues = [
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$B$13', null, 12), // Q1 to Q4 for 2010 to 2012
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$B$13', null, 12), // Q1 to Q4 for 2010 to 2012
|
||||
];
|
||||
// Set the Data values for each data series we want to plot
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
// Set the Data values for each data series we want to plot
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
$dataSeriesValues = [
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$C$2:$C$13', null, 12),
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$D$2:$D$13', null, 12),
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$E$2:$E$13', null, 12),
|
||||
];
|
||||
|
||||
// Build the dataseries
|
||||
// Build the dataseries
|
||||
$series = new DataSeries(
|
||||
DataSeries::TYPE_BARCHART, // plotType
|
||||
DataSeries::GROUPING_CLUSTERED, // plotGrouping
|
||||
@ -75,20 +75,20 @@ $series = new DataSeries(
|
||||
$xAxisTickValues, // plotCategory
|
||||
$dataSeriesValues // plotValues
|
||||
);
|
||||
// Set additional dataseries parameters
|
||||
// Make it a vertical column rather than a horizontal bar graph
|
||||
// Set additional dataseries parameters
|
||||
// Make it a vertical column rather than a horizontal bar graph
|
||||
$series->setPlotDirection(DataSeries::DIRECTION_COL);
|
||||
|
||||
// Set the series in the plot area
|
||||
// Set the series in the plot area
|
||||
$plotArea = new PlotArea(null, [$series]);
|
||||
// Set the chart legend
|
||||
// Set the chart legend
|
||||
$legend = new Legend(Legend::POSITION_BOTTOM, null, false);
|
||||
|
||||
$title = new Title('Test Grouped Column Chart');
|
||||
$xAxisLabel = new Title('Financial Period');
|
||||
$yAxisLabel = new Title('Value ($k)');
|
||||
|
||||
// Create the chart
|
||||
// Create the chart
|
||||
$chart = new Chart(
|
||||
'chart1', // name
|
||||
$title, // title
|
||||
@ -100,11 +100,11 @@ $chart = new Chart(
|
||||
$yAxisLabel // yAxisLabel
|
||||
);
|
||||
|
||||
// Set the position where the chart should appear in the worksheet
|
||||
// Set the position where the chart should appear in the worksheet
|
||||
$chart->setTopLeftPosition('G2');
|
||||
$chart->setBottomRightPosition('P20');
|
||||
|
||||
// Add the chart to the worksheet
|
||||
// Add the chart to the worksheet
|
||||
$worksheet->addChart($chart);
|
||||
|
||||
// Save Excel 2007 file
|
||||
|
@ -31,46 +31,46 @@ $worksheet->fromArray(
|
||||
]
|
||||
);
|
||||
|
||||
// Set the Labels for each data series we want to plot
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
// Set the Labels for each data series we want to plot
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
$dataSeriesLabels1 = [
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$B$1', null, 1), // Temperature
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$B$1', null, 1), // Temperature
|
||||
];
|
||||
$dataSeriesLabels2 = [
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C$1', null, 1), // Rainfall
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C$1', null, 1), // Rainfall
|
||||
];
|
||||
$dataSeriesLabels3 = [
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$D$1', null, 1), // Humidity
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$D$1', null, 1), // Humidity
|
||||
];
|
||||
|
||||
// Set the X-Axis Labels
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
// Set the X-Axis Labels
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
$xAxisTickValues = [
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$A$13', null, 12), // Jan to Dec
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$A$13', null, 12), // Jan to Dec
|
||||
];
|
||||
|
||||
// Set the Data values for each data series we want to plot
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
// Set the Data values for each data series we want to plot
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
$dataSeriesValues1 = [
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$B$2:$B$13', null, 12),
|
||||
];
|
||||
|
||||
// Build the dataseries
|
||||
// Build the dataseries
|
||||
$series1 = new DataSeries(
|
||||
DataSeries::TYPE_BARCHART, // plotType
|
||||
DataSeries::GROUPING_CLUSTERED, // plotGrouping
|
||||
@ -79,22 +79,22 @@ $series1 = new DataSeries(
|
||||
$xAxisTickValues, // plotCategory
|
||||
$dataSeriesValues1 // plotValues
|
||||
);
|
||||
// Set additional dataseries parameters
|
||||
// Make it a vertical column rather than a horizontal bar graph
|
||||
// Set additional dataseries parameters
|
||||
// Make it a vertical column rather than a horizontal bar graph
|
||||
$series1->setPlotDirection(DataSeries::DIRECTION_COL);
|
||||
|
||||
// Set the Data values for each data series we want to plot
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
// Set the Data values for each data series we want to plot
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
$dataSeriesValues2 = [
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$C$2:$C$13', null, 12),
|
||||
];
|
||||
|
||||
// Build the dataseries
|
||||
// Build the dataseries
|
||||
$series2 = new DataSeries(
|
||||
DataSeries::TYPE_LINECHART, // plotType
|
||||
DataSeries::GROUPING_STANDARD, // plotGrouping
|
||||
@ -104,18 +104,18 @@ $series2 = new DataSeries(
|
||||
$dataSeriesValues2 // plotValues
|
||||
);
|
||||
|
||||
// Set the Data values for each data series we want to plot
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
// Set the Data values for each data series we want to plot
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
$dataSeriesValues3 = [
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$D$2:$D$13', null, 12),
|
||||
];
|
||||
|
||||
// Build the dataseries
|
||||
// Build the dataseries
|
||||
$series3 = new DataSeries(
|
||||
DataSeries::TYPE_AREACHART, // plotType
|
||||
DataSeries::GROUPING_STANDARD, // plotGrouping
|
||||
@ -125,14 +125,14 @@ $series3 = new DataSeries(
|
||||
$dataSeriesValues3 // plotValues
|
||||
);
|
||||
|
||||
// Set the series in the plot area
|
||||
// Set the series in the plot area
|
||||
$plotArea = new PlotArea(null, [$series1, $series2, $series3]);
|
||||
// Set the chart legend
|
||||
// Set the chart legend
|
||||
$legend = new Legend(Legend::POSITION_RIGHT, null, false);
|
||||
|
||||
$title = new Title('Average Weather Chart for Crete');
|
||||
|
||||
// Create the chart
|
||||
// Create the chart
|
||||
$chart = new Chart(
|
||||
'chart1', // name
|
||||
$title, // title
|
||||
@ -144,11 +144,11 @@ $chart = new Chart(
|
||||
null // yAxisLabel
|
||||
);
|
||||
|
||||
// Set the position where the chart should appear in the worksheet
|
||||
// Set the position where the chart should appear in the worksheet
|
||||
$chart->setTopLeftPosition('F2');
|
||||
$chart->setBottomRightPosition('O16');
|
||||
|
||||
// Add the chart to the worksheet
|
||||
// Add the chart to the worksheet
|
||||
$worksheet->addChart($chart);
|
||||
|
||||
// Save Excel 2007 file
|
||||
|
@ -23,35 +23,35 @@ $worksheet->fromArray(
|
||||
]
|
||||
);
|
||||
|
||||
// Set the Labels for each data series we want to plot
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
// Set the Labels for each data series we want to plot
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
$dataSeriesLabels = [
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$B$1', null, 1), // 2010
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C$1', null, 1), // 2011
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$D$1', null, 1), // 2012
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$B$1', null, 1), // 2010
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C$1', null, 1), // 2011
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$D$1', null, 1), // 2012
|
||||
];
|
||||
// Set the X-Axis Labels
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
// Set the X-Axis Labels
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
$xAxisTickValues = [
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$A$5', null, 4), // Q1 to Q4
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$A$5', null, 4), // Q1 to Q4
|
||||
];
|
||||
// Set the Data values for each data series we want to plot
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
// Set the Data values for each data series we want to plot
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
$dataSeriesValues = [
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$B$2:$B$5', null, 4),
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$C$2:$C$5', null, 4),
|
||||
@ -59,7 +59,7 @@ $dataSeriesValues = [
|
||||
];
|
||||
$dataSeriesValues[2]->setLineWidth(60000);
|
||||
|
||||
// Build the dataseries
|
||||
// Build the dataseries
|
||||
$series = new DataSeries(
|
||||
DataSeries::TYPE_LINECHART, // plotType
|
||||
DataSeries::GROUPING_STACKED, // plotGrouping
|
||||
@ -69,15 +69,15 @@ $series = new DataSeries(
|
||||
$dataSeriesValues // plotValues
|
||||
);
|
||||
|
||||
// Set the series in the plot area
|
||||
// Set the series in the plot area
|
||||
$plotArea = new PlotArea(null, [$series]);
|
||||
// Set the chart legend
|
||||
// Set the chart legend
|
||||
$legend = new Legend(Legend::POSITION_TOPRIGHT, null, false);
|
||||
|
||||
$title = new Title('Test Stacked Line Chart');
|
||||
$yAxisLabel = new Title('Value ($k)');
|
||||
|
||||
// Create the chart
|
||||
// Create the chart
|
||||
$chart = new Chart(
|
||||
'chart1', // name
|
||||
$title, // title
|
||||
@ -89,11 +89,11 @@ $chart = new Chart(
|
||||
$yAxisLabel // yAxisLabel
|
||||
);
|
||||
|
||||
// Set the position where the chart should appear in the worksheet
|
||||
// Set the position where the chart should appear in the worksheet
|
||||
$chart->setTopLeftPosition('A7');
|
||||
$chart->setBottomRightPosition('H20');
|
||||
|
||||
// Add the chart to the worksheet
|
||||
// Add the chart to the worksheet
|
||||
$worksheet->addChart($chart);
|
||||
|
||||
// Save Excel 2007 file
|
||||
|
@ -23,42 +23,42 @@ $worksheet->fromArray(
|
||||
]
|
||||
);
|
||||
|
||||
// Set the Labels for each data series we want to plot
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
// Set the Labels for each data series we want to plot
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
$dataSeriesLabels1 = [
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$B$1', null, 1), // 2010
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C$1', null, 1), // 2011
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$D$1', null, 1), // 2012
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$B$1', null, 1), // 2010
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C$1', null, 1), // 2011
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$D$1', null, 1), // 2012
|
||||
];
|
||||
// Set the X-Axis Labels
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
// Set the X-Axis Labels
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
$xAxisTickValues1 = [
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$A$5', null, 4), // Q1 to Q4
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$A$5', null, 4), // Q1 to Q4
|
||||
];
|
||||
// Set the Data values for each data series we want to plot
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
// Set the Data values for each data series we want to plot
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
$dataSeriesValues1 = [
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$B$2:$B$5', null, 4),
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$C$2:$C$5', null, 4),
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$D$2:$D$5', null, 4),
|
||||
];
|
||||
|
||||
// Build the dataseries
|
||||
// Build the dataseries
|
||||
$series1 = new DataSeries(
|
||||
DataSeries::TYPE_AREACHART, // plotType
|
||||
DataSeries::GROUPING_PERCENT_STACKED, // plotGrouping
|
||||
@ -68,15 +68,15 @@ $series1 = new DataSeries(
|
||||
$dataSeriesValues1 // plotValues
|
||||
);
|
||||
|
||||
// Set the series in the plot area
|
||||
// Set the series in the plot area
|
||||
$plotArea1 = new PlotArea(null, [$series1]);
|
||||
// Set the chart legend
|
||||
// Set the chart legend
|
||||
$legend1 = new Legend(Legend::POSITION_TOPRIGHT, null, false);
|
||||
|
||||
$title1 = new Title('Test %age-Stacked Area Chart');
|
||||
$yAxisLabel1 = new Title('Value ($k)');
|
||||
|
||||
// Create the chart
|
||||
// Create the chart
|
||||
$chart1 = new Chart(
|
||||
'chart1', // name
|
||||
$title1, // title
|
||||
@ -88,49 +88,49 @@ $chart1 = new Chart(
|
||||
$yAxisLabel1 // yAxisLabel
|
||||
);
|
||||
|
||||
// Set the position where the chart should appear in the worksheet
|
||||
// Set the position where the chart should appear in the worksheet
|
||||
$chart1->setTopLeftPosition('A7');
|
||||
$chart1->setBottomRightPosition('H20');
|
||||
|
||||
// Add the chart to the worksheet
|
||||
// Add the chart to the worksheet
|
||||
$worksheet->addChart($chart1);
|
||||
|
||||
// Set the Labels for each data series we want to plot
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
// Set the Labels for each data series we want to plot
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
$dataSeriesLabels2 = [
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$B$1', null, 1), // 2010
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C$1', null, 1), // 2011
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$D$1', null, 1), // 2012
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$B$1', null, 1), // 2010
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C$1', null, 1), // 2011
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$D$1', null, 1), // 2012
|
||||
];
|
||||
// Set the X-Axis Labels
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
// Set the X-Axis Labels
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
$xAxisTickValues2 = [
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$A$5', null, 4), // Q1 to Q4
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$A$5', null, 4), // Q1 to Q4
|
||||
];
|
||||
// Set the Data values for each data series we want to plot
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
// Set the Data values for each data series we want to plot
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
$dataSeriesValues2 = [
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$B$2:$B$5', null, 4),
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$C$2:$C$5', null, 4),
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$D$2:$D$5', null, 4),
|
||||
];
|
||||
|
||||
// Build the dataseries
|
||||
// Build the dataseries
|
||||
$series2 = new DataSeries(
|
||||
DataSeries::TYPE_BARCHART, // plotType
|
||||
DataSeries::GROUPING_STANDARD, // plotGrouping
|
||||
@ -139,19 +139,19 @@ $series2 = new DataSeries(
|
||||
$xAxisTickValues2, // plotCategory
|
||||
$dataSeriesValues2 // plotValues
|
||||
);
|
||||
// Set additional dataseries parameters
|
||||
// Make it a vertical column rather than a horizontal bar graph
|
||||
// Set additional dataseries parameters
|
||||
// Make it a vertical column rather than a horizontal bar graph
|
||||
$series2->setPlotDirection(DataSeries::DIRECTION_COL);
|
||||
|
||||
// Set the series in the plot area
|
||||
// Set the series in the plot area
|
||||
$plotArea2 = new PlotArea(null, [$series2]);
|
||||
// Set the chart legend
|
||||
// Set the chart legend
|
||||
$legend2 = new Legend(Legend::POSITION_RIGHT, null, false);
|
||||
|
||||
$title2 = new Title('Test Column Chart');
|
||||
$yAxisLabel2 = new Title('Value ($k)');
|
||||
|
||||
// Create the chart
|
||||
// Create the chart
|
||||
$chart2 = new Chart(
|
||||
'chart2', // name
|
||||
$title2, // title
|
||||
@ -163,11 +163,11 @@ $chart2 = new Chart(
|
||||
$yAxisLabel2 // yAxisLabel
|
||||
);
|
||||
|
||||
// Set the position where the chart should appear in the worksheet
|
||||
// Set the position where the chart should appear in the worksheet
|
||||
$chart2->setTopLeftPosition('I7');
|
||||
$chart2->setBottomRightPosition('P20');
|
||||
|
||||
// Add the chart to the worksheet
|
||||
// Add the chart to the worksheet
|
||||
$worksheet->addChart($chart2);
|
||||
|
||||
// Save Excel 2007 file
|
||||
|
@ -24,38 +24,38 @@ $worksheet->fromArray(
|
||||
]
|
||||
);
|
||||
|
||||
// Set the Labels for each data series we want to plot
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
// Set the Labels for each data series we want to plot
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
$dataSeriesLabels1 = [
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C$1', null, 1), // 2011
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C$1', null, 1), // 2011
|
||||
];
|
||||
// Set the X-Axis Labels
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
// Set the X-Axis Labels
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
$xAxisTickValues1 = [
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$A$5', null, 4), // Q1 to Q4
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$A$5', null, 4), // Q1 to Q4
|
||||
];
|
||||
// Set the Data values for each data series we want to plot
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
// Set the Data values for each data series we want to plot
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
$dataSeriesValues1 = [
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$C$2:$C$5', null, 4),
|
||||
];
|
||||
|
||||
// Build the dataseries
|
||||
// Build the dataseries
|
||||
$series1 = new DataSeries(
|
||||
DataSeries::TYPE_PIECHART, // plotType
|
||||
null, // plotGrouping (Pie charts don't have any grouping)
|
||||
@ -65,19 +65,19 @@ $series1 = new DataSeries(
|
||||
$dataSeriesValues1 // plotValues
|
||||
);
|
||||
|
||||
// Set up a layout object for the Pie chart
|
||||
// Set up a layout object for the Pie chart
|
||||
$layout1 = new Layout();
|
||||
$layout1->setShowVal(true);
|
||||
$layout1->setShowPercent(true);
|
||||
|
||||
// Set the series in the plot area
|
||||
// Set the series in the plot area
|
||||
$plotArea1 = new PlotArea($layout1, [$series1]);
|
||||
// Set the chart legend
|
||||
// Set the chart legend
|
||||
$legend1 = new Legend(Legend::POSITION_RIGHT, null, false);
|
||||
|
||||
$title1 = new Title('Test Pie Chart');
|
||||
|
||||
// Create the chart
|
||||
// Create the chart
|
||||
$chart1 = new Chart(
|
||||
'chart1', // name
|
||||
$title1, // title
|
||||
@ -86,48 +86,48 @@ $chart1 = new Chart(
|
||||
true, // plotVisibleOnly
|
||||
0, // displayBlanksAs
|
||||
null, // xAxisLabel
|
||||
null // yAxisLabel - Pie charts don't have a Y-Axis
|
||||
null // yAxisLabel - Pie charts don't have a Y-Axis
|
||||
);
|
||||
|
||||
// Set the position where the chart should appear in the worksheet
|
||||
// Set the position where the chart should appear in the worksheet
|
||||
$chart1->setTopLeftPosition('A7');
|
||||
$chart1->setBottomRightPosition('H20');
|
||||
|
||||
// Add the chart to the worksheet
|
||||
// Add the chart to the worksheet
|
||||
$worksheet->addChart($chart1);
|
||||
|
||||
// Set the Labels for each data series we want to plot
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
// Set the Labels for each data series we want to plot
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
$dataSeriesLabels2 = [
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C$1', null, 1), // 2011
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C$1', null, 1), // 2011
|
||||
];
|
||||
// Set the X-Axis Labels
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
// Set the X-Axis Labels
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
$xAxisTickValues2 = [
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$A$5', null, 4), // Q1 to Q4
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$A$5', null, 4), // Q1 to Q4
|
||||
];
|
||||
// Set the Data values for each data series we want to plot
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
// Set the Data values for each data series we want to plot
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
$dataSeriesValues2 = [
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$C$2:$C$5', null, 4),
|
||||
];
|
||||
|
||||
// Build the dataseries
|
||||
// Build the dataseries
|
||||
$series2 = new DataSeries(
|
||||
DataSeries::TYPE_DONUTCHART, // plotType
|
||||
null, // plotGrouping (Donut charts don't have any grouping)
|
||||
@ -137,17 +137,17 @@ $series2 = new DataSeries(
|
||||
$dataSeriesValues2 // plotValues
|
||||
);
|
||||
|
||||
// Set up a layout object for the Pie chart
|
||||
// Set up a layout object for the Pie chart
|
||||
$layout2 = new Layout();
|
||||
$layout2->setShowVal(true);
|
||||
$layout2->setShowCatName(true);
|
||||
|
||||
// Set the series in the plot area
|
||||
// Set the series in the plot area
|
||||
$plotArea2 = new PlotArea($layout2, [$series2]);
|
||||
|
||||
$title2 = new Title('Test Donut Chart');
|
||||
|
||||
// Create the chart
|
||||
// Create the chart
|
||||
$chart2 = new Chart(
|
||||
'chart2', // name
|
||||
$title2, // title
|
||||
@ -156,14 +156,14 @@ $chart2 = new Chart(
|
||||
true, // plotVisibleOnly
|
||||
0, // displayBlanksAs
|
||||
null, // xAxisLabel
|
||||
null // yAxisLabel - Like Pie charts, Donut charts don't have a Y-Axis
|
||||
null // yAxisLabel - Like Pie charts, Donut charts don't have a Y-Axis
|
||||
);
|
||||
|
||||
// Set the position where the chart should appear in the worksheet
|
||||
// Set the position where the chart should appear in the worksheet
|
||||
$chart2->setTopLeftPosition('I7');
|
||||
$chart2->setBottomRightPosition('P20');
|
||||
|
||||
// Add the chart to the worksheet
|
||||
// Add the chart to the worksheet
|
||||
$worksheet->addChart($chart2);
|
||||
|
||||
// Save Excel 2007 file
|
||||
|
@ -32,41 +32,41 @@ $worksheet->fromArray(
|
||||
]
|
||||
);
|
||||
|
||||
// Set the Labels for each data series we want to plot
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
// Set the Labels for each data series we want to plot
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
$dataSeriesLabels = [
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C$1', null, 1), // 2011
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$D$1', null, 1), // 2012
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C$1', null, 1), // 2011
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$D$1', null, 1), // 2012
|
||||
];
|
||||
// Set the X-Axis Labels
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
// Set the X-Axis Labels
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
$xAxisTickValues = [
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$A$13', null, 12), // Jan to Dec
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$A$13', null, 12), // Jan to Dec
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$A$13', null, 12), // Jan to Dec
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$A$13', null, 12), // Jan to Dec
|
||||
];
|
||||
// Set the Data values for each data series we want to plot
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
// Set the Data values for each data series we want to plot
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
$dataSeriesValues = [
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$C$2:$C$13', null, 12),
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$D$2:$D$13', null, 12),
|
||||
];
|
||||
|
||||
// Build the dataseries
|
||||
// Build the dataseries
|
||||
$series = new DataSeries(
|
||||
DataSeries::TYPE_RADARCHART, // plotType
|
||||
null, // plotGrouping (Radar charts don't have any grouping)
|
||||
@ -79,17 +79,17 @@ $series = new DataSeries(
|
||||
DataSeries::STYLE_MARKER // plotStyle
|
||||
);
|
||||
|
||||
// Set up a layout object for the Pie chart
|
||||
// Set up a layout object for the Pie chart
|
||||
$layout = new Layout();
|
||||
|
||||
// Set the series in the plot area
|
||||
// Set the series in the plot area
|
||||
$plotArea = new PlotArea($layout, [$series]);
|
||||
// Set the chart legend
|
||||
// Set the chart legend
|
||||
$legend = new Legend(Legend::POSITION_RIGHT, null, false);
|
||||
|
||||
$title = new Title('Test Radar Chart');
|
||||
|
||||
// Create the chart
|
||||
// Create the chart
|
||||
$chart = new Chart(
|
||||
'chart1', // name
|
||||
$title, // title
|
||||
@ -98,14 +98,14 @@ $chart = new Chart(
|
||||
true, // plotVisibleOnly
|
||||
0, // displayBlanksAs
|
||||
null, // xAxisLabel
|
||||
null // yAxisLabel - Radar charts don't have a Y-Axis
|
||||
null // yAxisLabel - Radar charts don't have a Y-Axis
|
||||
);
|
||||
|
||||
// Set the position where the chart should appear in the worksheet
|
||||
// Set the position where the chart should appear in the worksheet
|
||||
$chart->setTopLeftPosition('F2');
|
||||
$chart->setBottomRightPosition('M15');
|
||||
|
||||
// Add the chart to the worksheet
|
||||
// Add the chart to the worksheet
|
||||
$worksheet->addChart($chart);
|
||||
|
||||
// Save Excel 2007 file
|
||||
|
@ -23,36 +23,36 @@ $worksheet->fromArray(
|
||||
]
|
||||
);
|
||||
|
||||
// Set the Labels for each data series we want to plot
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
// Set the Labels for each data series we want to plot
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
$dataSeriesLabels = [
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$B$1', null, 1), // 2010
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C$1', null, 1), // 2011
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$D$1', null, 1), // 2012
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$B$1', null, 1), // 2010
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C$1', null, 1), // 2011
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$D$1', null, 1), // 2012
|
||||
];
|
||||
// Set the X-Axis Labels
|
||||
// Set the X-Axis Labels
|
||||
$xAxisTickValues = [
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$A$5', null, 4), // Q1 to Q4
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$A$5', null, 4), // Q1 to Q4
|
||||
];
|
||||
// Set the Data values for each data series we want to plot
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
// Set the Data values for each data series we want to plot
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
$dataSeriesValues = [
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$B$2:$B$5', null, 4),
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$C$2:$C$5', null, 4),
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$D$2:$D$5', null, 4),
|
||||
];
|
||||
|
||||
// Build the dataseries
|
||||
// Build the dataseries
|
||||
$series = new DataSeries(
|
||||
DataSeries::TYPE_SCATTERCHART, // plotType
|
||||
null, // plotGrouping (Scatter charts don't have any grouping)
|
||||
@ -65,15 +65,15 @@ $series = new DataSeries(
|
||||
DataSeries::STYLE_LINEMARKER // plotStyle
|
||||
);
|
||||
|
||||
// Set the series in the plot area
|
||||
// Set the series in the plot area
|
||||
$plotArea = new PlotArea(null, [$series]);
|
||||
// Set the chart legend
|
||||
// Set the chart legend
|
||||
$legend = new Legend(Legend::POSITION_TOPRIGHT, null, false);
|
||||
|
||||
$title = new Title('Test Scatter Chart');
|
||||
$yAxisLabel = new Title('Value ($k)');
|
||||
|
||||
// Create the chart
|
||||
// Create the chart
|
||||
$chart = new Chart(
|
||||
'chart1', // name
|
||||
$title, // title
|
||||
@ -85,11 +85,11 @@ $chart = new Chart(
|
||||
$yAxisLabel // yAxisLabel
|
||||
);
|
||||
|
||||
// Set the position where the chart should appear in the worksheet
|
||||
// Set the position where the chart should appear in the worksheet
|
||||
$chart->setTopLeftPosition('A7');
|
||||
$chart->setBottomRightPosition('H20');
|
||||
|
||||
// Add the chart to the worksheet
|
||||
// Add the chart to the worksheet
|
||||
$worksheet->addChart($chart);
|
||||
|
||||
// Save Excel 2007 file
|
||||
|
@ -29,36 +29,36 @@ $worksheet->fromArray(
|
||||
);
|
||||
$worksheet->getStyle('B2:E6')->getNumberFormat()->setFormatCode(NumberFormat::FORMAT_NUMBER_00);
|
||||
|
||||
// Set the Labels for each data series we want to plot
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
// Set the Labels for each data series we want to plot
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
$dataSeriesLabels = [
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$B$1', null, 1), //Max / Open
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C$1', null, 1), //Min / Close
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$D$1', null, 1), //Min Threshold / Min
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$E$1', null, 1), //Max Threshold / Max
|
||||
];
|
||||
// Set the X-Axis Labels
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
// Set the X-Axis Labels
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
$xAxisTickValues = [
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$A$6', null, 5), // Counts
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$A$6', null, 5), // Counts
|
||||
];
|
||||
// Set the Data values for each data series we want to plot
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
// Set the Data values for each data series we want to plot
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
$dataSeriesValues = [
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$B$2:$B$6', null, 5),
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$C$2:$C$6', null, 5),
|
||||
@ -66,7 +66,7 @@ $dataSeriesValues = [
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$E$2:$E$6', null, 5),
|
||||
];
|
||||
|
||||
// Build the dataseries
|
||||
// Build the dataseries
|
||||
$series = new DataSeries(
|
||||
DataSeries::TYPE_STOCKCHART, // plotType
|
||||
null, // plotGrouping - if we set this to not null, then xlsx throws error
|
||||
@ -76,16 +76,16 @@ $series = new DataSeries(
|
||||
$dataSeriesValues // plotValues
|
||||
);
|
||||
|
||||
// Set the series in the plot area
|
||||
// Set the series in the plot area
|
||||
$plotArea = new PlotArea(null, [$series]);
|
||||
// Set the chart legend
|
||||
// Set the chart legend
|
||||
$legend = new Legend(Legend::POSITION_RIGHT, null, false);
|
||||
|
||||
$title = new Title('Test Stock Chart');
|
||||
$xAxisLabel = new Title('Counts');
|
||||
$yAxisLabel = new Title('Values');
|
||||
|
||||
// Create the chart
|
||||
// Create the chart
|
||||
$chart = new Chart(
|
||||
'stock-chart', // name
|
||||
$title, // title
|
||||
@ -97,11 +97,11 @@ $chart = new Chart(
|
||||
$yAxisLabel // yAxisLabel
|
||||
);
|
||||
|
||||
// Set the position where the chart should appear in the worksheet
|
||||
// Set the position where the chart should appear in the worksheet
|
||||
$chart->setTopLeftPosition('A7');
|
||||
$chart->setBottomRightPosition('H20');
|
||||
|
||||
// Add the chart to the worksheet
|
||||
// Add the chart to the worksheet
|
||||
$worksheet->addChart($chart);
|
||||
|
||||
// Save Excel 2007 file
|
||||
|
@ -57,7 +57,7 @@ for ($startRow = 2; $startRow <= 240; $startRow += $chunkSize) {
|
||||
// Load only the rows that match our filter from $inputFileName to a PhpSpreadsheet Object
|
||||
$spreadsheet = $reader->load($inputFileName);
|
||||
|
||||
// Do some processing here
|
||||
// Do some processing here
|
||||
|
||||
$sheetData = $spreadsheet->getActiveSheet()->toArray(null, true, true, true);
|
||||
var_dump($sheetData);
|
||||
|
@ -60,7 +60,7 @@ for ($startRow = 2; $startRow <= 240; $startRow += $chunkSize) {
|
||||
// Load only the rows that match our filter from $inputFileName to a PhpSpreadsheet Object
|
||||
$spreadsheet = $reader->load($inputFileName);
|
||||
|
||||
// Do some processing here
|
||||
// Do some processing here
|
||||
|
||||
$sheetData = $spreadsheet->getActiveSheet()->toArray(null, true, true, true);
|
||||
var_dump($sheetData);
|
||||
|
54
inc/vendor/phpoffice/phpspreadsheet/samples/Reader/20_Reader_worksheet_hyperlink_image.php
vendored
Normal file
54
inc/vendor/phpoffice/phpspreadsheet/samples/Reader/20_Reader_worksheet_hyperlink_image.php
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
|
||||
require __DIR__ . '/../Header.php';
|
||||
$inputFileType = 'Xlsx';
|
||||
|
||||
$helper->log('Start');
|
||||
|
||||
$spreadsheet = new Spreadsheet();
|
||||
|
||||
$aSheet = $spreadsheet->getActiveSheet();
|
||||
|
||||
$gdImage = @imagecreatetruecolor(120, 20);
|
||||
$textColor = imagecolorallocate($gdImage, 255, 255, 255);
|
||||
imagestring($gdImage, 1, 5, 5, 'Created with PhpSpreadsheet', $textColor);
|
||||
|
||||
$baseUrl = 'https://phpspreadsheet.readthedocs.io/';
|
||||
|
||||
$drawing = new \PhpOffice\PhpSpreadsheet\Worksheet\MemoryDrawing();
|
||||
$drawing->setName('In-Memory image 1');
|
||||
$drawing->setDescription('In-Memory image 1');
|
||||
$drawing->setCoordinates('A1');
|
||||
$drawing->setImageResource($gdImage);
|
||||
$drawing->setRenderingFunction(
|
||||
\PhpOffice\PhpSpreadsheet\Worksheet\MemoryDrawing::RENDERING_JPEG
|
||||
);
|
||||
$drawing->setMimeType(\PhpOffice\PhpSpreadsheet\Worksheet\MemoryDrawing::MIMETYPE_DEFAULT);
|
||||
$drawing->setHeight(36);
|
||||
$helper->log('Write image');
|
||||
|
||||
$hyperLink = new \PhpOffice\PhpSpreadsheet\Cell\Hyperlink($baseUrl, 'test image');
|
||||
$drawing->setHyperlink($hyperLink);
|
||||
$helper->log('Write link: ' . $baseUrl);
|
||||
|
||||
$drawing->setWorksheet($aSheet);
|
||||
|
||||
$filename = tempnam(\PhpOffice\PhpSpreadsheet\Shared\File::sysGetTempDir(), 'phpspreadsheet-test');
|
||||
|
||||
$writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, $inputFileType);
|
||||
$writer->save($filename);
|
||||
|
||||
$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader($inputFileType);
|
||||
|
||||
$reloadedSpreadsheet = $reader->load($filename);
|
||||
unlink($filename);
|
||||
|
||||
$helper->log('reloaded Spreadsheet');
|
||||
|
||||
foreach ($reloadedSpreadsheet->getActiveSheet()->getDrawingCollection() as $pDrawing) {
|
||||
$helper->log('Read link: ' . $pDrawing->getHyperlink()->getUrl());
|
||||
}
|
||||
|
||||
$helper->log('end');
|
@ -25,24 +25,24 @@ foreach ($customPropertyList as $customPropertyName) {
|
||||
|
||||
// Manipulate properties as appropriate for display purposes
|
||||
switch ($propertyType) {
|
||||
case 'i': // integer
|
||||
case 'i': // integer
|
||||
$propertyType = 'integer number';
|
||||
|
||||
break;
|
||||
case 'f': // float
|
||||
case 'f': // float
|
||||
$propertyType = 'floating point number';
|
||||
|
||||
break;
|
||||
case 's': // string
|
||||
case 's': // string
|
||||
$propertyType = 'string';
|
||||
|
||||
break;
|
||||
case 'd': // date
|
||||
case 'd': // date
|
||||
$propertyValue = date('l, d<\s\up>S</\s\up> F Y g:i A', $propertyValue);
|
||||
$propertyType = 'date';
|
||||
|
||||
break;
|
||||
case 'b': // boolean
|
||||
case 'b': // boolean
|
||||
$propertyValue = ($propertyValue) ? 'TRUE' : 'FALSE';
|
||||
$propertyType = 'boolean';
|
||||
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -20,42 +20,42 @@ $worksheet->fromArray(
|
||||
]
|
||||
);
|
||||
|
||||
// Set the Labels for each data series we want to plot
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
// Set the Labels for each data series we want to plot
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
$dataSeriesLabels = [
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$B$1', null, 1), // 2010
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C$1', null, 1), // 2011
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$D$1', null, 1), // 2012
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$B$1', null, 1), // 2010
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C$1', null, 1), // 2011
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$D$1', null, 1), // 2012
|
||||
];
|
||||
// Set the X-Axis Labels
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
// Set the X-Axis Labels
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
$xAxisTickValues = [
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$A$5', null, 4), // Q1 to Q4
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$A$5', null, 4), // Q1 to Q4
|
||||
];
|
||||
// Set the Data values for each data series we want to plot
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
// Set the Data values for each data series we want to plot
|
||||
// Datatype
|
||||
// Cell reference for data
|
||||
// Format Code
|
||||
// Number of datapoints in series
|
||||
// Data values
|
||||
// Data Marker
|
||||
$dataSeriesValues = [
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$B$2:$B$5', null, 4),
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$C$2:$C$5', null, 4),
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$D$2:$D$5', null, 4),
|
||||
];
|
||||
|
||||
// Build the dataseries
|
||||
// Build the dataseries
|
||||
$series = new DataSeries(
|
||||
DataSeries::TYPE_BARCHART, // plotType
|
||||
DataSeries::GROUPING_CLUSTERED, // plotGrouping
|
||||
@ -64,19 +64,19 @@ $series = new DataSeries(
|
||||
$xAxisTickValues, // plotCategory
|
||||
$dataSeriesValues // plotValues
|
||||
);
|
||||
// Set additional dataseries parameters
|
||||
// Make it a horizontal bar rather than a vertical column graph
|
||||
// Set additional dataseries parameters
|
||||
// Make it a horizontal bar rather than a vertical column graph
|
||||
$series->setPlotDirection(DataSeries::DIRECTION_BAR);
|
||||
|
||||
// Set the series in the plot area
|
||||
// Set the series in the plot area
|
||||
$plotArea = new PlotArea(null, [$series]);
|
||||
// Set the chart legend
|
||||
// Set the chart legend
|
||||
$legend = new Legend(Legend::POSITION_RIGHT, null, false);
|
||||
|
||||
$title = new Title('Test Bar Chart');
|
||||
$yAxisLabel = new Title('Value ($k)');
|
||||
|
||||
// Create the chart
|
||||
// Create the chart
|
||||
$chart = new Chart(
|
||||
'chart1', // name
|
||||
$title, // title
|
||||
@ -88,11 +88,11 @@ $chart = new Chart(
|
||||
$yAxisLabel // yAxisLabel
|
||||
);
|
||||
|
||||
// Set the position where the chart should appear in the worksheet
|
||||
// Set the position where the chart should appear in the worksheet
|
||||
$chart->setTopLeftPosition('A7');
|
||||
$chart->setBottomRightPosition('H20');
|
||||
|
||||
// Add the chart to the worksheet
|
||||
// Add the chart to the worksheet
|
||||
$worksheet->addChart($chart);
|
||||
|
||||
return $spreadsheet;
|
||||
|
@ -224,6 +224,16 @@ class Calculation
|
||||
'functionCall' => 'acosh',
|
||||
'argumentCount' => '1',
|
||||
],
|
||||
'ACOT' => [
|
||||
'category' => Category::CATEGORY_MATH_AND_TRIG,
|
||||
'functionCall' => [MathTrig::class, 'ACOT'],
|
||||
'argumentCount' => '1',
|
||||
],
|
||||
'ACOTH' => [
|
||||
'category' => Category::CATEGORY_MATH_AND_TRIG,
|
||||
'functionCall' => [MathTrig::class, 'ACOTH'],
|
||||
'argumentCount' => '1',
|
||||
],
|
||||
'ADDRESS' => [
|
||||
'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE,
|
||||
'functionCall' => [LookupRef::class, 'cellAddress'],
|
||||
@ -359,6 +369,31 @@ class Calculation
|
||||
'functionCall' => [Statistical::class, 'BINOMDIST'],
|
||||
'argumentCount' => '4',
|
||||
],
|
||||
'BITAND' => [
|
||||
'category' => Category::CATEGORY_ENGINEERING,
|
||||
'functionCall' => [Engineering::class, 'BITAND'],
|
||||
'argumentCount' => '2',
|
||||
],
|
||||
'BITOR' => [
|
||||
'category' => Category::CATEGORY_ENGINEERING,
|
||||
'functionCall' => [Engineering::class, 'BITOR'],
|
||||
'argumentCount' => '2',
|
||||
],
|
||||
'BITXOR' => [
|
||||
'category' => Category::CATEGORY_ENGINEERING,
|
||||
'functionCall' => [Engineering::class, 'BITOR'],
|
||||
'argumentCount' => '2',
|
||||
],
|
||||
'BITLSHIFT' => [
|
||||
'category' => Category::CATEGORY_ENGINEERING,
|
||||
'functionCall' => [Engineering::class, 'BITLSHIFT'],
|
||||
'argumentCount' => '2',
|
||||
],
|
||||
'BITRSHIFT' => [
|
||||
'category' => Category::CATEGORY_ENGINEERING,
|
||||
'functionCall' => [Engineering::class, 'BITRSHIFT'],
|
||||
'argumentCount' => '2',
|
||||
],
|
||||
'CEILING' => [
|
||||
'category' => Category::CATEGORY_MATH_AND_TRIG,
|
||||
'functionCall' => [MathTrig::class, 'CEILING'],
|
||||
@ -425,6 +460,11 @@ class Calculation
|
||||
'functionCall' => [Engineering::class, 'COMPLEX'],
|
||||
'argumentCount' => '2,3',
|
||||
],
|
||||
'CONCAT' => [
|
||||
'category' => Category::CATEGORY_TEXT_AND_DATA,
|
||||
'functionCall' => [TextData::class, 'CONCATENATE'],
|
||||
'argumentCount' => '1+',
|
||||
],
|
||||
'CONCATENATE' => [
|
||||
'category' => Category::CATEGORY_TEXT_AND_DATA,
|
||||
'functionCall' => [TextData::class, 'CONCATENATE'],
|
||||
@ -455,6 +495,16 @@ class Calculation
|
||||
'functionCall' => 'cosh',
|
||||
'argumentCount' => '1',
|
||||
],
|
||||
'COT' => [
|
||||
'category' => Category::CATEGORY_MATH_AND_TRIG,
|
||||
'functionCall' => [MathTrig::class, 'COT'],
|
||||
'argumentCount' => '1',
|
||||
],
|
||||
'COTH' => [
|
||||
'category' => Category::CATEGORY_MATH_AND_TRIG,
|
||||
'functionCall' => [MathTrig::class, 'COTH'],
|
||||
'argumentCount' => '1',
|
||||
],
|
||||
'COUNT' => [
|
||||
'category' => Category::CATEGORY_STATISTICAL,
|
||||
'functionCall' => [Statistical::class, 'COUNT'],
|
||||
@ -520,6 +570,16 @@ class Calculation
|
||||
'functionCall' => [Statistical::class, 'CRITBINOM'],
|
||||
'argumentCount' => '3',
|
||||
],
|
||||
'CSC' => [
|
||||
'category' => Category::CATEGORY_MATH_AND_TRIG,
|
||||
'functionCall' => [MathTrig::class, 'CSC'],
|
||||
'argumentCount' => '1',
|
||||
],
|
||||
'CSCH' => [
|
||||
'category' => Category::CATEGORY_MATH_AND_TRIG,
|
||||
'functionCall' => [MathTrig::class, 'CSCH'],
|
||||
'argumentCount' => '1',
|
||||
],
|
||||
'CUBEKPIMEMBER' => [
|
||||
'category' => Category::CATEGORY_CUBE,
|
||||
'functionCall' => [Functions::class, 'DUMMY'],
|
||||
@ -735,11 +795,21 @@ class Calculation
|
||||
'functionCall' => [Engineering::class, 'ERF'],
|
||||
'argumentCount' => '1,2',
|
||||
],
|
||||
'ERF.PRECISE' => [
|
||||
'category' => Category::CATEGORY_ENGINEERING,
|
||||
'functionCall' => [Engineering::class, 'ERFPRECISE'],
|
||||
'argumentCount' => '1',
|
||||
],
|
||||
'ERFC' => [
|
||||
'category' => Category::CATEGORY_ENGINEERING,
|
||||
'functionCall' => [Engineering::class, 'ERFC'],
|
||||
'argumentCount' => '1',
|
||||
],
|
||||
'ERFC.PRECISE' => [
|
||||
'category' => Category::CATEGORY_ENGINEERING,
|
||||
'functionCall' => [Engineering::class, 'ERFC'],
|
||||
'argumentCount' => '1',
|
||||
],
|
||||
'ERROR.TYPE' => [
|
||||
'category' => Category::CATEGORY_INFORMATION,
|
||||
'functionCall' => [Functions::class, 'errorType'],
|
||||
@ -752,7 +822,7 @@ class Calculation
|
||||
],
|
||||
'EXACT' => [
|
||||
'category' => Category::CATEGORY_TEXT_AND_DATA,
|
||||
'functionCall' => [Functions::class, 'DUMMY'],
|
||||
'functionCall' => [TextData::class, 'EXACT'],
|
||||
'argumentCount' => '2',
|
||||
],
|
||||
'EXP' => [
|
||||
@ -825,6 +895,13 @@ class Calculation
|
||||
'functionCall' => [Statistical::class, 'FORECAST'],
|
||||
'argumentCount' => '3',
|
||||
],
|
||||
'FORMULATEXT' => [
|
||||
'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE,
|
||||
'functionCall' => [LookupRef::class, 'FORMULATEXT'],
|
||||
'argumentCount' => '1',
|
||||
'passCellReference' => true,
|
||||
'passByReference' => [true],
|
||||
],
|
||||
'FREQUENCY' => [
|
||||
'category' => Category::CATEGORY_STATISTICAL,
|
||||
'functionCall' => [Functions::class, 'DUMMY'],
|
||||
@ -961,6 +1038,26 @@ class Calculation
|
||||
'functionCall' => [Engineering::class, 'IMCOS'],
|
||||
'argumentCount' => '1',
|
||||
],
|
||||
'IMCOSH' => [
|
||||
'category' => Category::CATEGORY_ENGINEERING,
|
||||
'functionCall' => [Engineering::class, 'IMCOSH'],
|
||||
'argumentCount' => '1',
|
||||
],
|
||||
'IMCOT' => [
|
||||
'category' => Category::CATEGORY_ENGINEERING,
|
||||
'functionCall' => [Engineering::class, 'IMCOT'],
|
||||
'argumentCount' => '1',
|
||||
],
|
||||
'IMCSC' => [
|
||||
'category' => Category::CATEGORY_ENGINEERING,
|
||||
'functionCall' => [Engineering::class, 'IMCSC'],
|
||||
'argumentCount' => '1',
|
||||
],
|
||||
'IMCSCH' => [
|
||||
'category' => Category::CATEGORY_ENGINEERING,
|
||||
'functionCall' => [Engineering::class, 'IMCSCH'],
|
||||
'argumentCount' => '1',
|
||||
],
|
||||
'IMDIV' => [
|
||||
'category' => Category::CATEGORY_ENGINEERING,
|
||||
'functionCall' => [Engineering::class, 'IMDIV'],
|
||||
@ -1001,11 +1098,26 @@ class Calculation
|
||||
'functionCall' => [Engineering::class, 'IMREAL'],
|
||||
'argumentCount' => '1',
|
||||
],
|
||||
'IMSEC' => [
|
||||
'category' => Category::CATEGORY_ENGINEERING,
|
||||
'functionCall' => [Engineering::class, 'IMSEC'],
|
||||
'argumentCount' => '1',
|
||||
],
|
||||
'IMSECH' => [
|
||||
'category' => Category::CATEGORY_ENGINEERING,
|
||||
'functionCall' => [Engineering::class, 'IMSECH'],
|
||||
'argumentCount' => '1',
|
||||
],
|
||||
'IMSIN' => [
|
||||
'category' => Category::CATEGORY_ENGINEERING,
|
||||
'functionCall' => [Engineering::class, 'IMSIN'],
|
||||
'argumentCount' => '1',
|
||||
],
|
||||
'IMSINH' => [
|
||||
'category' => Category::CATEGORY_ENGINEERING,
|
||||
'functionCall' => [Engineering::class, 'IMSINH'],
|
||||
'argumentCount' => '1',
|
||||
],
|
||||
'IMSQRT' => [
|
||||
'category' => Category::CATEGORY_ENGINEERING,
|
||||
'functionCall' => [Engineering::class, 'IMSQRT'],
|
||||
@ -1021,6 +1133,11 @@ class Calculation
|
||||
'functionCall' => [Engineering::class, 'IMSUM'],
|
||||
'argumentCount' => '1+',
|
||||
],
|
||||
'IMTAN' => [
|
||||
'category' => Category::CATEGORY_ENGINEERING,
|
||||
'functionCall' => [Engineering::class, 'IMTAN'],
|
||||
'argumentCount' => '1',
|
||||
],
|
||||
'INDEX' => [
|
||||
'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE,
|
||||
'functionCall' => [LookupRef::class, 'INDEX'],
|
||||
@ -1114,6 +1231,11 @@ class Calculation
|
||||
'functionCall' => [Functions::class, 'isOdd'],
|
||||
'argumentCount' => '1',
|
||||
],
|
||||
'ISOWEEKNUM' => [
|
||||
'category' => Category::CATEGORY_DATE_AND_TIME,
|
||||
'functionCall' => [DateTime::class, 'ISOWEEKNUM'],
|
||||
'argumentCount' => '1',
|
||||
],
|
||||
'ISPMT' => [
|
||||
'category' => Category::CATEGORY_FINANCIAL,
|
||||
'functionCall' => [Financial::class, 'ISPMT'],
|
||||
@ -1394,6 +1516,11 @@ class Calculation
|
||||
'functionCall' => [Financial::class, 'NPV'],
|
||||
'argumentCount' => '2+',
|
||||
],
|
||||
'NUMBERVALUE' => [
|
||||
'category' => Category::CATEGORY_TEXT_AND_DATA,
|
||||
'functionCall' => [TextData::class, 'NUMBERVALUE'],
|
||||
'argumentCount' => '1+',
|
||||
],
|
||||
'OCT2BIN' => [
|
||||
'category' => Category::CATEGORY_ENGINEERING,
|
||||
'functionCall' => [Engineering::class, 'OCTTOBIN'],
|
||||
@ -1446,6 +1573,11 @@ class Calculation
|
||||
'functionCall' => [Logical::class, 'logicalOr'],
|
||||
'argumentCount' => '1+',
|
||||
],
|
||||
'PDURATION' => [
|
||||
'category' => Category::CATEGORY_FINANCIAL,
|
||||
'functionCall' => [Financial::class, 'PDURATION'],
|
||||
'argumentCount' => '3',
|
||||
],
|
||||
'PEARSON' => [
|
||||
'category' => Category::CATEGORY_STATISTICAL,
|
||||
'functionCall' => [Statistical::class, 'CORREL'],
|
||||
@ -1627,6 +1759,11 @@ class Calculation
|
||||
'functionCall' => [LookupRef::class, 'ROWS'],
|
||||
'argumentCount' => '1',
|
||||
],
|
||||
'RRI' => [
|
||||
'category' => Category::CATEGORY_FINANCIAL,
|
||||
'functionCall' => [Financial::class, 'RRI'],
|
||||
'argumentCount' => '3',
|
||||
],
|
||||
'RSQ' => [
|
||||
'category' => Category::CATEGORY_STATISTICAL,
|
||||
'functionCall' => [Statistical::class, 'RSQ'],
|
||||
@ -1647,6 +1784,16 @@ class Calculation
|
||||
'functionCall' => [TextData::class, 'SEARCHINSENSITIVE'],
|
||||
'argumentCount' => '2,3',
|
||||
],
|
||||
'SEC' => [
|
||||
'category' => Category::CATEGORY_MATH_AND_TRIG,
|
||||
'functionCall' => [MathTrig::class, 'SEC'],
|
||||
'argumentCount' => '1',
|
||||
],
|
||||
'SECH' => [
|
||||
'category' => Category::CATEGORY_MATH_AND_TRIG,
|
||||
'functionCall' => [MathTrig::class, 'SECH'],
|
||||
'argumentCount' => '1',
|
||||
],
|
||||
'SECOND' => [
|
||||
'category' => Category::CATEGORY_DATE_AND_TIME,
|
||||
'functionCall' => [DateTime::class, 'SECOND'],
|
||||
@ -1838,6 +1985,11 @@ class Calculation
|
||||
'functionCall' => [TextData::class, 'TEXTFORMAT'],
|
||||
'argumentCount' => '2',
|
||||
],
|
||||
'TEXTJOIN' => [
|
||||
'category' => Category::CATEGORY_TEXT_AND_DATA,
|
||||
'functionCall' => [TextData::class, 'TEXTJOIN'],
|
||||
'argumentCount' => '3+',
|
||||
],
|
||||
'TIME' => [
|
||||
'category' => Category::CATEGORY_DATE_AND_TIME,
|
||||
'functionCall' => [DateTime::class, 'TIME'],
|
||||
@ -1898,6 +2050,16 @@ class Calculation
|
||||
'functionCall' => [Functions::class, 'TYPE'],
|
||||
'argumentCount' => '1',
|
||||
],
|
||||
'UNICHAR' => [
|
||||
'category' => Category::CATEGORY_TEXT_AND_DATA,
|
||||
'functionCall' => [TextData::class, 'CHARACTER'],
|
||||
'argumentCount' => '1',
|
||||
],
|
||||
'UNICODE' => [
|
||||
'category' => Category::CATEGORY_TEXT_AND_DATA,
|
||||
'functionCall' => [TextData::class, 'ASCIICODE'],
|
||||
'argumentCount' => '1',
|
||||
],
|
||||
'UPPER' => [
|
||||
'category' => Category::CATEGORY_TEXT_AND_DATA,
|
||||
'functionCall' => [TextData::class, 'UPPERCASE'],
|
||||
@ -1918,6 +2080,16 @@ class Calculation
|
||||
'functionCall' => [Statistical::class, 'VARFunc'],
|
||||
'argumentCount' => '1+',
|
||||
],
|
||||
'VAR.P' => [
|
||||
'category' => Category::CATEGORY_STATISTICAL,
|
||||
'functionCall' => [Statistical::class, 'VARP'],
|
||||
'argumentCount' => '1+',
|
||||
],
|
||||
'VAR.S' => [
|
||||
'category' => Category::CATEGORY_STATISTICAL,
|
||||
'functionCall' => [Statistical::class, 'VARFunc'],
|
||||
'argumentCount' => '1+',
|
||||
],
|
||||
'VARA' => [
|
||||
'category' => Category::CATEGORY_STATISTICAL,
|
||||
'functionCall' => [Statistical::class, 'VARA'],
|
||||
@ -1973,6 +2145,11 @@ class Calculation
|
||||
'functionCall' => [Financial::class, 'XNPV'],
|
||||
'argumentCount' => '3',
|
||||
],
|
||||
'XOR' => [
|
||||
'category' => Category::CATEGORY_LOGICAL,
|
||||
'functionCall' => [Logical::class, 'logicalXor'],
|
||||
'argumentCount' => '1+',
|
||||
],
|
||||
'YEAR' => [
|
||||
'category' => Category::CATEGORY_DATE_AND_TIME,
|
||||
'functionCall' => [DateTime::class, 'YEAR'],
|
||||
@ -2395,10 +2572,10 @@ class Calculation
|
||||
|
||||
if (self::$functionReplaceToLocale === null) {
|
||||
self::$functionReplaceToLocale = [];
|
||||
foreach (array_values(self::$localeFunctions) as $localeFunctionName) {
|
||||
foreach (self::$localeFunctions as $localeFunctionName) {
|
||||
self::$functionReplaceToLocale[] = '$1' . trim($localeFunctionName) . '$2';
|
||||
}
|
||||
foreach (array_values(self::$localeBoolean) as $localeBoolean) {
|
||||
foreach (self::$localeBoolean as $localeBoolean) {
|
||||
self::$functionReplaceToLocale[] = '$1' . trim($localeBoolean) . '$2';
|
||||
}
|
||||
}
|
||||
@ -2414,10 +2591,10 @@ class Calculation
|
||||
{
|
||||
if (self::$functionReplaceFromLocale === null) {
|
||||
self::$functionReplaceFromLocale = [];
|
||||
foreach (array_values(self::$localeFunctions) as $localeFunctionName) {
|
||||
foreach (self::$localeFunctions as $localeFunctionName) {
|
||||
self::$functionReplaceFromLocale[] = '/(@?[^\w\.])' . preg_quote($localeFunctionName, '/') . '([\s]*\()/Ui';
|
||||
}
|
||||
foreach (array_values(self::$localeBoolean) as $excelBoolean) {
|
||||
foreach (self::$localeBoolean as $excelBoolean) {
|
||||
self::$functionReplaceFromLocale[] = '/(@?[^\w\.])' . preg_quote($excelBoolean, '/') . '([^\w\.])/Ui';
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ class DateTime
|
||||
/**
|
||||
* Identify if a year is a leap year or not.
|
||||
*
|
||||
* @param int $year The year to test
|
||||
* @param int|string $year The year to test
|
||||
*
|
||||
* @return bool TRUE if the year is a leap year, otherwise FALSE
|
||||
*/
|
||||
@ -70,7 +70,7 @@ class DateTime
|
||||
(Functions::getCompatibilityMode() == Functions::COMPATIBILITY_GNUMERIC)) {
|
||||
return Functions::VALUE();
|
||||
}
|
||||
if ((is_object($dateValue)) && ($dateValue instanceof \DateTime)) {
|
||||
if ((is_object($dateValue)) && ($dateValue instanceof \DateTimeImmutable)) {
|
||||
$dateValue = Date::PHPToExcel($dateValue);
|
||||
} else {
|
||||
$saveReturnDateType = Functions::getReturnDateType();
|
||||
@ -650,7 +650,7 @@ class DateTime
|
||||
* or a standard date string
|
||||
* @param string $unit
|
||||
*
|
||||
* @return int Interval between the dates
|
||||
* @return int|string Interval between the dates
|
||||
*/
|
||||
public static function DATEDIF($startDate = 0, $endDate = 0, $unit = 'D')
|
||||
{
|
||||
@ -792,7 +792,7 @@ class DateTime
|
||||
* occur on the 31st of a month become equal to the 30th of the
|
||||
* same month.
|
||||
*
|
||||
* @return int Number of days between start date and end date
|
||||
* @return int|string Number of days between start date and end date
|
||||
*/
|
||||
public static function DAYS360($startDate = 0, $endDate = 0, $method = false)
|
||||
{
|
||||
@ -942,7 +942,7 @@ class DateTime
|
||||
* @param mixed $endDate Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard date string
|
||||
*
|
||||
* @return int Interval between the dates
|
||||
* @return int|string Interval between the dates
|
||||
*/
|
||||
public static function NETWORKDAYS($startDate, $endDate, ...$dateArgs)
|
||||
{
|
||||
@ -1127,7 +1127,7 @@ class DateTime
|
||||
* @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard date string
|
||||
*
|
||||
* @return int Day of the month
|
||||
* @return int|string Day of the month
|
||||
*/
|
||||
public static function DAYOFMONTH($dateValue = 1)
|
||||
{
|
||||
@ -1169,7 +1169,7 @@ class DateTime
|
||||
* 2 Numbers 1 (Monday) through 7 (Sunday).
|
||||
* 3 Numbers 0 (Monday) through 6 (Sunday).
|
||||
*
|
||||
* @return int Day of the week value
|
||||
* @return int|string Day of the week value
|
||||
*/
|
||||
public static function WEEKDAY($dateValue = 1, $style = 1)
|
||||
{
|
||||
@ -1248,7 +1248,7 @@ class DateTime
|
||||
* 1 or omitted Week begins on Sunday.
|
||||
* 2 Week begins on Monday.
|
||||
*
|
||||
* @return int Week Number
|
||||
* @return int|string Week Number
|
||||
*/
|
||||
public static function WEEKNUM($dateValue = 1, $method = 1)
|
||||
{
|
||||
@ -1286,6 +1286,37 @@ class DateTime
|
||||
return (int) $weekOfYear;
|
||||
}
|
||||
|
||||
/**
|
||||
* ISOWEEKNUM.
|
||||
*
|
||||
* Returns the ISO 8601 week number of the year for a specified date.
|
||||
*
|
||||
* Excel Function:
|
||||
* ISOWEEKNUM(dateValue)
|
||||
*
|
||||
* @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard date string
|
||||
*
|
||||
* @return int|string Week Number
|
||||
*/
|
||||
public static function ISOWEEKNUM($dateValue = 1)
|
||||
{
|
||||
$dateValue = Functions::flattenSingleValue($dateValue);
|
||||
|
||||
if ($dateValue === null) {
|
||||
$dateValue = 1;
|
||||
} elseif (is_string($dateValue = self::getDateValue($dateValue))) {
|
||||
return Functions::VALUE();
|
||||
} elseif ($dateValue < 0.0) {
|
||||
return Functions::NAN();
|
||||
}
|
||||
|
||||
// Execute function
|
||||
$PHPDateObject = Date::excelToDateTimeObject($dateValue);
|
||||
|
||||
return (int) $PHPDateObject->format('W');
|
||||
}
|
||||
|
||||
/**
|
||||
* MONTHOFYEAR.
|
||||
*
|
||||
@ -1298,7 +1329,7 @@ class DateTime
|
||||
* @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard date string
|
||||
*
|
||||
* @return int Month of the year
|
||||
* @return int|string Month of the year
|
||||
*/
|
||||
public static function MONTHOFYEAR($dateValue = 1)
|
||||
{
|
||||
@ -1331,7 +1362,7 @@ class DateTime
|
||||
* @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard date string
|
||||
*
|
||||
* @return int Year
|
||||
* @return int|string Year
|
||||
*/
|
||||
public static function YEAR($dateValue = 1)
|
||||
{
|
||||
@ -1363,7 +1394,7 @@ class DateTime
|
||||
* @param mixed $timeValue Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard time string
|
||||
*
|
||||
* @return int Hour
|
||||
* @return int|string Hour
|
||||
*/
|
||||
public static function HOUROFDAY($timeValue = 0)
|
||||
{
|
||||
@ -1404,7 +1435,7 @@ class DateTime
|
||||
* @param mixed $timeValue Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard time string
|
||||
*
|
||||
* @return int Minute
|
||||
* @return int|string Minute
|
||||
*/
|
||||
public static function MINUTE($timeValue = 0)
|
||||
{
|
||||
@ -1445,7 +1476,7 @@ class DateTime
|
||||
* @param mixed $timeValue Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard time string
|
||||
*
|
||||
* @return int Second
|
||||
* @return int|string Second
|
||||
*/
|
||||
public static function SECOND($timeValue = 0)
|
||||
{
|
||||
|
@ -2,6 +2,9 @@
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation;
|
||||
|
||||
use Complex\Complex;
|
||||
use Complex\Exception as ComplexException;
|
||||
|
||||
class Engineering
|
||||
{
|
||||
/**
|
||||
@ -718,83 +721,23 @@ class Engineering
|
||||
*
|
||||
* Parses a complex number into its real and imaginary parts, and an I or J suffix
|
||||
*
|
||||
* @deprecated 2.0.0 No longer used by internal code. Please use the Complex\Complex class instead
|
||||
*
|
||||
* @param string $complexNumber The complex number
|
||||
*
|
||||
* @return string[] Indexed on "real", "imaginary" and "suffix"
|
||||
* @return mixed[] Indexed on "real", "imaginary" and "suffix"
|
||||
*/
|
||||
public static function parseComplex($complexNumber)
|
||||
{
|
||||
$workString = (string) $complexNumber;
|
||||
|
||||
$realNumber = $imaginary = 0;
|
||||
// Extract the suffix, if there is one
|
||||
$suffix = substr($workString, -1);
|
||||
if (!is_numeric($suffix)) {
|
||||
$workString = substr($workString, 0, -1);
|
||||
} else {
|
||||
$suffix = '';
|
||||
}
|
||||
|
||||
// Split the input into its Real and Imaginary components
|
||||
$leadingSign = 0;
|
||||
if (strlen($workString) > 0) {
|
||||
$leadingSign = (($workString[0] == '+') || ($workString[0] == '-')) ? 1 : 0;
|
||||
}
|
||||
$power = '';
|
||||
$realNumber = strtok($workString, '+-');
|
||||
if (strtoupper(substr($realNumber, -1)) == 'E') {
|
||||
$power = strtok('+-');
|
||||
++$leadingSign;
|
||||
}
|
||||
|
||||
$realNumber = substr($workString, 0, strlen($realNumber) + strlen($power) + $leadingSign);
|
||||
|
||||
if ($suffix != '') {
|
||||
$imaginary = substr($workString, strlen($realNumber));
|
||||
|
||||
if (($imaginary == '') && (($realNumber == '') || ($realNumber == '+') || ($realNumber == '-'))) {
|
||||
$imaginary = $realNumber . '1';
|
||||
$realNumber = '0';
|
||||
} elseif ($imaginary == '') {
|
||||
$imaginary = $realNumber;
|
||||
$realNumber = '0';
|
||||
} elseif (($imaginary == '+') || ($imaginary == '-')) {
|
||||
$imaginary .= '1';
|
||||
}
|
||||
}
|
||||
$complex = new Complex($complexNumber);
|
||||
|
||||
return [
|
||||
'real' => $realNumber,
|
||||
'imaginary' => $imaginary,
|
||||
'suffix' => $suffix,
|
||||
'real' => $complex->getReal(),
|
||||
'imaginary' => $complex->getImaginary(),
|
||||
'suffix' => $complex->getSuffix(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleans the leading characters in a complex number string.
|
||||
*
|
||||
* @param string $complexNumber The complex number to clean
|
||||
*
|
||||
* @return string The "cleaned" complex number
|
||||
*/
|
||||
private static function cleanComplex($complexNumber)
|
||||
{
|
||||
if ($complexNumber[0] == '+') {
|
||||
$complexNumber = substr($complexNumber, 1);
|
||||
}
|
||||
if ($complexNumber[0] == '0') {
|
||||
$complexNumber = substr($complexNumber, 1);
|
||||
}
|
||||
if ($complexNumber[0] == '.') {
|
||||
$complexNumber = '0' . $complexNumber;
|
||||
}
|
||||
if ($complexNumber[0] == '+') {
|
||||
$complexNumber = substr($complexNumber, 1);
|
||||
}
|
||||
|
||||
return $complexNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a number base string value with leading zeroes.
|
||||
*
|
||||
@ -1745,10 +1688,10 @@ class Engineering
|
||||
/**
|
||||
* COMPLEX.
|
||||
*
|
||||
* Converts real and imaginary coefficients into a complex number of the form x + yi or x + yj.
|
||||
* Converts real and imaginary coefficients into a complex number of the form x +/- yi or x +/- yj.
|
||||
*
|
||||
* Excel Function:
|
||||
* COMPLEX(realNumber,imaginary[,places])
|
||||
* COMPLEX(realNumber,imaginary[,suffix])
|
||||
*
|
||||
* @category Engineering Functions
|
||||
*
|
||||
@ -1768,34 +1711,9 @@ class Engineering
|
||||
if (((is_numeric($realNumber)) && (is_numeric($imaginary))) &&
|
||||
(($suffix == 'i') || ($suffix == 'j') || ($suffix == ''))
|
||||
) {
|
||||
$realNumber = (float) $realNumber;
|
||||
$imaginary = (float) $imaginary;
|
||||
$complex = new Complex($realNumber, $imaginary, $suffix);
|
||||
|
||||
if ($suffix == '') {
|
||||
$suffix = 'i';
|
||||
}
|
||||
if ($realNumber == 0.0) {
|
||||
if ($imaginary == 0.0) {
|
||||
return (string) '0';
|
||||
} elseif ($imaginary == 1.0) {
|
||||
return (string) $suffix;
|
||||
} elseif ($imaginary == -1.0) {
|
||||
return (string) '-' . $suffix;
|
||||
}
|
||||
|
||||
return (string) $imaginary . $suffix;
|
||||
} elseif ($imaginary == 0.0) {
|
||||
return (string) $realNumber;
|
||||
} elseif ($imaginary == 1.0) {
|
||||
return (string) $realNumber . '+' . $suffix;
|
||||
} elseif ($imaginary == -1.0) {
|
||||
return (string) $realNumber . '-' . $suffix;
|
||||
}
|
||||
if ($imaginary > 0) {
|
||||
$imaginary = (string) '+' . $imaginary;
|
||||
}
|
||||
|
||||
return (string) $realNumber . $imaginary . $suffix;
|
||||
return (string) $complex;
|
||||
}
|
||||
|
||||
return Functions::VALUE();
|
||||
@ -1820,9 +1738,7 @@ class Engineering
|
||||
{
|
||||
$complexNumber = Functions::flattenSingleValue($complexNumber);
|
||||
|
||||
$parsedComplex = self::parseComplex($complexNumber);
|
||||
|
||||
return $parsedComplex['imaginary'];
|
||||
return (new Complex($complexNumber))->getImaginary();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1843,9 +1759,7 @@ class Engineering
|
||||
{
|
||||
$complexNumber = Functions::flattenSingleValue($complexNumber);
|
||||
|
||||
$parsedComplex = self::parseComplex($complexNumber);
|
||||
|
||||
return $parsedComplex['real'];
|
||||
return (new Complex($complexNumber))->getReal();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1864,12 +1778,7 @@ class Engineering
|
||||
{
|
||||
$complexNumber = Functions::flattenSingleValue($complexNumber);
|
||||
|
||||
$parsedComplex = self::parseComplex($complexNumber);
|
||||
|
||||
return sqrt(
|
||||
($parsedComplex['real'] * $parsedComplex['real']) +
|
||||
($parsedComplex['imaginary'] * $parsedComplex['imaginary'])
|
||||
);
|
||||
return (new Complex($complexNumber))->abs();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1883,27 +1792,18 @@ class Engineering
|
||||
*
|
||||
* @param string $complexNumber the complex number for which you want the argument theta
|
||||
*
|
||||
* @return float
|
||||
* @return float|string
|
||||
*/
|
||||
public static function IMARGUMENT($complexNumber)
|
||||
{
|
||||
$complexNumber = Functions::flattenSingleValue($complexNumber);
|
||||
$parsedComplex = self::parseComplex($complexNumber);
|
||||
if ($parsedComplex['real'] == 0.0) {
|
||||
if ($parsedComplex['imaginary'] == 0.0) {
|
||||
return Functions::DIV0();
|
||||
} elseif ($parsedComplex['imaginary'] < 0.0) {
|
||||
return M_PI / -2;
|
||||
}
|
||||
|
||||
return M_PI / 2;
|
||||
} elseif ($parsedComplex['real'] > 0.0) {
|
||||
return atan($parsedComplex['imaginary'] / $parsedComplex['real']);
|
||||
} elseif ($parsedComplex['imaginary'] < 0.0) {
|
||||
return 0 - (M_PI - atan(abs($parsedComplex['imaginary']) / abs($parsedComplex['real'])));
|
||||
$complex = new Complex($complexNumber);
|
||||
if ($complex->getReal() == 0.0 && $complex->getImaginary() == 0.0) {
|
||||
return Functions::DIV0();
|
||||
}
|
||||
|
||||
return M_PI - atan($parsedComplex['imaginary'] / abs($parsedComplex['real']));
|
||||
return $complex->argument();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1922,19 +1822,7 @@ class Engineering
|
||||
{
|
||||
$complexNumber = Functions::flattenSingleValue($complexNumber);
|
||||
|
||||
$parsedComplex = self::parseComplex($complexNumber);
|
||||
|
||||
if ($parsedComplex['imaginary'] == 0.0) {
|
||||
return $parsedComplex['real'];
|
||||
}
|
||||
|
||||
return self::cleanComplex(
|
||||
self::COMPLEX(
|
||||
$parsedComplex['real'],
|
||||
0 - $parsedComplex['imaginary'],
|
||||
$parsedComplex['suffix']
|
||||
)
|
||||
);
|
||||
return (string) (new Complex($complexNumber))->conjugate();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1953,19 +1841,83 @@ class Engineering
|
||||
{
|
||||
$complexNumber = Functions::flattenSingleValue($complexNumber);
|
||||
|
||||
$parsedComplex = self::parseComplex($complexNumber);
|
||||
return (string) (new Complex($complexNumber))->cos();
|
||||
}
|
||||
|
||||
if ($parsedComplex['imaginary'] == 0.0) {
|
||||
return cos($parsedComplex['real']);
|
||||
}
|
||||
/**
|
||||
* IMCOSH.
|
||||
*
|
||||
* Returns the hyperbolic cosine of a complex number in x + yi or x + yj text format.
|
||||
*
|
||||
* Excel Function:
|
||||
* IMCOSH(complexNumber)
|
||||
*
|
||||
* @param string $complexNumber the complex number for which you want the hyperbolic cosine
|
||||
*
|
||||
* @return float|string
|
||||
*/
|
||||
public static function IMCOSH($complexNumber)
|
||||
{
|
||||
$complexNumber = Functions::flattenSingleValue($complexNumber);
|
||||
|
||||
return self::IMCONJUGATE(
|
||||
self::COMPLEX(
|
||||
cos($parsedComplex['real']) * cosh($parsedComplex['imaginary']),
|
||||
sin($parsedComplex['real']) * sinh($parsedComplex['imaginary']),
|
||||
$parsedComplex['suffix']
|
||||
)
|
||||
);
|
||||
return (string) (new Complex($complexNumber))->cosh();
|
||||
}
|
||||
|
||||
/**
|
||||
* IMCOT.
|
||||
*
|
||||
* Returns the cotangent of a complex number in x + yi or x + yj text format.
|
||||
*
|
||||
* Excel Function:
|
||||
* IMCOT(complexNumber)
|
||||
*
|
||||
* @param string $complexNumber the complex number for which you want the cotangent
|
||||
*
|
||||
* @return float|string
|
||||
*/
|
||||
public static function IMCOT($complexNumber)
|
||||
{
|
||||
$complexNumber = Functions::flattenSingleValue($complexNumber);
|
||||
|
||||
return (string) (new Complex($complexNumber))->cot();
|
||||
}
|
||||
|
||||
/**
|
||||
* IMCSC.
|
||||
*
|
||||
* Returns the cosecant of a complex number in x + yi or x + yj text format.
|
||||
*
|
||||
* Excel Function:
|
||||
* IMCSC(complexNumber)
|
||||
*
|
||||
* @param string $complexNumber the complex number for which you want the cosecant
|
||||
*
|
||||
* @return float|string
|
||||
*/
|
||||
public static function IMCSC($complexNumber)
|
||||
{
|
||||
$complexNumber = Functions::flattenSingleValue($complexNumber);
|
||||
|
||||
return (string) (new Complex($complexNumber))->csc();
|
||||
}
|
||||
|
||||
/**
|
||||
* IMCSCH.
|
||||
*
|
||||
* Returns the hyperbolic cosecant of a complex number in x + yi or x + yj text format.
|
||||
*
|
||||
* Excel Function:
|
||||
* IMCSCH(complexNumber)
|
||||
*
|
||||
* @param string $complexNumber the complex number for which you want the hyperbolic cosecant
|
||||
*
|
||||
* @return float|string
|
||||
*/
|
||||
public static function IMCSCH($complexNumber)
|
||||
{
|
||||
$complexNumber = Functions::flattenSingleValue($complexNumber);
|
||||
|
||||
return (string) (new Complex($complexNumber))->csch();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1984,17 +1936,83 @@ class Engineering
|
||||
{
|
||||
$complexNumber = Functions::flattenSingleValue($complexNumber);
|
||||
|
||||
$parsedComplex = self::parseComplex($complexNumber);
|
||||
return (string) (new Complex($complexNumber))->sin();
|
||||
}
|
||||
|
||||
if ($parsedComplex['imaginary'] == 0.0) {
|
||||
return sin($parsedComplex['real']);
|
||||
}
|
||||
/**
|
||||
* IMSINH.
|
||||
*
|
||||
* Returns the hyperbolic sine of a complex number in x + yi or x + yj text format.
|
||||
*
|
||||
* Excel Function:
|
||||
* IMSINH(complexNumber)
|
||||
*
|
||||
* @param string $complexNumber the complex number for which you want the hyperbolic sine
|
||||
*
|
||||
* @return float|string
|
||||
*/
|
||||
public static function IMSINH($complexNumber)
|
||||
{
|
||||
$complexNumber = Functions::flattenSingleValue($complexNumber);
|
||||
|
||||
return self::COMPLEX(
|
||||
sin($parsedComplex['real']) * cosh($parsedComplex['imaginary']),
|
||||
cos($parsedComplex['real']) * sinh($parsedComplex['imaginary']),
|
||||
$parsedComplex['suffix']
|
||||
);
|
||||
return (string) (new Complex($complexNumber))->sinh();
|
||||
}
|
||||
|
||||
/**
|
||||
* IMSEC.
|
||||
*
|
||||
* Returns the secant of a complex number in x + yi or x + yj text format.
|
||||
*
|
||||
* Excel Function:
|
||||
* IMSEC(complexNumber)
|
||||
*
|
||||
* @param string $complexNumber the complex number for which you want the secant
|
||||
*
|
||||
* @return float|string
|
||||
*/
|
||||
public static function IMSEC($complexNumber)
|
||||
{
|
||||
$complexNumber = Functions::flattenSingleValue($complexNumber);
|
||||
|
||||
return (string) (new Complex($complexNumber))->sec();
|
||||
}
|
||||
|
||||
/**
|
||||
* IMSECH.
|
||||
*
|
||||
* Returns the hyperbolic secant of a complex number in x + yi or x + yj text format.
|
||||
*
|
||||
* Excel Function:
|
||||
* IMSECH(complexNumber)
|
||||
*
|
||||
* @param string $complexNumber the complex number for which you want the hyperbolic secant
|
||||
*
|
||||
* @return float|string
|
||||
*/
|
||||
public static function IMSECH($complexNumber)
|
||||
{
|
||||
$complexNumber = Functions::flattenSingleValue($complexNumber);
|
||||
|
||||
return (string) (new Complex($complexNumber))->sech();
|
||||
}
|
||||
|
||||
/**
|
||||
* IMTAN.
|
||||
*
|
||||
* Returns the tangent of a complex number in x + yi or x + yj text format.
|
||||
*
|
||||
* Excel Function:
|
||||
* IMTAN(complexNumber)
|
||||
*
|
||||
* @param string $complexNumber the complex number for which you want the tangent
|
||||
*
|
||||
* @return float|string
|
||||
*/
|
||||
public static function IMTAN($complexNumber)
|
||||
{
|
||||
$complexNumber = Functions::flattenSingleValue($complexNumber);
|
||||
|
||||
return (string) (new Complex($complexNumber))->tan();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2013,22 +2031,12 @@ class Engineering
|
||||
{
|
||||
$complexNumber = Functions::flattenSingleValue($complexNumber);
|
||||
|
||||
$parsedComplex = self::parseComplex($complexNumber);
|
||||
|
||||
$theta = self::IMARGUMENT($complexNumber);
|
||||
if ($theta === Functions::DIV0()) {
|
||||
return '0';
|
||||
}
|
||||
|
||||
$d1 = cos($theta / 2);
|
||||
$d2 = sin($theta / 2);
|
||||
$r = sqrt(sqrt(($parsedComplex['real'] * $parsedComplex['real']) + ($parsedComplex['imaginary'] * $parsedComplex['imaginary'])));
|
||||
|
||||
if ($parsedComplex['suffix'] == '') {
|
||||
return self::COMPLEX($d1 * $r, $d2 * $r);
|
||||
}
|
||||
|
||||
return self::COMPLEX($d1 * $r, $d2 * $r, $parsedComplex['suffix']);
|
||||
return (string) (new Complex($complexNumber))->sqrt();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2047,20 +2055,12 @@ class Engineering
|
||||
{
|
||||
$complexNumber = Functions::flattenSingleValue($complexNumber);
|
||||
|
||||
$parsedComplex = self::parseComplex($complexNumber);
|
||||
|
||||
if (($parsedComplex['real'] == 0.0) && ($parsedComplex['imaginary'] == 0.0)) {
|
||||
$complex = new Complex($complexNumber);
|
||||
if ($complex->getReal() == 0.0 && $complex->getImaginary() == 0.0) {
|
||||
return Functions::NAN();
|
||||
}
|
||||
|
||||
$logR = log(sqrt(($parsedComplex['real'] * $parsedComplex['real']) + ($parsedComplex['imaginary'] * $parsedComplex['imaginary'])));
|
||||
$t = self::IMARGUMENT($complexNumber);
|
||||
|
||||
if ($parsedComplex['suffix'] == '') {
|
||||
return self::COMPLEX($logR, $t);
|
||||
}
|
||||
|
||||
return self::COMPLEX($logR, $t, $parsedComplex['suffix']);
|
||||
return (string) (new Complex($complexNumber))->ln();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2079,15 +2079,12 @@ class Engineering
|
||||
{
|
||||
$complexNumber = Functions::flattenSingleValue($complexNumber);
|
||||
|
||||
$parsedComplex = self::parseComplex($complexNumber);
|
||||
|
||||
if (($parsedComplex['real'] == 0.0) && ($parsedComplex['imaginary'] == 0.0)) {
|
||||
$complex = new Complex($complexNumber);
|
||||
if ($complex->getReal() == 0.0 && $complex->getImaginary() == 0.0) {
|
||||
return Functions::NAN();
|
||||
} elseif (($parsedComplex['real'] > 0.0) && ($parsedComplex['imaginary'] == 0.0)) {
|
||||
return log10($parsedComplex['real']);
|
||||
}
|
||||
|
||||
return self::IMPRODUCT(log10(self::EULER), self::IMLN($complexNumber));
|
||||
return (string) (new Complex($complexNumber))->log10();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2106,15 +2103,12 @@ class Engineering
|
||||
{
|
||||
$complexNumber = Functions::flattenSingleValue($complexNumber);
|
||||
|
||||
$parsedComplex = self::parseComplex($complexNumber);
|
||||
|
||||
if (($parsedComplex['real'] == 0.0) && ($parsedComplex['imaginary'] == 0.0)) {
|
||||
$complex = new Complex($complexNumber);
|
||||
if ($complex->getReal() == 0.0 && $complex->getImaginary() == 0.0) {
|
||||
return Functions::NAN();
|
||||
} elseif (($parsedComplex['real'] > 0.0) && ($parsedComplex['imaginary'] == 0.0)) {
|
||||
return log($parsedComplex['real'], 2);
|
||||
}
|
||||
|
||||
return self::IMPRODUCT(log(self::EULER, 2), self::IMLN($complexNumber));
|
||||
return (string) (new Complex($complexNumber))->log2();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2133,21 +2127,7 @@ class Engineering
|
||||
{
|
||||
$complexNumber = Functions::flattenSingleValue($complexNumber);
|
||||
|
||||
$parsedComplex = self::parseComplex($complexNumber);
|
||||
|
||||
if (($parsedComplex['real'] == 0.0) && ($parsedComplex['imaginary'] == 0.0)) {
|
||||
return '1';
|
||||
}
|
||||
|
||||
$e = exp($parsedComplex['real']);
|
||||
$eX = $e * cos($parsedComplex['imaginary']);
|
||||
$eY = $e * sin($parsedComplex['imaginary']);
|
||||
|
||||
if ($parsedComplex['suffix'] == '') {
|
||||
return self::COMPLEX($eX, $eY);
|
||||
}
|
||||
|
||||
return self::COMPLEX($eX, $eY, $parsedComplex['suffix']);
|
||||
return (string) (new Complex($complexNumber))->exp();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2172,18 +2152,7 @@ class Engineering
|
||||
return Functions::VALUE();
|
||||
}
|
||||
|
||||
$parsedComplex = self::parseComplex($complexNumber);
|
||||
|
||||
$r = sqrt(($parsedComplex['real'] * $parsedComplex['real']) + ($parsedComplex['imaginary'] * $parsedComplex['imaginary']));
|
||||
$rPower = pow($r, $realNumber);
|
||||
$theta = self::IMARGUMENT($complexNumber) * $realNumber;
|
||||
if ($theta == 0) {
|
||||
return 1;
|
||||
} elseif ($parsedComplex['imaginary'] == 0.0) {
|
||||
return self::COMPLEX($rPower * cos($theta), $rPower * sin($theta), $parsedComplex['suffix']);
|
||||
}
|
||||
|
||||
return self::COMPLEX($rPower * cos($theta), $rPower * sin($theta), $parsedComplex['suffix']);
|
||||
return (string) (new Complex($complexNumber))->pow($realNumber);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2204,32 +2173,11 @@ class Engineering
|
||||
$complexDividend = Functions::flattenSingleValue($complexDividend);
|
||||
$complexDivisor = Functions::flattenSingleValue($complexDivisor);
|
||||
|
||||
$parsedComplexDividend = self::parseComplex($complexDividend);
|
||||
$parsedComplexDivisor = self::parseComplex($complexDivisor);
|
||||
|
||||
if (($parsedComplexDividend['suffix'] != '') && ($parsedComplexDivisor['suffix'] != '') &&
|
||||
($parsedComplexDividend['suffix'] != $parsedComplexDivisor['suffix'])
|
||||
) {
|
||||
try {
|
||||
return (string) (new Complex($complexDividend))->divideby(new Complex($complexDivisor));
|
||||
} catch (ComplexException $e) {
|
||||
return Functions::NAN();
|
||||
}
|
||||
if (($parsedComplexDividend['suffix'] != '') && ($parsedComplexDivisor['suffix'] == '')) {
|
||||
$parsedComplexDivisor['suffix'] = $parsedComplexDividend['suffix'];
|
||||
}
|
||||
|
||||
$d1 = ($parsedComplexDividend['real'] * $parsedComplexDivisor['real']) + ($parsedComplexDividend['imaginary'] * $parsedComplexDivisor['imaginary']);
|
||||
$d2 = ($parsedComplexDividend['imaginary'] * $parsedComplexDivisor['real']) - ($parsedComplexDividend['real'] * $parsedComplexDivisor['imaginary']);
|
||||
$d3 = ($parsedComplexDivisor['real'] * $parsedComplexDivisor['real']) + ($parsedComplexDivisor['imaginary'] * $parsedComplexDivisor['imaginary']);
|
||||
|
||||
$r = $d1 / $d3;
|
||||
$i = $d2 / $d3;
|
||||
|
||||
if ($i > 0.0) {
|
||||
return self::cleanComplex($r . '+' . $i . $parsedComplexDivisor['suffix']);
|
||||
} elseif ($i < 0.0) {
|
||||
return self::cleanComplex($r . $i . $parsedComplexDivisor['suffix']);
|
||||
}
|
||||
|
||||
return $r;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2250,21 +2198,11 @@ class Engineering
|
||||
$complexNumber1 = Functions::flattenSingleValue($complexNumber1);
|
||||
$complexNumber2 = Functions::flattenSingleValue($complexNumber2);
|
||||
|
||||
$parsedComplex1 = self::parseComplex($complexNumber1);
|
||||
$parsedComplex2 = self::parseComplex($complexNumber2);
|
||||
|
||||
if ((($parsedComplex1['suffix'] != '') && ($parsedComplex2['suffix'] != '')) &&
|
||||
($parsedComplex1['suffix'] != $parsedComplex2['suffix'])
|
||||
) {
|
||||
try {
|
||||
return (string) (new Complex($complexNumber1))->subtract(new Complex($complexNumber2));
|
||||
} catch (ComplexException $e) {
|
||||
return Functions::NAN();
|
||||
} elseif (($parsedComplex1['suffix'] == '') && ($parsedComplex2['suffix'] != '')) {
|
||||
$parsedComplex1['suffix'] = $parsedComplex2['suffix'];
|
||||
}
|
||||
|
||||
$d1 = $parsedComplex1['real'] - $parsedComplex2['real'];
|
||||
$d2 = $parsedComplex1['imaginary'] - $parsedComplex2['imaginary'];
|
||||
|
||||
return self::COMPLEX($d1, $d2, $parsedComplex1['suffix']);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2282,29 +2220,19 @@ class Engineering
|
||||
public static function IMSUM(...$complexNumbers)
|
||||
{
|
||||
// Return value
|
||||
$returnValue = self::parseComplex('0');
|
||||
$activeSuffix = '';
|
||||
|
||||
// Loop through the arguments
|
||||
$returnValue = new Complex(0.0);
|
||||
$aArgs = Functions::flattenArray($complexNumbers);
|
||||
foreach ($aArgs as $arg) {
|
||||
$parsedComplex = self::parseComplex($arg);
|
||||
|
||||
if ($activeSuffix == '') {
|
||||
$activeSuffix = $parsedComplex['suffix'];
|
||||
} elseif (($parsedComplex['suffix'] != '') && ($activeSuffix != $parsedComplex['suffix'])) {
|
||||
return Functions::NAN();
|
||||
try {
|
||||
// Loop through the arguments
|
||||
foreach ($aArgs as $complex) {
|
||||
$returnValue = $returnValue->add(new Complex($complex));
|
||||
}
|
||||
|
||||
$returnValue['real'] += $parsedComplex['real'];
|
||||
$returnValue['imaginary'] += $parsedComplex['imaginary'];
|
||||
} catch (ComplexException $e) {
|
||||
return Functions::NAN();
|
||||
}
|
||||
|
||||
if ($returnValue['imaginary'] == 0.0) {
|
||||
$activeSuffix = '';
|
||||
}
|
||||
|
||||
return self::COMPLEX($returnValue['real'], $returnValue['imaginary'], $activeSuffix);
|
||||
return (string) $returnValue;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2322,29 +2250,19 @@ class Engineering
|
||||
public static function IMPRODUCT(...$complexNumbers)
|
||||
{
|
||||
// Return value
|
||||
$returnValue = self::parseComplex('1');
|
||||
$activeSuffix = '';
|
||||
|
||||
// Loop through the arguments
|
||||
$returnValue = new Complex(1.0);
|
||||
$aArgs = Functions::flattenArray($complexNumbers);
|
||||
foreach ($aArgs as $arg) {
|
||||
$parsedComplex = self::parseComplex($arg);
|
||||
|
||||
$workValue = $returnValue;
|
||||
if (($parsedComplex['suffix'] != '') && ($activeSuffix == '')) {
|
||||
$activeSuffix = $parsedComplex['suffix'];
|
||||
} elseif (($parsedComplex['suffix'] != '') && ($activeSuffix != $parsedComplex['suffix'])) {
|
||||
return Functions::NAN();
|
||||
try {
|
||||
// Loop through the arguments
|
||||
foreach ($aArgs as $complex) {
|
||||
$returnValue = $returnValue->multiply(new Complex($complex));
|
||||
}
|
||||
$returnValue['real'] = ($workValue['real'] * $parsedComplex['real']) - ($workValue['imaginary'] * $parsedComplex['imaginary']);
|
||||
$returnValue['imaginary'] = ($workValue['real'] * $parsedComplex['imaginary']) + ($workValue['imaginary'] * $parsedComplex['real']);
|
||||
} catch (ComplexException $e) {
|
||||
return Functions::NAN();
|
||||
}
|
||||
|
||||
if ($returnValue['imaginary'] == 0.0) {
|
||||
$activeSuffix = '';
|
||||
}
|
||||
|
||||
return self::COMPLEX($returnValue['real'], $returnValue['imaginary'], $activeSuffix);
|
||||
return (string) $returnValue;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2423,6 +2341,179 @@ class Engineering
|
||||
return self::$twoSqrtPi * $sum;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate arguments passed to the bitwise functions.
|
||||
*
|
||||
* @param mixed $value
|
||||
*
|
||||
* @throws Exception
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
private static function validateBitwiseArgument($value)
|
||||
{
|
||||
$value = Functions::flattenSingleValue($value);
|
||||
|
||||
if (is_int($value)) {
|
||||
return $value;
|
||||
} elseif (is_numeric($value)) {
|
||||
if ($value == (int) ($value)) {
|
||||
$value = (int) ($value);
|
||||
if (($value > pow(2, 48) - 1) || ($value < 0)) {
|
||||
throw new Exception(Functions::NAN());
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
throw new Exception(Functions::NAN());
|
||||
}
|
||||
|
||||
throw new Exception(Functions::VALUE());
|
||||
}
|
||||
|
||||
/**
|
||||
* BITAND.
|
||||
*
|
||||
* Returns the bitwise AND of two integer values.
|
||||
*
|
||||
* Excel Function:
|
||||
* BITAND(number1, number2)
|
||||
*
|
||||
* @category Engineering Functions
|
||||
*
|
||||
* @param int $number1
|
||||
* @param int $number2
|
||||
*
|
||||
* @return int|string
|
||||
*/
|
||||
public static function BITAND($number1, $number2)
|
||||
{
|
||||
try {
|
||||
$number1 = self::validateBitwiseArgument($number1);
|
||||
$number2 = self::validateBitwiseArgument($number2);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
return $number1 & $number2;
|
||||
}
|
||||
|
||||
/**
|
||||
* BITOR.
|
||||
*
|
||||
* Returns the bitwise OR of two integer values.
|
||||
*
|
||||
* Excel Function:
|
||||
* BITOR(number1, number2)
|
||||
*
|
||||
* @category Engineering Functions
|
||||
*
|
||||
* @param int $number1
|
||||
* @param int $number2
|
||||
*
|
||||
* @return int|string
|
||||
*/
|
||||
public static function BITOR($number1, $number2)
|
||||
{
|
||||
try {
|
||||
$number1 = self::validateBitwiseArgument($number1);
|
||||
$number2 = self::validateBitwiseArgument($number2);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
return $number1 | $number2;
|
||||
}
|
||||
|
||||
/**
|
||||
* BITXOR.
|
||||
*
|
||||
* Returns the bitwise XOR of two integer values.
|
||||
*
|
||||
* Excel Function:
|
||||
* BITXOR(number1, number2)
|
||||
*
|
||||
* @category Engineering Functions
|
||||
*
|
||||
* @param int $number1
|
||||
* @param int $number2
|
||||
*
|
||||
* @return int|string
|
||||
*/
|
||||
public static function BITXOR($number1, $number2)
|
||||
{
|
||||
try {
|
||||
$number1 = self::validateBitwiseArgument($number1);
|
||||
$number2 = self::validateBitwiseArgument($number2);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
return $number1 ^ $number2;
|
||||
}
|
||||
|
||||
/**
|
||||
* BITLSHIFT.
|
||||
*
|
||||
* Returns the number value shifted left by shift_amount bits.
|
||||
*
|
||||
* Excel Function:
|
||||
* BITLSHIFT(number, shift_amount)
|
||||
*
|
||||
* @category Engineering Functions
|
||||
*
|
||||
* @param int $number
|
||||
* @param int $shiftAmount
|
||||
*
|
||||
* @return int|string
|
||||
*/
|
||||
public static function BITLSHIFT($number, $shiftAmount)
|
||||
{
|
||||
try {
|
||||
$number = self::validateBitwiseArgument($number);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
$shiftAmount = Functions::flattenSingleValue($shiftAmount);
|
||||
|
||||
$result = $number << $shiftAmount;
|
||||
if ($result > pow(2, 48) - 1) {
|
||||
return Functions::NAN();
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* BITRSHIFT.
|
||||
*
|
||||
* Returns the number value shifted right by shift_amount bits.
|
||||
*
|
||||
* Excel Function:
|
||||
* BITRSHIFT(number, shift_amount)
|
||||
*
|
||||
* @category Engineering Functions
|
||||
*
|
||||
* @param int $number
|
||||
* @param int $shiftAmount
|
||||
*
|
||||
* @return int|string
|
||||
*/
|
||||
public static function BITRSHIFT($number, $shiftAmount)
|
||||
{
|
||||
try {
|
||||
$number = self::validateBitwiseArgument($number);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
$shiftAmount = Functions::flattenSingleValue($shiftAmount);
|
||||
|
||||
return $number >> $shiftAmount;
|
||||
}
|
||||
|
||||
/**
|
||||
* ERF.
|
||||
*
|
||||
@ -2431,7 +2522,7 @@ class Engineering
|
||||
* Note: In Excel 2007 or earlier, if you input a negative value for the upper or lower bound arguments,
|
||||
* the function would return a #NUM! error. However, in Excel 2010, the function algorithm was
|
||||
* improved, so that it can now calculate the function for both positive and negative ranges.
|
||||
* PhpSpreadsheet follows Excel 2010 behaviour, and accepts nagative arguments.
|
||||
* PhpSpreadsheet follows Excel 2010 behaviour, and accepts negative arguments.
|
||||
*
|
||||
* Excel Function:
|
||||
* ERF(lower[,upper])
|
||||
@ -2440,7 +2531,7 @@ class Engineering
|
||||
* @param float $upper upper bound for integrating ERF.
|
||||
* If omitted, ERF integrates between zero and lower_limit
|
||||
*
|
||||
* @return float
|
||||
* @return float|string
|
||||
*/
|
||||
public static function ERF($lower, $upper = null)
|
||||
{
|
||||
@ -2459,6 +2550,25 @@ class Engineering
|
||||
return Functions::VALUE();
|
||||
}
|
||||
|
||||
/**
|
||||
* ERFPRECISE.
|
||||
*
|
||||
* Returns the error function integrated between the lower and upper bound arguments.
|
||||
*
|
||||
* Excel Function:
|
||||
* ERF.PRECISE(limit)
|
||||
*
|
||||
* @param float $limit bound for integrating ERF
|
||||
*
|
||||
* @return float|string
|
||||
*/
|
||||
public static function ERFPRECISE($limit)
|
||||
{
|
||||
$limit = Functions::flattenSingleValue($limit);
|
||||
|
||||
return self::ERF($limit);
|
||||
}
|
||||
|
||||
//
|
||||
// Private method to calculate the erfc value
|
||||
//
|
||||
@ -2507,7 +2617,7 @@ class Engineering
|
||||
*
|
||||
* @param float $x The lower bound for integrating ERFC
|
||||
*
|
||||
* @return float
|
||||
* @return float|string
|
||||
*/
|
||||
public static function ERFC($x)
|
||||
{
|
||||
|
@ -6,7 +6,7 @@ use PhpOffice\PhpSpreadsheet\Shared\Date;
|
||||
|
||||
class Financial
|
||||
{
|
||||
const FINANCIAL_MAX_ITERATIONS = 128;
|
||||
const FINANCIAL_MAX_ITERATIONS = 32;
|
||||
|
||||
const FINANCIAL_PRECISION = 1.0e-08;
|
||||
|
||||
@ -63,8 +63,8 @@ class Financial
|
||||
*
|
||||
* Returns the number of days in a specified year, as defined by the "basis" value
|
||||
*
|
||||
* @param int $year The year against which we're testing
|
||||
* @param int $basis The type of day count:
|
||||
* @param int|string $year The year against which we're testing
|
||||
* @param int|string $basis The type of day count:
|
||||
* 0 or omitted US (NASD) 360
|
||||
* 1 Actual (365 or 366 in a leap year)
|
||||
* 2 360
|
||||
@ -144,7 +144,7 @@ class Financial
|
||||
* 3 Actual/365
|
||||
* 4 European 30/360
|
||||
*
|
||||
* @return float
|
||||
* @return float|string
|
||||
*/
|
||||
public static function ACCRINT($issue, $firstinterest, $settlement, $rate, $par = 1000, $frequency = 1, $basis = 0)
|
||||
{
|
||||
@ -197,7 +197,7 @@ class Financial
|
||||
* 3 Actual/365
|
||||
* 4 European 30/360
|
||||
*
|
||||
* @return float
|
||||
* @return float|string
|
||||
*/
|
||||
public static function ACCRINTM($issue, $settlement, $rate, $par = 1000, $basis = 0)
|
||||
{
|
||||
@ -401,7 +401,7 @@ class Financial
|
||||
* 3 Actual/365
|
||||
* 4 European 30/360
|
||||
*
|
||||
* @return float
|
||||
* @return float|string
|
||||
*/
|
||||
public static function COUPDAYBS($settlement, $maturity, $frequency, $basis = 0)
|
||||
{
|
||||
@ -460,7 +460,7 @@ class Financial
|
||||
* 3 Actual/365
|
||||
* 4 European 30/360
|
||||
*
|
||||
* @return float
|
||||
* @return float|string
|
||||
*/
|
||||
public static function COUPDAYS($settlement, $maturity, $frequency, $basis = 0)
|
||||
{
|
||||
@ -489,7 +489,7 @@ class Financial
|
||||
case 1:
|
||||
// Actual/actual
|
||||
if ($frequency == 1) {
|
||||
$daysPerYear = self::daysPerYear(DateTime::YEAR($maturity), $basis);
|
||||
$daysPerYear = self::daysPerYear(DateTime::YEAR($settlement), $basis);
|
||||
|
||||
return $daysPerYear / $frequency;
|
||||
}
|
||||
@ -534,7 +534,7 @@ class Financial
|
||||
* 3 Actual/365
|
||||
* 4 European 30/360
|
||||
*
|
||||
* @return float
|
||||
* @return float|string
|
||||
*/
|
||||
public static function COUPDAYSNC($settlement, $maturity, $frequency, $basis = 0)
|
||||
{
|
||||
@ -651,7 +651,7 @@ class Financial
|
||||
* 3 Actual/365
|
||||
* 4 European 30/360
|
||||
*
|
||||
* @return int
|
||||
* @return int|string
|
||||
*/
|
||||
public static function COUPNUM($settlement, $maturity, $frequency, $basis = 0)
|
||||
{
|
||||
@ -769,7 +769,7 @@ class Financial
|
||||
* 0 or omitted At the end of the period.
|
||||
* 1 At the beginning of the period.
|
||||
*
|
||||
* @return float
|
||||
* @return float|string
|
||||
*/
|
||||
public static function CUMIPMT($rate, $nper, $pv, $start, $end, $type = 0)
|
||||
{
|
||||
@ -817,7 +817,7 @@ class Financial
|
||||
* 0 or omitted At the end of the period.
|
||||
* 1 At the beginning of the period.
|
||||
*
|
||||
* @return float
|
||||
* @return float|string
|
||||
*/
|
||||
public static function CUMPRINC($rate, $nper, $pv, $start, $end, $type = 0)
|
||||
{
|
||||
@ -870,7 +870,7 @@ class Financial
|
||||
* @param int $month Number of months in the first year. If month is omitted,
|
||||
* it defaults to 12.
|
||||
*
|
||||
* @return float
|
||||
* @return float|string
|
||||
*/
|
||||
public static function DB($cost, $salvage, $life, $period, $month = 12)
|
||||
{
|
||||
@ -940,7 +940,7 @@ class Financial
|
||||
* If factor is omitted, it is assumed to be 2 (the
|
||||
* double-declining balance method).
|
||||
*
|
||||
* @return float
|
||||
* @return float|string
|
||||
*/
|
||||
public static function DDB($cost, $salvage, $life, $period, $factor = 2.0)
|
||||
{
|
||||
@ -1004,7 +1004,7 @@ class Financial
|
||||
* 3 Actual/365
|
||||
* 4 European 30/360
|
||||
*
|
||||
* @return float
|
||||
* @return float|string
|
||||
*/
|
||||
public static function DISC($settlement, $maturity, $price, $redemption, $basis = 0)
|
||||
{
|
||||
@ -1049,7 +1049,7 @@ class Financial
|
||||
* @param float $fractional_dollar Fractional Dollar
|
||||
* @param int $fraction Fraction
|
||||
*
|
||||
* @return float
|
||||
* @return float|string
|
||||
*/
|
||||
public static function DOLLARDE($fractional_dollar = null, $fraction = 0)
|
||||
{
|
||||
@ -1087,7 +1087,7 @@ class Financial
|
||||
* @param float $decimal_dollar Decimal Dollar
|
||||
* @param int $fraction Fraction
|
||||
*
|
||||
* @return float
|
||||
* @return float|string
|
||||
*/
|
||||
public static function DOLLARFR($decimal_dollar = null, $fraction = 0)
|
||||
{
|
||||
@ -1124,7 +1124,7 @@ class Financial
|
||||
* @param float $nominal_rate Nominal interest rate
|
||||
* @param int $npery Number of compounding payments per year
|
||||
*
|
||||
* @return float
|
||||
* @return float|string
|
||||
*/
|
||||
public static function EFFECT($nominal_rate = 0, $npery = 0)
|
||||
{
|
||||
@ -1160,7 +1160,7 @@ class Financial
|
||||
* 0 or omitted At the end of the period.
|
||||
* 1 At the beginning of the period.
|
||||
*
|
||||
* @return float
|
||||
* @return float|string
|
||||
*/
|
||||
public static function FV($rate = 0, $nper = 0, $pmt = 0, $pv = 0, $type = 0)
|
||||
{
|
||||
@ -1230,7 +1230,7 @@ class Financial
|
||||
* 3 Actual/365
|
||||
* 4 European 30/360
|
||||
*
|
||||
* @return float
|
||||
* @return float|string
|
||||
*/
|
||||
public static function INTRATE($settlement, $maturity, $investment, $redemption, $basis = 0)
|
||||
{
|
||||
@ -1275,7 +1275,7 @@ class Financial
|
||||
* @param float $fv Future Value
|
||||
* @param int $type Payment type: 0 = at the end of each period, 1 = at the beginning of each period
|
||||
*
|
||||
* @return float
|
||||
* @return float|string
|
||||
*/
|
||||
public static function IPMT($rate, $per, $nper, $pv, $fv = 0, $type = 0)
|
||||
{
|
||||
@ -1318,7 +1318,7 @@ class Financial
|
||||
* calculate the internal rate of return.
|
||||
* @param float $guess A number that you guess is close to the result of IRR
|
||||
*
|
||||
* @return float
|
||||
* @return float|string
|
||||
*/
|
||||
public static function IRR($values, $guess = 0.1)
|
||||
{
|
||||
@ -1428,7 +1428,7 @@ class Financial
|
||||
* @param float $finance_rate The interest rate you pay on the money used in the cash flows
|
||||
* @param float $reinvestment_rate The interest rate you receive on the cash flows as you reinvest them
|
||||
*
|
||||
* @return float
|
||||
* @return float|string
|
||||
*/
|
||||
public static function MIRR($values, $finance_rate, $reinvestment_rate)
|
||||
{
|
||||
@ -1470,7 +1470,7 @@ class Financial
|
||||
* @param float $effect_rate Effective interest rate
|
||||
* @param int $npery Number of compounding payments per year
|
||||
*
|
||||
* @return float
|
||||
* @return float|string
|
||||
*/
|
||||
public static function NOMINAL($effect_rate = 0, $npery = 0)
|
||||
{
|
||||
@ -1497,7 +1497,7 @@ class Financial
|
||||
* @param float $fv Future Value
|
||||
* @param int $type Payment type: 0 = at the end of each period, 1 = at the beginning of each period
|
||||
*
|
||||
* @return float
|
||||
* @return float|string
|
||||
*/
|
||||
public static function NPER($rate = 0, $pmt = 0, $pv = 0, $fv = 0, $type = 0)
|
||||
{
|
||||
@ -1556,6 +1556,33 @@ class Financial
|
||||
return $returnValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* PDURATION.
|
||||
*
|
||||
* Calculates the number of periods required for an investment to reach a specified value.
|
||||
*
|
||||
* @param float $rate Interest rate per period
|
||||
* @param float $pv Present Value
|
||||
* @param float $fv Future Value
|
||||
*
|
||||
* @return float|string
|
||||
*/
|
||||
public static function PDURATION($rate = 0, $pv = 0, $fv = 0)
|
||||
{
|
||||
$rate = Functions::flattenSingleValue($rate);
|
||||
$pv = Functions::flattenSingleValue($pv);
|
||||
$fv = Functions::flattenSingleValue($fv);
|
||||
|
||||
// Validate parameters
|
||||
if (!is_numeric($rate) || !is_numeric($pv) || !is_numeric($fv)) {
|
||||
return Functions::VALUE();
|
||||
} elseif ($rate <= 0.0 || $pv <= 0.0 || $fv <= 0.0) {
|
||||
return Functions::NAN();
|
||||
}
|
||||
|
||||
return (log($fv) - log($pv)) / log(1 + $rate);
|
||||
}
|
||||
|
||||
/**
|
||||
* PMT.
|
||||
*
|
||||
@ -1933,6 +1960,33 @@ class Financial
|
||||
return Functions::VALUE();
|
||||
}
|
||||
|
||||
/**
|
||||
* RRI.
|
||||
*
|
||||
* Calculates the interest rate required for an investment to grow to a specified future value .
|
||||
*
|
||||
* @param float $nper The number of periods over which the investment is made
|
||||
* @param float $pv Present Value
|
||||
* @param float $fv Future Value
|
||||
*
|
||||
* @return float|string
|
||||
*/
|
||||
public static function RRI($nper = 0, $pv = 0, $fv = 0)
|
||||
{
|
||||
$nper = Functions::flattenSingleValue($nper);
|
||||
$pv = Functions::flattenSingleValue($pv);
|
||||
$fv = Functions::flattenSingleValue($fv);
|
||||
|
||||
// Validate parameters
|
||||
if (!is_numeric($nper) || !is_numeric($pv) || !is_numeric($fv)) {
|
||||
return Functions::VALUE();
|
||||
} elseif ($nper <= 0.0 || $pv <= 0.0 || $fv < 0.0) {
|
||||
return Functions::NAN();
|
||||
}
|
||||
|
||||
return pow($fv / $pv, 1 / $nper) - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* SLN.
|
||||
*
|
||||
@ -1942,7 +1996,7 @@ class Financial
|
||||
* @param mixed $salvage Value at the end of the depreciation
|
||||
* @param mixed $life Number of periods over which the asset is depreciated
|
||||
*
|
||||
* @return float
|
||||
* @return float|string
|
||||
*/
|
||||
public static function SLN($cost, $salvage, $life)
|
||||
{
|
||||
@ -1972,7 +2026,7 @@ class Financial
|
||||
* @param mixed $life Number of periods over which the asset is depreciated
|
||||
* @param mixed $period Period
|
||||
*
|
||||
* @return float
|
||||
* @return float|string
|
||||
*/
|
||||
public static function SYD($cost, $salvage, $life, $period)
|
||||
{
|
||||
|
@ -277,7 +277,7 @@ class Functions
|
||||
|
||||
return '=' . $condition;
|
||||
}
|
||||
preg_match('/([<>=]+)(.*)/', $condition, $matches);
|
||||
preg_match('/(=|<[>=]?|>=?)(.*)/', $condition, $matches);
|
||||
list(, $operator, $operand) = $matches;
|
||||
|
||||
if (!is_numeric($operand)) {
|
||||
@ -355,7 +355,7 @@ class Functions
|
||||
return false;
|
||||
}
|
||||
|
||||
return in_array($value, array_values(self::$errorCodes));
|
||||
return in_array($value, self::$errorCodes);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -648,17 +648,26 @@ class Functions
|
||||
/**
|
||||
* ISFORMULA.
|
||||
*
|
||||
* @param mixed $value The cell to check
|
||||
* @param mixed $cellReference The cell to check
|
||||
* @param Cell $pCell The current cell (containing this formula)
|
||||
*
|
||||
* @return bool|string
|
||||
*/
|
||||
public static function isFormula($value = '', Cell $pCell = null)
|
||||
public static function isFormula($cellReference = '', Cell $pCell = null)
|
||||
{
|
||||
if ($pCell === null) {
|
||||
return self::REF();
|
||||
}
|
||||
|
||||
return substr($pCell->getWorksheet()->getCell($value)->getValue(), 0, 1) === '=';
|
||||
preg_match('/^' . Calculation::CALCULATION_REGEXP_CELLREF . '$/i', $cellReference, $matches);
|
||||
|
||||
$cellReference = $matches[6] . $matches[7];
|
||||
$worksheetName = trim($matches[3], "'");
|
||||
|
||||
$worksheet = (!empty($worksheetName))
|
||||
? $pCell->getWorksheet()->getParent()->getSheetByName($worksheetName)
|
||||
: $pCell->getWorksheet();
|
||||
|
||||
return $worksheet->getCell($cellReference)->isFormula();
|
||||
}
|
||||
}
|
||||
|
@ -38,6 +38,32 @@ class Logical
|
||||
return false;
|
||||
}
|
||||
|
||||
private static function countTrueValues(array $args)
|
||||
{
|
||||
$returnValue = 0;
|
||||
|
||||
foreach ($args as $arg) {
|
||||
// Is it a boolean value?
|
||||
if (is_bool($arg)) {
|
||||
$returnValue += $arg;
|
||||
} elseif ((is_numeric($arg)) && (!is_string($arg))) {
|
||||
$returnValue += ((int) $arg != 0);
|
||||
} elseif (is_string($arg)) {
|
||||
$arg = strtoupper($arg);
|
||||
if (($arg == 'TRUE') || ($arg == Calculation::getTRUE())) {
|
||||
$arg = true;
|
||||
} elseif (($arg == 'FALSE') || ($arg == Calculation::getFALSE())) {
|
||||
$arg = false;
|
||||
} else {
|
||||
return Functions::VALUE();
|
||||
}
|
||||
$returnValue += ($arg != 0);
|
||||
}
|
||||
}
|
||||
|
||||
return $returnValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* LOGICAL_AND.
|
||||
*
|
||||
@ -62,37 +88,23 @@ class Logical
|
||||
*/
|
||||
public static function logicalAnd(...$args)
|
||||
{
|
||||
// Return value
|
||||
$returnValue = true;
|
||||
$args = Functions::flattenArray($args);
|
||||
|
||||
// Loop through the arguments
|
||||
$aArgs = Functions::flattenArray($args);
|
||||
$argCount = -1;
|
||||
foreach ($aArgs as $argCount => $arg) {
|
||||
// Is it a boolean value?
|
||||
if (is_bool($arg)) {
|
||||
$returnValue = $returnValue && $arg;
|
||||
} elseif ((is_numeric($arg)) && (!is_string($arg))) {
|
||||
$returnValue = $returnValue && ($arg != 0);
|
||||
} elseif (is_string($arg)) {
|
||||
$arg = strtoupper($arg);
|
||||
if (($arg == 'TRUE') || ($arg == Calculation::getTRUE())) {
|
||||
$arg = true;
|
||||
} elseif (($arg == 'FALSE') || ($arg == Calculation::getFALSE())) {
|
||||
$arg = false;
|
||||
} else {
|
||||
return Functions::VALUE();
|
||||
}
|
||||
$returnValue = $returnValue && ($arg != 0);
|
||||
}
|
||||
}
|
||||
|
||||
// Return
|
||||
if ($argCount < 0) {
|
||||
if (count($args) == 0) {
|
||||
return Functions::VALUE();
|
||||
}
|
||||
|
||||
return $returnValue;
|
||||
$args = array_filter($args, function ($value) {
|
||||
return $value !== null || (is_string($value) && trim($value) == '');
|
||||
});
|
||||
$argCount = count($args);
|
||||
|
||||
$returnValue = self::countTrueValues($args);
|
||||
if (is_string($returnValue)) {
|
||||
return $returnValue;
|
||||
}
|
||||
|
||||
return ($returnValue > 0) && ($returnValue == $argCount);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -119,37 +131,65 @@ class Logical
|
||||
*/
|
||||
public static function logicalOr(...$args)
|
||||
{
|
||||
// Return value
|
||||
$returnValue = false;
|
||||
$args = Functions::flattenArray($args);
|
||||
|
||||
// Loop through the arguments
|
||||
$aArgs = Functions::flattenArray($args);
|
||||
$argCount = -1;
|
||||
foreach ($aArgs as $argCount => $arg) {
|
||||
// Is it a boolean value?
|
||||
if (is_bool($arg)) {
|
||||
$returnValue = $returnValue || $arg;
|
||||
} elseif ((is_numeric($arg)) && (!is_string($arg))) {
|
||||
$returnValue = $returnValue || ($arg != 0);
|
||||
} elseif (is_string($arg)) {
|
||||
$arg = strtoupper($arg);
|
||||
if (($arg == 'TRUE') || ($arg == Calculation::getTRUE())) {
|
||||
$arg = true;
|
||||
} elseif (($arg == 'FALSE') || ($arg == Calculation::getFALSE())) {
|
||||
$arg = false;
|
||||
} else {
|
||||
return Functions::VALUE();
|
||||
}
|
||||
$returnValue = $returnValue || ($arg != 0);
|
||||
}
|
||||
}
|
||||
|
||||
// Return
|
||||
if ($argCount < 0) {
|
||||
if (count($args) == 0) {
|
||||
return Functions::VALUE();
|
||||
}
|
||||
|
||||
return $returnValue;
|
||||
$args = array_filter($args, function ($value) {
|
||||
return $value !== null || (is_string($value) && trim($value) == '');
|
||||
});
|
||||
|
||||
$returnValue = self::countTrueValues($args);
|
||||
if (is_string($returnValue)) {
|
||||
return $returnValue;
|
||||
}
|
||||
|
||||
return $returnValue > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* LOGICAL_XOR.
|
||||
*
|
||||
* Returns the Exclusive Or logical operation for one or more supplied conditions.
|
||||
* i.e. the Xor function returns TRUE if an odd number of the supplied conditions evaluate to TRUE, and FALSE otherwise.
|
||||
*
|
||||
* Excel Function:
|
||||
* =XOR(logical1[,logical2[, ...]])
|
||||
*
|
||||
* The arguments must evaluate to logical values such as TRUE or FALSE, or the arguments must be arrays
|
||||
* or references that contain logical values.
|
||||
*
|
||||
* Boolean arguments are treated as True or False as appropriate
|
||||
* Integer or floating point arguments are treated as True, except for 0 or 0.0 which are False
|
||||
* If any argument value is a string, or a Null, the function returns a #VALUE! error, unless the string holds
|
||||
* the value TRUE or FALSE, in which case it is evaluated as the corresponding boolean value
|
||||
*
|
||||
* @category Logical Functions
|
||||
*
|
||||
* @param mixed $args Data values
|
||||
*
|
||||
* @return bool|string the logical XOR of the arguments
|
||||
*/
|
||||
public static function logicalXor(...$args)
|
||||
{
|
||||
$args = Functions::flattenArray($args);
|
||||
|
||||
if (count($args) == 0) {
|
||||
return Functions::VALUE();
|
||||
}
|
||||
|
||||
$args = array_filter($args, function ($value) {
|
||||
return $value !== null || (is_string($value) && trim($value) == '');
|
||||
});
|
||||
|
||||
$returnValue = self::countTrueValues($args);
|
||||
if (is_string($returnValue)) {
|
||||
return $returnValue;
|
||||
}
|
||||
|
||||
return $returnValue % 2 == 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -176,6 +216,7 @@ class Logical
|
||||
public static function NOT($logical = false)
|
||||
{
|
||||
$logical = Functions::flattenSingleValue($logical);
|
||||
|
||||
if (is_string($logical)) {
|
||||
$logical = strtoupper($logical);
|
||||
if (($logical == 'TRUE') || ($logical == Calculation::getTRUE())) {
|
||||
|
@ -866,4 +866,33 @@ class LookupRef
|
||||
|
||||
return self::VLOOKUP($lookup_value, $lookup_vector, 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* FORMULATEXT.
|
||||
*
|
||||
* @param mixed $cellReference The cell to check
|
||||
* @param Cell $pCell The current cell (containing this formula)
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function FORMULATEXT($cellReference = '', Cell $pCell = null)
|
||||
{
|
||||
if ($pCell === null) {
|
||||
return Functions::REF();
|
||||
}
|
||||
|
||||
preg_match('/^' . Calculation::CALCULATION_REGEXP_CELLREF . '$/i', $cellReference, $matches);
|
||||
|
||||
$cellReference = $matches[6] . $matches[7];
|
||||
$worksheetName = trim($matches[3], "'");
|
||||
$worksheet = (!empty($worksheetName))
|
||||
? $pCell->getWorksheet()->getParent()->getSheetByName($worksheetName)
|
||||
: $pCell->getWorksheet();
|
||||
|
||||
if (!$worksheet->getCell($cellReference)->isFormula()) {
|
||||
return Functions::NA();
|
||||
}
|
||||
|
||||
return $worksheet->getCell($cellReference)->getValue();
|
||||
}
|
||||
}
|
||||
|
@ -1081,30 +1081,55 @@ class MathTrig
|
||||
);
|
||||
}
|
||||
|
||||
protected static function filterFormulaArgs($cellReference, $args)
|
||||
{
|
||||
return array_filter(
|
||||
$args,
|
||||
function ($index) use ($cellReference) {
|
||||
list(, $row, $column) = explode('.', $index);
|
||||
if ($cellReference->getWorksheet()->cellExists($column . $row)) {
|
||||
//take this cell out if it contains the SUBTOTAL or AGGREGATE functions in a formula
|
||||
$isFormula = $cellReference->getWorksheet()->getCell($column . $row)->isFormula();
|
||||
$cellFormula = !preg_match('/^=.*\b(SUBTOTAL|AGGREGATE)\s*\(/i', $cellReference->getWorksheet()->getCell($column . $row)->getValue());
|
||||
|
||||
return !$isFormula || $cellFormula;
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
ARRAY_FILTER_USE_KEY
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* SUBTOTAL.
|
||||
*
|
||||
* Returns a subtotal in a list or database.
|
||||
*
|
||||
* @param int the number 1 to 11 that specifies which function to
|
||||
* use in calculating subtotals within a list
|
||||
* use in calculating subtotals within a range
|
||||
* list
|
||||
* Numbers 101 to 111 shadow the functions of 1 to 11
|
||||
* but ignore any values in the range that are
|
||||
* in hidden rows or columns
|
||||
* @param array of mixed Data Series
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public static function SUBTOTAL(...$args)
|
||||
{
|
||||
$cellReference = array_pop($args);
|
||||
$aArgs = Functions::flattenArrayIndexed($args);
|
||||
$cellReference = array_pop($aArgs);
|
||||
$subtotal = array_shift($aArgs);
|
||||
|
||||
// Calculate
|
||||
if ((is_numeric($subtotal)) && (!is_string($subtotal))) {
|
||||
if ($subtotal > 100) {
|
||||
$aArgs = self::filterHiddenArgs($cellReference, $aArgs);
|
||||
$subtotal = $subtotal - 100;
|
||||
$subtotal -= 100;
|
||||
}
|
||||
|
||||
$aArgs = self::filterFormulaArgs($cellReference, $aArgs);
|
||||
switch ($subtotal) {
|
||||
case 1:
|
||||
return Statistical::AVERAGE($aArgs);
|
||||
@ -1433,4 +1458,178 @@ class MathTrig
|
||||
|
||||
return ((int) ($value * $adjust)) / $adjust;
|
||||
}
|
||||
|
||||
/**
|
||||
* SEC.
|
||||
*
|
||||
* Returns the secant of an angle.
|
||||
*
|
||||
* @param float $angle Number
|
||||
*
|
||||
* @return float|string The secant of the angle
|
||||
*/
|
||||
public static function SEC($angle)
|
||||
{
|
||||
$angle = Functions::flattenSingleValue($angle);
|
||||
|
||||
if (!is_numeric($angle)) {
|
||||
return Functions::VALUE();
|
||||
}
|
||||
|
||||
$result = cos($angle);
|
||||
|
||||
return ($result == 0.0) ? Functions::DIV0() : 1 / $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* SECH.
|
||||
*
|
||||
* Returns the hyperbolic secant of an angle.
|
||||
*
|
||||
* @param float $angle Number
|
||||
*
|
||||
* @return float|string The hyperbolic secant of the angle
|
||||
*/
|
||||
public static function SECH($angle)
|
||||
{
|
||||
$angle = Functions::flattenSingleValue($angle);
|
||||
|
||||
if (!is_numeric($angle)) {
|
||||
return Functions::VALUE();
|
||||
}
|
||||
|
||||
$result = cosh($angle);
|
||||
|
||||
return ($result == 0.0) ? Functions::DIV0() : 1 / $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* CSC.
|
||||
*
|
||||
* Returns the cosecant of an angle.
|
||||
*
|
||||
* @param float $angle Number
|
||||
*
|
||||
* @return float|string The cosecant of the angle
|
||||
*/
|
||||
public static function CSC($angle)
|
||||
{
|
||||
$angle = Functions::flattenSingleValue($angle);
|
||||
|
||||
if (!is_numeric($angle)) {
|
||||
return Functions::VALUE();
|
||||
}
|
||||
|
||||
$result = sin($angle);
|
||||
|
||||
return ($result == 0.0) ? Functions::DIV0() : 1 / $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* CSCH.
|
||||
*
|
||||
* Returns the hyperbolic cosecant of an angle.
|
||||
*
|
||||
* @param float $angle Number
|
||||
*
|
||||
* @return float|string The hyperbolic cosecant of the angle
|
||||
*/
|
||||
public static function CSCH($angle)
|
||||
{
|
||||
$angle = Functions::flattenSingleValue($angle);
|
||||
|
||||
if (!is_numeric($angle)) {
|
||||
return Functions::VALUE();
|
||||
}
|
||||
|
||||
$result = sinh($angle);
|
||||
|
||||
return ($result == 0.0) ? Functions::DIV0() : 1 / $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* COT.
|
||||
*
|
||||
* Returns the cotangent of an angle.
|
||||
*
|
||||
* @param float $angle Number
|
||||
*
|
||||
* @return float|string The cotangent of the angle
|
||||
*/
|
||||
public static function COT($angle)
|
||||
{
|
||||
$angle = Functions::flattenSingleValue($angle);
|
||||
|
||||
if (!is_numeric($angle)) {
|
||||
return Functions::VALUE();
|
||||
}
|
||||
|
||||
$result = tan($angle);
|
||||
|
||||
return ($result == 0.0) ? Functions::DIV0() : 1 / $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* COTH.
|
||||
*
|
||||
* Returns the hyperbolic cotangent of an angle.
|
||||
*
|
||||
* @param float $angle Number
|
||||
*
|
||||
* @return float|string The hyperbolic cotangent of the angle
|
||||
*/
|
||||
public static function COTH($angle)
|
||||
{
|
||||
$angle = Functions::flattenSingleValue($angle);
|
||||
|
||||
if (!is_numeric($angle)) {
|
||||
return Functions::VALUE();
|
||||
}
|
||||
|
||||
$result = tanh($angle);
|
||||
|
||||
return ($result == 0.0) ? Functions::DIV0() : 1 / $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* ACOT.
|
||||
*
|
||||
* Returns the arccotangent of a number.
|
||||
*
|
||||
* @param float $number Number
|
||||
*
|
||||
* @return float|string The arccotangent of the number
|
||||
*/
|
||||
public static function ACOT($number)
|
||||
{
|
||||
$number = Functions::flattenSingleValue($number);
|
||||
|
||||
if (!is_numeric($number)) {
|
||||
return Functions::VALUE();
|
||||
}
|
||||
|
||||
return (M_PI / 2) - atan($number);
|
||||
}
|
||||
|
||||
/**
|
||||
* ACOTH.
|
||||
*
|
||||
* Returns the hyperbolic arccotangent of a number.
|
||||
*
|
||||
* @param float $number Number
|
||||
*
|
||||
* @return float|string The hyperbolic arccotangent of the number
|
||||
*/
|
||||
public static function ACOTH($number)
|
||||
{
|
||||
$number = Functions::flattenSingleValue($number);
|
||||
|
||||
if (!is_numeric($number)) {
|
||||
return Functions::VALUE();
|
||||
}
|
||||
|
||||
$result = log(($number + 1) / ($number - 1)) / 2;
|
||||
|
||||
return is_nan($result) ? Functions::NAN() : $result;
|
||||
}
|
||||
}
|
||||
|
@ -577,4 +577,96 @@ class TextData
|
||||
|
||||
return (float) $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* NUMBERVALUE.
|
||||
*
|
||||
* @param mixed $value Value to check
|
||||
* @param string $decimalSeparator decimal separator, defaults to locale defined value
|
||||
* @param string $groupSeparator group/thosands separator, defaults to locale defined value
|
||||
*
|
||||
* @return float|string
|
||||
*/
|
||||
public static function NUMBERVALUE($value = '', $decimalSeparator = null, $groupSeparator = null)
|
||||
{
|
||||
$value = Functions::flattenSingleValue($value);
|
||||
$decimalSeparator = Functions::flattenSingleValue($decimalSeparator);
|
||||
$groupSeparator = Functions::flattenSingleValue($groupSeparator);
|
||||
|
||||
if (!is_numeric($value)) {
|
||||
$decimalSeparator = empty($decimalSeparator) ? StringHelper::getDecimalSeparator() : $decimalSeparator;
|
||||
$groupSeparator = empty($groupSeparator) ? StringHelper::getThousandsSeparator() : $groupSeparator;
|
||||
|
||||
$decimalPositions = preg_match_all('/' . preg_quote($decimalSeparator) . '/', $value, $matches, PREG_OFFSET_CAPTURE);
|
||||
if ($decimalPositions > 1) {
|
||||
return Functions::VALUE();
|
||||
}
|
||||
$decimalOffset = array_pop($matches[0])[1];
|
||||
if (strpos($value, $groupSeparator, $decimalOffset) !== false) {
|
||||
return Functions::VALUE();
|
||||
}
|
||||
|
||||
$value = str_replace([$groupSeparator, $decimalSeparator], ['', '.'], $value);
|
||||
|
||||
// Handle the special case of trailing % signs
|
||||
$percentageString = rtrim($value, '%');
|
||||
if (!is_numeric($percentageString)) {
|
||||
return Functions::VALUE();
|
||||
}
|
||||
|
||||
$percentageAdjustment = strlen($value) - strlen($percentageString);
|
||||
if ($percentageAdjustment) {
|
||||
$value = (float) $percentageString;
|
||||
$value /= pow(10, $percentageAdjustment * 2);
|
||||
}
|
||||
}
|
||||
|
||||
return (float) $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares two text strings and returns TRUE if they are exactly the same, FALSE otherwise.
|
||||
* EXACT is case-sensitive but ignores formatting differences.
|
||||
* Use EXACT to test text being entered into a document.
|
||||
*
|
||||
* @param $value1
|
||||
* @param $value2
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function EXACT($value1, $value2)
|
||||
{
|
||||
$value1 = Functions::flattenSingleValue($value1);
|
||||
$value2 = Functions::flattenSingleValue($value2);
|
||||
|
||||
return (string) $value2 === (string) $value1;
|
||||
}
|
||||
|
||||
/**
|
||||
* TEXTJOIN.
|
||||
*
|
||||
* @param mixed $delimiter
|
||||
* @param mixed $ignoreEmpty
|
||||
* @param mixed $args
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function TEXTJOIN($delimiter, $ignoreEmpty, ...$args)
|
||||
{
|
||||
// Loop through arguments
|
||||
$aArgs = Functions::flattenArray($args);
|
||||
foreach ($aArgs as $key => &$arg) {
|
||||
if ($ignoreEmpty && trim($arg) == '') {
|
||||
unset($aArgs[$key]);
|
||||
} elseif (is_bool($arg)) {
|
||||
if (Functions::getCompatibilityMode() == Functions::COMPATIBILITY_OPENOFFICE) {
|
||||
$arg = (int) $arg;
|
||||
} else {
|
||||
$arg = ($arg) ? Calculation::getTRUE() : Calculation::getFALSE();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return implode($delimiter, $aArgs);
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,8 @@ ACCRINT
|
||||
ACCRINTM
|
||||
ACOS
|
||||
ACOSH
|
||||
ACOT
|
||||
ACOTH
|
||||
ADDRESS
|
||||
AMORDEGRC
|
||||
AMORLINC
|
||||
@ -30,6 +32,11 @@ BIN2DEC
|
||||
BIN2HEX
|
||||
BIN2OCT
|
||||
BINOMDIST
|
||||
BITAND
|
||||
BITLSHIFT
|
||||
BITOR
|
||||
BITRSHIFT
|
||||
BITXOR
|
||||
CEILING
|
||||
CELL
|
||||
CHAR
|
||||
@ -43,12 +50,15 @@ COLUMN
|
||||
COLUMNS
|
||||
COMBIN
|
||||
COMPLEX
|
||||
CONCAT
|
||||
CONCATENATE
|
||||
CONFIDENCE
|
||||
CONVERT
|
||||
CORREL
|
||||
COS
|
||||
COSH
|
||||
COT
|
||||
COTH
|
||||
COUNT
|
||||
COUNTA
|
||||
COUNTBLANK
|
||||
@ -62,6 +72,8 @@ COUPNUM
|
||||
COUPPCD
|
||||
COVAR
|
||||
CRITBINOM
|
||||
CSC
|
||||
CSCH
|
||||
CUBEKPIMEMBER
|
||||
CUBEMEMBER
|
||||
CUBEMEMBERPROPERTY
|
||||
@ -105,7 +117,9 @@ EDATE
|
||||
EFFECT
|
||||
EOMONTH
|
||||
ERF
|
||||
ERF.PRECISE
|
||||
ERFC
|
||||
ERFC.PRECISE
|
||||
ERROR.TYPE
|
||||
EVEN
|
||||
EXACT
|
||||
@ -149,6 +163,10 @@ IMAGINARY
|
||||
IMARGUMENT
|
||||
IMCONJUGATE
|
||||
IMCOS
|
||||
IMCOSH
|
||||
IMCOT
|
||||
IMCSC
|
||||
IMCSCH
|
||||
IMEXP
|
||||
IMLN
|
||||
IMLOG10
|
||||
@ -156,10 +174,14 @@ IMLOG2
|
||||
IMPOWER
|
||||
IMPRODUCT
|
||||
IMREAL
|
||||
IMSEC
|
||||
IMSECH
|
||||
IMSIN
|
||||
IMSINH
|
||||
IMSQRT
|
||||
IMSUB
|
||||
IMSUM
|
||||
IMTAN
|
||||
INDEX
|
||||
INDIRECT
|
||||
INFO
|
||||
@ -177,6 +199,7 @@ ISNA
|
||||
ISNONTEXT
|
||||
ISNUMBER
|
||||
ISODD
|
||||
ISOWEEKNUM
|
||||
ISPMT
|
||||
ISREF
|
||||
ISTEXT
|
||||
@ -229,6 +252,7 @@ NOT
|
||||
NOW
|
||||
NPER
|
||||
NPV
|
||||
NUMBERVALUE
|
||||
OCT2BIN
|
||||
OCT2DEC
|
||||
OCT2HEX
|
||||
@ -239,6 +263,7 @@ ODDLPRICE
|
||||
ODDLYIELD
|
||||
OFFSET
|
||||
OR
|
||||
PDURATION
|
||||
PEARSON
|
||||
PERCENTILE
|
||||
PERCENTRANK
|
||||
@ -275,10 +300,13 @@ ROUNDDOWN
|
||||
ROUNDUP
|
||||
ROW
|
||||
ROWS
|
||||
RRI
|
||||
RSQ
|
||||
RTD
|
||||
SEARCH
|
||||
SEARCHB
|
||||
SEC
|
||||
SECH
|
||||
SECOND
|
||||
SERIESSUM
|
||||
SIGN
|
||||
@ -292,6 +320,8 @@ SQRT
|
||||
SQRTPI
|
||||
STANDARDIZE
|
||||
STDEV
|
||||
STDEV.A
|
||||
STDEV.P
|
||||
STDEVA
|
||||
STDEVP
|
||||
STDEVPA
|
||||
@ -315,6 +345,7 @@ TBILLPRICE
|
||||
TBILLYIELD
|
||||
TDIST
|
||||
TEXT
|
||||
TEXTJOIN
|
||||
TIME
|
||||
TIMEVALUE
|
||||
TINV
|
||||
@ -327,6 +358,8 @@ TRUE
|
||||
TRUNC
|
||||
TTEST
|
||||
TYPE
|
||||
UNICHAR
|
||||
UNIORD
|
||||
UPPER
|
||||
USDOLLAR
|
||||
VALUE
|
||||
@ -342,6 +375,7 @@ WEIBULL
|
||||
WORKDAY
|
||||
XIRR
|
||||
XNPV
|
||||
XOR
|
||||
YEAR
|
||||
YEARFRAC
|
||||
YIELD
|
||||
|
@ -327,7 +327,7 @@ abstract class Coordinate
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract all cell references in range.
|
||||
* Extract all cell references in range, which may be comprised of multiple cell ranges.
|
||||
*
|
||||
* @param string $pRange Range (e.g. A1 or A1:C10 or A1:E10 A20:E25)
|
||||
*
|
||||
@ -335,49 +335,12 @@ abstract class Coordinate
|
||||
*/
|
||||
public static function extractAllCellReferencesInRange($pRange)
|
||||
{
|
||||
// Returnvalue
|
||||
$returnValue = [];
|
||||
|
||||
// Explode spaces
|
||||
$cellBlocks = explode(' ', str_replace('$', '', strtoupper($pRange)));
|
||||
$cellBlocks = self::getCellBlocksFromRangeString($pRange);
|
||||
foreach ($cellBlocks as $cellBlock) {
|
||||
// Single cell?
|
||||
if (!self::coordinateIsRange($cellBlock)) {
|
||||
$returnValue[] = $cellBlock;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// Range...
|
||||
$ranges = self::splitRange($cellBlock);
|
||||
foreach ($ranges as $range) {
|
||||
// Single cell?
|
||||
if (!isset($range[1])) {
|
||||
$returnValue[] = $range[0];
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// Range...
|
||||
list($rangeStart, $rangeEnd) = $range;
|
||||
sscanf($rangeStart, '%[A-Z]%d', $startCol, $startRow);
|
||||
sscanf($rangeEnd, '%[A-Z]%d', $endCol, $endRow);
|
||||
++$endCol;
|
||||
|
||||
// Current data
|
||||
$currentCol = $startCol;
|
||||
$currentRow = $startRow;
|
||||
|
||||
// Loop cells
|
||||
while ($currentCol != $endCol) {
|
||||
while ($currentRow <= $endRow) {
|
||||
$returnValue[] = $currentCol . $currentRow;
|
||||
++$currentRow;
|
||||
}
|
||||
++$currentCol;
|
||||
$currentRow = $startRow;
|
||||
}
|
||||
}
|
||||
$returnValue = array_merge($returnValue, self::getReferencesForCellBlock($cellBlock));
|
||||
}
|
||||
|
||||
// Sort the result by column and row
|
||||
@ -392,6 +355,60 @@ abstract class Coordinate
|
||||
return array_values($sortKeys);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all cell references for an individual cell block.
|
||||
*
|
||||
* @param string $cellBlock A cell range e.g. A4:B5
|
||||
*
|
||||
* @return array All individual cells in that range
|
||||
*/
|
||||
private static function getReferencesForCellBlock($cellBlock)
|
||||
{
|
||||
$returnValue = [];
|
||||
|
||||
// Single cell?
|
||||
if (!self::coordinateIsRange($cellBlock)) {
|
||||
return (array) $cellBlock;
|
||||
}
|
||||
|
||||
// Range...
|
||||
$ranges = self::splitRange($cellBlock);
|
||||
foreach ($ranges as $range) {
|
||||
// Single cell?
|
||||
if (!isset($range[1])) {
|
||||
$returnValue[] = $range[0];
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// Range...
|
||||
list($rangeStart, $rangeEnd) = $range;
|
||||
list($startColumn, $startRow) = self::coordinateFromString($rangeStart);
|
||||
list($endColumn, $endRow) = self::coordinateFromString($rangeEnd);
|
||||
$startColumnIndex = self::columnIndexFromString($startColumn);
|
||||
$endColumnIndex = self::columnIndexFromString($endColumn);
|
||||
++$endColumnIndex;
|
||||
|
||||
// Current data
|
||||
$currentColumnIndex = $startColumnIndex;
|
||||
$currentRow = $startRow;
|
||||
|
||||
self::validateRange($cellBlock, $startColumnIndex, $endColumnIndex, $currentRow, $endRow);
|
||||
|
||||
// Loop cells
|
||||
while ($currentColumnIndex < $endColumnIndex) {
|
||||
while ($currentRow <= $endRow) {
|
||||
$returnValue[] = self::stringFromColumnIndex($currentColumnIndex) . $currentRow;
|
||||
++$currentRow;
|
||||
}
|
||||
++$currentColumnIndex;
|
||||
$currentRow = $startRow;
|
||||
}
|
||||
}
|
||||
|
||||
return $returnValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an associative array of single cell coordinates to values to an associative array
|
||||
* of cell ranges to values. Only adjacent cell coordinates with the same
|
||||
@ -477,4 +494,33 @@ abstract class Coordinate
|
||||
|
||||
return $mergedCoordCollection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the individual cell blocks from a range string, splitting by space and removing any $ characters.
|
||||
*
|
||||
* @param string $pRange
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
private static function getCellBlocksFromRangeString($pRange)
|
||||
{
|
||||
return explode(' ', str_replace('$', '', strtoupper($pRange)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that the given range is valid, i.e. that the start column and row are not greater than the end column and
|
||||
* row.
|
||||
*
|
||||
* @param string $cellBlock The original range, for displaying a meaningful error message
|
||||
* @param int $startColumnIndex
|
||||
* @param int $endColumnIndex
|
||||
* @param int $currentRow
|
||||
* @param int $endRow
|
||||
*/
|
||||
private static function validateRange($cellBlock, $startColumnIndex, $endColumnIndex, $currentRow, $endRow)
|
||||
{
|
||||
if ($startColumnIndex >= $endColumnIndex || $currentRow > $endRow) {
|
||||
throw new Exception('Invalid range: "' . $cellBlock . '"');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -89,6 +89,14 @@ class Hyperlink
|
||||
return strpos($this->url, 'sheet://') !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getTypeHyperlink()
|
||||
{
|
||||
return $this->isInternal() ? '' : 'External';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get hash code.
|
||||
*
|
||||
|
@ -217,7 +217,7 @@ class DataSeries
|
||||
/**
|
||||
* Get Plot Order.
|
||||
*
|
||||
* @return string
|
||||
* @return int[]
|
||||
*/
|
||||
public function getPlotOrder()
|
||||
{
|
||||
|
@ -603,6 +603,13 @@ class Html
|
||||
$this->stringData = '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse HTML formatting and return the resulting RichText.
|
||||
*
|
||||
* @param string $html
|
||||
*
|
||||
* @return RichText
|
||||
*/
|
||||
public function toRichTextObject($html)
|
||||
{
|
||||
$this->initialise();
|
||||
@ -611,8 +618,8 @@ class Html
|
||||
$dom = new DOMDocument();
|
||||
// Load the HTML file into the DOM object
|
||||
// Note the use of error suppression, because typically this will be an html fragment, so not fully valid markup
|
||||
@$dom->loadHTML($html);
|
||||
|
||||
$prefix = '<?xml encoding="UTF-8">';
|
||||
@$dom->loadHTML($prefix . $html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
|
||||
// Discard excess white space
|
||||
$dom->preserveWhiteSpace = false;
|
||||
|
||||
|
@ -4,6 +4,22 @@ namespace PhpOffice\PhpSpreadsheet\Helper;
|
||||
|
||||
class Migrator
|
||||
{
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
private $from;
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
private $to;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->from = array_keys($this->getMapping());
|
||||
$this->to = array_values($this->getMapping());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the ordered mapping from old PHPExcel class names to new PhpSpreadsheet one.
|
||||
*
|
||||
@ -204,7 +220,6 @@ class Migrator
|
||||
'PHPExcel_Settings' => \PhpOffice\PhpSpreadsheet\Settings::class,
|
||||
'PHPExcel_Style' => \PhpOffice\PhpSpreadsheet\Style\Style::class,
|
||||
'PHPExcel_Worksheet' => \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet::class,
|
||||
'PHPExcel' => \PhpOffice\PhpSpreadsheet\Spreadsheet::class,
|
||||
];
|
||||
|
||||
$methods = [
|
||||
@ -249,19 +264,25 @@ class Migrator
|
||||
{
|
||||
$patterns = [
|
||||
'/*.md',
|
||||
'/*.php',
|
||||
'/*.phtml',
|
||||
'/*.txt',
|
||||
'/*.TXT',
|
||||
'/*.php',
|
||||
'/*.phpt',
|
||||
'/*.php3',
|
||||
'/*.php4',
|
||||
'/*.php5',
|
||||
'/*.phtml',
|
||||
];
|
||||
|
||||
$from = array_keys($this->getMapping());
|
||||
$to = array_values($this->getMapping());
|
||||
|
||||
foreach ($patterns as $pattern) {
|
||||
foreach (glob($path . $pattern) as $file) {
|
||||
if (strpos($path, '/vendor/') !== false) {
|
||||
echo $file . " skipped\n";
|
||||
|
||||
continue;
|
||||
}
|
||||
$original = file_get_contents($file);
|
||||
$converted = str_replace($from, $to, $original);
|
||||
$converted = $this->replace($original);
|
||||
|
||||
if ($original !== $converted) {
|
||||
echo $file . " converted\n";
|
||||
@ -290,4 +311,23 @@ class Migrator
|
||||
$this->recursiveReplace($path);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrate the given code from PHPExcel to PhpSpreadsheet.
|
||||
*
|
||||
* @param string $original
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function replace($original)
|
||||
{
|
||||
$converted = str_replace($this->from, $this->to, $original);
|
||||
|
||||
// The string "PHPExcel" gets special treatment because of how common it might be.
|
||||
// This regex requires a word boundary around the string, and it can't be
|
||||
// preceded by $ or -> (goal is to filter out cases where a variable is named $PHPExcel or similar)
|
||||
$converted = preg_replace('~(?<!\$|->)(\b|\\\\)PHPExcel\b~', '\\' . \PhpOffice\PhpSpreadsheet\Spreadsheet::class, $converted);
|
||||
|
||||
return $converted;
|
||||
}
|
||||
}
|
||||
|
@ -50,6 +50,13 @@ class Csv extends BaseReader
|
||||
*/
|
||||
private $contiguousRow = -1;
|
||||
|
||||
/**
|
||||
* The character that can escape the enclosure.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $escapeCharacter = '\\';
|
||||
|
||||
/**
|
||||
* Create a new CSV Reader instance.
|
||||
*/
|
||||
@ -254,7 +261,7 @@ class Csv extends BaseReader
|
||||
$worksheetInfo[0]['totalColumns'] = 0;
|
||||
|
||||
// Loop through each line of the file in turn
|
||||
while (($rowData = fgetcsv($fileHandle, 0, $this->delimiter, $this->enclosure)) !== false) {
|
||||
while (($rowData = fgetcsv($fileHandle, 0, $this->delimiter, $this->enclosure, $this->escapeCharacter)) !== false) {
|
||||
++$worksheetInfo[0]['totalRows'];
|
||||
$worksheetInfo[0]['lastColumnIndex'] = max($worksheetInfo[0]['lastColumnIndex'], count($rowData) - 1);
|
||||
}
|
||||
@ -326,7 +333,7 @@ class Csv extends BaseReader
|
||||
}
|
||||
|
||||
// Loop through each line of the file in turn
|
||||
while (($rowData = fgetcsv($fileHandle, 0, $this->delimiter, $this->enclosure)) !== false) {
|
||||
while (($rowData = fgetcsv($fileHandle, 0, $this->delimiter, $this->enclosure, $this->escapeCharacter)) !== false) {
|
||||
$columnLetter = 'A';
|
||||
foreach ($rowData as $rowDatum) {
|
||||
if ($rowDatum != '' && $this->readFilter->readCell($columnLetter, $currentRow)) {
|
||||
@ -458,6 +465,30 @@ class Csv extends BaseReader
|
||||
return $this->contiguous;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set escape backslashes.
|
||||
*
|
||||
* @param string $escapeCharacter
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setEscapeCharacter($escapeCharacter)
|
||||
{
|
||||
$this->escapeCharacter = $escapeCharacter;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get escape backslashes.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getEscapeCharacter()
|
||||
{
|
||||
return $this->escapeCharacter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can the current IReader read the file?
|
||||
*
|
||||
@ -476,6 +507,12 @@ class Csv extends BaseReader
|
||||
|
||||
fclose($this->fileHandle);
|
||||
|
||||
// Trust file extension if any
|
||||
if (strtolower(pathinfo($pFilename, PATHINFO_EXTENSION)) === 'csv') {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Attempt to guess mimetype
|
||||
$type = mime_content_type($pFilename);
|
||||
$supportedTypes = [
|
||||
'text/csv',
|
||||
|
@ -554,6 +554,7 @@ class Html extends BaseReader
|
||||
$row = 0;
|
||||
$column = 'A';
|
||||
$content = '';
|
||||
$this->rowspan = [];
|
||||
$this->processDomElement($dom, $spreadsheet->getActiveSheet(), $row, $column, $content);
|
||||
|
||||
// Return
|
||||
|
@ -7,9 +7,9 @@ interface IReadFilter
|
||||
/**
|
||||
* Should this cell be read?
|
||||
*
|
||||
* @param $column string Column address (as a string value like "A", or "IV")
|
||||
* @param $row int Row number
|
||||
* @param $worksheetName string Optional worksheet name
|
||||
* @param string $column Column address (as a string value like "A", or "IV")
|
||||
* @param int $row Row number
|
||||
* @param string $worksheetName Optional worksheet name
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
|
@ -3,6 +3,7 @@
|
||||
namespace PhpOffice\PhpSpreadsheet\Reader;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
|
||||
use PhpOffice\PhpSpreadsheet\Cell\Hyperlink;
|
||||
use PhpOffice\PhpSpreadsheet\Document\Properties;
|
||||
use PhpOffice\PhpSpreadsheet\NamedRange;
|
||||
use PhpOffice\PhpSpreadsheet\Reader\Xlsx\Chart;
|
||||
@ -25,6 +26,7 @@ use PhpOffice\PhpSpreadsheet\Style\Style;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\HeaderFooterDrawing;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
||||
use SimpleXMLElement;
|
||||
use XMLReader;
|
||||
use ZipArchive;
|
||||
|
||||
@ -115,15 +117,17 @@ class Xlsx extends BaseReader
|
||||
$zip->open($pFilename);
|
||||
|
||||
// The files we're looking at here are small enough that simpleXML is more efficient than XMLReader
|
||||
//~ http://schemas.openxmlformats.org/package/2006/relationships");
|
||||
$rels = simplexml_load_string(
|
||||
$this->securityScan($this->getFromZipArchive($zip, '_rels/.rels'))
|
||||
); //~ http://schemas.openxmlformats.org/package/2006/relationships");
|
||||
);
|
||||
foreach ($rels->Relationship as $rel) {
|
||||
switch ($rel['Type']) {
|
||||
case 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument':
|
||||
//~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"
|
||||
$xmlWorkbook = simplexml_load_string(
|
||||
$this->securityScan($this->getFromZipArchive($zip, "{$rel['Target']}"))
|
||||
); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"
|
||||
);
|
||||
|
||||
if ($xmlWorkbook->sheets) {
|
||||
foreach ($xmlWorkbook->sheets->sheet as $eleSheet) {
|
||||
@ -157,8 +161,8 @@ class Xlsx extends BaseReader
|
||||
$zip = new ZipArchive();
|
||||
$zip->open($pFilename);
|
||||
|
||||
//~ http://schemas.openxmlformats.org/package/2006/relationships"
|
||||
$rels = simplexml_load_string(
|
||||
//~ http://schemas.openxmlformats.org/package/2006/relationships"
|
||||
$this->securityScan($this->getFromZipArchive($zip, '_rels/.rels')),
|
||||
'SimpleXMLElement',
|
||||
Settings::getLibXmlLoaderOptions()
|
||||
@ -166,8 +170,9 @@ class Xlsx extends BaseReader
|
||||
foreach ($rels->Relationship as $rel) {
|
||||
if ($rel['Type'] == 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument') {
|
||||
$dir = dirname($rel['Target']);
|
||||
|
||||
//~ http://schemas.openxmlformats.org/package/2006/relationships"
|
||||
$relsWorkbook = simplexml_load_string(
|
||||
//~ http://schemas.openxmlformats.org/package/2006/relationships"
|
||||
$this->securityScan(
|
||||
$this->getFromZipArchive($zip, "$dir/_rels/" . basename($rel['Target']) . '.rels')
|
||||
),
|
||||
@ -183,8 +188,8 @@ class Xlsx extends BaseReader
|
||||
}
|
||||
}
|
||||
|
||||
//~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"
|
||||
$xmlWorkbook = simplexml_load_string(
|
||||
//~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"
|
||||
$this->securityScan(
|
||||
$this->getFromZipArchive($zip, "{$rel['Target']}")
|
||||
),
|
||||
@ -193,7 +198,7 @@ class Xlsx extends BaseReader
|
||||
);
|
||||
if ($xmlWorkbook->sheets) {
|
||||
$dir = dirname($rel['Target']);
|
||||
/** @var \SimpleXMLElement $eleSheet */
|
||||
/** @var SimpleXMLElement $eleSheet */
|
||||
foreach ($xmlWorkbook->sheets->sheet as $eleSheet) {
|
||||
$tmpInfo = [
|
||||
'worksheetName' => (string) $eleSheet['name'],
|
||||
@ -316,6 +321,60 @@ class Xlsx extends BaseReader
|
||||
return $contents;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Worksheet column attributes by attributes array passed.
|
||||
*
|
||||
* @param Worksheet $docSheet
|
||||
* @param string $column A, B, ... DX, ...
|
||||
* @param array $columnAttributes array of attributes (indexes are attribute name, values are value)
|
||||
* 'xfIndex', 'visible', 'collapsed', 'outlineLevel', 'width', ... ?
|
||||
*/
|
||||
private function setColumnAttributes(Worksheet $docSheet, $column, array $columnAttributes)
|
||||
{
|
||||
if (isset($columnAttributes['xfIndex'])) {
|
||||
$docSheet->getColumnDimension($column)->setXfIndex($columnAttributes['xfIndex']);
|
||||
}
|
||||
if (isset($columnAttributes['visible'])) {
|
||||
$docSheet->getColumnDimension($column)->setVisible($columnAttributes['visible']);
|
||||
}
|
||||
if (isset($columnAttributes['collapsed'])) {
|
||||
$docSheet->getColumnDimension($column)->setCollapsed($columnAttributes['collapsed']);
|
||||
}
|
||||
if (isset($columnAttributes['outlineLevel'])) {
|
||||
$docSheet->getColumnDimension($column)->setOutlineLevel($columnAttributes['outlineLevel']);
|
||||
}
|
||||
if (isset($columnAttributes['width'])) {
|
||||
$docSheet->getColumnDimension($column)->setWidth($columnAttributes['width']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Worksheet row attributes by attributes array passed.
|
||||
*
|
||||
* @param Worksheet $docSheet
|
||||
* @param int $row 1, 2, 3, ... 99, ...
|
||||
* @param array $rowAttributes array of attributes (indexes are attribute name, values are value)
|
||||
* 'xfIndex', 'visible', 'collapsed', 'outlineLevel', 'rowHeight', ... ?
|
||||
*/
|
||||
private function setRowAttributes(Worksheet $docSheet, $row, array $rowAttributes)
|
||||
{
|
||||
if (isset($rowAttributes['xfIndex'])) {
|
||||
$docSheet->getRowDimension($row)->setXfIndex($rowAttributes['xfIndex']);
|
||||
}
|
||||
if (isset($rowAttributes['visible'])) {
|
||||
$docSheet->getRowDimension($row)->setVisible($rowAttributes['visible']);
|
||||
}
|
||||
if (isset($rowAttributes['collapsed'])) {
|
||||
$docSheet->getRowDimension($row)->setCollapsed($rowAttributes['collapsed']);
|
||||
}
|
||||
if (isset($rowAttributes['outlineLevel'])) {
|
||||
$docSheet->getRowDimension($row)->setOutlineLevel($rowAttributes['outlineLevel']);
|
||||
}
|
||||
if (isset($rowAttributes['rowHeight'])) {
|
||||
$docSheet->getRowDimension($row)->setRowHeight($rowAttributes['rowHeight']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads Spreadsheet from file.
|
||||
*
|
||||
@ -336,13 +395,14 @@ class Xlsx extends BaseReader
|
||||
$excel->removeCellStyleXfByIndex(0); // remove the default style
|
||||
$excel->removeCellXfByIndex(0); // remove the default style
|
||||
}
|
||||
$unparsedLoadedData = [];
|
||||
|
||||
$zip = new ZipArchive();
|
||||
$zip->open($pFilename);
|
||||
|
||||
// Read the theme first, because we need the colour scheme when reading the styles
|
||||
//~ http://schemas.openxmlformats.org/package/2006/relationships"
|
||||
$wbRels = simplexml_load_string(
|
||||
//~ http://schemas.openxmlformats.org/package/2006/relationships"
|
||||
$this->securityScan($this->getFromZipArchive($zip, 'xl/_rels/workbook.xml.rels')),
|
||||
'SimpleXMLElement',
|
||||
Settings::getLibXmlLoaderOptions()
|
||||
@ -388,8 +448,8 @@ class Xlsx extends BaseReader
|
||||
}
|
||||
}
|
||||
|
||||
//~ http://schemas.openxmlformats.org/package/2006/relationships"
|
||||
$rels = simplexml_load_string(
|
||||
//~ http://schemas.openxmlformats.org/package/2006/relationships"
|
||||
$this->securityScan($this->getFromZipArchive($zip, '_rels/.rels')),
|
||||
'SimpleXMLElement',
|
||||
Settings::getLibXmlLoaderOptions()
|
||||
@ -444,7 +504,7 @@ class Xlsx extends BaseReader
|
||||
);
|
||||
if (is_object($xmlCore)) {
|
||||
$docProps = $excel->getProperties();
|
||||
/** @var \SimpleXMLElement $xmlProperty */
|
||||
/** @var SimpleXMLElement $xmlProperty */
|
||||
foreach ($xmlCore as $xmlProperty) {
|
||||
$cellDataOfficeAttributes = $xmlProperty->attributes();
|
||||
if (isset($cellDataOfficeAttributes['name'])) {
|
||||
@ -470,8 +530,8 @@ class Xlsx extends BaseReader
|
||||
break;
|
||||
case 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument':
|
||||
$dir = dirname($rel['Target']);
|
||||
//~ http://schemas.openxmlformats.org/package/2006/relationships"
|
||||
$relsWorkbook = simplexml_load_string(
|
||||
//~ http://schemas.openxmlformats.org/package/2006/relationships"
|
||||
$this->securityScan($this->getFromZipArchive($zip, "$dir/_rels/" . basename($rel['Target']) . '.rels')),
|
||||
'SimpleXMLElement',
|
||||
Settings::getLibXmlLoaderOptions()
|
||||
@ -480,8 +540,8 @@ class Xlsx extends BaseReader
|
||||
|
||||
$sharedStrings = [];
|
||||
$xpath = self::getArrayItem($relsWorkbook->xpath("rel:Relationship[@Type='http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings']"));
|
||||
//~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"
|
||||
$xmlStrings = simplexml_load_string(
|
||||
//~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"
|
||||
$this->securityScan($this->getFromZipArchive($zip, "$dir/$xpath[Target]")),
|
||||
'SimpleXMLElement',
|
||||
Settings::getLibXmlLoaderOptions()
|
||||
@ -527,8 +587,8 @@ class Xlsx extends BaseReader
|
||||
$styles = [];
|
||||
$cellStyles = [];
|
||||
$xpath = self::getArrayItem($relsWorkbook->xpath("rel:Relationship[@Type='http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles']"));
|
||||
//~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"
|
||||
$xmlStyles = simplexml_load_string(
|
||||
//~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"
|
||||
$this->securityScan($this->getFromZipArchive($zip, "$dir/$xpath[Target]")),
|
||||
'SimpleXMLElement',
|
||||
Settings::getLibXmlLoaderOptions()
|
||||
@ -638,8 +698,8 @@ class Xlsx extends BaseReader
|
||||
}
|
||||
}
|
||||
|
||||
//~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"
|
||||
$xmlWorkbook = simplexml_load_string(
|
||||
//~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"
|
||||
$this->securityScan($this->getFromZipArchive($zip, "{$rel['Target']}")),
|
||||
'SimpleXMLElement',
|
||||
Settings::getLibXmlLoaderOptions()
|
||||
@ -655,6 +715,9 @@ class Xlsx extends BaseReader
|
||||
}
|
||||
}
|
||||
|
||||
// Set protection
|
||||
$this->readProtection($excel, $xmlWorkbook);
|
||||
|
||||
$sheetId = 0; // keep track of new sheet id in final workbook
|
||||
$oldSheetId = -1; // keep track of old sheet id in final workbook
|
||||
$countSkippedSheets = 0; // keep track of number of skipped sheets
|
||||
@ -663,7 +726,7 @@ class Xlsx extends BaseReader
|
||||
$charts = $chartDetails = [];
|
||||
|
||||
if ($xmlWorkbook->sheets) {
|
||||
/** @var \SimpleXMLElement $eleSheet */
|
||||
/** @var SimpleXMLElement $eleSheet */
|
||||
foreach ($xmlWorkbook->sheets->sheet as $eleSheet) {
|
||||
++$oldSheetId;
|
||||
|
||||
@ -687,8 +750,8 @@ class Xlsx extends BaseReader
|
||||
// reverse
|
||||
$docSheet->setTitle((string) $eleSheet['name'], false, false);
|
||||
$fileWorksheet = $worksheets[(string) self::getArrayItem($eleSheet->attributes('http://schemas.openxmlformats.org/officeDocument/2006/relationships'), 'id')];
|
||||
//~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"
|
||||
$xmlSheet = simplexml_load_string(
|
||||
//~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"
|
||||
$this->securityScan($this->getFromZipArchive($zip, "$dir/$fileWorksheet")),
|
||||
'SimpleXMLElement',
|
||||
Settings::getLibXmlLoaderOptions()
|
||||
@ -811,30 +874,6 @@ class Xlsx extends BaseReader
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($xmlSheet->cols) && !$this->readDataOnly) {
|
||||
foreach ($xmlSheet->cols->col as $col) {
|
||||
for ($i = (int) ($col['min']); $i <= (int) ($col['max']); ++$i) {
|
||||
if ($col['style'] && !$this->readDataOnly) {
|
||||
$docSheet->getColumnDimension(Coordinate::stringFromColumnIndex($i))->setXfIndex((int) ($col['style']));
|
||||
}
|
||||
if (self::boolean($col['hidden'])) {
|
||||
$docSheet->getColumnDimension(Coordinate::stringFromColumnIndex($i))->setVisible(false);
|
||||
}
|
||||
if (self::boolean($col['collapsed'])) {
|
||||
$docSheet->getColumnDimension(Coordinate::stringFromColumnIndex($i))->setCollapsed(true);
|
||||
}
|
||||
if ($col['outlineLevel'] > 0) {
|
||||
$docSheet->getColumnDimension(Coordinate::stringFromColumnIndex($i))->setOutlineLevel((int) ($col['outlineLevel']));
|
||||
}
|
||||
$docSheet->getColumnDimension(Coordinate::stringFromColumnIndex($i))->setWidth((float) ($col['width']));
|
||||
|
||||
if ((int) ($col['max']) == 16384) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($xmlSheet->printOptions) && !$this->readDataOnly) {
|
||||
if (self::boolean((string) $xmlSheet->printOptions['gridLinesSet'])) {
|
||||
$docSheet->setShowGridlines(true);
|
||||
@ -850,25 +889,11 @@ class Xlsx extends BaseReader
|
||||
}
|
||||
}
|
||||
|
||||
$this->readColumnsAndRowsAttributes($xmlSheet, $docSheet);
|
||||
|
||||
if ($xmlSheet && $xmlSheet->sheetData && $xmlSheet->sheetData->row) {
|
||||
$cIndex = 1; // Cell Start from 1
|
||||
foreach ($xmlSheet->sheetData->row as $row) {
|
||||
if ($row['ht'] && !$this->readDataOnly) {
|
||||
$docSheet->getRowDimension((int) ($row['r']))->setRowHeight((float) ($row['ht']));
|
||||
}
|
||||
if (self::boolean($row['hidden']) && !$this->readDataOnly) {
|
||||
$docSheet->getRowDimension((int) ($row['r']))->setVisible(false);
|
||||
}
|
||||
if (self::boolean($row['collapsed'])) {
|
||||
$docSheet->getRowDimension((int) ($row['r']))->setCollapsed(true);
|
||||
}
|
||||
if ($row['outlineLevel'] > 0) {
|
||||
$docSheet->getRowDimension((int) ($row['r']))->setOutlineLevel((int) ($row['outlineLevel']));
|
||||
}
|
||||
if ($row['s'] && !$this->readDataOnly) {
|
||||
$docSheet->getRowDimension((int) ($row['r']))->setXfIndex((int) ($row['s']));
|
||||
}
|
||||
|
||||
$rowIndex = 1;
|
||||
foreach ($row->c as $c) {
|
||||
$r = (string) $c['r'];
|
||||
@ -883,7 +908,7 @@ class Xlsx extends BaseReader
|
||||
if ($this->getReadFilter() !== null) {
|
||||
$coordinates = Coordinate::coordinateFromString($r);
|
||||
|
||||
if (!$this->getReadFilter()->readCell($coordinates[0], $coordinates[1], $docSheet->getTitle())) {
|
||||
if (!$this->getReadFilter()->readCell($coordinates[0], (int) $coordinates[1], $docSheet->getTitle())) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@ -1068,8 +1093,8 @@ class Xlsx extends BaseReader
|
||||
}
|
||||
// Or Date Group elements
|
||||
foreach ($filters->dateGroupItem as $dateGroupItem) {
|
||||
// Operator is undefined, but always treated as EQUAL
|
||||
$column->createRule()->setRule(
|
||||
// Operator is undefined, but always treated as EQUAL
|
||||
null,
|
||||
[
|
||||
'year' => (string) $dateGroupItem['year'],
|
||||
@ -1106,8 +1131,8 @@ class Xlsx extends BaseReader
|
||||
$column->setFilterType(Column::AUTOFILTER_FILTERTYPE_DYNAMICFILTER);
|
||||
// We should only ever have one dynamic filter
|
||||
foreach ($filterColumn->dynamicFilter as $filterRule) {
|
||||
// Operator is undefined, but always treated as EQUAL
|
||||
$column->createRule()->setRule(
|
||||
// Operator is undefined, but always treated as EQUAL
|
||||
null,
|
||||
(string) $filterRule['val'],
|
||||
(string) $filterRule['type']
|
||||
@ -1185,6 +1210,11 @@ class Xlsx extends BaseReader
|
||||
self::boolean((string) $xmlSheet->pageSetup['useFirstPageNumber'])) {
|
||||
$docPageSetup->setFirstPageNumber((int) ($xmlSheet->pageSetup['firstPageNumber']));
|
||||
}
|
||||
|
||||
$relAttributes = $xmlSheet->pageSetup->attributes('http://schemas.openxmlformats.org/officeDocument/2006/relationships');
|
||||
if (isset($relAttributes['id'])) {
|
||||
$unparsedLoadedData['sheets'][$docSheet->getCodeName()]['pageSetupRelId'] = (string) $relAttributes['id'];
|
||||
}
|
||||
}
|
||||
|
||||
if ($xmlSheet && $xmlSheet->headerFooter && !$this->readDataOnly) {
|
||||
@ -1268,13 +1298,23 @@ class Xlsx extends BaseReader
|
||||
}
|
||||
}
|
||||
|
||||
// unparsed sheet AlternateContent
|
||||
if ($xmlSheet && !$this->readDataOnly) {
|
||||
$mc = $xmlSheet->children('http://schemas.openxmlformats.org/markup-compatibility/2006');
|
||||
if ($mc->AlternateContent) {
|
||||
foreach ($mc->AlternateContent as $alternateContent) {
|
||||
$unparsedLoadedData['sheets'][$docSheet->getCodeName()]['AlternateContents'][] = $alternateContent->asXML();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add hyperlinks
|
||||
$hyperlinks = [];
|
||||
if (!$this->readDataOnly) {
|
||||
// Locate hyperlink relations
|
||||
if ($zip->locateName(dirname("$dir/$fileWorksheet") . '/_rels/' . basename($fileWorksheet) . '.rels')) {
|
||||
//~ http://schemas.openxmlformats.org/package/2006/relationships"
|
||||
$relsWorksheet = simplexml_load_string(
|
||||
//~ http://schemas.openxmlformats.org/package/2006/relationships"
|
||||
$this->securityScan(
|
||||
$this->getFromZipArchive($zip, dirname("$dir/$fileWorksheet") . '/_rels/' . basename($fileWorksheet) . '.rels')
|
||||
),
|
||||
@ -1290,7 +1330,7 @@ class Xlsx extends BaseReader
|
||||
|
||||
// Loop through hyperlinks
|
||||
if ($xmlSheet && $xmlSheet->hyperlinks) {
|
||||
/** @var \SimpleXMLElement $hyperlink */
|
||||
/** @var SimpleXMLElement $hyperlink */
|
||||
foreach ($xmlSheet->hyperlinks->hyperlink as $hyperlink) {
|
||||
// Link url
|
||||
$linkRel = $hyperlink->attributes('http://schemas.openxmlformats.org/officeDocument/2006/relationships');
|
||||
@ -1322,8 +1362,8 @@ class Xlsx extends BaseReader
|
||||
if (!$this->readDataOnly) {
|
||||
// Locate comment relations
|
||||
if ($zip->locateName(dirname("$dir/$fileWorksheet") . '/_rels/' . basename($fileWorksheet) . '.rels')) {
|
||||
//~ http://schemas.openxmlformats.org/package/2006/relationships"
|
||||
$relsWorksheet = simplexml_load_string(
|
||||
//~ http://schemas.openxmlformats.org/package/2006/relationships"
|
||||
$this->securityScan(
|
||||
$this->getFromZipArchive($zip, dirname("$dir/$fileWorksheet") . '/_rels/' . basename($fileWorksheet) . '.rels')
|
||||
),
|
||||
@ -1367,6 +1407,9 @@ class Xlsx extends BaseReader
|
||||
}
|
||||
}
|
||||
|
||||
// later we will remove from it real vmlComments
|
||||
$unparsedVmlDrawings = $vmlComments;
|
||||
|
||||
// Loop through VML comments
|
||||
foreach ($vmlComments as $relName => $relPath) {
|
||||
// Load VML comments file
|
||||
@ -1407,7 +1450,7 @@ class Xlsx extends BaseReader
|
||||
|
||||
if (($column !== null) && ($row !== null)) {
|
||||
// Set comment properties
|
||||
$comment = $docSheet->getCommentByColumnAndRow((string) $column, $row + 1);
|
||||
$comment = $docSheet->getCommentByColumnAndRow($column + 1, $row + 1);
|
||||
$comment->getFillColor()->setRGB($fillColor);
|
||||
|
||||
// Parse style
|
||||
@ -1431,16 +1474,31 @@ class Xlsx extends BaseReader
|
||||
$comment->setVisible($stylePair[1] == 'visible');
|
||||
}
|
||||
}
|
||||
|
||||
unset($unparsedVmlDrawings[$relName]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// unparsed vmlDrawing
|
||||
if ($unparsedVmlDrawings) {
|
||||
foreach ($unparsedVmlDrawings as $rId => $relPath) {
|
||||
$rId = substr($rId, 3); // rIdXXX
|
||||
$unparsedVmlDrawing = &$unparsedLoadedData['sheets'][$docSheet->getCodeName()]['vmlDrawings'];
|
||||
$unparsedVmlDrawing[$rId] = [];
|
||||
$unparsedVmlDrawing[$rId]['filePath'] = self::dirAdd("$dir/$fileWorksheet", $relPath);
|
||||
$unparsedVmlDrawing[$rId]['relFilePath'] = $relPath;
|
||||
$unparsedVmlDrawing[$rId]['content'] = $this->securityScan($this->getFromZipArchive($zip, $unparsedVmlDrawing[$rId]['filePath']));
|
||||
unset($unparsedVmlDrawing);
|
||||
}
|
||||
}
|
||||
|
||||
// Header/footer images
|
||||
if ($xmlSheet && $xmlSheet->legacyDrawingHF && !$this->readDataOnly) {
|
||||
if ($zip->locateName(dirname("$dir/$fileWorksheet") . '/_rels/' . basename($fileWorksheet) . '.rels')) {
|
||||
//~ http://schemas.openxmlformats.org/package/2006/relationships"
|
||||
$relsWorksheet = simplexml_load_string(
|
||||
//~ http://schemas.openxmlformats.org/package/2006/relationships"
|
||||
$this->securityScan(
|
||||
$this->getFromZipArchive($zip, dirname("$dir/$fileWorksheet") . '/_rels/' . basename($fileWorksheet) . '.rels')
|
||||
),
|
||||
@ -1457,8 +1515,8 @@ class Xlsx extends BaseReader
|
||||
|
||||
if ($vmlRelationship != '') {
|
||||
// Fetch linked images
|
||||
//~ http://schemas.openxmlformats.org/package/2006/relationships"
|
||||
$relsVML = simplexml_load_string(
|
||||
//~ http://schemas.openxmlformats.org/package/2006/relationships"
|
||||
$this->securityScan(
|
||||
$this->getFromZipArchive($zip, dirname($vmlRelationship) . '/_rels/' . basename($vmlRelationship) . '.rels')
|
||||
),
|
||||
@ -1520,8 +1578,8 @@ class Xlsx extends BaseReader
|
||||
|
||||
// TODO: Autoshapes from twoCellAnchors!
|
||||
if ($zip->locateName(dirname("$dir/$fileWorksheet") . '/_rels/' . basename($fileWorksheet) . '.rels')) {
|
||||
//~ http://schemas.openxmlformats.org/package/2006/relationships"
|
||||
$relsWorksheet = simplexml_load_string(
|
||||
//~ http://schemas.openxmlformats.org/package/2006/relationships"
|
||||
$this->securityScan(
|
||||
$this->getFromZipArchive($zip, dirname("$dir/$fileWorksheet") . '/_rels/' . basename($fileWorksheet) . '.rels')
|
||||
),
|
||||
@ -1537,8 +1595,8 @@ class Xlsx extends BaseReader
|
||||
if ($xmlSheet->drawing && !$this->readDataOnly) {
|
||||
foreach ($xmlSheet->drawing as $drawing) {
|
||||
$fileDrawing = $drawings[(string) self::getArrayItem($drawing->attributes('http://schemas.openxmlformats.org/officeDocument/2006/relationships'), 'id')];
|
||||
//~ http://schemas.openxmlformats.org/package/2006/relationships"
|
||||
$relsDrawing = simplexml_load_string(
|
||||
//~ http://schemas.openxmlformats.org/package/2006/relationships"
|
||||
$this->securityScan(
|
||||
$this->getFromZipArchive($zip, dirname($fileDrawing) . '/_rels/' . basename($fileDrawing) . '.rels')
|
||||
),
|
||||
@ -1546,9 +1604,12 @@ class Xlsx extends BaseReader
|
||||
Settings::getLibXmlLoaderOptions()
|
||||
);
|
||||
$images = [];
|
||||
|
||||
$hyperlinks = [];
|
||||
if ($relsDrawing && $relsDrawing->Relationship) {
|
||||
foreach ($relsDrawing->Relationship as $ele) {
|
||||
if ($ele['Type'] == 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink') {
|
||||
$hyperlinks[(string) $ele['Id']] = (string) $ele['Target'];
|
||||
}
|
||||
if ($ele['Type'] == 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image') {
|
||||
$images[(string) $ele['Id']] = self::dirAdd($fileDrawing, $ele['Target']);
|
||||
} elseif ($ele['Type'] == 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart') {
|
||||
@ -1570,12 +1631,15 @@ class Xlsx extends BaseReader
|
||||
if ($xmlDrawing->oneCellAnchor) {
|
||||
foreach ($xmlDrawing->oneCellAnchor as $oneCellAnchor) {
|
||||
if ($oneCellAnchor->pic->blipFill) {
|
||||
/** @var \SimpleXMLElement $blip */
|
||||
/** @var SimpleXMLElement $blip */
|
||||
$blip = $oneCellAnchor->pic->blipFill->children('http://schemas.openxmlformats.org/drawingml/2006/main')->blip;
|
||||
/** @var \SimpleXMLElement $xfrm */
|
||||
/** @var SimpleXMLElement $xfrm */
|
||||
$xfrm = $oneCellAnchor->pic->spPr->children('http://schemas.openxmlformats.org/drawingml/2006/main')->xfrm;
|
||||
/** @var \SimpleXMLElement $outerShdw */
|
||||
/** @var SimpleXMLElement $outerShdw */
|
||||
$outerShdw = $oneCellAnchor->pic->spPr->children('http://schemas.openxmlformats.org/drawingml/2006/main')->effectLst->outerShdw;
|
||||
/** @var \SimpleXMLElement $hlinkClick */
|
||||
$hlinkClick = $oneCellAnchor->pic->nvPicPr->cNvPr->children('http://schemas.openxmlformats.org/drawingml/2006/main')->hlinkClick;
|
||||
|
||||
$objDrawing = new \PhpOffice\PhpSpreadsheet\Worksheet\Drawing();
|
||||
$objDrawing->setName((string) self::getArrayItem($oneCellAnchor->pic->nvPicPr->cNvPr->attributes(), 'name'));
|
||||
$objDrawing->setDescription((string) self::getArrayItem($oneCellAnchor->pic->nvPicPr->cNvPr->attributes(), 'descr'));
|
||||
@ -1606,6 +1670,9 @@ class Xlsx extends BaseReader
|
||||
$shadow->getColor()->setRGB(self::getArrayItem($outerShdw->srgbClr->attributes(), 'val'));
|
||||
$shadow->setAlpha(self::getArrayItem($outerShdw->srgbClr->alpha->attributes(), 'val') / 1000);
|
||||
}
|
||||
|
||||
$this->readHyperLinkDrawing($objDrawing, $oneCellAnchor, $hyperlinks);
|
||||
|
||||
$objDrawing->setWorksheet($docSheet);
|
||||
} else {
|
||||
// ? Can charts be positioned with a oneCellAnchor ?
|
||||
@ -1623,6 +1690,7 @@ class Xlsx extends BaseReader
|
||||
$blip = $twoCellAnchor->pic->blipFill->children('http://schemas.openxmlformats.org/drawingml/2006/main')->blip;
|
||||
$xfrm = $twoCellAnchor->pic->spPr->children('http://schemas.openxmlformats.org/drawingml/2006/main')->xfrm;
|
||||
$outerShdw = $twoCellAnchor->pic->spPr->children('http://schemas.openxmlformats.org/drawingml/2006/main')->effectLst->outerShdw;
|
||||
$hlinkClick = $twoCellAnchor->pic->nvPicPr->cNvPr->children('http://schemas.openxmlformats.org/drawingml/2006/main')->hlinkClick;
|
||||
$objDrawing = new \PhpOffice\PhpSpreadsheet\Worksheet\Drawing();
|
||||
$objDrawing->setName((string) self::getArrayItem($twoCellAnchor->pic->nvPicPr->cNvPr->attributes(), 'name'));
|
||||
$objDrawing->setDescription((string) self::getArrayItem($twoCellAnchor->pic->nvPicPr->cNvPr->attributes(), 'descr'));
|
||||
@ -1654,6 +1722,9 @@ class Xlsx extends BaseReader
|
||||
$shadow->getColor()->setRGB(self::getArrayItem($outerShdw->srgbClr->attributes(), 'val'));
|
||||
$shadow->setAlpha(self::getArrayItem($outerShdw->srgbClr->alpha->attributes(), 'val') / 1000);
|
||||
}
|
||||
|
||||
$this->readHyperLinkDrawing($objDrawing, $twoCellAnchor, $hyperlinks);
|
||||
|
||||
$objDrawing->setWorksheet($docSheet);
|
||||
} elseif (($this->includeCharts) && ($twoCellAnchor->graphicFrame)) {
|
||||
$fromCoordinate = Coordinate::stringFromColumnIndex(((string) $twoCellAnchor->from->col) + 1) . ($twoCellAnchor->from->row + 1);
|
||||
@ -1663,7 +1734,7 @@ class Xlsx extends BaseReader
|
||||
$toOffsetX = Drawing::EMUToPixels($twoCellAnchor->to->colOff);
|
||||
$toOffsetY = Drawing::EMUToPixels($twoCellAnchor->to->rowOff);
|
||||
$graphic = $twoCellAnchor->graphicFrame->children('http://schemas.openxmlformats.org/drawingml/2006/main')->graphic;
|
||||
/** @var \SimpleXMLElement $chartRef */
|
||||
/** @var SimpleXMLElement $chartRef */
|
||||
$chartRef = $graphic->graphicData->children('http://schemas.openxmlformats.org/drawingml/2006/chart')->chart;
|
||||
$thisChart = (string) $chartRef->attributes('http://schemas.openxmlformats.org/officeDocument/2006/relationships');
|
||||
|
||||
@ -1680,9 +1751,33 @@ class Xlsx extends BaseReader
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// store original rId of drawing files
|
||||
$unparsedLoadedData['sheets'][$docSheet->getCodeName()]['drawingOriginalIds'] = [];
|
||||
foreach ($relsWorksheet->Relationship as $ele) {
|
||||
if ($ele['Type'] == 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing') {
|
||||
$unparsedLoadedData['sheets'][$docSheet->getCodeName()]['drawingOriginalIds'][(string) $ele['Target']] = (string) $ele['Id'];
|
||||
}
|
||||
}
|
||||
|
||||
// unparsed drawing AlternateContent
|
||||
$xmlAltDrawing = simplexml_load_string(
|
||||
$this->securityScan($this->getFromZipArchive($zip, $fileDrawing)),
|
||||
'SimpleXMLElement',
|
||||
Settings::getLibXmlLoaderOptions()
|
||||
)->children('http://schemas.openxmlformats.org/markup-compatibility/2006');
|
||||
|
||||
if ($xmlAltDrawing->AlternateContent) {
|
||||
foreach ($xmlAltDrawing->AlternateContent as $alternateContent) {
|
||||
$unparsedLoadedData['sheets'][$docSheet->getCodeName()]['drawingAlternateContents'][] = $alternateContent->asXML();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->readFormControlProperties($excel, $zip, $dir, $fileWorksheet, $docSheet, $unparsedLoadedData);
|
||||
$this->readPrinterSettings($excel, $zip, $dir, $fileWorksheet, $docSheet, $unparsedLoadedData);
|
||||
|
||||
// Loop through definedNames
|
||||
if ($xmlWorkbook->definedNames) {
|
||||
foreach ($xmlWorkbook->definedNames->definedName as $definedName) {
|
||||
@ -1826,8 +1921,10 @@ class Xlsx extends BaseReader
|
||||
}
|
||||
|
||||
if ((!$this->readDataOnly) || (!empty($this->loadSheetsOnly))) {
|
||||
$workbookView = $xmlWorkbook->bookViews->workbookView;
|
||||
|
||||
// active sheet index
|
||||
$activeTab = (int) ($xmlWorkbook->bookViews->workbookView['activeTab']); // refers to old sheet index
|
||||
$activeTab = (int) ($workbookView['activeTab']); // refers to old sheet index
|
||||
|
||||
// keep active sheet index if sheet is still loaded, else first sheet is set as the active
|
||||
if (isset($mapSheetId[$activeTab]) && $mapSheetId[$activeTab] !== null) {
|
||||
@ -1838,6 +1935,46 @@ class Xlsx extends BaseReader
|
||||
}
|
||||
$excel->setActiveSheetIndex(0);
|
||||
}
|
||||
|
||||
if (isset($workbookView['showHorizontalScroll'])) {
|
||||
$showHorizontalScroll = (string) $workbookView['showHorizontalScroll'];
|
||||
$excel->setShowHorizontalScroll($this->castXsdBooleanToBool($showHorizontalScroll));
|
||||
}
|
||||
|
||||
if (isset($workbookView['showVerticalScroll'])) {
|
||||
$showVerticalScroll = (string) $workbookView['showVerticalScroll'];
|
||||
$excel->setShowVerticalScroll($this->castXsdBooleanToBool($showVerticalScroll));
|
||||
}
|
||||
|
||||
if (isset($workbookView['showSheetTabs'])) {
|
||||
$showSheetTabs = (string) $workbookView['showSheetTabs'];
|
||||
$excel->setShowSheetTabs($this->castXsdBooleanToBool($showSheetTabs));
|
||||
}
|
||||
|
||||
if (isset($workbookView['minimized'])) {
|
||||
$minimized = (string) $workbookView['minimized'];
|
||||
$excel->setMinimized($this->castXsdBooleanToBool($minimized));
|
||||
}
|
||||
|
||||
if (isset($workbookView['autoFilterDateGrouping'])) {
|
||||
$autoFilterDateGrouping = (string) $workbookView['autoFilterDateGrouping'];
|
||||
$excel->setAutoFilterDateGrouping($this->castXsdBooleanToBool($autoFilterDateGrouping));
|
||||
}
|
||||
|
||||
if (isset($workbookView['firstSheet'])) {
|
||||
$firstSheet = (string) $workbookView['firstSheet'];
|
||||
$excel->setFirstSheetIndex((int) $firstSheet);
|
||||
}
|
||||
|
||||
if (isset($workbookView['visibility'])) {
|
||||
$visibility = (string) $workbookView['visibility'];
|
||||
$excel->setVisibility($visibility);
|
||||
}
|
||||
|
||||
if (isset($workbookView['tabRatio'])) {
|
||||
$tabRatio = (string) $workbookView['tabRatio'];
|
||||
$excel->setTabRatio((int) $tabRatio);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
@ -1852,6 +1989,18 @@ class Xlsx extends BaseReader
|
||||
'SimpleXMLElement',
|
||||
Settings::getLibXmlLoaderOptions()
|
||||
);
|
||||
|
||||
// Default content types
|
||||
foreach ($contentTypes->Default as $contentType) {
|
||||
switch ($contentType['ContentType']) {
|
||||
case 'application/vnd.openxmlformats-officedocument.spreadsheetml.printerSettings':
|
||||
$unparsedLoadedData['default_content_types'][(string) $contentType['Extension']] = (string) $contentType['ContentType'];
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Override content types
|
||||
foreach ($contentTypes->Override as $contentType) {
|
||||
switch ($contentType['ContentType']) {
|
||||
case 'application/vnd.openxmlformats-officedocument.drawingml.chart+xml':
|
||||
@ -1876,10 +2025,20 @@ class Xlsx extends BaseReader
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
// unparsed
|
||||
case 'application/vnd.ms-excel.controlproperties+xml':
|
||||
$unparsedLoadedData['override_content_types'][(string) $contentType['PartName']] = (string) $contentType['ContentType'];
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$excel->setUnparsedLoadedData($unparsedLoadedData);
|
||||
|
||||
$zip->close();
|
||||
|
||||
return $excel;
|
||||
@ -1912,7 +2071,7 @@ class Xlsx extends BaseReader
|
||||
|
||||
/**
|
||||
* @param Style $docStyle
|
||||
* @param \SimpleXMLElement|\stdClass $style
|
||||
* @param SimpleXMLElement|\stdClass $style
|
||||
*/
|
||||
private static function readStyle(Style $docStyle, $style)
|
||||
{
|
||||
@ -1953,7 +2112,7 @@ class Xlsx extends BaseReader
|
||||
// fill
|
||||
if (isset($style->fill)) {
|
||||
if ($style->fill->gradientFill) {
|
||||
/** @var \SimpleXMLElement $gradientFill */
|
||||
/** @var SimpleXMLElement $gradientFill */
|
||||
$gradientFill = $style->fill->gradientFill[0];
|
||||
if (!empty($gradientFill['type'])) {
|
||||
$docStyle->getFill()->setFillType((string) $gradientFill['type']);
|
||||
@ -2042,7 +2201,7 @@ class Xlsx extends BaseReader
|
||||
|
||||
/**
|
||||
* @param Border $docBorder
|
||||
* @param \SimpleXMLElement $eleBorder
|
||||
* @param SimpleXMLElement $eleBorder
|
||||
*/
|
||||
private static function readBorder(Border $docBorder, $eleBorder)
|
||||
{
|
||||
@ -2055,7 +2214,7 @@ class Xlsx extends BaseReader
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \SimpleXMLElement | null $is
|
||||
* @param SimpleXMLElement | null $is
|
||||
*
|
||||
* @return RichText
|
||||
*/
|
||||
@ -2215,4 +2374,227 @@ class Xlsx extends BaseReader
|
||||
|
||||
return $value === 'true' || $value === 'TRUE';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \PhpOffice\PhpSpreadsheet\Worksheet\Drawing $objDrawing
|
||||
* @param \SimpleXMLElement $cellAnchor
|
||||
* @param array $hyperlinks
|
||||
*/
|
||||
private function readHyperLinkDrawing($objDrawing, $cellAnchor, $hyperlinks)
|
||||
{
|
||||
$hlinkClick = $cellAnchor->pic->nvPicPr->cNvPr->children('http://schemas.openxmlformats.org/drawingml/2006/main')->hlinkClick;
|
||||
|
||||
if ($hlinkClick->count() === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
$hlinkId = (string) $hlinkClick->attributes('http://schemas.openxmlformats.org/officeDocument/2006/relationships')['id'];
|
||||
$hyperlink = new Hyperlink(
|
||||
$hyperlinks[$hlinkId],
|
||||
(string) self::getArrayItem($cellAnchor->pic->nvPicPr->cNvPr->attributes(), 'name')
|
||||
);
|
||||
$objDrawing->setHyperlink($hyperlink);
|
||||
}
|
||||
|
||||
private function readProtection(Spreadsheet $excel, SimpleXMLElement $xmlWorkbook)
|
||||
{
|
||||
if (!$xmlWorkbook->workbookProtection) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($xmlWorkbook->workbookProtection['lockRevision']) {
|
||||
$excel->getSecurity()->setLockRevision((bool) $xmlWorkbook->workbookProtection['lockRevision']);
|
||||
}
|
||||
|
||||
if ($xmlWorkbook->workbookProtection['lockStructure']) {
|
||||
$excel->getSecurity()->setLockStructure((bool) $xmlWorkbook->workbookProtection['lockStructure']);
|
||||
}
|
||||
|
||||
if ($xmlWorkbook->workbookProtection['lockWindows']) {
|
||||
$excel->getSecurity()->setLockWindows((bool) $xmlWorkbook->workbookProtection['lockWindows']);
|
||||
}
|
||||
|
||||
if ($xmlWorkbook->workbookProtection['revisionsPassword']) {
|
||||
$excel->getSecurity()->setRevisionsPassword((string) $xmlWorkbook->workbookProtection['revisionsPassword'], true);
|
||||
}
|
||||
|
||||
if ($xmlWorkbook->workbookProtection['workbookPassword']) {
|
||||
$excel->getSecurity()->setWorkbookPassword((string) $xmlWorkbook->workbookProtection['workbookPassword'], true);
|
||||
}
|
||||
}
|
||||
|
||||
private function readFormControlProperties(Spreadsheet $excel, ZipArchive $zip, $dir, $fileWorksheet, $docSheet, array &$unparsedLoadedData)
|
||||
{
|
||||
if (!$zip->locateName(dirname("$dir/$fileWorksheet") . '/_rels/' . basename($fileWorksheet) . '.rels')) {
|
||||
return;
|
||||
}
|
||||
|
||||
//~ http://schemas.openxmlformats.org/package/2006/relationships"
|
||||
$relsWorksheet = simplexml_load_string(
|
||||
$this->securityScan(
|
||||
$this->getFromZipArchive($zip, dirname("$dir/$fileWorksheet") . '/_rels/' . basename($fileWorksheet) . '.rels')
|
||||
),
|
||||
'SimpleXMLElement',
|
||||
Settings::getLibXmlLoaderOptions()
|
||||
);
|
||||
$ctrlProps = [];
|
||||
foreach ($relsWorksheet->Relationship as $ele) {
|
||||
if ($ele['Type'] == 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/ctrlProp') {
|
||||
$ctrlProps[(string) $ele['Id']] = $ele;
|
||||
}
|
||||
}
|
||||
|
||||
$unparsedCtrlProps = &$unparsedLoadedData['sheets'][$docSheet->getCodeName()]['ctrlProps'];
|
||||
foreach ($ctrlProps as $rId => $ctrlProp) {
|
||||
$rId = substr($rId, 3); // rIdXXX
|
||||
$unparsedCtrlProps[$rId] = [];
|
||||
$unparsedCtrlProps[$rId]['filePath'] = self::dirAdd("$dir/$fileWorksheet", $ctrlProp['Target']);
|
||||
$unparsedCtrlProps[$rId]['relFilePath'] = (string) $ctrlProp['Target'];
|
||||
$unparsedCtrlProps[$rId]['content'] = $this->securityScan($this->getFromZipArchive($zip, $unparsedCtrlProps[$rId]['filePath']));
|
||||
}
|
||||
unset($unparsedCtrlProps);
|
||||
}
|
||||
|
||||
private function readPrinterSettings(Spreadsheet $excel, ZipArchive $zip, $dir, $fileWorksheet, $docSheet, array &$unparsedLoadedData)
|
||||
{
|
||||
if (!$zip->locateName(dirname("$dir/$fileWorksheet") . '/_rels/' . basename($fileWorksheet) . '.rels')) {
|
||||
return;
|
||||
}
|
||||
|
||||
//~ http://schemas.openxmlformats.org/package/2006/relationships"
|
||||
$relsWorksheet = simplexml_load_string(
|
||||
$this->securityScan(
|
||||
$this->getFromZipArchive($zip, dirname("$dir/$fileWorksheet") . '/_rels/' . basename($fileWorksheet) . '.rels')
|
||||
),
|
||||
'SimpleXMLElement',
|
||||
Settings::getLibXmlLoaderOptions()
|
||||
);
|
||||
$sheetPrinterSettings = [];
|
||||
foreach ($relsWorksheet->Relationship as $ele) {
|
||||
if ($ele['Type'] == 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/printerSettings') {
|
||||
$sheetPrinterSettings[(string) $ele['Id']] = $ele;
|
||||
}
|
||||
}
|
||||
|
||||
$unparsedPrinterSettings = &$unparsedLoadedData['sheets'][$docSheet->getCodeName()]['printerSettings'];
|
||||
foreach ($sheetPrinterSettings as $rId => $printerSettings) {
|
||||
$rId = substr($rId, 3); // rIdXXX
|
||||
$unparsedPrinterSettings[$rId] = [];
|
||||
$unparsedPrinterSettings[$rId]['filePath'] = self::dirAdd("$dir/$fileWorksheet", $printerSettings['Target']);
|
||||
$unparsedPrinterSettings[$rId]['relFilePath'] = (string) $printerSettings['Target'];
|
||||
$unparsedPrinterSettings[$rId]['content'] = $this->securityScan($this->getFromZipArchive($zip, $unparsedPrinterSettings[$rId]['filePath']));
|
||||
}
|
||||
unset($unparsedPrinterSettings);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an 'xsd:boolean' XML value to a PHP boolean value.
|
||||
* A valid 'xsd:boolean' XML value can be one of the following
|
||||
* four values: 'true', 'false', '1', '0'. It is case sensitive.
|
||||
*
|
||||
* Note that just doing '(bool) $xsdBoolean' is not safe,
|
||||
* since '(bool) "false"' returns true.
|
||||
*
|
||||
* @see https://www.w3.org/TR/xmlschema11-2/#boolean
|
||||
*
|
||||
* @param string $xsdBoolean An XML string value of type 'xsd:boolean'
|
||||
*
|
||||
* @return bool Boolean value
|
||||
*/
|
||||
private function castXsdBooleanToBool($xsdBoolean)
|
||||
{
|
||||
if ($xsdBoolean === 'false') {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (bool) $xsdBoolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read columns and rows attributes from XML and set them on the worksheet.
|
||||
*
|
||||
* @param SimpleXMLElement $xmlSheet
|
||||
* @param Worksheet $docSheet
|
||||
*/
|
||||
private function readColumnsAndRowsAttributes(SimpleXMLElement $xmlSheet, Worksheet $docSheet)
|
||||
{
|
||||
$columnsAttributes = [];
|
||||
$rowsAttributes = [];
|
||||
if (isset($xmlSheet->cols) && !$this->readDataOnly) {
|
||||
foreach ($xmlSheet->cols->col as $col) {
|
||||
for ($i = (int) ($col['min']); $i <= (int) ($col['max']); ++$i) {
|
||||
if ($col['style'] && !$this->readDataOnly) {
|
||||
$columnsAttributes[Coordinate::stringFromColumnIndex($i)]['xfIndex'] = (int) $col['style'];
|
||||
}
|
||||
if (self::boolean($col['hidden'])) {
|
||||
$columnsAttributes[Coordinate::stringFromColumnIndex($i)]['visible'] = false;
|
||||
}
|
||||
if (self::boolean($col['collapsed'])) {
|
||||
$columnsAttributes[Coordinate::stringFromColumnIndex($i)]['collapsed'] = true;
|
||||
}
|
||||
if ($col['outlineLevel'] > 0) {
|
||||
$columnsAttributes[Coordinate::stringFromColumnIndex($i)]['outlineLevel'] = (int) $col['outlineLevel'];
|
||||
}
|
||||
$columnsAttributes[Coordinate::stringFromColumnIndex($i)]['width'] = (float) $col['width'];
|
||||
|
||||
if ((int) ($col['max']) == 16384) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($xmlSheet && $xmlSheet->sheetData && $xmlSheet->sheetData->row) {
|
||||
foreach ($xmlSheet->sheetData->row as $row) {
|
||||
if ($row['ht'] && !$this->readDataOnly) {
|
||||
$rowsAttributes[(int) $row['r']]['rowHeight'] = (float) $row['ht'];
|
||||
}
|
||||
if (self::boolean($row['hidden']) && !$this->readDataOnly) {
|
||||
$rowsAttributes[(int) $row['r']]['visible'] = false;
|
||||
}
|
||||
if (self::boolean($row['collapsed'])) {
|
||||
$rowsAttributes[(int) $row['r']]['collapsed'] = true;
|
||||
}
|
||||
if ($row['outlineLevel'] > 0) {
|
||||
$rowsAttributes[(int) $row['r']]['outlineLevel'] = (int) $row['outlineLevel'];
|
||||
}
|
||||
if ($row['s'] && !$this->readDataOnly) {
|
||||
$rowsAttributes[(int) $row['r']]['xfIndex'] = (int) $row['s'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// set columns/rows attributes
|
||||
$columnsAttributesSet = [];
|
||||
$rowsAttributesSet = [];
|
||||
foreach ($columnsAttributes as $coordColumn => $columnAttributes) {
|
||||
foreach ($rowsAttributes as $coordRow => $rowAttributes) {
|
||||
if ($this->getReadFilter() !== null) {
|
||||
if (!$this->getReadFilter()->readCell($coordColumn, $coordRow, $docSheet->getTitle())) {
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($columnsAttributesSet[$coordColumn])) {
|
||||
$this->setColumnAttributes($docSheet, $coordColumn, $columnAttributes);
|
||||
$columnsAttributesSet[$coordColumn] = true;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($rowsAttributes as $coordRow => $rowAttributes) {
|
||||
foreach ($columnsAttributes as $coordColumn => $columnAttributes) {
|
||||
if ($this->getReadFilter() !== null) {
|
||||
if (!$this->getReadFilter()->readCell($coordColumn, $coordRow, $docSheet->getTitle())) {
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($rowsAttributesSet[$coordRow])) {
|
||||
$this->setRowAttributes($docSheet, $coordRow, $rowAttributes);
|
||||
$rowsAttributesSet[$coordRow] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -76,7 +76,7 @@ class Xml extends BaseReader
|
||||
// Read sample data (first 2 KB will do)
|
||||
$data = fread($fileHandle, 2048);
|
||||
fclose($fileHandle);
|
||||
$data = strtr($data, "'", '"'); // fix headers with single quote
|
||||
$data = str_replace("'", '"', $data); // fix headers with single quote
|
||||
|
||||
$valid = true;
|
||||
foreach ($signature as $match) {
|
||||
|
@ -256,7 +256,7 @@ class Date
|
||||
/**
|
||||
* Convert a Unix timestamp to an MS Excel serialized date/time value.
|
||||
*
|
||||
* @param DateTimeInterface $dateValue Unix Timestamp
|
||||
* @param int $dateValue Unix Timestamp
|
||||
*
|
||||
* @return float MS Excel serialized date/time value
|
||||
*/
|
||||
|
@ -1000,7 +1000,7 @@ class Matrix
|
||||
*/
|
||||
public function times(...$args)
|
||||
{
|
||||
if (count() > 0) {
|
||||
if (count($args) > 0) {
|
||||
$match = implode(',', array_map('gettype', $args));
|
||||
|
||||
switch ($match) {
|
||||
@ -1094,7 +1094,7 @@ class Matrix
|
||||
*/
|
||||
public function power(...$args)
|
||||
{
|
||||
if (count() > 0) {
|
||||
if (count($args) > 0) {
|
||||
$match = implode(',', array_map('gettype', $args));
|
||||
|
||||
switch ($match) {
|
||||
|
@ -142,7 +142,7 @@ class BestFit
|
||||
*
|
||||
* @param int $dp Number of places of decimal precision to display
|
||||
*
|
||||
* @return string
|
||||
* @return float
|
||||
*/
|
||||
public function getSlope($dp = 0)
|
||||
{
|
||||
@ -158,7 +158,7 @@ class BestFit
|
||||
*
|
||||
* @param int $dp Number of places of decimal precision to display
|
||||
*
|
||||
* @return string
|
||||
* @return float
|
||||
*/
|
||||
public function getSlopeSE($dp = 0)
|
||||
{
|
||||
@ -174,7 +174,7 @@ class BestFit
|
||||
*
|
||||
* @param int $dp Number of places of decimal precision to display
|
||||
*
|
||||
* @return string
|
||||
* @return float
|
||||
*/
|
||||
public function getIntersect($dp = 0)
|
||||
{
|
||||
@ -190,7 +190,7 @@ class BestFit
|
||||
*
|
||||
* @param int $dp Number of places of decimal precision to display
|
||||
*
|
||||
* @return string
|
||||
* @return float
|
||||
*/
|
||||
public function getIntersectSE($dp = 0)
|
||||
{
|
||||
@ -217,6 +217,13 @@ class BestFit
|
||||
return $this->goodnessOfFit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the goodness of fit for this regression.
|
||||
*
|
||||
* @param int $dp Number of places of decimal precision to return
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function getGoodnessOfFitPercent($dp = 0)
|
||||
{
|
||||
if ($dp != 0) {
|
||||
@ -242,6 +249,11 @@ class BestFit
|
||||
return $this->stdevOfResiduals;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $dp Number of places of decimal precision to return
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function getSSRegression($dp = 0)
|
||||
{
|
||||
if ($dp != 0) {
|
||||
@ -251,6 +263,11 @@ class BestFit
|
||||
return $this->SSRegression;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $dp Number of places of decimal precision to return
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function getSSResiduals($dp = 0)
|
||||
{
|
||||
if ($dp != 0) {
|
||||
@ -260,6 +277,11 @@ class BestFit
|
||||
return $this->SSResiduals;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $dp Number of places of decimal precision to return
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function getDFResiduals($dp = 0)
|
||||
{
|
||||
if ($dp != 0) {
|
||||
@ -269,6 +291,11 @@ class BestFit
|
||||
return $this->DFResiduals;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $dp Number of places of decimal precision to return
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function getF($dp = 0)
|
||||
{
|
||||
if ($dp != 0) {
|
||||
@ -278,6 +305,11 @@ class BestFit
|
||||
return $this->f;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $dp Number of places of decimal precision to return
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function getCovariance($dp = 0)
|
||||
{
|
||||
if ($dp != 0) {
|
||||
@ -287,6 +319,11 @@ class BestFit
|
||||
return $this->covariance;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $dp Number of places of decimal precision to return
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function getCorrelation($dp = 0)
|
||||
{
|
||||
if ($dp != 0) {
|
||||
@ -296,6 +333,9 @@ class BestFit
|
||||
return $this->correlation;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return float[]
|
||||
*/
|
||||
public function getYBestFitValues()
|
||||
{
|
||||
return $this->yBestFitValues;
|
||||
|
@ -164,7 +164,7 @@ class PolynomialBestFit extends BestFit
|
||||
$this->intersect = array_shift($coefficients);
|
||||
$this->slope = $coefficients;
|
||||
|
||||
$this->calculateGoodnessOfFit($x_sum, $y_sum, $xx_sum, $yy_sum, $xy_sum);
|
||||
$this->calculateGoodnessOfFit($x_sum, $y_sum, $xx_sum, $yy_sum, $xy_sum, 0, 0, 0);
|
||||
foreach ($this->xValues as $xKey => $xValue) {
|
||||
$this->yBestFitValues[$xKey] = $this->getValueOfYForX($xValue);
|
||||
}
|
||||
|
@ -9,6 +9,17 @@ use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
||||
|
||||
class Spreadsheet
|
||||
{
|
||||
// Allowable values for workbook window visilbity
|
||||
const VISIBILITY_VISIBLE = 'visible';
|
||||
const VISIBILITY_HIDDEN = 'hidden';
|
||||
const VISIBILITY_VERY_HIDDEN = 'veryHidden';
|
||||
|
||||
private static $workbookViewVisibilityValues = [
|
||||
self::VISIBILITY_VISIBLE,
|
||||
self::VISIBILITY_HIDDEN,
|
||||
self::VISIBILITY_VERY_HIDDEN,
|
||||
];
|
||||
|
||||
/**
|
||||
* Unique ID.
|
||||
*
|
||||
@ -115,6 +126,75 @@ class Spreadsheet
|
||||
*/
|
||||
private $ribbonBinObjects;
|
||||
|
||||
/**
|
||||
* List of unparsed loaded data for export to same format with better compatibility.
|
||||
* It has to be minimized when the library start to support currently unparsed data.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $unparsedLoadedData = [];
|
||||
|
||||
/**
|
||||
* Controls visibility of the horizonal scroll bar in the application.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $showHorizontalScroll = true;
|
||||
|
||||
/**
|
||||
* Controls visibility of the horizonal scroll bar in the application.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $showVerticalScroll = true;
|
||||
|
||||
/**
|
||||
* Controls visibility of the sheet tabs in the application.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $showSheetTabs = true;
|
||||
|
||||
/**
|
||||
* Specifies a boolean value that indicates whether the workbook window
|
||||
* is minimized.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $minimized = false;
|
||||
|
||||
/**
|
||||
* Specifies a boolean value that indicates whether to group dates
|
||||
* when presenting the user with filtering optiomd in the user
|
||||
* interface.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $autoFilterDateGrouping = true;
|
||||
|
||||
/**
|
||||
* Specifies the index to the first sheet in the book view.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $firstSheetIndex = 0;
|
||||
|
||||
/**
|
||||
* Specifies the visible status of the workbook.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $visibility = self::VISIBILITY_VISIBLE;
|
||||
|
||||
/**
|
||||
* Specifies the ratio between the workbook tabs bar and the horizontal
|
||||
* scroll bar. TabRatio is assumed to be out of 1000 of the horizontal
|
||||
* window width.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $tabRatio = 600;
|
||||
|
||||
/**
|
||||
* The workbook has macros ?
|
||||
*
|
||||
@ -256,6 +336,32 @@ class Spreadsheet
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* List of unparsed loaded data for export to same format with better compatibility.
|
||||
* It has to be minimized when the library start to support currently unparsed data.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getUnparsedLoadedData()
|
||||
{
|
||||
return $this->unparsedLoadedData;
|
||||
}
|
||||
|
||||
/**
|
||||
* List of unparsed loaded data for export to same format with better compatibility.
|
||||
* It has to be minimized when the library start to support currently unparsed data.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @param array $unparsedLoadedData
|
||||
*/
|
||||
public function setUnparsedLoadedData(array $unparsedLoadedData)
|
||||
{
|
||||
$this->unparsedLoadedData = $unparsedLoadedData;
|
||||
}
|
||||
|
||||
/**
|
||||
* return the extension of a filename. Internal use for a array_map callback (php<5.3 don't like lambda function).
|
||||
*
|
||||
@ -1182,4 +1288,203 @@ class Spreadsheet
|
||||
{
|
||||
return $this->uniqueID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the visibility of the horizonal scroll bar in the application.
|
||||
*
|
||||
* @return bool True if horizonal scroll bar is visible
|
||||
*/
|
||||
public function getShowHorizontalScroll()
|
||||
{
|
||||
return $this->showHorizontalScroll;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the visibility of the horizonal scroll bar in the application.
|
||||
*
|
||||
* @param bool $showHorizontalScroll True if horizonal scroll bar is visible
|
||||
*/
|
||||
public function setShowHorizontalScroll($showHorizontalScroll)
|
||||
{
|
||||
$this->showHorizontalScroll = (bool) $showHorizontalScroll;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the visibility of the vertical scroll bar in the application.
|
||||
*
|
||||
* @return bool True if vertical scroll bar is visible
|
||||
*/
|
||||
public function getShowVerticalScroll()
|
||||
{
|
||||
return $this->showVerticalScroll;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the visibility of the vertical scroll bar in the application.
|
||||
*
|
||||
* @param bool $showVerticalScroll True if vertical scroll bar is visible
|
||||
*/
|
||||
public function setShowVerticalScroll($showVerticalScroll)
|
||||
{
|
||||
$this->showVerticalScroll = (bool) $showVerticalScroll;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the visibility of the sheet tabs in the application.
|
||||
*
|
||||
* @return bool True if the sheet tabs are visible
|
||||
*/
|
||||
public function getShowSheetTabs()
|
||||
{
|
||||
return $this->showSheetTabs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the visibility of the sheet tabs in the application.
|
||||
*
|
||||
* @param bool $showSheetTabs True if sheet tabs are visible
|
||||
*/
|
||||
public function setShowSheetTabs($showSheetTabs)
|
||||
{
|
||||
$this->showSheetTabs = (bool) $showSheetTabs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the workbook window is minimized.
|
||||
*
|
||||
* @return bool true if workbook window is minimized
|
||||
*/
|
||||
public function getMinimized()
|
||||
{
|
||||
return $this->minimized;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether the workbook window is minimized.
|
||||
*
|
||||
* @param bool $minimized true if workbook window is minimized
|
||||
*/
|
||||
public function setMinimized($minimized)
|
||||
{
|
||||
$this->minimized = (bool) $minimized;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether to group dates when presenting the user with
|
||||
* filtering optiomd in the user interface.
|
||||
*
|
||||
* @return bool true if workbook window is minimized
|
||||
*/
|
||||
public function getAutoFilterDateGrouping()
|
||||
{
|
||||
return $this->autoFilterDateGrouping;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether to group dates when presenting the user with
|
||||
* filtering optiomd in the user interface.
|
||||
*
|
||||
* @param bool $autoFilterDateGrouping true if workbook window is minimized
|
||||
*/
|
||||
public function setAutoFilterDateGrouping($autoFilterDateGrouping)
|
||||
{
|
||||
$this->autoFilterDateGrouping = (bool) $autoFilterDateGrouping;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the first sheet in the book view.
|
||||
*
|
||||
* @return int First sheet in book view
|
||||
*/
|
||||
public function getFirstSheetIndex()
|
||||
{
|
||||
return $this->firstSheetIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the first sheet in the book view.
|
||||
*
|
||||
* @param int $firstSheetIndex First sheet in book view
|
||||
*
|
||||
* @throws Exception if the given value is invalid
|
||||
*/
|
||||
public function setFirstSheetIndex($firstSheetIndex)
|
||||
{
|
||||
if ($firstSheetIndex >= 0) {
|
||||
$this->firstSheetIndex = (int) $firstSheetIndex;
|
||||
} else {
|
||||
throw new Exception('First sheet index must be a positive integer.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the visibility status of the workbook.
|
||||
*
|
||||
* This may be one of the following three values:
|
||||
* - visibile
|
||||
*
|
||||
* @return string Visible status
|
||||
*/
|
||||
public function getVisibility()
|
||||
{
|
||||
return $this->visibility;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the visibility status of the workbook.
|
||||
*
|
||||
* Valid values are:
|
||||
* - 'visible' (self::VISIBILITY_VISIBLE):
|
||||
* Workbook window is visible
|
||||
* - 'hidden' (self::VISIBILITY_HIDDEN):
|
||||
* Workbook window is hidden, but can be shown by the user
|
||||
* via the user interface
|
||||
* - 'veryHidden' (self::VISIBILITY_VERY_HIDDEN):
|
||||
* Workbook window is hidden and cannot be shown in the
|
||||
* user interface.
|
||||
*
|
||||
* @param string $visibility visibility status of the workbook
|
||||
*
|
||||
* @throws Exception if the given value is invalid
|
||||
*/
|
||||
public function setVisibility($visibility)
|
||||
{
|
||||
if ($visibility === null) {
|
||||
$visibility = self::VISIBILITY_VISIBLE;
|
||||
}
|
||||
|
||||
if (in_array($visibility, self::$workbookViewVisibilityValues)) {
|
||||
$this->visibility = $visibility;
|
||||
} else {
|
||||
throw new Exception('Invalid visibility value.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ratio between the workbook tabs bar and the horizontal scroll bar.
|
||||
* TabRatio is assumed to be out of 1000 of the horizontal window width.
|
||||
*
|
||||
* @return int Ratio between the workbook tabs bar and the horizontal scroll bar
|
||||
*/
|
||||
public function getTabRatio()
|
||||
{
|
||||
return $this->tabRatio;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the ratio between the workbook tabs bar and the horizontal scroll bar
|
||||
* TabRatio is assumed to be out of 1000 of the horizontal window width.
|
||||
*
|
||||
* @param int $tabRatio Ratio between the tabs bar and the horizontal scroll bar
|
||||
*
|
||||
* @throws Exception if the given value is invalid
|
||||
*/
|
||||
public function setTabRatio($tabRatio)
|
||||
{
|
||||
if ($tabRatio >= 0 || $tabRatio <= 1000) {
|
||||
$this->tabRatio = (int) $tabRatio;
|
||||
} else {
|
||||
throw new Exception('Tab ratio must be between 0 and 1000.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -589,7 +589,7 @@ class NumberFormat extends Supervisor
|
||||
}
|
||||
|
||||
// Convert any other escaped characters to quoted strings, e.g. (\T to "T")
|
||||
$format = preg_replace('/(\\\(.))(?=(?:[^"]|"[^"]*")*$)/u', '"${2}"', $format);
|
||||
$format = preg_replace('/(\\\([^ ]))(?=(?:[^"]|"[^"]*")*$)/u', '"${2}"', $format);
|
||||
|
||||
// Get the sections, there can be up to four sections, separated with a semi-colon (but only if not a quoted literal)
|
||||
$sections = preg_split('/(;)(?=(?:[^"]|"[^"]*")*$)/u', $format);
|
||||
|
@ -333,6 +333,9 @@ class Style extends Supervisor
|
||||
}
|
||||
}
|
||||
|
||||
// restore initial cell selection range
|
||||
$this->getActiveSheet()->getStyle($pRange);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@ -841,7 +841,7 @@ class AutoFilter
|
||||
$vars = get_object_vars($this);
|
||||
foreach ($vars as $key => $value) {
|
||||
if (is_object($value)) {
|
||||
if ($key == 'workSheet') {
|
||||
if ($key === 'workSheet') {
|
||||
// Detach from worksheet
|
||||
$this->{$key} = null;
|
||||
} else {
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Worksheet;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Cell\Hyperlink;
|
||||
use PhpOffice\PhpSpreadsheet\Exception as PhpSpreadsheetException;
|
||||
use PhpOffice\PhpSpreadsheet\IComparable;
|
||||
|
||||
@ -98,6 +99,13 @@ class BaseDrawing implements IComparable
|
||||
*/
|
||||
protected $shadow;
|
||||
|
||||
/**
|
||||
* Image hyperlink.
|
||||
*
|
||||
* @var null|Hyperlink
|
||||
*/
|
||||
private $hyperlink;
|
||||
|
||||
/**
|
||||
* Create a new BaseDrawing.
|
||||
*/
|
||||
@ -501,11 +509,29 @@ class BaseDrawing implements IComparable
|
||||
{
|
||||
$vars = get_object_vars($this);
|
||||
foreach ($vars as $key => $value) {
|
||||
if (is_object($value)) {
|
||||
if ($key == 'worksheet') {
|
||||
$this->worksheet = null;
|
||||
} elseif (is_object($value)) {
|
||||
$this->$key = clone $value;
|
||||
} else {
|
||||
$this->$key = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param null|Hyperlink $pHyperlink
|
||||
*/
|
||||
public function setHyperlink(Hyperlink $pHyperlink = null)
|
||||
{
|
||||
$this->hyperlink = $pHyperlink;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|Hyperlink
|
||||
*/
|
||||
public function getHyperlink()
|
||||
{
|
||||
return $this->hyperlink;
|
||||
}
|
||||
}
|
||||
|
@ -37,6 +37,13 @@ class Worksheet implements IComparable
|
||||
const SHEETSTATE_HIDDEN = 'hidden';
|
||||
const SHEETSTATE_VERYHIDDEN = 'veryHidden';
|
||||
|
||||
/**
|
||||
* Maximum 31 characters allowed for sheet title.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const SHEET_TITLE_MAXIMUM_LENGTH = 31;
|
||||
|
||||
/**
|
||||
* Invalid characters in sheet title.
|
||||
*
|
||||
@ -434,9 +441,9 @@ class Worksheet implements IComparable
|
||||
throw new Exception('Invalid character found in sheet code name');
|
||||
}
|
||||
|
||||
// Maximum 31 characters allowed for sheet title
|
||||
if ($CharCount > 31) {
|
||||
throw new Exception('Maximum 31 characters allowed in sheet code name.');
|
||||
// Enforce maximum characters allowed for sheet title
|
||||
if ($CharCount > self::SHEET_TITLE_MAXIMUM_LENGTH) {
|
||||
throw new Exception('Maximum ' . self::SHEET_TITLE_MAXIMUM_LENGTH . ' characters allowed in sheet code name.');
|
||||
}
|
||||
|
||||
return $pValue;
|
||||
@ -458,9 +465,9 @@ class Worksheet implements IComparable
|
||||
throw new Exception('Invalid character found in sheet title');
|
||||
}
|
||||
|
||||
// Maximum 31 characters allowed for sheet title
|
||||
if (Shared\StringHelper::countCharacters($pValue) > 31) {
|
||||
throw new Exception('Maximum 31 characters allowed in sheet title.');
|
||||
// Enforce maximum characters allowed for sheet title
|
||||
if (Shared\StringHelper::countCharacters($pValue) > self::SHEET_TITLE_MAXIMUM_LENGTH) {
|
||||
throw new Exception('Maximum ' . self::SHEET_TITLE_MAXIMUM_LENGTH . ' characters allowed in sheet title.');
|
||||
}
|
||||
|
||||
return $pValue;
|
||||
@ -2956,13 +2963,14 @@ class Worksheet implements IComparable
|
||||
$newCollection = $this->cellCollection->cloneCellCollection($this);
|
||||
$this->cellCollection = $newCollection;
|
||||
} elseif ($key == 'drawingCollection') {
|
||||
$newCollection = new ArrayObject();
|
||||
foreach ($this->drawingCollection as $id => $item) {
|
||||
$currentCollection = $this->drawingCollection;
|
||||
$this->drawingCollection = new ArrayObject();
|
||||
foreach ($currentCollection as $item) {
|
||||
if (is_object($item)) {
|
||||
$newCollection[$id] = clone $this->drawingCollection[$id];
|
||||
$newDrawing = clone $item;
|
||||
$newDrawing->setWorksheet($this);
|
||||
}
|
||||
}
|
||||
$this->drawingCollection = $newCollection;
|
||||
} elseif (($key == 'autoFilter') && ($this->autoFilter instanceof AutoFilter)) {
|
||||
$newAutoFilter = clone $this->autoFilter;
|
||||
$this->autoFilter = $newAutoFilter;
|
||||
|
@ -827,7 +827,7 @@ class Worksheet extends BIFFwriter
|
||||
$formula = substr($formula, 1);
|
||||
} else {
|
||||
// Error handling
|
||||
$this->writeString($row, $col, 'Unrecognised character for formula');
|
||||
$this->writeString($row, $col, 'Unrecognised character for formula', 0);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
@ -137,9 +137,9 @@ class Xlsx extends BaseWriter
|
||||
}
|
||||
|
||||
$hashTablesArray = ['stylesConditionalHashTable', 'fillHashTable', 'fontHashTable',
|
||||
'bordersHashTable', 'numFmtHashTable', 'drawingHashTable',
|
||||
'styleHashTable',
|
||||
];
|
||||
'bordersHashTable', 'numFmtHashTable', 'drawingHashTable',
|
||||
'styleHashTable',
|
||||
];
|
||||
|
||||
// Set HashTable variables
|
||||
foreach ($hashTablesArray as $tableName) {
|
||||
@ -290,12 +290,26 @@ class Xlsx extends BaseWriter
|
||||
}
|
||||
}
|
||||
|
||||
$chartRef1 = $chartRef2 = 0;
|
||||
$chartRef1 = 0;
|
||||
// Add worksheet relationships (drawings, ...)
|
||||
for ($i = 0; $i < $this->spreadSheet->getSheetCount(); ++$i) {
|
||||
// Add relationships
|
||||
$zip->addFromString('xl/worksheets/_rels/sheet' . ($i + 1) . '.xml.rels', $this->getWriterPart('Rels')->writeWorksheetRelationships($this->spreadSheet->getSheet($i), ($i + 1), $this->includeCharts));
|
||||
|
||||
// Add unparsedLoadedData
|
||||
$sheetCodeName = $this->spreadSheet->getSheet($i)->getCodeName();
|
||||
$unparsedLoadedData = $this->spreadSheet->getUnparsedLoadedData();
|
||||
if (isset($unparsedLoadedData['sheets'][$sheetCodeName]['ctrlProps'])) {
|
||||
foreach ($unparsedLoadedData['sheets'][$sheetCodeName]['ctrlProps'] as $ctrlProp) {
|
||||
$zip->addFromString($ctrlProp['filePath'], $ctrlProp['content']);
|
||||
}
|
||||
}
|
||||
if (isset($unparsedLoadedData['sheets'][$sheetCodeName]['printerSettings'])) {
|
||||
foreach ($unparsedLoadedData['sheets'][$sheetCodeName]['printerSettings'] as $ctrlProp) {
|
||||
$zip->addFromString($ctrlProp['filePath'], $ctrlProp['content']);
|
||||
}
|
||||
}
|
||||
|
||||
$drawings = $this->spreadSheet->getSheet($i)->getDrawingCollection();
|
||||
$drawingCount = count($drawings);
|
||||
if ($this->includeCharts) {
|
||||
@ -307,6 +321,9 @@ class Xlsx extends BaseWriter
|
||||
// Drawing relationships
|
||||
$zip->addFromString('xl/drawings/_rels/drawing' . ($i + 1) . '.xml.rels', $this->getWriterPart('Rels')->writeDrawingRelationships($this->spreadSheet->getSheet($i), $chartRef1, $this->includeCharts));
|
||||
|
||||
// Drawings
|
||||
$zip->addFromString('xl/drawings/drawing' . ($i + 1) . '.xml', $this->getWriterPart('Drawing')->writeDrawings($this->spreadSheet->getSheet($i), $this->includeCharts));
|
||||
} elseif (isset($unparsedLoadedData['sheets'][$sheetCodeName]['drawingAlternateContents'])) {
|
||||
// Drawings
|
||||
$zip->addFromString('xl/drawings/drawing' . ($i + 1) . '.xml', $this->getWriterPart('Drawing')->writeDrawings($this->spreadSheet->getSheet($i), $this->includeCharts));
|
||||
}
|
||||
@ -320,6 +337,13 @@ class Xlsx extends BaseWriter
|
||||
$zip->addFromString('xl/comments' . ($i + 1) . '.xml', $this->getWriterPart('Comments')->writeComments($this->spreadSheet->getSheet($i)));
|
||||
}
|
||||
|
||||
// Add unparsed relationship parts
|
||||
if (isset($unparsedLoadedData['sheets'][$this->spreadSheet->getSheet($i)->getCodeName()]['vmlDrawings'])) {
|
||||
foreach ($unparsedLoadedData['sheets'][$this->spreadSheet->getSheet($i)->getCodeName()]['vmlDrawings'] as $vmlDrawing) {
|
||||
$zip->addFromString($vmlDrawing['filePath'], $vmlDrawing['content']);
|
||||
}
|
||||
}
|
||||
|
||||
// Add header/footer relationship parts
|
||||
if (count($this->spreadSheet->getSheet($i)->getHeaderFooter()->getImages()) > 0) {
|
||||
// VML Drawings
|
||||
|
@ -57,7 +57,8 @@ class ContentTypes extends WriterPart
|
||||
// Yes : not standard content but "macroEnabled"
|
||||
$this->writeOverrideContentType($objWriter, '/xl/workbook.xml', 'application/vnd.ms-excel.sheet.macroEnabled.main+xml');
|
||||
//... and define a new type for the VBA project
|
||||
$this->writeDefaultContentType($objWriter, 'bin', 'application/vnd.ms-office.vbaProject');
|
||||
// Better use Override, because we can use 'bin' also for xl\printerSettings\printerSettings1.bin
|
||||
$this->writeOverrideContentType($objWriter, '/xl/vbaProject.bin', 'application/vnd.ms-office.vbaProject');
|
||||
if ($spreadsheet->hasMacrosCertificate()) {
|
||||
// signed macros ?
|
||||
// Yes : add needed information
|
||||
@ -88,14 +89,16 @@ class ContentTypes extends WriterPart
|
||||
$this->writeOverrideContentType($objWriter, '/xl/sharedStrings.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml');
|
||||
|
||||
// Add worksheet relationship content types
|
||||
$unparsedLoadedData = $spreadsheet->getUnparsedLoadedData();
|
||||
$chart = 1;
|
||||
for ($i = 0; $i < $sheetCount; ++$i) {
|
||||
$drawings = $spreadsheet->getSheet($i)->getDrawingCollection();
|
||||
$drawingCount = count($drawings);
|
||||
$chartCount = ($includeCharts) ? $spreadsheet->getSheet($i)->getChartCount() : 0;
|
||||
$hasUnparsedDrawing = isset($unparsedLoadedData['sheets'][$spreadsheet->getSheet($i)->getCodeName()]['drawingOriginalIds']);
|
||||
|
||||
// We need a drawing relationship for the worksheet if we have either drawings or charts
|
||||
if (($drawingCount > 0) || ($chartCount > 0)) {
|
||||
if (($drawingCount > 0) || ($chartCount > 0) || $hasUnparsedDrawing) {
|
||||
$this->writeOverrideContentType($objWriter, '/xl/drawings/drawing' . ($i + 1) . '.xml', 'application/vnd.openxmlformats-officedocument.drawing+xml');
|
||||
}
|
||||
|
||||
@ -160,6 +163,20 @@ class ContentTypes extends WriterPart
|
||||
}
|
||||
}
|
||||
|
||||
// unparsed defaults
|
||||
if (isset($unparsedLoadedData['default_content_types'])) {
|
||||
foreach ($unparsedLoadedData['default_content_types'] as $extName => $contentType) {
|
||||
$this->writeDefaultContentType($objWriter, $extName, $contentType);
|
||||
}
|
||||
}
|
||||
|
||||
// unparsed overrides
|
||||
if (isset($unparsedLoadedData['override_content_types'])) {
|
||||
foreach ($unparsedLoadedData['override_content_types'] as $partName => $overrideType) {
|
||||
$this->writeOverrideContentType($objWriter, $partName, $overrideType);
|
||||
}
|
||||
}
|
||||
|
||||
$objWriter->endElement();
|
||||
|
||||
// Return
|
||||
|
@ -43,7 +43,12 @@ class Drawing extends WriterPart
|
||||
$i = 1;
|
||||
$iterator = $pWorksheet->getDrawingCollection()->getIterator();
|
||||
while ($iterator->valid()) {
|
||||
$this->writeDrawing($objWriter, $iterator->current(), $i);
|
||||
/** @var BaseDrawing $pDrawing */
|
||||
$pDrawing = $iterator->current();
|
||||
$pRelationId = $i;
|
||||
$hlinkClickId = $pDrawing->getHyperlink() === null ? null : ++$i;
|
||||
|
||||
$this->writeDrawing($objWriter, $pDrawing, $pRelationId, $hlinkClickId);
|
||||
|
||||
$iterator->next();
|
||||
++$i;
|
||||
@ -59,6 +64,14 @@ class Drawing extends WriterPart
|
||||
}
|
||||
}
|
||||
|
||||
// unparsed AlternateContent
|
||||
$unparsedLoadedData = $pWorksheet->getParent()->getUnparsedLoadedData();
|
||||
if (isset($unparsedLoadedData['sheets'][$pWorksheet->getCodeName()]['drawingAlternateContents'])) {
|
||||
foreach ($unparsedLoadedData['sheets'][$pWorksheet->getCodeName()]['drawingAlternateContents'] as $drawingAlternateContent) {
|
||||
$objWriter->writeRaw($drawingAlternateContent);
|
||||
}
|
||||
}
|
||||
|
||||
$objWriter->endElement();
|
||||
|
||||
// Return
|
||||
@ -142,10 +155,11 @@ class Drawing extends WriterPart
|
||||
* @param XMLWriter $objWriter XML Writer
|
||||
* @param BaseDrawing $pDrawing
|
||||
* @param int $pRelationId
|
||||
* @param null|int $hlinkClickId
|
||||
*
|
||||
* @throws WriterException
|
||||
*/
|
||||
public function writeDrawing(XMLWriter $objWriter, BaseDrawing $pDrawing, $pRelationId = -1)
|
||||
public function writeDrawing(XMLWriter $objWriter, BaseDrawing $pDrawing, $pRelationId = -1, $hlinkClickId = null)
|
||||
{
|
||||
if ($pRelationId >= 0) {
|
||||
// xdr:oneCellAnchor
|
||||
@ -179,6 +193,10 @@ class Drawing extends WriterPart
|
||||
$objWriter->writeAttribute('id', $pRelationId);
|
||||
$objWriter->writeAttribute('name', $pDrawing->getName());
|
||||
$objWriter->writeAttribute('descr', $pDrawing->getDescription());
|
||||
|
||||
//a:hlinkClick
|
||||
$this->writeHyperLinkDrawing($objWriter, $hlinkClickId);
|
||||
|
||||
$objWriter->endElement();
|
||||
|
||||
// xdr:cNvPicPr
|
||||
@ -482,4 +500,20 @@ class Drawing extends WriterPart
|
||||
|
||||
return $aDrawings;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param XMLWriter $objWriter
|
||||
* @param null|int $hlinkClickId
|
||||
*/
|
||||
private function writeHyperLinkDrawing(XMLWriter $objWriter, $hlinkClickId)
|
||||
{
|
||||
if ($hlinkClickId === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$objWriter->startElement('a:hlinkClick');
|
||||
$objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships');
|
||||
$objWriter->writeAttribute('r:id', 'rId' . $hlinkClickId);
|
||||
$objWriter->endElement();
|
||||
}
|
||||
}
|
||||
|
@ -195,18 +195,31 @@ class Rels extends WriterPart
|
||||
|
||||
// Write drawing relationships?
|
||||
$d = 0;
|
||||
$drawingOriginalIds = [];
|
||||
$unparsedLoadedData = $pWorksheet->getParent()->getUnparsedLoadedData();
|
||||
if (isset($unparsedLoadedData['sheets'][$pWorksheet->getCodeName()]['drawingOriginalIds'])) {
|
||||
$drawingOriginalIds = $unparsedLoadedData['sheets'][$pWorksheet->getCodeName()]['drawingOriginalIds'];
|
||||
}
|
||||
|
||||
if ($includeCharts) {
|
||||
$charts = $pWorksheet->getChartCollection();
|
||||
} else {
|
||||
$charts = [];
|
||||
}
|
||||
if (($pWorksheet->getDrawingCollection()->count() > 0) ||
|
||||
(count($charts) > 0)) {
|
||||
|
||||
if (($pWorksheet->getDrawingCollection()->count() > 0) || (count($charts) > 0) || $drawingOriginalIds) {
|
||||
$relPath = '../drawings/drawing' . $pWorksheetId . '.xml';
|
||||
$rId = ++$d;
|
||||
|
||||
if (isset($drawingOriginalIds[$relPath])) {
|
||||
$rId = (int) (substr($drawingOriginalIds[$relPath], 3));
|
||||
}
|
||||
|
||||
$this->writeRelationship(
|
||||
$objWriter,
|
||||
++$d,
|
||||
$rId,
|
||||
'http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing',
|
||||
'../drawings/drawing' . $pWorksheetId . '.xml'
|
||||
$relPath
|
||||
);
|
||||
}
|
||||
|
||||
@ -255,11 +268,32 @@ class Rels extends WriterPart
|
||||
);
|
||||
}
|
||||
|
||||
$this->writeUnparsedRelationship($pWorksheet, $objWriter, 'ctrlProps', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/ctrlProp');
|
||||
$this->writeUnparsedRelationship($pWorksheet, $objWriter, 'vmlDrawings', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing');
|
||||
$this->writeUnparsedRelationship($pWorksheet, $objWriter, 'printerSettings', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/printerSettings');
|
||||
|
||||
$objWriter->endElement();
|
||||
|
||||
return $objWriter->getData();
|
||||
}
|
||||
|
||||
private function writeUnparsedRelationship(\PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $pWorksheet, XMLWriter $objWriter, $relationship, $type)
|
||||
{
|
||||
$unparsedLoadedData = $pWorksheet->getParent()->getUnparsedLoadedData();
|
||||
if (!isset($unparsedLoadedData['sheets'][$pWorksheet->getCodeName()][$relationship])) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($unparsedLoadedData['sheets'][$pWorksheet->getCodeName()][$relationship] as $rId => $value) {
|
||||
$this->writeRelationship(
|
||||
$objWriter,
|
||||
$rId,
|
||||
$type,
|
||||
$value['relFilePath']
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write drawing relationships to XML format.
|
||||
*
|
||||
@ -295,12 +329,16 @@ class Rels extends WriterPart
|
||||
if ($iterator->current() instanceof \PhpOffice\PhpSpreadsheet\Worksheet\Drawing
|
||||
|| $iterator->current() instanceof MemoryDrawing) {
|
||||
// Write relationship for image drawing
|
||||
/** @var \PhpOffice\PhpSpreadsheet\Worksheet\Drawing $drawing */
|
||||
$drawing = $iterator->current();
|
||||
$this->writeRelationship(
|
||||
$objWriter,
|
||||
$i,
|
||||
'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image',
|
||||
'../media/' . str_replace(' ', '', $iterator->current()->getIndexedFilename())
|
||||
'../media/' . str_replace(' ', '', $drawing->getIndexedFilename())
|
||||
);
|
||||
|
||||
$i = $this->writeDrawingHyperLink($objWriter, $drawing, $i);
|
||||
}
|
||||
|
||||
$iterator->next();
|
||||
@ -398,4 +436,31 @@ class Rels extends WriterPart
|
||||
throw new WriterException('Invalid parameters passed.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $objWriter
|
||||
* @param \PhpOffice\PhpSpreadsheet\Worksheet\Drawing $drawing
|
||||
* @param $i
|
||||
*
|
||||
* @throws WriterException
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
private function writeDrawingHyperLink($objWriter, $drawing, $i)
|
||||
{
|
||||
if ($drawing->getHyperlink() === null) {
|
||||
return $i;
|
||||
}
|
||||
|
||||
++$i;
|
||||
$this->writeRelationship(
|
||||
$objWriter,
|
||||
$i,
|
||||
'http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink',
|
||||
$drawing->getHyperlink()->getUrl(),
|
||||
$drawing->getHyperlink()->getTypeHyperlink()
|
||||
);
|
||||
|
||||
return $i;
|
||||
}
|
||||
}
|
||||
|
@ -117,14 +117,14 @@ class Workbook extends WriterPart
|
||||
$objWriter->startElement('workbookView');
|
||||
|
||||
$objWriter->writeAttribute('activeTab', $spreadsheet->getActiveSheetIndex());
|
||||
$objWriter->writeAttribute('autoFilterDateGrouping', '1');
|
||||
$objWriter->writeAttribute('firstSheet', '0');
|
||||
$objWriter->writeAttribute('minimized', '0');
|
||||
$objWriter->writeAttribute('showHorizontalScroll', '1');
|
||||
$objWriter->writeAttribute('showSheetTabs', '1');
|
||||
$objWriter->writeAttribute('showVerticalScroll', '1');
|
||||
$objWriter->writeAttribute('tabRatio', '600');
|
||||
$objWriter->writeAttribute('visibility', 'visible');
|
||||
$objWriter->writeAttribute('autoFilterDateGrouping', ($spreadsheet->getAutoFilterDateGrouping() ? 'true' : 'false'));
|
||||
$objWriter->writeAttribute('firstSheet', $spreadsheet->getFirstSheetIndex());
|
||||
$objWriter->writeAttribute('minimized', ($spreadsheet->getMinimized() ? 'true' : 'false'));
|
||||
$objWriter->writeAttribute('showHorizontalScroll', ($spreadsheet->getShowHorizontalScroll() ? 'true' : 'false'));
|
||||
$objWriter->writeAttribute('showSheetTabs', ($spreadsheet->getShowSheetTabs() ? 'true' : 'false'));
|
||||
$objWriter->writeAttribute('showVerticalScroll', ($spreadsheet->getShowVerticalScroll() ? 'true' : 'false'));
|
||||
$objWriter->writeAttribute('tabRatio', $spreadsheet->getTabRatio());
|
||||
$objWriter->writeAttribute('visibility', $spreadsheet->getVisibility());
|
||||
|
||||
$objWriter->endElement();
|
||||
|
||||
@ -175,6 +175,7 @@ class Workbook extends WriterPart
|
||||
// fullCalcOnLoad isn't needed if we've recalculating for the save
|
||||
$objWriter->writeAttribute('calcCompleted', ($recalcRequired) ? 1 : 0);
|
||||
$objWriter->writeAttribute('fullCalcOnLoad', ($recalcRequired) ? 0 : 1);
|
||||
$objWriter->writeAttribute('forceFullCalc', ($recalcRequired) ? 0 : 1);
|
||||
|
||||
$objWriter->endElement();
|
||||
}
|
||||
|
@ -51,6 +51,12 @@ class Worksheet extends WriterPart
|
||||
$objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main');
|
||||
$objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships');
|
||||
|
||||
$objWriter->writeAttribute('xmlns:xdr', 'http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing');
|
||||
$objWriter->writeAttribute('xmlns:x14', 'http://schemas.microsoft.com/office/spreadsheetml/2009/9/main');
|
||||
$objWriter->writeAttribute('xmlns:mc', 'http://schemas.openxmlformats.org/markup-compatibility/2006');
|
||||
$objWriter->writeAttribute('mc:Ignorable', 'x14ac');
|
||||
$objWriter->writeAttribute('xmlns:x14ac', 'http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac');
|
||||
|
||||
// sheetPr
|
||||
$this->writeSheetPr($objWriter, $pSheet);
|
||||
|
||||
@ -114,6 +120,9 @@ class Worksheet extends WriterPart
|
||||
// LegacyDrawingHF
|
||||
$this->writeLegacyDrawingHF($objWriter, $pSheet);
|
||||
|
||||
// AlternateContent
|
||||
$this->writeAlternateContent($objWriter, $pSheet);
|
||||
|
||||
$objWriter->endElement();
|
||||
|
||||
// Return
|
||||
@ -237,6 +246,7 @@ class Worksheet extends WriterPart
|
||||
}
|
||||
|
||||
$activeCell = $pSheet->getActiveCell();
|
||||
$sqref = $pSheet->getSelectedCells();
|
||||
|
||||
// Pane
|
||||
$pane = '';
|
||||
@ -248,6 +258,7 @@ class Worksheet extends WriterPart
|
||||
|
||||
$topLeftCell = $pSheet->getTopLeftCell();
|
||||
$activeCell = $topLeftCell;
|
||||
$sqref = $topLeftCell;
|
||||
|
||||
// pane
|
||||
$pane = 'topRight';
|
||||
@ -283,7 +294,7 @@ class Worksheet extends WriterPart
|
||||
$objWriter->writeAttribute('pane', $pane);
|
||||
}
|
||||
$objWriter->writeAttribute('activeCell', $activeCell);
|
||||
$objWriter->writeAttribute('sqref', $activeCell);
|
||||
$objWriter->writeAttribute('sqref', $sqref);
|
||||
$objWriter->endElement();
|
||||
|
||||
$objWriter->endElement();
|
||||
@ -843,6 +854,11 @@ class Worksheet extends WriterPart
|
||||
$objWriter->writeAttribute('useFirstPageNumber', '1');
|
||||
}
|
||||
|
||||
$getUnparsedLoadedData = $pSheet->getParent()->getUnparsedLoadedData();
|
||||
if (isset($getUnparsedLoadedData['sheets'][$pSheet->getCodeName()]['pageSetupRelId'])) {
|
||||
$objWriter->writeAttribute('r:id', $getUnparsedLoadedData['sheets'][$pSheet->getCodeName()]['pageSetupRelId']);
|
||||
}
|
||||
|
||||
$objWriter->endElement();
|
||||
}
|
||||
|
||||
@ -1142,16 +1158,27 @@ class Worksheet extends WriterPart
|
||||
* @param PhpspreadsheetWorksheet $pSheet Worksheet
|
||||
* @param bool $includeCharts Flag indicating if we should include drawing details for charts
|
||||
*/
|
||||
private function writeDrawings(XMLWriter $objWriter = null, PhpspreadsheetWorksheet $pSheet = null, $includeCharts = false)
|
||||
private function writeDrawings(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet, $includeCharts = false)
|
||||
{
|
||||
$unparsedLoadedData = $pSheet->getParent()->getUnparsedLoadedData();
|
||||
$hasUnparsedDrawing = isset($unparsedLoadedData['sheets'][$pSheet->getCodeName()]['drawingOriginalIds']);
|
||||
$chartCount = ($includeCharts) ? $pSheet->getChartCollection()->count() : 0;
|
||||
// If sheet contains drawings, add the relationships
|
||||
if (($pSheet->getDrawingCollection()->count() > 0) ||
|
||||
($chartCount > 0)) {
|
||||
$objWriter->startElement('drawing');
|
||||
$objWriter->writeAttribute('r:id', 'rId1');
|
||||
$objWriter->endElement();
|
||||
if ($chartCount == 0 && $pSheet->getDrawingCollection()->count() == 0 && !$hasUnparsedDrawing) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If sheet contains drawings, add the relationships
|
||||
$objWriter->startElement('drawing');
|
||||
|
||||
$rId = 'rId1';
|
||||
if (isset($unparsedLoadedData['sheets'][$pSheet->getCodeName()]['drawingOriginalIds'])) {
|
||||
$drawingOriginalIds = $unparsedLoadedData['sheets'][$pSheet->getCodeName()]['drawingOriginalIds'];
|
||||
// take first. In future can be overriten
|
||||
$rId = reset($drawingOriginalIds);
|
||||
}
|
||||
|
||||
$objWriter->writeAttribute('r:id', $rId);
|
||||
$objWriter->endElement();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1185,4 +1212,15 @@ class Worksheet extends WriterPart
|
||||
$objWriter->endElement();
|
||||
}
|
||||
}
|
||||
|
||||
private function writeAlternateContent(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
|
||||
{
|
||||
if (empty($pSheet->getParent()->getUnparsedLoadedData()['sheets'][$pSheet->getCodeName()]['AlternateContents'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($pSheet->getParent()->getUnparsedLoadedData()['sheets'][$pSheet->getCodeName()]['AlternateContents'] as $alternateContent) {
|
||||
$objWriter->writeRaw($alternateContent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
120
inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Calculation/CalculationTest.php
vendored
Normal file
120
inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Calculation/CalculationTest.php
vendored
Normal file
@ -0,0 +1,120 @@
|
||||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Calculation;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class CalculationTest extends TestCase
|
||||
{
|
||||
public function setUp()
|
||||
{
|
||||
Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
$calculation = Calculation::getInstance();
|
||||
$calculation->setLocale('en_us');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerBinaryComparisonOperation
|
||||
*
|
||||
* @param mixed $formula
|
||||
* @param mixed $expectedResultExcel
|
||||
* @param mixed $expectedResultOpenOffice
|
||||
*/
|
||||
public function testBinaryComparisonOperation($formula, $expectedResultExcel, $expectedResultOpenOffice)
|
||||
{
|
||||
Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
|
||||
$resultExcel = Calculation::getInstance()->_calculateFormulaValue($formula);
|
||||
self::assertEquals($expectedResultExcel, $resultExcel, 'should be Excel compatible');
|
||||
|
||||
Functions::setCompatibilityMode(Functions::COMPATIBILITY_OPENOFFICE);
|
||||
$resultOpenOffice = Calculation::getInstance()->_calculateFormulaValue($formula);
|
||||
self::assertEquals($expectedResultOpenOffice, $resultOpenOffice, 'should be OpenOffice compatible');
|
||||
}
|
||||
|
||||
public function providerBinaryComparisonOperation()
|
||||
{
|
||||
return require 'data/CalculationBinaryComparisonOperation.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerGetFunctions
|
||||
*
|
||||
* @param string $category
|
||||
* @param array|string $functionCall
|
||||
* @param string $argumentCount
|
||||
*/
|
||||
public function testGetFunctions($category, $functionCall, $argumentCount)
|
||||
{
|
||||
self::assertInternalType('callable', $functionCall);
|
||||
}
|
||||
|
||||
public function providerGetFunctions()
|
||||
{
|
||||
return Calculation::getInstance()->getFunctions();
|
||||
}
|
||||
|
||||
public function testIsImplemented()
|
||||
{
|
||||
$calculation = Calculation::getInstance();
|
||||
self::assertFalse($calculation->isImplemented('non-existing-function'));
|
||||
self::assertFalse($calculation->isImplemented('AREAS'));
|
||||
self::assertTrue($calculation->isImplemented('coUNt'));
|
||||
self::assertTrue($calculation->isImplemented('abs'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerCanLoadAllSupportedLocales
|
||||
*
|
||||
* @param string $locale
|
||||
*/
|
||||
public function testCanLoadAllSupportedLocales($locale)
|
||||
{
|
||||
$calculation = Calculation::getInstance();
|
||||
self::assertTrue($calculation->setLocale($locale));
|
||||
}
|
||||
|
||||
public function providerCanLoadAllSupportedLocales()
|
||||
{
|
||||
return [
|
||||
['bg'],
|
||||
['cs'],
|
||||
['da'],
|
||||
['de'],
|
||||
['en_us'],
|
||||
['es'],
|
||||
['fi'],
|
||||
['fr'],
|
||||
['hu'],
|
||||
['it'],
|
||||
['nl'],
|
||||
['no'],
|
||||
['pl'],
|
||||
['pt'],
|
||||
['pt_br'],
|
||||
['ru'],
|
||||
['sv'],
|
||||
['tr'],
|
||||
];
|
||||
}
|
||||
|
||||
public function testDoesHandleXlfnFunctions()
|
||||
{
|
||||
$calculation = Calculation::getInstance();
|
||||
|
||||
$tree = $calculation->parseFormula('=_xlfn.ISFORMULA(A1)');
|
||||
self::assertCount(3, $tree);
|
||||
$function = $tree[2];
|
||||
self::assertEquals('Function', $function['type']);
|
||||
|
||||
$tree = $calculation->parseFormula('=_xlfn.STDEV.S(A1:B2)');
|
||||
self::assertCount(5, $tree);
|
||||
$function = $tree[4];
|
||||
self::assertEquals('Function', $function['type']);
|
||||
}
|
||||
}
|
487
inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Calculation/DateTimeTest.php
vendored
Normal file
487
inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Calculation/DateTimeTest.php
vendored
Normal file
@ -0,0 +1,487 @@
|
||||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Calculation;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\DateTime;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\Date;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
/**
|
||||
* Class DateTimeTest.
|
||||
*/
|
||||
class DateTimeTest extends TestCase
|
||||
{
|
||||
public function setUp()
|
||||
{
|
||||
Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerDATE
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testDATE($expectedResult, ...$args)
|
||||
{
|
||||
$result = DateTime::DATE(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerDATE()
|
||||
{
|
||||
return require 'data/Calculation/DateTime/DATE.php';
|
||||
}
|
||||
|
||||
public function testDATEtoPHP()
|
||||
{
|
||||
Functions::setReturnDateType(Functions::RETURNDATE_PHP_NUMERIC);
|
||||
$result = DateTime::DATE(2012, 1, 31);
|
||||
Functions::setReturnDateType(Functions::RETURNDATE_EXCEL);
|
||||
self::assertEquals(1327968000, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function testDATEtoPHPObject()
|
||||
{
|
||||
Functions::setReturnDateType(Functions::RETURNDATE_PHP_OBJECT);
|
||||
$result = DateTime::DATE(2012, 1, 31);
|
||||
Functions::setReturnDateType(Functions::RETURNDATE_EXCEL);
|
||||
// Must return an object...
|
||||
self::assertInternalType('object', $result);
|
||||
// ... of the correct type
|
||||
self::assertTrue(is_a($result, 'DateTime'));
|
||||
// ... with the correct value
|
||||
self::assertEquals($result->format('d-M-Y'), '31-Jan-2012');
|
||||
}
|
||||
|
||||
public function testDATEwith1904Calendar()
|
||||
{
|
||||
Date::setExcelCalendar(Date::CALENDAR_MAC_1904);
|
||||
$result = DateTime::DATE(1918, 11, 11);
|
||||
Date::setExcelCalendar(Date::CALENDAR_WINDOWS_1900);
|
||||
self::assertEquals($result, 5428);
|
||||
}
|
||||
|
||||
public function testDATEwith1904CalendarError()
|
||||
{
|
||||
Date::setExcelCalendar(Date::CALENDAR_MAC_1904);
|
||||
$result = DateTime::DATE(1901, 1, 31);
|
||||
Date::setExcelCalendar(Date::CALENDAR_WINDOWS_1900);
|
||||
self::assertEquals($result, '#NUM!');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerDATEVALUE
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testDATEVALUE($expectedResult, ...$args)
|
||||
{
|
||||
$result = DateTime::DATEVALUE(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerDATEVALUE()
|
||||
{
|
||||
return require 'data/Calculation/DateTime/DATEVALUE.php';
|
||||
}
|
||||
|
||||
public function testDATEVALUEtoPHP()
|
||||
{
|
||||
Functions::setReturnDateType(Functions::RETURNDATE_PHP_NUMERIC);
|
||||
$result = DateTime::DATEVALUE('2012-1-31');
|
||||
Functions::setReturnDateType(Functions::RETURNDATE_EXCEL);
|
||||
self::assertEquals(1327968000, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function testDATEVALUEtoPHPObject()
|
||||
{
|
||||
Functions::setReturnDateType(Functions::RETURNDATE_PHP_OBJECT);
|
||||
$result = DateTime::DATEVALUE('2012-1-31');
|
||||
Functions::setReturnDateType(Functions::RETURNDATE_EXCEL);
|
||||
// Must return an object...
|
||||
self::assertInternalType('object', $result);
|
||||
// ... of the correct type
|
||||
self::assertTrue(is_a($result, 'DateTime'));
|
||||
// ... with the correct value
|
||||
self::assertEquals($result->format('d-M-Y'), '31-Jan-2012');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerYEAR
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testYEAR($expectedResult, ...$args)
|
||||
{
|
||||
$result = DateTime::YEAR(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerYEAR()
|
||||
{
|
||||
return require 'data/Calculation/DateTime/YEAR.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerMONTH
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testMONTH($expectedResult, ...$args)
|
||||
{
|
||||
$result = DateTime::MONTHOFYEAR(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerMONTH()
|
||||
{
|
||||
return require 'data/Calculation/DateTime/MONTH.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerWEEKNUM
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testWEEKNUM($expectedResult, ...$args)
|
||||
{
|
||||
$result = DateTime::WEEKNUM(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerWEEKNUM()
|
||||
{
|
||||
return require 'data/Calculation/DateTime/WEEKNUM.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerISOWEEKNUM
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
* @param mixed $dateValue
|
||||
*/
|
||||
public function testISOWEEKNUM($expectedResult, $dateValue)
|
||||
{
|
||||
$result = DateTime::ISOWEEKNUM($dateValue);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerISOWEEKNUM()
|
||||
{
|
||||
return require 'data/Calculation/DateTime/ISOWEEKNUM.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerWEEKDAY
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testWEEKDAY($expectedResult, ...$args)
|
||||
{
|
||||
$result = DateTime::WEEKDAY(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerWEEKDAY()
|
||||
{
|
||||
return require 'data/Calculation/DateTime/WEEKDAY.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerDAY
|
||||
*
|
||||
* @param mixed $expectedResultExcel
|
||||
* @param mixed $expectedResultOpenOffice
|
||||
*/
|
||||
public function testDAY($expectedResultExcel, $expectedResultOpenOffice, ...$args)
|
||||
{
|
||||
$resultExcel = DateTime::DAYOFMONTH(...$args);
|
||||
self::assertEquals($expectedResultExcel, $resultExcel, null, 1E-8);
|
||||
|
||||
Functions::setCompatibilityMode(Functions::COMPATIBILITY_OPENOFFICE);
|
||||
$resultOpenOffice = DateTime::DAYOFMONTH(...$args);
|
||||
self::assertEquals($expectedResultOpenOffice, $resultOpenOffice, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerDAY()
|
||||
{
|
||||
return require 'data/Calculation/DateTime/DAY.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerTIME
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testTIME($expectedResult, ...$args)
|
||||
{
|
||||
$result = DateTime::TIME(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerTIME()
|
||||
{
|
||||
return require 'data/Calculation/DateTime/TIME.php';
|
||||
}
|
||||
|
||||
public function testTIMEtoPHP()
|
||||
{
|
||||
Functions::setReturnDateType(Functions::RETURNDATE_PHP_NUMERIC);
|
||||
$result = DateTime::TIME(7, 30, 20);
|
||||
Functions::setReturnDateType(Functions::RETURNDATE_EXCEL);
|
||||
self::assertEquals(27020, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function testTIMEtoPHPObject()
|
||||
{
|
||||
Functions::setReturnDateType(Functions::RETURNDATE_PHP_OBJECT);
|
||||
$result = DateTime::TIME(7, 30, 20);
|
||||
Functions::setReturnDateType(Functions::RETURNDATE_EXCEL);
|
||||
// Must return an object...
|
||||
self::assertInternalType('object', $result);
|
||||
// ... of the correct type
|
||||
self::assertTrue(is_a($result, 'DateTime'));
|
||||
// ... with the correct value
|
||||
self::assertEquals($result->format('H:i:s'), '07:30:20');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerTIMEVALUE
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testTIMEVALUE($expectedResult, ...$args)
|
||||
{
|
||||
$result = DateTime::TIMEVALUE(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerTIMEVALUE()
|
||||
{
|
||||
return require 'data/Calculation/DateTime/TIMEVALUE.php';
|
||||
}
|
||||
|
||||
public function testTIMEVALUEtoPHP()
|
||||
{
|
||||
Functions::setReturnDateType(Functions::RETURNDATE_PHP_NUMERIC);
|
||||
$result = DateTime::TIMEVALUE('7:30:20');
|
||||
Functions::setReturnDateType(Functions::RETURNDATE_EXCEL);
|
||||
self::assertEquals(23420, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function testTIMEVALUEtoPHPObject()
|
||||
{
|
||||
Functions::setReturnDateType(Functions::RETURNDATE_PHP_OBJECT);
|
||||
$result = DateTime::TIMEVALUE('7:30:20');
|
||||
Functions::setReturnDateType(Functions::RETURNDATE_EXCEL);
|
||||
// Must return an object...
|
||||
self::assertInternalType('object', $result);
|
||||
// ... of the correct type
|
||||
self::assertTrue(is_a($result, 'DateTime'));
|
||||
// ... with the correct value
|
||||
self::assertEquals($result->format('H:i:s'), '07:30:20');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerHOUR
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testHOUR($expectedResult, ...$args)
|
||||
{
|
||||
$result = DateTime::HOUROFDAY(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerHOUR()
|
||||
{
|
||||
return require 'data/Calculation/DateTime/HOUR.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerMINUTE
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testMINUTE($expectedResult, ...$args)
|
||||
{
|
||||
$result = DateTime::MINUTE(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerMINUTE()
|
||||
{
|
||||
return require 'data/Calculation/DateTime/MINUTE.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerSECOND
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testSECOND($expectedResult, ...$args)
|
||||
{
|
||||
$result = DateTime::SECOND(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerSECOND()
|
||||
{
|
||||
return require 'data/Calculation/DateTime/SECOND.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerNETWORKDAYS
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testNETWORKDAYS($expectedResult, ...$args)
|
||||
{
|
||||
$result = DateTime::NETWORKDAYS(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerNETWORKDAYS()
|
||||
{
|
||||
return require 'data/Calculation/DateTime/NETWORKDAYS.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerWORKDAY
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testWORKDAY($expectedResult, ...$args)
|
||||
{
|
||||
$result = DateTime::WORKDAY(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerWORKDAY()
|
||||
{
|
||||
return require 'data/Calculation/DateTime/WORKDAY.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerEDATE
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testEDATE($expectedResult, ...$args)
|
||||
{
|
||||
$result = DateTime::EDATE(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerEDATE()
|
||||
{
|
||||
return require 'data/Calculation/DateTime/EDATE.php';
|
||||
}
|
||||
|
||||
public function testEDATEtoPHP()
|
||||
{
|
||||
Functions::setReturnDateType(Functions::RETURNDATE_PHP_NUMERIC);
|
||||
$result = DateTime::EDATE('2012-1-26', -1);
|
||||
Functions::setReturnDateType(Functions::RETURNDATE_EXCEL);
|
||||
self::assertEquals(1324857600, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function testEDATEtoPHPObject()
|
||||
{
|
||||
Functions::setReturnDateType(Functions::RETURNDATE_PHP_OBJECT);
|
||||
$result = DateTime::EDATE('2012-1-26', -1);
|
||||
Functions::setReturnDateType(Functions::RETURNDATE_EXCEL);
|
||||
// Must return an object...
|
||||
self::assertInternalType('object', $result);
|
||||
// ... of the correct type
|
||||
self::assertTrue(is_a($result, 'DateTime'));
|
||||
// ... with the correct value
|
||||
self::assertEquals($result->format('d-M-Y'), '26-Dec-2011');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerEOMONTH
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testEOMONTH($expectedResult, ...$args)
|
||||
{
|
||||
$result = DateTime::EOMONTH(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerEOMONTH()
|
||||
{
|
||||
return require 'data/Calculation/DateTime/EOMONTH.php';
|
||||
}
|
||||
|
||||
public function testEOMONTHtoPHP()
|
||||
{
|
||||
Functions::setReturnDateType(Functions::RETURNDATE_PHP_NUMERIC);
|
||||
$result = DateTime::EOMONTH('2012-1-26', -1);
|
||||
Functions::setReturnDateType(Functions::RETURNDATE_EXCEL);
|
||||
self::assertEquals(1325289600, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function testEOMONTHtoPHPObject()
|
||||
{
|
||||
Functions::setReturnDateType(Functions::RETURNDATE_PHP_OBJECT);
|
||||
$result = DateTime::EOMONTH('2012-1-26', -1);
|
||||
Functions::setReturnDateType(Functions::RETURNDATE_EXCEL);
|
||||
// Must return an object...
|
||||
self::assertInternalType('object', $result);
|
||||
// ... of the correct type
|
||||
self::assertTrue(is_a($result, 'DateTime'));
|
||||
// ... with the correct value
|
||||
self::assertEquals($result->format('d-M-Y'), '31-Dec-2011');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerDATEDIF
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testDATEDIF($expectedResult, ...$args)
|
||||
{
|
||||
$result = DateTime::DATEDIF(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerDATEDIF()
|
||||
{
|
||||
return require 'data/Calculation/DateTime/DATEDIF.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerDAYS360
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testDAYS360($expectedResult, ...$args)
|
||||
{
|
||||
$result = DateTime::DAYS360(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerDAYS360()
|
||||
{
|
||||
return require 'data/Calculation/DateTime/DAYS360.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerYEARFRAC
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testYEARFRAC($expectedResult, ...$args)
|
||||
{
|
||||
$result = DateTime::YEARFRAC(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerYEARFRAC()
|
||||
{
|
||||
return require 'data/Calculation/DateTime/YEARFRAC.php';
|
||||
}
|
||||
}
|
1009
inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Calculation/EngineeringTest.php
vendored
Normal file
1009
inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Calculation/EngineeringTest.php
vendored
Normal file
File diff suppressed because it is too large
Load Diff
613
inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Calculation/FinancialTest.php
vendored
Normal file
613
inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Calculation/FinancialTest.php
vendored
Normal file
@ -0,0 +1,613 @@
|
||||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Calculation;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Financial;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class FinancialTest extends TestCase
|
||||
{
|
||||
public function setUp()
|
||||
{
|
||||
Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerACCRINT
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testACCRINT($expectedResult, ...$args)
|
||||
{
|
||||
$result = Financial::ACCRINT(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerACCRINT()
|
||||
{
|
||||
return require 'data/Calculation/Financial/ACCRINT.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerACCRINTM
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testACCRINTM($expectedResult, ...$args)
|
||||
{
|
||||
$result = Financial::ACCRINTM(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerACCRINTM()
|
||||
{
|
||||
return require 'data/Calculation/Financial/ACCRINTM.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerAMORDEGRC
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testAMORDEGRC($expectedResult, ...$args)
|
||||
{
|
||||
$result = Financial::AMORDEGRC(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerAMORDEGRC()
|
||||
{
|
||||
return require 'data/Calculation/Financial/AMORDEGRC.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerAMORLINC
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testAMORLINC($expectedResult, ...$args)
|
||||
{
|
||||
$result = Financial::AMORLINC(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerAMORLINC()
|
||||
{
|
||||
return require 'data/Calculation/Financial/AMORLINC.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerCOUPDAYBS
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testCOUPDAYBS($expectedResult, ...$args)
|
||||
{
|
||||
$result = Financial::COUPDAYBS(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerCOUPDAYBS()
|
||||
{
|
||||
return require 'data/Calculation/Financial/COUPDAYBS.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerCOUPDAYS
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testCOUPDAYS($expectedResult, ...$args)
|
||||
{
|
||||
$result = Financial::COUPDAYS(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerCOUPDAYS()
|
||||
{
|
||||
return require 'data/Calculation/Financial/COUPDAYS.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerCOUPDAYSNC
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testCOUPDAYSNC($expectedResult, ...$args)
|
||||
{
|
||||
$result = Financial::COUPDAYSNC(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerCOUPDAYSNC()
|
||||
{
|
||||
return require 'data/Calculation/Financial/COUPDAYSNC.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerCOUPNCD
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testCOUPNCD($expectedResult, ...$args)
|
||||
{
|
||||
$result = Financial::COUPNCD(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerCOUPNCD()
|
||||
{
|
||||
return require 'data/Calculation/Financial/COUPNCD.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerCOUPNUM
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testCOUPNUM($expectedResult, ...$args)
|
||||
{
|
||||
$result = Financial::COUPNUM(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerCOUPNUM()
|
||||
{
|
||||
return require 'data/Calculation/Financial/COUPNUM.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerCOUPPCD
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testCOUPPCD($expectedResult, ...$args)
|
||||
{
|
||||
$result = Financial::COUPPCD(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerCOUPPCD()
|
||||
{
|
||||
return require 'data/Calculation/Financial/COUPPCD.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerCUMIPMT
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testCUMIPMT($expectedResult, ...$args)
|
||||
{
|
||||
$result = Financial::CUMIPMT(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerCUMIPMT()
|
||||
{
|
||||
return require 'data/Calculation/Financial/CUMIPMT.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerCUMPRINC
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testCUMPRINC($expectedResult, ...$args)
|
||||
{
|
||||
$result = Financial::CUMPRINC(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerCUMPRINC()
|
||||
{
|
||||
return require 'data/Calculation/Financial/CUMPRINC.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerDB
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testDB($expectedResult, ...$args)
|
||||
{
|
||||
$result = Financial::DB(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerDB()
|
||||
{
|
||||
return require 'data/Calculation/Financial/DB.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerDDB
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testDDB($expectedResult, ...$args)
|
||||
{
|
||||
$result = Financial::DDB(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerDDB()
|
||||
{
|
||||
return require 'data/Calculation/Financial/DDB.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerDISC
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testDISC($expectedResult, ...$args)
|
||||
{
|
||||
$result = Financial::DISC(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerDISC()
|
||||
{
|
||||
return require 'data/Calculation/Financial/DISC.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerDOLLARDE
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testDOLLARDE($expectedResult, ...$args)
|
||||
{
|
||||
$result = Financial::DOLLARDE(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerDOLLARDE()
|
||||
{
|
||||
return require 'data/Calculation/Financial/DOLLARDE.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerDOLLARFR
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testDOLLARFR($expectedResult, ...$args)
|
||||
{
|
||||
$result = Financial::DOLLARFR(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerDOLLARFR()
|
||||
{
|
||||
return require 'data/Calculation/Financial/DOLLARFR.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerEFFECT
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testEFFECT($expectedResult, ...$args)
|
||||
{
|
||||
$result = Financial::EFFECT(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerEFFECT()
|
||||
{
|
||||
return require 'data/Calculation/Financial/EFFECT.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerFV
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testFV($expectedResult, ...$args)
|
||||
{
|
||||
$result = Financial::FV(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerFV()
|
||||
{
|
||||
return require 'data/Calculation/Financial/FV.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerFVSCHEDULE
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testFVSCHEDULE($expectedResult, ...$args)
|
||||
{
|
||||
$result = Financial::FVSCHEDULE(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerFVSCHEDULE()
|
||||
{
|
||||
return require 'data/Calculation/Financial/FVSCHEDULE.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerINTRATE
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testINTRATE($expectedResult, ...$args)
|
||||
{
|
||||
$result = Financial::INTRATE(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerINTRATE()
|
||||
{
|
||||
return require 'data/Calculation/Financial/INTRATE.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerIPMT
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testIPMT($expectedResult, ...$args)
|
||||
{
|
||||
$result = Financial::IPMT(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerIPMT()
|
||||
{
|
||||
return require 'data/Calculation/Financial/IPMT.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerIRR
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testIRR($expectedResult, ...$args)
|
||||
{
|
||||
$result = Financial::IRR(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerIRR()
|
||||
{
|
||||
return require 'data/Calculation/Financial/IRR.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerISPMT
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testISPMT($expectedResult, ...$args)
|
||||
{
|
||||
$result = Financial::ISPMT(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerISPMT()
|
||||
{
|
||||
return require 'data/Calculation/Financial/ISPMT.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerMIRR
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testMIRR($expectedResult, ...$args)
|
||||
{
|
||||
$result = Financial::MIRR(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerMIRR()
|
||||
{
|
||||
return require 'data/Calculation/Financial/MIRR.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerNOMINAL
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testNOMINAL($expectedResult, ...$args)
|
||||
{
|
||||
$result = Financial::NOMINAL(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerNOMINAL()
|
||||
{
|
||||
return require 'data/Calculation/Financial/NOMINAL.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerNPER
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testNPER($expectedResult, ...$args)
|
||||
{
|
||||
$result = Financial::NPER(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerNPER()
|
||||
{
|
||||
return require 'data/Calculation/Financial/NPER.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerNPV
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testNPV($expectedResult, ...$args)
|
||||
{
|
||||
$result = Financial::NPV(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerNPV()
|
||||
{
|
||||
return require 'data/Calculation/Financial/NPV.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerPRICE
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testPRICE($expectedResult, ...$args)
|
||||
{
|
||||
$this->markTestIncomplete('TODO: This test should be fixed');
|
||||
|
||||
$result = Financial::PRICE(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerPRICE()
|
||||
{
|
||||
return require 'data/Calculation/Financial/PRICE.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerPRICEDISC
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testPRICEDISC($expectedResult, array $args)
|
||||
{
|
||||
$result = Financial::PRICEDISC(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerPRICEDISC()
|
||||
{
|
||||
return require 'data/Calculation/Financial/PRICEDISC.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerPV
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testPV($expectedResult, array $args)
|
||||
{
|
||||
$result = Financial::PV(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerPV()
|
||||
{
|
||||
return require 'data/Calculation/Financial/PV.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerRATE
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testRATE($expectedResult, ...$args)
|
||||
{
|
||||
$this->markTestIncomplete('TODO: This test should be fixed');
|
||||
|
||||
$result = Financial::RATE(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerRATE()
|
||||
{
|
||||
return require 'data/Calculation/Financial/RATE.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerXIRR
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testXIRR($expectedResult, ...$args)
|
||||
{
|
||||
$this->markTestIncomplete('TODO: This test should be fixed');
|
||||
|
||||
$result = Financial::XIRR(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerXIRR()
|
||||
{
|
||||
return require 'data/Calculation/Financial/XIRR.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerPDURATION
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testPDURATION($expectedResult, array $args)
|
||||
{
|
||||
$result = Financial::PDURATION(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerPDURATION()
|
||||
{
|
||||
return require 'data/Calculation/Financial/PDURATION.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerRRI
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testRRI($expectedResult, array $args)
|
||||
{
|
||||
$result = Financial::RRI(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerRRI()
|
||||
{
|
||||
return require 'data/Calculation/Financial/RRI.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerSLN
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testSLN($expectedResult, array $args)
|
||||
{
|
||||
$result = Financial::SLN(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerSLN()
|
||||
{
|
||||
return require 'data/Calculation/Financial/SLN.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerSYD
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testSYD($expectedResult, array $args)
|
||||
{
|
||||
$result = Financial::SYD(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerSYD()
|
||||
{
|
||||
return require 'data/Calculation/Financial/SYD.php';
|
||||
}
|
||||
}
|
385
inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Calculation/FunctionsTest.php
vendored
Normal file
385
inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Calculation/FunctionsTest.php
vendored
Normal file
@ -0,0 +1,385 @@
|
||||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Calculation;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
use PhpOffice\PhpSpreadsheet\Cell\Cell;
|
||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class FunctionsTest extends TestCase
|
||||
{
|
||||
public function setUp()
|
||||
{
|
||||
Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
|
||||
Functions::setReturnDateType(Functions::RETURNDATE_EXCEL);
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
|
||||
Functions::setReturnDateType(Functions::RETURNDATE_EXCEL);
|
||||
}
|
||||
|
||||
public function testCompatibilityMode()
|
||||
{
|
||||
$result = Functions::setCompatibilityMode(Functions::COMPATIBILITY_GNUMERIC);
|
||||
// Test for a true response for success
|
||||
$this->assertTrue($result);
|
||||
// Test that mode has been changed
|
||||
$this->assertEquals(Functions::COMPATIBILITY_GNUMERIC, Functions::getCompatibilityMode());
|
||||
}
|
||||
|
||||
public function testInvalidCompatibilityMode()
|
||||
{
|
||||
$result = Functions::setCompatibilityMode('INVALIDMODE');
|
||||
// Test for a false response for failure
|
||||
$this->assertFalse($result);
|
||||
// Test that mode has not been changed
|
||||
$this->assertEquals(Functions::COMPATIBILITY_EXCEL, Functions::getCompatibilityMode());
|
||||
}
|
||||
|
||||
public function testReturnDateType()
|
||||
{
|
||||
$result = Functions::setReturnDateType(Functions::RETURNDATE_PHP_OBJECT);
|
||||
// Test for a true response for success
|
||||
$this->assertTrue($result);
|
||||
// Test that mode has been changed
|
||||
$this->assertEquals(Functions::RETURNDATE_PHP_OBJECT, Functions::getReturnDateType());
|
||||
}
|
||||
|
||||
public function testInvalidReturnDateType()
|
||||
{
|
||||
$result = Functions::setReturnDateType('INVALIDTYPE');
|
||||
// Test for a false response for failure
|
||||
$this->assertFalse($result);
|
||||
// Test that mode has not been changed
|
||||
$this->assertEquals(Functions::RETURNDATE_EXCEL, Functions::getReturnDateType());
|
||||
}
|
||||
|
||||
public function testDUMMY()
|
||||
{
|
||||
$result = Functions::DUMMY();
|
||||
self::assertEquals('#Not Yet Implemented', $result);
|
||||
}
|
||||
|
||||
public function testDIV0()
|
||||
{
|
||||
$result = Functions::DIV0();
|
||||
self::assertEquals('#DIV/0!', $result);
|
||||
}
|
||||
|
||||
public function testNA()
|
||||
{
|
||||
$result = Functions::NA();
|
||||
self::assertEquals('#N/A', $result);
|
||||
}
|
||||
|
||||
public function testNAN()
|
||||
{
|
||||
$result = Functions::NAN();
|
||||
self::assertEquals('#NUM!', $result);
|
||||
}
|
||||
|
||||
public function testNAME()
|
||||
{
|
||||
$result = Functions::NAME();
|
||||
self::assertEquals('#NAME?', $result);
|
||||
}
|
||||
|
||||
public function testREF()
|
||||
{
|
||||
$result = Functions::REF();
|
||||
self::assertEquals('#REF!', $result);
|
||||
}
|
||||
|
||||
public function testNULL()
|
||||
{
|
||||
$result = Functions::null();
|
||||
self::assertEquals('#NULL!', $result);
|
||||
}
|
||||
|
||||
public function testVALUE()
|
||||
{
|
||||
$result = Functions::VALUE();
|
||||
self::assertEquals('#VALUE!', $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerIsBlank
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testIsBlank($expectedResult, ...$args)
|
||||
{
|
||||
$result = Functions::isBlank(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerIsBlank()
|
||||
{
|
||||
return require 'data/Calculation/Functions/IS_BLANK.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerIsErr
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testIsErr($expectedResult, ...$args)
|
||||
{
|
||||
$result = Functions::isErr(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerIsErr()
|
||||
{
|
||||
return require 'data/Calculation/Functions/IS_ERR.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerIsError
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testIsError($expectedResult, ...$args)
|
||||
{
|
||||
$result = Functions::isError(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerIsError()
|
||||
{
|
||||
return require 'data/Calculation/Functions/IS_ERROR.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerErrorType
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testErrorType($expectedResult, ...$args)
|
||||
{
|
||||
$result = Functions::errorType(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerErrorType()
|
||||
{
|
||||
return require 'data/Calculation/Functions/ERROR_TYPE.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerIsLogical
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testIsLogical($expectedResult, ...$args)
|
||||
{
|
||||
$result = Functions::isLogical(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerIsLogical()
|
||||
{
|
||||
return require 'data/Calculation/Functions/IS_LOGICAL.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerIsNa
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testIsNa($expectedResult, ...$args)
|
||||
{
|
||||
$result = Functions::isNa(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerIsNa()
|
||||
{
|
||||
return require 'data/Calculation/Functions/IS_NA.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerIsNumber
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testIsNumber($expectedResult, ...$args)
|
||||
{
|
||||
$result = Functions::isNumber(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerIsNumber()
|
||||
{
|
||||
return require 'data/Calculation/Functions/IS_NUMBER.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerIsText
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testIsText($expectedResult, ...$args)
|
||||
{
|
||||
$result = Functions::isText(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerIsText()
|
||||
{
|
||||
return require 'data/Calculation/Functions/IS_TEXT.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerIsNonText
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testIsNonText($expectedResult, ...$args)
|
||||
{
|
||||
$result = Functions::isNonText(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerIsNonText()
|
||||
{
|
||||
return require 'data/Calculation/Functions/IS_NONTEXT.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerIsEven
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testIsEven($expectedResult, ...$args)
|
||||
{
|
||||
$result = Functions::isEven(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerIsEven()
|
||||
{
|
||||
return require 'data/Calculation/Functions/IS_EVEN.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerIsOdd
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testIsOdd($expectedResult, ...$args)
|
||||
{
|
||||
$result = Functions::isOdd(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerIsOdd()
|
||||
{
|
||||
return require 'data/Calculation/Functions/IS_ODD.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerTYPE
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testTYPE($expectedResult, ...$args)
|
||||
{
|
||||
$result = Functions::TYPE(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerTYPE()
|
||||
{
|
||||
return require 'data/Calculation/Functions/TYPE.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerN
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testN($expectedResult, ...$args)
|
||||
{
|
||||
$result = Functions::n(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerN()
|
||||
{
|
||||
return require 'data/Calculation/Functions/N.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerIsFormula
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
* @param mixed $reference Reference to the cell we wish to test
|
||||
* @param mixed $value Value of the cell we wish to test
|
||||
*/
|
||||
public function testIsFormula($expectedResult, $reference, $value = 'undefined')
|
||||
{
|
||||
$ourCell = null;
|
||||
if ($value !== 'undefined') {
|
||||
$remoteCell = $this->getMockBuilder(Cell::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$remoteCell->method('isFormula')
|
||||
->will($this->returnValue(substr($value, 0, 1) == '='));
|
||||
|
||||
$remoteSheet = $this->getMockBuilder(Worksheet::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$remoteSheet->method('getCell')
|
||||
->will($this->returnValue($remoteCell));
|
||||
|
||||
$workbook = $this->getMockBuilder(Spreadsheet::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$workbook->method('getSheetByName')
|
||||
->will($this->returnValue($remoteSheet));
|
||||
|
||||
$sheet = $this->getMockBuilder(Worksheet::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$sheet->method('getCell')
|
||||
->will($this->returnValue($remoteCell));
|
||||
$sheet->method('getParent')
|
||||
->will($this->returnValue($workbook));
|
||||
|
||||
$ourCell = $this->getMockBuilder(Cell::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$ourCell->method('getWorksheet')
|
||||
->will($this->returnValue($sheet));
|
||||
}
|
||||
|
||||
$result = Functions::isFormula($reference, $ourCell);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerIsFormula()
|
||||
{
|
||||
return require 'data/Calculation/Functions/ISFORMULA.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerIfCondition
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testIfCondition($expectedResult, ...$args)
|
||||
{
|
||||
$result = Functions::ifCondition(...$args);
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
public function providerIfCondition()
|
||||
{
|
||||
return require 'data/Calculation/Functions/IF_CONDITION.php';
|
||||
}
|
||||
}
|
123
inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Calculation/LogicalTest.php
vendored
Normal file
123
inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Calculation/LogicalTest.php
vendored
Normal file
@ -0,0 +1,123 @@
|
||||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Calculation;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Logical;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class LogicalTest extends TestCase
|
||||
{
|
||||
public function setUp()
|
||||
{
|
||||
Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
|
||||
}
|
||||
|
||||
public function testTRUE()
|
||||
{
|
||||
$result = Logical::TRUE();
|
||||
self::assertTrue($result);
|
||||
}
|
||||
|
||||
public function testFALSE()
|
||||
{
|
||||
$result = Logical::FALSE();
|
||||
self::assertFalse($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerAND
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testAND($expectedResult, ...$args)
|
||||
{
|
||||
$result = Logical::logicalAnd(...$args);
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
public function providerAND()
|
||||
{
|
||||
return require 'data/Calculation/Logical/AND.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerOR
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testOR($expectedResult, ...$args)
|
||||
{
|
||||
$result = Logical::logicalOr(...$args);
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
public function providerOR()
|
||||
{
|
||||
return require 'data/Calculation/Logical/OR.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerXOR
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testXOR($expectedResult, ...$args)
|
||||
{
|
||||
$result = Logical::logicalXor(...$args);
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
public function providerXOR()
|
||||
{
|
||||
return require 'data/Calculation/Logical/XOR.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerNOT
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testNOT($expectedResult, ...$args)
|
||||
{
|
||||
$result = Logical::NOT(...$args);
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
public function providerNOT()
|
||||
{
|
||||
return require 'data/Calculation/Logical/NOT.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerIF
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testIF($expectedResult, ...$args)
|
||||
{
|
||||
$result = Logical::statementIf(...$args);
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
public function providerIF()
|
||||
{
|
||||
return require 'data/Calculation/Logical/IF.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerIFERROR
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testIFERROR($expectedResult, ...$args)
|
||||
{
|
||||
$result = Logical::IFERROR(...$args);
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
public function providerIFERROR()
|
||||
{
|
||||
return require 'data/Calculation/Logical/IFERROR.php';
|
||||
}
|
||||
}
|
172
inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Calculation/LookupRefTest.php
vendored
Normal file
172
inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Calculation/LookupRefTest.php
vendored
Normal file
@ -0,0 +1,172 @@
|
||||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Calculation;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\LookupRef;
|
||||
use PhpOffice\PhpSpreadsheet\Cell\Cell;
|
||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
/**
|
||||
* Class LookupRefTest.
|
||||
*/
|
||||
class LookupRefTest extends TestCase
|
||||
{
|
||||
public function setUp()
|
||||
{
|
||||
Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerHLOOKUP
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testHLOOKUP($expectedResult, ...$args)
|
||||
{
|
||||
$result = LookupRef::HLOOKUP(...$args);
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
public function providerHLOOKUP()
|
||||
{
|
||||
return require 'data/Calculation/LookupRef/HLOOKUP.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerVLOOKUP
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testVLOOKUP($expectedResult, ...$args)
|
||||
{
|
||||
$result = LookupRef::VLOOKUP(...$args);
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
public function providerVLOOKUP()
|
||||
{
|
||||
return require 'data/Calculation/LookupRef/VLOOKUP.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerMATCH
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testMATCH($expectedResult, ...$args)
|
||||
{
|
||||
$result = LookupRef::MATCH(...$args);
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
public function providerMATCH()
|
||||
{
|
||||
return require 'data/Calculation/LookupRef/MATCH.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerINDEX
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testINDEX($expectedResult, ...$args)
|
||||
{
|
||||
$result = LookupRef::INDEX(...$args);
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
public function providerINDEX()
|
||||
{
|
||||
return require 'data/Calculation/LookupRef/INDEX.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerCOLUMNS
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testCOLUMNS($expectedResult, ...$args)
|
||||
{
|
||||
$result = LookupRef::COLUMNS(...$args);
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
public function providerCOLUMNS()
|
||||
{
|
||||
return require 'data/Calculation/LookupRef/COLUMNS.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerROWS
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testROWS($expectedResult, ...$args)
|
||||
{
|
||||
$result = LookupRef::ROWS(...$args);
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
public function providerROWS()
|
||||
{
|
||||
return require 'data/Calculation/LookupRef/ROWS.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerFormulaText
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
* @param mixed $reference Reference to the cell we wish to test
|
||||
* @param mixed $value Value of the cell we wish to test
|
||||
*/
|
||||
public function testFormulaText($expectedResult, $reference, $value = 'undefined')
|
||||
{
|
||||
$ourCell = null;
|
||||
if ($value !== 'undefined') {
|
||||
$remoteCell = $this->getMockBuilder(Cell::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$remoteCell->method('isFormula')
|
||||
->will($this->returnValue(substr($value, 0, 1) == '='));
|
||||
$remoteCell->method('getValue')
|
||||
->will($this->returnValue($value));
|
||||
|
||||
$remoteSheet = $this->getMockBuilder(Worksheet::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$remoteSheet->method('getCell')
|
||||
->will($this->returnValue($remoteCell));
|
||||
|
||||
$workbook = $this->getMockBuilder(Spreadsheet::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$workbook->method('getSheetByName')
|
||||
->will($this->returnValue($remoteSheet));
|
||||
|
||||
$sheet = $this->getMockBuilder(Worksheet::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$sheet->method('getCell')
|
||||
->will($this->returnValue($remoteCell));
|
||||
$sheet->method('getParent')
|
||||
->will($this->returnValue($workbook));
|
||||
|
||||
$ourCell = $this->getMockBuilder(Cell::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$ourCell->method('getWorksheet')
|
||||
->will($this->returnValue($sheet));
|
||||
}
|
||||
|
||||
$result = LookupRef::FORMULATEXT($reference, $ourCell);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerFormulaText()
|
||||
{
|
||||
return require 'data/Calculation/LookupRef/FORMULATEXT.php';
|
||||
}
|
||||
}
|
881
inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Calculation/MathTrigTest.php
vendored
Normal file
881
inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Calculation/MathTrigTest.php
vendored
Normal file
@ -0,0 +1,881 @@
|
||||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Calculation;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
||||
use PhpOffice\PhpSpreadsheet\Cell\Cell;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\ColumnDimension;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\RowDimension;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class MathTrigTest extends TestCase
|
||||
{
|
||||
public function setUp()
|
||||
{
|
||||
Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerATAN2
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testATAN2($expectedResult, ...$args)
|
||||
{
|
||||
$result = MathTrig::ATAN2(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-12);
|
||||
}
|
||||
|
||||
public function providerATAN2()
|
||||
{
|
||||
return require 'data/Calculation/MathTrig/ATAN2.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerCEILING
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testCEILING($expectedResult, ...$args)
|
||||
{
|
||||
$result = MathTrig::CEILING(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-12);
|
||||
}
|
||||
|
||||
public function providerCEILING()
|
||||
{
|
||||
return require 'data/Calculation/MathTrig/CEILING.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerCOMBIN
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testCOMBIN($expectedResult, ...$args)
|
||||
{
|
||||
$result = MathTrig::COMBIN(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-12);
|
||||
}
|
||||
|
||||
public function providerCOMBIN()
|
||||
{
|
||||
return require 'data/Calculation/MathTrig/COMBIN.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerEVEN
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testEVEN($expectedResult, ...$args)
|
||||
{
|
||||
$result = MathTrig::EVEN(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-12);
|
||||
}
|
||||
|
||||
public function providerEVEN()
|
||||
{
|
||||
return require 'data/Calculation/MathTrig/EVEN.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerODD
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testODD($expectedResult, ...$args)
|
||||
{
|
||||
$result = MathTrig::ODD(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-12);
|
||||
}
|
||||
|
||||
public function providerODD()
|
||||
{
|
||||
return require 'data/Calculation/MathTrig/ODD.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerFACT
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testFACT($expectedResult, ...$args)
|
||||
{
|
||||
$result = MathTrig::FACT(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-12);
|
||||
}
|
||||
|
||||
public function providerFACT()
|
||||
{
|
||||
return require 'data/Calculation/MathTrig/FACT.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerFACTDOUBLE
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testFACTDOUBLE($expectedResult, ...$args)
|
||||
{
|
||||
$result = MathTrig::FACTDOUBLE(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-12);
|
||||
}
|
||||
|
||||
public function providerFACTDOUBLE()
|
||||
{
|
||||
return require 'data/Calculation/MathTrig/FACTDOUBLE.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerFLOOR
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testFLOOR($expectedResult, ...$args)
|
||||
{
|
||||
$result = MathTrig::FLOOR(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-12);
|
||||
}
|
||||
|
||||
public function providerFLOOR()
|
||||
{
|
||||
return require 'data/Calculation/MathTrig/FLOOR.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerGCD
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testGCD($expectedResult, ...$args)
|
||||
{
|
||||
$result = MathTrig::GCD(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-12);
|
||||
}
|
||||
|
||||
public function providerGCD()
|
||||
{
|
||||
return require 'data/Calculation/MathTrig/GCD.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerLCM
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testLCM($expectedResult, ...$args)
|
||||
{
|
||||
$result = MathTrig::LCM(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-12);
|
||||
}
|
||||
|
||||
public function providerLCM()
|
||||
{
|
||||
return require 'data/Calculation/MathTrig/LCM.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerINT
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testINT($expectedResult, ...$args)
|
||||
{
|
||||
$result = MathTrig::INT(...$args);
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
public function providerINT()
|
||||
{
|
||||
return require 'data/Calculation/MathTrig/INT.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerSIGN
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testSIGN($expectedResult, ...$args)
|
||||
{
|
||||
$result = MathTrig::SIGN(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-12);
|
||||
}
|
||||
|
||||
public function providerSIGN()
|
||||
{
|
||||
return require 'data/Calculation/MathTrig/SIGN.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerPOWER
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testPOWER($expectedResult, ...$args)
|
||||
{
|
||||
$result = MathTrig::POWER(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-12);
|
||||
}
|
||||
|
||||
public function providerPOWER()
|
||||
{
|
||||
return require 'data/Calculation/MathTrig/POWER.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerLOG
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testLOG($expectedResult, ...$args)
|
||||
{
|
||||
$result = MathTrig::logBase(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-12);
|
||||
}
|
||||
|
||||
public function providerLOG()
|
||||
{
|
||||
return require 'data/Calculation/MathTrig/LOG.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerMOD
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testMOD($expectedResult, ...$args)
|
||||
{
|
||||
$result = MathTrig::MOD(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-12);
|
||||
}
|
||||
|
||||
public function providerMOD()
|
||||
{
|
||||
return require 'data/Calculation/MathTrig/MOD.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerMDETERM
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testMDETERM($expectedResult, ...$args)
|
||||
{
|
||||
$result = MathTrig::MDETERM(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-12);
|
||||
}
|
||||
|
||||
public function providerMDETERM()
|
||||
{
|
||||
return require 'data/Calculation/MathTrig/MDETERM.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerMINVERSE
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testMINVERSE($expectedResult, ...$args)
|
||||
{
|
||||
$this->markTestIncomplete('TODO: This test should be fixed');
|
||||
|
||||
$result = MathTrig::MINVERSE(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-12);
|
||||
}
|
||||
|
||||
public function providerMINVERSE()
|
||||
{
|
||||
return require 'data/Calculation/MathTrig/MINVERSE.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerMMULT
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testMMULT($expectedResult, ...$args)
|
||||
{
|
||||
$this->markTestIncomplete('TODO: This test should be fixed');
|
||||
|
||||
$result = MathTrig::MMULT(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-12);
|
||||
}
|
||||
|
||||
public function providerMMULT()
|
||||
{
|
||||
return require 'data/Calculation/MathTrig/MMULT.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerMULTINOMIAL
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testMULTINOMIAL($expectedResult, ...$args)
|
||||
{
|
||||
$result = MathTrig::MULTINOMIAL(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-12);
|
||||
}
|
||||
|
||||
public function providerMULTINOMIAL()
|
||||
{
|
||||
return require 'data/Calculation/MathTrig/MULTINOMIAL.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerMROUND
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testMROUND($expectedResult, ...$args)
|
||||
{
|
||||
Calculation::setArrayReturnType(Calculation::RETURN_ARRAY_AS_VALUE);
|
||||
$result = MathTrig::MROUND(...$args);
|
||||
Calculation::setArrayReturnType(Calculation::RETURN_ARRAY_AS_ARRAY);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-12);
|
||||
}
|
||||
|
||||
public function providerMROUND()
|
||||
{
|
||||
return require 'data/Calculation/MathTrig/MROUND.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerPRODUCT
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testPRODUCT($expectedResult, ...$args)
|
||||
{
|
||||
$result = MathTrig::PRODUCT(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-12);
|
||||
}
|
||||
|
||||
public function providerPRODUCT()
|
||||
{
|
||||
return require 'data/Calculation/MathTrig/PRODUCT.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerQUOTIENT
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testQUOTIENT($expectedResult, ...$args)
|
||||
{
|
||||
$result = MathTrig::QUOTIENT(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-12);
|
||||
}
|
||||
|
||||
public function providerQUOTIENT()
|
||||
{
|
||||
return require 'data/Calculation/MathTrig/QUOTIENT.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerROUNDUP
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testROUNDUP($expectedResult, ...$args)
|
||||
{
|
||||
$result = MathTrig::ROUNDUP(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-12);
|
||||
}
|
||||
|
||||
public function providerROUNDUP()
|
||||
{
|
||||
return require 'data/Calculation/MathTrig/ROUNDUP.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerROUNDDOWN
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testROUNDDOWN($expectedResult, ...$args)
|
||||
{
|
||||
$result = MathTrig::ROUNDDOWN(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-12);
|
||||
}
|
||||
|
||||
public function providerROUNDDOWN()
|
||||
{
|
||||
return require 'data/Calculation/MathTrig/ROUNDDOWN.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerSERIESSUM
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testSERIESSUM($expectedResult, ...$args)
|
||||
{
|
||||
$result = MathTrig::SERIESSUM(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-12);
|
||||
}
|
||||
|
||||
public function providerSERIESSUM()
|
||||
{
|
||||
return require 'data/Calculation/MathTrig/SERIESSUM.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerSUMSQ
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testSUMSQ($expectedResult, ...$args)
|
||||
{
|
||||
$result = MathTrig::SUMSQ(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-12);
|
||||
}
|
||||
|
||||
public function providerSUMSQ()
|
||||
{
|
||||
return require 'data/Calculation/MathTrig/SUMSQ.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerSUMPRODUCT
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testSUMPRODUCT($expectedResult, ...$args)
|
||||
{
|
||||
$result = MathTrig::SUMPRODUCT(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-12);
|
||||
}
|
||||
|
||||
public function providerSUMPRODUCT()
|
||||
{
|
||||
return require 'data/Calculation/MathTrig/SUMPRODUCT.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerSUMX2MY2
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testSUMX2MY2($expectedResult, ...$args)
|
||||
{
|
||||
$result = MathTrig::SUMX2MY2(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-12);
|
||||
}
|
||||
|
||||
public function providerSUMX2MY2()
|
||||
{
|
||||
return require 'data/Calculation/MathTrig/SUMX2MY2.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerSUMX2PY2
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testSUMX2PY2($expectedResult, ...$args)
|
||||
{
|
||||
$result = MathTrig::SUMX2PY2(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-12);
|
||||
}
|
||||
|
||||
public function providerSUMX2PY2()
|
||||
{
|
||||
return require 'data/Calculation/MathTrig/SUMX2PY2.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerSUMXMY2
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testSUMXMY2($expectedResult, ...$args)
|
||||
{
|
||||
$result = MathTrig::SUMXMY2(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-12);
|
||||
}
|
||||
|
||||
public function providerSUMXMY2()
|
||||
{
|
||||
return require 'data/Calculation/MathTrig/SUMXMY2.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerTRUNC
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testTRUNC($expectedResult, ...$args)
|
||||
{
|
||||
$result = MathTrig::TRUNC(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-12);
|
||||
}
|
||||
|
||||
public function providerTRUNC()
|
||||
{
|
||||
return require 'data/Calculation/MathTrig/TRUNC.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerROMAN
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testROMAN($expectedResult, ...$args)
|
||||
{
|
||||
$result = MathTrig::ROMAN(...$args);
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
public function providerROMAN()
|
||||
{
|
||||
return require 'data/Calculation/MathTrig/ROMAN.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerSQRTPI
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testSQRTPI($expectedResult, ...$args)
|
||||
{
|
||||
$result = MathTrig::SQRTPI(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-12);
|
||||
}
|
||||
|
||||
public function providerSQRTPI()
|
||||
{
|
||||
return require 'data/Calculation/MathTrig/SQRTPI.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerSUMIF
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testSUMIF($expectedResult, ...$args)
|
||||
{
|
||||
$result = MathTrig::SUMIF(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-12);
|
||||
}
|
||||
|
||||
public function providerSUMIF()
|
||||
{
|
||||
return require 'data/Calculation/MathTrig/SUMIF.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerSUBTOTAL
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testSUBTOTAL($expectedResult, ...$args)
|
||||
{
|
||||
$cell = $this->getMockBuilder(Cell::class)
|
||||
->setMethods(['getValue'])
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$cell->method('getValue')
|
||||
->willReturn(null);
|
||||
$worksheet = $this->getMockBuilder(Worksheet::class)
|
||||
->setMethods(['cellExists', 'getCell'])
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$worksheet->method('cellExists')
|
||||
->willReturn(true);
|
||||
$worksheet->method('getCell')
|
||||
->willReturn($cell);
|
||||
$cellReference = $this->getMockBuilder(Cell::class)
|
||||
->setMethods(['getWorksheet'])
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$cellReference->method('getWorksheet')
|
||||
->willReturn($worksheet);
|
||||
|
||||
array_push($args, $cellReference);
|
||||
$result = MathTrig::SUBTOTAL(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-12);
|
||||
}
|
||||
|
||||
public function providerSUBTOTAL()
|
||||
{
|
||||
return require 'data/Calculation/MathTrig/SUBTOTAL.php';
|
||||
}
|
||||
|
||||
protected function rowVisibility()
|
||||
{
|
||||
$data = [1 => false, 2 => true, 3 => false, 4 => true, 5 => false, 6 => false, 7 => false, 8 => true, 9 => false, 10 => true, 11 => true];
|
||||
foreach ($data as $k => $v) {
|
||||
yield $k => $v;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerHiddenSUBTOTAL
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testHiddenSUBTOTAL($expectedResult, ...$args)
|
||||
{
|
||||
$visibilityGenerator = $this->rowVisibility();
|
||||
|
||||
$rowDimension = $this->getMockBuilder(RowDimension::class)
|
||||
->setMethods(['getVisible'])
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$rowDimension->method('getVisible')
|
||||
->will($this->returnCallback(function () use ($visibilityGenerator) {
|
||||
$result = $visibilityGenerator->current();
|
||||
$visibilityGenerator->next();
|
||||
|
||||
return $result;
|
||||
}));
|
||||
$columnDimension = $this->getMockBuilder(ColumnDimension::class)
|
||||
->setMethods(['getVisible'])
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$columnDimension->method('getVisible')
|
||||
->willReturn(true);
|
||||
$cell = $this->getMockBuilder(Cell::class)
|
||||
->setMethods(['getValue'])
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$cell->method('getValue')
|
||||
->willReturn('');
|
||||
$worksheet = $this->getMockBuilder(Worksheet::class)
|
||||
->setMethods(['cellExists', 'getCell', 'getRowDimension', 'getColumnDimension'])
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$worksheet->method('cellExists')
|
||||
->willReturn(true);
|
||||
$worksheet->method('getCell')
|
||||
->willReturn($cell);
|
||||
$worksheet->method('getRowDimension')
|
||||
->willReturn($rowDimension);
|
||||
$worksheet->method('getColumnDimension')
|
||||
->willReturn($columnDimension);
|
||||
$cellReference = $this->getMockBuilder(Cell::class)
|
||||
->setMethods(['getWorksheet'])
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$cellReference->method('getWorksheet')
|
||||
->willReturn($worksheet);
|
||||
|
||||
array_push($args, $cellReference);
|
||||
$result = MathTrig::SUBTOTAL(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-12);
|
||||
}
|
||||
|
||||
public function providerHiddenSUBTOTAL()
|
||||
{
|
||||
return require 'data/Calculation/MathTrig/SUBTOTALHIDDEN.php';
|
||||
}
|
||||
|
||||
protected function cellValues(array $cellValues)
|
||||
{
|
||||
foreach ($cellValues as $k => $v) {
|
||||
yield $k => $v;
|
||||
}
|
||||
}
|
||||
|
||||
protected function cellIsFormula(array $cellValues)
|
||||
{
|
||||
foreach ($cellValues as $cellValue) {
|
||||
yield $cellValue[0] === '=';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerNestedSUBTOTAL
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testNestedSUBTOTAL($expectedResult, ...$args)
|
||||
{
|
||||
$cellValueGenerator = $this->cellValues(Functions::flattenArray(array_slice($args, 1)));
|
||||
$cellIsFormulaGenerator = $this->cellIsFormula(Functions::flattenArray(array_slice($args, 1)));
|
||||
|
||||
$cell = $this->getMockBuilder(Cell::class)
|
||||
->setMethods(['getValue', 'isFormula'])
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$cell->method('getValue')
|
||||
->will($this->returnCallback(function () use ($cellValueGenerator) {
|
||||
$result = $cellValueGenerator->current();
|
||||
$cellValueGenerator->next();
|
||||
|
||||
return $result;
|
||||
}));
|
||||
$cell->method('isFormula')
|
||||
->will($this->returnCallback(function () use ($cellIsFormulaGenerator) {
|
||||
$result = $cellIsFormulaGenerator->current();
|
||||
$cellIsFormulaGenerator->next();
|
||||
|
||||
return $result;
|
||||
}));
|
||||
$worksheet = $this->getMockBuilder(Worksheet::class)
|
||||
->setMethods(['cellExists', 'getCell'])
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$worksheet->method('cellExists')
|
||||
->willReturn(true);
|
||||
$worksheet->method('getCell')
|
||||
->willReturn($cell);
|
||||
$cellReference = $this->getMockBuilder(Cell::class)
|
||||
->setMethods(['getWorksheet'])
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$cellReference->method('getWorksheet')
|
||||
->willReturn($worksheet);
|
||||
|
||||
array_push($args, $cellReference);
|
||||
|
||||
$result = MathTrig::SUBTOTAL(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-12);
|
||||
}
|
||||
|
||||
public function providerNestedSUBTOTAL()
|
||||
{
|
||||
return require 'data/Calculation/MathTrig/SUBTOTALNESTED.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerSEC
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
* @param mixed $angle
|
||||
*/
|
||||
public function testSEC($expectedResult, $angle)
|
||||
{
|
||||
$result = MathTrig::SEC($angle);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-12);
|
||||
}
|
||||
|
||||
public function providerSEC()
|
||||
{
|
||||
return require 'data/Calculation/MathTrig/SEC.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerSECH
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
* @param mixed $angle
|
||||
*/
|
||||
public function testSECH($expectedResult, $angle)
|
||||
{
|
||||
$result = MathTrig::SECH($angle);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-12);
|
||||
}
|
||||
|
||||
public function providerSECH()
|
||||
{
|
||||
return require 'data/Calculation/MathTrig/SECH.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerCSC
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
* @param mixed $angle
|
||||
*/
|
||||
public function testCSC($expectedResult, $angle)
|
||||
{
|
||||
$result = MathTrig::CSC($angle);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-12);
|
||||
}
|
||||
|
||||
public function providerCSC()
|
||||
{
|
||||
return require 'data/Calculation/MathTrig/CSC.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerCSCH
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
* @param mixed $angle
|
||||
*/
|
||||
public function testCSCH($expectedResult, $angle)
|
||||
{
|
||||
$result = MathTrig::CSCH($angle);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-12);
|
||||
}
|
||||
|
||||
public function providerCSCH()
|
||||
{
|
||||
return require 'data/Calculation/MathTrig/CSCH.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerCOT
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
* @param mixed $angle
|
||||
*/
|
||||
public function testCOT($expectedResult, $angle)
|
||||
{
|
||||
$result = MathTrig::COT($angle);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-12);
|
||||
}
|
||||
|
||||
public function providerCOT()
|
||||
{
|
||||
return require 'data/Calculation/MathTrig/COT.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerCOTH
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
* @param mixed $angle
|
||||
*/
|
||||
public function testCOTH($expectedResult, $angle)
|
||||
{
|
||||
$result = MathTrig::COTH($angle);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-12);
|
||||
}
|
||||
|
||||
public function providerCOTH()
|
||||
{
|
||||
return require 'data/Calculation/MathTrig/COTH.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerACOT
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
* @param mixed $number
|
||||
*/
|
||||
public function testACOT($expectedResult, $number)
|
||||
{
|
||||
$result = MathTrig::ACOT($number);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-12);
|
||||
}
|
||||
|
||||
public function providerACOT()
|
||||
{
|
||||
return require 'data/Calculation/MathTrig/ACOT.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerACOTH
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
* @param mixed $number
|
||||
*/
|
||||
public function testACOTH($expectedResult, $number)
|
||||
{
|
||||
$result = MathTrig::ACOTH($number);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-12);
|
||||
}
|
||||
|
||||
public function providerACOTH()
|
||||
{
|
||||
return require 'data/Calculation/MathTrig/ACOTH.php';
|
||||
}
|
||||
}
|
431
inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Calculation/TextDataTest.php
vendored
Normal file
431
inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Calculation/TextDataTest.php
vendored
Normal file
@ -0,0 +1,431 @@
|
||||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Calculation;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\TextData;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\StringHelper;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class TextDataTest extends TestCase
|
||||
{
|
||||
public function setUp()
|
||||
{
|
||||
Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
|
||||
StringHelper::setDecimalSeparator('.');
|
||||
StringHelper::setThousandsSeparator(',');
|
||||
StringHelper::setCurrencyCode('$');
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
|
||||
StringHelper::setDecimalSeparator('.');
|
||||
StringHelper::setThousandsSeparator(',');
|
||||
StringHelper::setCurrencyCode('$');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerCHAR
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testCHAR($expectedResult, ...$args)
|
||||
{
|
||||
$result = TextData::CHARACTER(...$args);
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
public function providerCHAR()
|
||||
{
|
||||
return require 'data/Calculation/TextData/CHAR.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerCODE
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testCODE($expectedResult, ...$args)
|
||||
{
|
||||
$result = TextData::ASCIICODE(...$args);
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
public function providerCODE()
|
||||
{
|
||||
return require 'data/Calculation/TextData/CODE.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerCONCATENATE
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testCONCATENATE($expectedResult, ...$args)
|
||||
{
|
||||
$result = TextData::CONCATENATE(...$args);
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
public function providerCONCATENATE()
|
||||
{
|
||||
return require 'data/Calculation/TextData/CONCATENATE.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerLEFT
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testLEFT($expectedResult, ...$args)
|
||||
{
|
||||
$result = TextData::LEFT(...$args);
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
public function providerLEFT()
|
||||
{
|
||||
return require 'data/Calculation/TextData/LEFT.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerMID
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testMID($expectedResult, ...$args)
|
||||
{
|
||||
$result = TextData::MID(...$args);
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
public function providerMID()
|
||||
{
|
||||
return require 'data/Calculation/TextData/MID.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerRIGHT
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testRIGHT($expectedResult, ...$args)
|
||||
{
|
||||
$result = TextData::RIGHT(...$args);
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
public function providerRIGHT()
|
||||
{
|
||||
return require 'data/Calculation/TextData/RIGHT.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerLOWER
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testLOWER($expectedResult, ...$args)
|
||||
{
|
||||
$result = TextData::LOWERCASE(...$args);
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
public function providerLOWER()
|
||||
{
|
||||
return require 'data/Calculation/TextData/LOWER.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerUPPER
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testUPPER($expectedResult, ...$args)
|
||||
{
|
||||
$result = TextData::UPPERCASE(...$args);
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
public function providerUPPER()
|
||||
{
|
||||
return require 'data/Calculation/TextData/UPPER.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerPROPER
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testPROPER($expectedResult, ...$args)
|
||||
{
|
||||
$result = TextData::PROPERCASE(...$args);
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
public function providerPROPER()
|
||||
{
|
||||
return require 'data/Calculation/TextData/PROPER.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerLEN
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testLEN($expectedResult, ...$args)
|
||||
{
|
||||
$result = TextData::STRINGLENGTH(...$args);
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
public function providerLEN()
|
||||
{
|
||||
return require 'data/Calculation/TextData/LEN.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerSEARCH
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testSEARCH($expectedResult, ...$args)
|
||||
{
|
||||
$result = TextData::SEARCHINSENSITIVE(...$args);
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
public function providerSEARCH()
|
||||
{
|
||||
return require 'data/Calculation/TextData/SEARCH.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerFIND
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testFIND($expectedResult, ...$args)
|
||||
{
|
||||
$result = TextData::SEARCHSENSITIVE(...$args);
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
public function providerFIND()
|
||||
{
|
||||
return require 'data/Calculation/TextData/FIND.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerREPLACE
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testREPLACE($expectedResult, ...$args)
|
||||
{
|
||||
$result = TextData::REPLACE(...$args);
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
public function providerREPLACE()
|
||||
{
|
||||
return require 'data/Calculation/TextData/REPLACE.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerSUBSTITUTE
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testSUBSTITUTE($expectedResult, ...$args)
|
||||
{
|
||||
$result = TextData::SUBSTITUTE(...$args);
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
public function providerSUBSTITUTE()
|
||||
{
|
||||
return require 'data/Calculation/TextData/SUBSTITUTE.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerTRIM
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testTRIM($expectedResult, ...$args)
|
||||
{
|
||||
$result = TextData::TRIMSPACES(...$args);
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
public function providerTRIM()
|
||||
{
|
||||
return require 'data/Calculation/TextData/TRIM.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerCLEAN
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testCLEAN($expectedResult, ...$args)
|
||||
{
|
||||
$result = TextData::TRIMNONPRINTABLE(...$args);
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
public function providerCLEAN()
|
||||
{
|
||||
return require 'data/Calculation/TextData/CLEAN.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerDOLLAR
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testDOLLAR($expectedResult, ...$args)
|
||||
{
|
||||
$result = TextData::DOLLAR(...$args);
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
public function providerDOLLAR()
|
||||
{
|
||||
return require 'data/Calculation/TextData/DOLLAR.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerFIXED
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testFIXED($expectedResult, ...$args)
|
||||
{
|
||||
$result = TextData::FIXEDFORMAT(...$args);
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
public function providerFIXED()
|
||||
{
|
||||
return require 'data/Calculation/TextData/FIXED.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerT
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testT($expectedResult, ...$args)
|
||||
{
|
||||
$result = TextData::RETURNSTRING(...$args);
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
public function providerT()
|
||||
{
|
||||
return require 'data/Calculation/TextData/T.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerTEXT
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testTEXT($expectedResult, ...$args)
|
||||
{
|
||||
// Enforce decimal and thousands separator values to UK/US, and currency code to USD
|
||||
StringHelper::setDecimalSeparator('.');
|
||||
StringHelper::setThousandsSeparator(',');
|
||||
StringHelper::setCurrencyCode('$');
|
||||
|
||||
$result = TextData::TEXTFORMAT(...$args);
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
public function providerTEXT()
|
||||
{
|
||||
return require 'data/Calculation/TextData/TEXT.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerVALUE
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testVALUE($expectedResult, ...$args)
|
||||
{
|
||||
StringHelper::setDecimalSeparator('.');
|
||||
StringHelper::setThousandsSeparator(' ');
|
||||
StringHelper::setCurrencyCode('$');
|
||||
|
||||
$result = TextData::VALUE(...$args);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
}
|
||||
|
||||
public function providerVALUE()
|
||||
{
|
||||
return require 'data/Calculation/TextData/VALUE.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerEXACT
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
* @param array $args
|
||||
*/
|
||||
public function testEXACT($expectedResult, ...$args)
|
||||
{
|
||||
StringHelper::setDecimalSeparator('.');
|
||||
StringHelper::setThousandsSeparator(' ');
|
||||
StringHelper::setCurrencyCode('$');
|
||||
|
||||
$result = TextData::EXACT(...$args);
|
||||
self::assertSame($expectedResult, $result, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function providerEXACT()
|
||||
{
|
||||
return require 'data/Calculation/TextData/EXACT.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerTEXTJOIN
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
* @param array $args
|
||||
*/
|
||||
public function testTEXTJOIN($expectedResult, array $args)
|
||||
{
|
||||
$result = TextData::TEXTJOIN(...$args);
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
public function providerTEXTJOIN()
|
||||
{
|
||||
return require 'data/Calculation/TextData/TEXTJOIN.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerNUMBERVALUE
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
* @param array $args
|
||||
*/
|
||||
public function testNUMBERVALUE($expectedResult, array $args)
|
||||
{
|
||||
$result = TextData::NUMBERVALUE(...$args);
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
public function providerNUMBERVALUE()
|
||||
{
|
||||
return require 'data/Calculation/TextData/NUMBERVALUE.php';
|
||||
}
|
||||
}
|
79
inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Cell/AdvancedValueBinderTest.php
vendored
Normal file
79
inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Cell/AdvancedValueBinderTest.php
vendored
Normal file
@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Cell;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Cell\AdvancedValueBinder;
|
||||
use PhpOffice\PhpSpreadsheet\Cell\Cell;
|
||||
use PhpOffice\PhpSpreadsheet\Cell\DataType;
|
||||
use PhpOffice\PhpSpreadsheet\Collection\Cells;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\StringHelper;
|
||||
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class AdvancedValueBinderTest extends TestCase
|
||||
{
|
||||
public function provider()
|
||||
{
|
||||
$currencyUSD = NumberFormat::FORMAT_CURRENCY_USD_SIMPLE;
|
||||
$currencyEURO = str_replace('$', '€', NumberFormat::FORMAT_CURRENCY_USD_SIMPLE);
|
||||
|
||||
return [
|
||||
['10%', 0.1, NumberFormat::FORMAT_PERCENTAGE_00, ',', '.', '$'],
|
||||
['$10.11', 10.11, $currencyUSD, ',', '.', '$'],
|
||||
['$1,010.12', 1010.12, $currencyUSD, ',', '.', '$'],
|
||||
['$20,20', 20.2, $currencyUSD, '.', ',', '$'],
|
||||
['$2.020,20', 2020.2, $currencyUSD, '.', ',', '$'],
|
||||
['€2.020,20', 2020.2, $currencyEURO, '.', ',', '€'],
|
||||
['€ 2.020,20', 2020.2, $currencyEURO, '.', ',', '€'],
|
||||
['€2,020.22', 2020.22, $currencyEURO, ',', '.', '€'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provider
|
||||
*
|
||||
* @param mixed $value
|
||||
* @param mixed $valueBinded
|
||||
* @param mixed $format
|
||||
* @param mixed $thousandsSeparator
|
||||
* @param mixed $decimalSeparator
|
||||
* @param mixed $currencyCode
|
||||
*/
|
||||
public function testCurrency($value, $valueBinded, $format, $thousandsSeparator, $decimalSeparator, $currencyCode)
|
||||
{
|
||||
$sheet = $this->getMockBuilder(Worksheet::class)
|
||||
->setMethods(['getStyle', 'getNumberFormat', 'setFormatCode', 'getCellCollection'])
|
||||
->getMock();
|
||||
$cellCollection = $this->getMockBuilder(Cells::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$cellCollection->expects($this->any())
|
||||
->method('getParent')
|
||||
->will($this->returnValue($sheet));
|
||||
|
||||
$sheet->expects($this->once())
|
||||
->method('getStyle')
|
||||
->will($this->returnSelf());
|
||||
$sheet->expects($this->once())
|
||||
->method('getNumberFormat')
|
||||
->will($this->returnSelf());
|
||||
$sheet->expects($this->once())
|
||||
->method('setFormatCode')
|
||||
->with($format)
|
||||
->will($this->returnSelf());
|
||||
$sheet->expects($this->any())
|
||||
->method('getCellCollection')
|
||||
->will($this->returnValue($cellCollection));
|
||||
|
||||
StringHelper::setCurrencyCode($currencyCode);
|
||||
StringHelper::setDecimalSeparator($decimalSeparator);
|
||||
StringHelper::setThousandsSeparator($thousandsSeparator);
|
||||
|
||||
$cell = new Cell(null, DataType::TYPE_STRING, $sheet);
|
||||
|
||||
$binder = new AdvancedValueBinder();
|
||||
$binder->bindValue($cell, $value);
|
||||
self::assertEquals($valueBinded, $cell->getValue());
|
||||
}
|
||||
}
|
367
inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Cell/CoordinateTest.php
vendored
Normal file
367
inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Cell/CoordinateTest.php
vendored
Normal file
@ -0,0 +1,367 @@
|
||||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Cell;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
|
||||
use PhpOffice\PhpSpreadsheet\Exception;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class CoordinateTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider providerColumnString
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
* @param mixed $string
|
||||
*/
|
||||
public function testColumnIndexFromString($expectedResult, $string)
|
||||
{
|
||||
$columnIndex = Coordinate::columnIndexFromString($string);
|
||||
self::assertEquals($expectedResult, $columnIndex);
|
||||
|
||||
$stringBack = Coordinate::stringFromColumnIndex($columnIndex);
|
||||
self::assertEquals($stringBack, $string, 'should be able to get the original input with opposite method');
|
||||
}
|
||||
|
||||
public function providerColumnString()
|
||||
{
|
||||
return require 'data/ColumnString.php';
|
||||
}
|
||||
|
||||
public function testColumnIndexFromStringTooLong()
|
||||
{
|
||||
$cellAddress = 'ABCD';
|
||||
|
||||
try {
|
||||
Coordinate::columnIndexFromString($cellAddress);
|
||||
} catch (\Exception $e) {
|
||||
self::assertInstanceOf(Exception::class, $e);
|
||||
self::assertEquals($e->getMessage(), 'Column string index can not be longer than 3 characters');
|
||||
|
||||
return;
|
||||
}
|
||||
$this->fail('An expected exception has not been raised.');
|
||||
}
|
||||
|
||||
public function testColumnIndexFromStringTooShort()
|
||||
{
|
||||
$cellAddress = '';
|
||||
|
||||
try {
|
||||
Coordinate::columnIndexFromString($cellAddress);
|
||||
} catch (\Exception $e) {
|
||||
self::assertInstanceOf(Exception::class, $e);
|
||||
self::assertEquals($e->getMessage(), 'Column string index can not be empty');
|
||||
|
||||
return;
|
||||
}
|
||||
$this->fail('An expected exception has not been raised.');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerColumnIndex
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
* @param int $columnIndex
|
||||
*/
|
||||
public function testStringFromColumnIndex($expectedResult, $columnIndex)
|
||||
{
|
||||
$string = Coordinate::stringFromColumnIndex($columnIndex);
|
||||
self::assertEquals($expectedResult, $string);
|
||||
|
||||
$columnIndexBack = Coordinate::columnIndexFromString($string);
|
||||
self::assertEquals($columnIndexBack, $columnIndex, 'should be able to get the original input with opposite method');
|
||||
}
|
||||
|
||||
public function providerColumnIndex()
|
||||
{
|
||||
return require 'data/ColumnIndex.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerCoordinates
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testCoordinateFromString($expectedResult, ...$args)
|
||||
{
|
||||
$result = Coordinate::coordinateFromString(...$args);
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
public function providerCoordinates()
|
||||
{
|
||||
return require 'data/CellCoordinates.php';
|
||||
}
|
||||
|
||||
public function testCoordinateFromStringWithRangeAddress()
|
||||
{
|
||||
$cellAddress = 'A1:AI2012';
|
||||
|
||||
try {
|
||||
Coordinate::coordinateFromString($cellAddress);
|
||||
} catch (\Exception $e) {
|
||||
self::assertInstanceOf(Exception::class, $e);
|
||||
self::assertEquals($e->getMessage(), 'Cell coordinate string can not be a range of cells');
|
||||
|
||||
return;
|
||||
}
|
||||
$this->fail('An expected exception has not been raised.');
|
||||
}
|
||||
|
||||
public function testCoordinateFromStringWithEmptyAddress()
|
||||
{
|
||||
$cellAddress = '';
|
||||
|
||||
try {
|
||||
Coordinate::coordinateFromString($cellAddress);
|
||||
} catch (\Exception $e) {
|
||||
self::assertInstanceOf(Exception::class, $e);
|
||||
self::assertEquals($e->getMessage(), 'Cell coordinate can not be zero-length string');
|
||||
|
||||
return;
|
||||
}
|
||||
$this->fail('An expected exception has not been raised.');
|
||||
}
|
||||
|
||||
public function testCoordinateFromStringWithInvalidAddress()
|
||||
{
|
||||
$cellAddress = 'AI';
|
||||
|
||||
try {
|
||||
Coordinate::coordinateFromString($cellAddress);
|
||||
} catch (\Exception $e) {
|
||||
self::assertInstanceOf(Exception::class, $e);
|
||||
self::assertEquals($e->getMessage(), 'Invalid cell coordinate ' . $cellAddress);
|
||||
|
||||
return;
|
||||
}
|
||||
$this->fail('An expected exception has not been raised.');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerAbsoluteCoordinates
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testAbsoluteCoordinateFromString($expectedResult, ...$args)
|
||||
{
|
||||
$result = Coordinate::absoluteCoordinate(...$args);
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
public function providerAbsoluteCoordinates()
|
||||
{
|
||||
return require 'data/CellAbsoluteCoordinate.php';
|
||||
}
|
||||
|
||||
public function testAbsoluteCoordinateFromStringWithRangeAddress()
|
||||
{
|
||||
$cellAddress = 'A1:AI2012';
|
||||
|
||||
try {
|
||||
Coordinate::absoluteCoordinate($cellAddress);
|
||||
} catch (\Exception $e) {
|
||||
self::assertInstanceOf(Exception::class, $e);
|
||||
self::assertEquals($e->getMessage(), 'Cell coordinate string can not be a range of cells');
|
||||
|
||||
return;
|
||||
}
|
||||
$this->fail('An expected exception has not been raised.');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerAbsoluteReferences
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testAbsoluteReferenceFromString($expectedResult, ...$args)
|
||||
{
|
||||
$result = Coordinate::absoluteReference(...$args);
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
public function providerAbsoluteReferences()
|
||||
{
|
||||
return require 'data/CellAbsoluteReference.php';
|
||||
}
|
||||
|
||||
public function testAbsoluteReferenceFromStringWithRangeAddress()
|
||||
{
|
||||
$cellAddress = 'A1:AI2012';
|
||||
|
||||
try {
|
||||
Coordinate::absoluteReference($cellAddress);
|
||||
} catch (\Exception $e) {
|
||||
self::assertInstanceOf(Exception::class, $e);
|
||||
self::assertEquals($e->getMessage(), 'Cell coordinate string can not be a range of cells');
|
||||
|
||||
return;
|
||||
}
|
||||
$this->fail('An expected exception has not been raised.');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerSplitRange
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testSplitRange($expectedResult, ...$args)
|
||||
{
|
||||
$result = Coordinate::splitRange(...$args);
|
||||
foreach ($result as $key => $split) {
|
||||
if (!is_array($expectedResult[$key])) {
|
||||
self::assertEquals($expectedResult[$key], $split[0]);
|
||||
} else {
|
||||
self::assertEquals($expectedResult[$key], $split);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function providerSplitRange()
|
||||
{
|
||||
return require 'data/CellSplitRange.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerBuildRange
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testBuildRange($expectedResult, ...$args)
|
||||
{
|
||||
$result = Coordinate::buildRange(...$args);
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
public function providerBuildRange()
|
||||
{
|
||||
return require 'data/CellBuildRange.php';
|
||||
}
|
||||
|
||||
public function testBuildRangeInvalid()
|
||||
{
|
||||
$this->expectException(\TypeError::class);
|
||||
|
||||
if (PHP_MAJOR_VERSION < 7) {
|
||||
$this->markTestSkipped('Cannot catch type hinting error with PHP 5.6');
|
||||
}
|
||||
|
||||
$cellRange = '';
|
||||
Coordinate::buildRange($cellRange);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerRangeBoundaries
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testRangeBoundaries($expectedResult, ...$args)
|
||||
{
|
||||
$result = Coordinate::rangeBoundaries(...$args);
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
public function providerRangeBoundaries()
|
||||
{
|
||||
return require 'data/CellRangeBoundaries.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerRangeDimension
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testRangeDimension($expectedResult, ...$args)
|
||||
{
|
||||
$result = Coordinate::rangeDimension(...$args);
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
public function providerRangeDimension()
|
||||
{
|
||||
return require 'data/CellRangeDimension.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerGetRangeBoundaries
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testGetRangeBoundaries($expectedResult, ...$args)
|
||||
{
|
||||
$result = Coordinate::getRangeBoundaries(...$args);
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
public function providerGetRangeBoundaries()
|
||||
{
|
||||
return require 'data/CellGetRangeBoundaries.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerExtractAllCellReferencesInRange
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testExtractAllCellReferencesInRange($expectedResult, ...$args)
|
||||
{
|
||||
$result = Coordinate::extractAllCellReferencesInRange(...$args);
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
public function providerExtractAllCellReferencesInRange()
|
||||
{
|
||||
return require 'data/CellExtractAllCellReferencesInRange.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerInvalidRange
|
||||
*
|
||||
* @param string $range
|
||||
*/
|
||||
public function testExtractAllCellReferencesInRangeInvalidRange($range)
|
||||
{
|
||||
$this->expectException(Exception::class);
|
||||
$this->expectExceptionMessage('Invalid range: "' . $range . '"');
|
||||
|
||||
Coordinate::extractAllCellReferencesInRange($range);
|
||||
}
|
||||
|
||||
public function providerInvalidRange()
|
||||
{
|
||||
return [['Z1:A1'], ['A4:A1'], ['B1:A1'], ['AA1:Z1']];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerMergeRangesInCollection
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testMergeRangesInCollection($expectedResult, ...$args)
|
||||
{
|
||||
$result = Coordinate::mergeRangesInCollection(...$args);
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
public function providerMergeRangesInCollection()
|
||||
{
|
||||
return require 'data/CellMergeRangesInCollection.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerCoordinateIsRange
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testCoordinateIsRange($expectedResult, ...$args)
|
||||
{
|
||||
$result = Coordinate::coordinateIsRange(...$args);
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
public function providerCoordinateIsRange()
|
||||
{
|
||||
return require 'data/CoordinateIsRange.php';
|
||||
}
|
||||
}
|
17
inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Cell/DataTypeTest.php
vendored
Normal file
17
inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Cell/DataTypeTest.php
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Cell;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Cell\DataType;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class DataTypeTest extends TestCase
|
||||
{
|
||||
public function testGetErrorCodes()
|
||||
{
|
||||
$result = DataType::getErrorCodes();
|
||||
self::assertInternalType('array', $result);
|
||||
self::assertGreaterThan(0, count($result));
|
||||
self::assertArrayHasKey('#NULL!', $result);
|
||||
}
|
||||
}
|
19
inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Cell/DataValidationTest.php
vendored
Normal file
19
inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Cell/DataValidationTest.php
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Cell;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Cell\DataValidation;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class DataValidationTest extends TestCase
|
||||
{
|
||||
public function testNoValidation()
|
||||
{
|
||||
$dataValidation = new DataValidation();
|
||||
self::assertSame('090624f04837265d79323c4a1b7e89d1', $dataValidation->getHashCode());
|
||||
$dataValidation->setType(DataValidation::TYPE_CUSTOM);
|
||||
|
||||
self::assertSame('778f6c9e0ffcd5eaa7d8e1432d67f919', $dataValidation->getHashCode());
|
||||
self::assertSame('778f6c9e0ffcd5eaa7d8e1432d67f919', $dataValidation->getHashCode(), 'getHashCode() should not have side effect');
|
||||
}
|
||||
}
|
73
inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Cell/DataValidatorTest.php
vendored
Normal file
73
inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Cell/DataValidatorTest.php
vendored
Normal file
@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Cell;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Cell\DataValidation;
|
||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class DataValidatorTest extends TestCase
|
||||
{
|
||||
public function testNoValidation()
|
||||
{
|
||||
$spreadsheet = new Spreadsheet();
|
||||
$sheet = $spreadsheet->getActiveSheet();
|
||||
$testCell = $sheet->getCell('A1');
|
||||
|
||||
self::assertTrue($testCell->hasValidValue(), 'a cell without any validation data is always valid');
|
||||
}
|
||||
|
||||
public function testUnsupportedType()
|
||||
{
|
||||
$spreadsheet = new Spreadsheet();
|
||||
$sheet = $spreadsheet->getActiveSheet();
|
||||
$testCell = $sheet->getCell('A1');
|
||||
|
||||
$validation = $testCell->getDataValidation();
|
||||
$validation->setType(DataValidation::TYPE_CUSTOM);
|
||||
$validation->setAllowBlank(true);
|
||||
|
||||
self::assertFalse($testCell->hasValidValue(), 'cannot assert that value is valid when the validation type is not supported');
|
||||
}
|
||||
|
||||
public function testList()
|
||||
{
|
||||
$spreadsheet = new Spreadsheet();
|
||||
$sheet = $spreadsheet->getActiveSheet();
|
||||
$testCell = $sheet->getCell('A1');
|
||||
|
||||
$validation = $testCell->getDataValidation();
|
||||
$validation->setType(DataValidation::TYPE_LIST);
|
||||
|
||||
// blank value
|
||||
$testCell->setValue('');
|
||||
$validation->setAllowBlank(true);
|
||||
self::assertTrue($testCell->hasValidValue(), 'cell can be empty');
|
||||
$validation->setAllowBlank(false);
|
||||
self::assertFalse($testCell->hasValidValue(), 'cell can not be empty');
|
||||
|
||||
// inline list
|
||||
$validation->setFormula1('"yes,no"');
|
||||
$testCell->setValue('foo');
|
||||
self::assertFalse($testCell->hasValidValue(), "cell value ('foo') is not allowed");
|
||||
$testCell->setValue('yes');
|
||||
self::assertTrue($testCell->hasValidValue(), "cell value ('yes') has to be allowed");
|
||||
|
||||
// list from cells
|
||||
$sheet->getCell('B1')->setValue(5);
|
||||
$sheet->getCell('B2')->setValue(6);
|
||||
$sheet->getCell('B3')->setValue(7);
|
||||
$testCell = $sheet->getCell('A1'); // redefine $testCell, because it has broken coordinates after using other cells
|
||||
$validation->setFormula1('B1:B3');
|
||||
$testCell->setValue('10');
|
||||
self::assertFalse($testCell->hasValidValue(), "cell value ('10') is not allowed");
|
||||
$testCell = $sheet->getCell('A1'); // redefine $testCell, because it has broken coordinates after using other cells
|
||||
$testCell->setValue('5');
|
||||
self::assertTrue($testCell->hasValidValue(), "cell value ('5') has to be allowed");
|
||||
|
||||
$testCell = $sheet->getCell('A1'); // redefine $testCell, because it has broken coordinates after using other cells
|
||||
$validation->setFormula1('broken : cell : coordinates');
|
||||
|
||||
self::assertFalse($testCell->hasValidValue(), 'invalid formula should not throw exceptions');
|
||||
}
|
||||
}
|
86
inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Cell/DefaultValueBinderTest.php
vendored
Normal file
86
inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Cell/DefaultValueBinderTest.php
vendored
Normal file
@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Cell;
|
||||
|
||||
use DateTime;
|
||||
use DateTimeImmutable;
|
||||
use PhpOffice\PhpSpreadsheet\Cell\Cell;
|
||||
use PhpOffice\PhpSpreadsheet\Cell\DataType;
|
||||
use PhpOffice\PhpSpreadsheet\Cell\DefaultValueBinder;
|
||||
use PhpOffice\PhpSpreadsheet\RichText\RichText;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class DefaultValueBinderTest extends TestCase
|
||||
{
|
||||
private $cellStub;
|
||||
|
||||
private function createCellStub()
|
||||
{
|
||||
// Create a stub for the Cell class.
|
||||
$this->cellStub = $this->getMockBuilder(Cell::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
// Configure the stub.
|
||||
$this->cellStub->expects($this->any())
|
||||
->method('setValueExplicit')
|
||||
->will($this->returnValue(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider binderProvider
|
||||
*
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function testBindValue($value)
|
||||
{
|
||||
$this->createCellStub();
|
||||
$binder = new DefaultValueBinder();
|
||||
$result = $binder->bindValue($this->cellStub, $value);
|
||||
self::assertTrue($result);
|
||||
}
|
||||
|
||||
public function binderProvider()
|
||||
{
|
||||
return [
|
||||
[null],
|
||||
[''],
|
||||
['ABC'],
|
||||
['=SUM(A1:B2)'],
|
||||
[true],
|
||||
[false],
|
||||
[123],
|
||||
[-123.456],
|
||||
['123'],
|
||||
['-123.456'],
|
||||
['#REF!'],
|
||||
[new DateTime()],
|
||||
[new DateTimeImmutable()],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerDataTypeForValue
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
*/
|
||||
public function testDataTypeForValue($expectedResult, ...$args)
|
||||
{
|
||||
$result = DefaultValueBinder::dataTypeForValue(...$args);
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
public function providerDataTypeForValue()
|
||||
{
|
||||
return require 'data/Cell/DefaultValueBinder.php';
|
||||
}
|
||||
|
||||
public function testDataTypeForRichTextObject()
|
||||
{
|
||||
$objRichText = new RichText();
|
||||
$objRichText->createText('Hello World');
|
||||
|
||||
$expectedResult = DataType::TYPE_INLINE;
|
||||
$result = DefaultValueBinder::dataTypeForValue($objRichText);
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
}
|
81
inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Cell/HyperlinkTest.php
vendored
Normal file
81
inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Cell/HyperlinkTest.php
vendored
Normal file
@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Cell;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Cell\Hyperlink;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class HyperlinkTest extends TestCase
|
||||
{
|
||||
public function testGetUrl()
|
||||
{
|
||||
$urlValue = 'https://www.example.com';
|
||||
|
||||
$testInstance = new Hyperlink($urlValue);
|
||||
|
||||
$result = $testInstance->getUrl();
|
||||
self::assertEquals($urlValue, $result);
|
||||
}
|
||||
|
||||
public function testSetUrl()
|
||||
{
|
||||
$initialUrlValue = 'https://www.example.com';
|
||||
$newUrlValue = 'http://github.com/PHPOffice/PhpSpreadsheet';
|
||||
|
||||
$testInstance = new Hyperlink($initialUrlValue);
|
||||
$result = $testInstance->setUrl($newUrlValue);
|
||||
self::assertInstanceOf(Hyperlink::class, $result);
|
||||
|
||||
$result = $testInstance->getUrl();
|
||||
self::assertEquals($newUrlValue, $result);
|
||||
}
|
||||
|
||||
public function testGetTooltip()
|
||||
{
|
||||
$tooltipValue = 'PhpSpreadsheet Web Site';
|
||||
|
||||
$testInstance = new Hyperlink(null, $tooltipValue);
|
||||
|
||||
$result = $testInstance->getTooltip();
|
||||
self::assertEquals($tooltipValue, $result);
|
||||
}
|
||||
|
||||
public function testSetTooltip()
|
||||
{
|
||||
$initialTooltipValue = 'PhpSpreadsheet Web Site';
|
||||
$newTooltipValue = 'PhpSpreadsheet Repository on Github';
|
||||
|
||||
$testInstance = new Hyperlink(null, $initialTooltipValue);
|
||||
$result = $testInstance->setTooltip($newTooltipValue);
|
||||
self::assertInstanceOf(Hyperlink::class, $result);
|
||||
|
||||
$result = $testInstance->getTooltip();
|
||||
self::assertEquals($newTooltipValue, $result);
|
||||
}
|
||||
|
||||
public function testIsInternal()
|
||||
{
|
||||
$initialUrlValue = 'https://www.example.com';
|
||||
$newUrlValue = 'sheet://Worksheet1!A1';
|
||||
|
||||
$testInstance = new Hyperlink($initialUrlValue);
|
||||
$result = $testInstance->isInternal();
|
||||
self::assertFalse($result);
|
||||
|
||||
$testInstance->setUrl($newUrlValue);
|
||||
$result = $testInstance->isInternal();
|
||||
self::assertTrue($result);
|
||||
}
|
||||
|
||||
public function testGetHashCode()
|
||||
{
|
||||
$urlValue = 'https://www.example.com';
|
||||
$tooltipValue = 'PhpSpreadsheet Web Site';
|
||||
$initialExpectedHash = '3a8d5a682dba27276dce538c39402437';
|
||||
|
||||
$testInstance = new Hyperlink($urlValue, $tooltipValue);
|
||||
|
||||
$result = $testInstance->getHashCode();
|
||||
self::assertEquals($initialExpectedHash, $result);
|
||||
}
|
||||
}
|
62
inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Chart/DataSeriesValuesTest.php
vendored
Normal file
62
inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Chart/DataSeriesValuesTest.php
vendored
Normal file
@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Chart;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Chart\DataSeriesValues;
|
||||
use PhpOffice\PhpSpreadsheet\Exception;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class DataSeriesValuesTest extends TestCase
|
||||
{
|
||||
public function testSetDataType()
|
||||
{
|
||||
$dataTypeValues = [
|
||||
'Number',
|
||||
'String',
|
||||
];
|
||||
|
||||
$testInstance = new DataSeriesValues();
|
||||
|
||||
foreach ($dataTypeValues as $dataTypeValue) {
|
||||
$result = $testInstance->setDataType($dataTypeValue);
|
||||
self::assertInstanceOf(DataSeriesValues::class, $result);
|
||||
}
|
||||
}
|
||||
|
||||
public function testSetInvalidDataTypeThrowsException()
|
||||
{
|
||||
$testInstance = new DataSeriesValues();
|
||||
|
||||
try {
|
||||
$testInstance->setDataType('BOOLEAN');
|
||||
} catch (Exception $e) {
|
||||
self::assertEquals($e->getMessage(), 'Invalid datatype for chart data series values');
|
||||
|
||||
return;
|
||||
}
|
||||
$this->fail('An expected exception has not been raised.');
|
||||
}
|
||||
|
||||
public function testGetDataType()
|
||||
{
|
||||
$dataTypeValue = 'String';
|
||||
|
||||
$testInstance = new DataSeriesValues();
|
||||
$testInstance->setDataType($dataTypeValue);
|
||||
|
||||
$result = $testInstance->getDataType();
|
||||
self::assertEquals($dataTypeValue, $result);
|
||||
}
|
||||
|
||||
public function testGetLineWidth()
|
||||
{
|
||||
$testInstance = new DataSeriesValues();
|
||||
self::assertEquals(12700, $testInstance->getLineWidth(), 'should have default');
|
||||
|
||||
$testInstance->setLineWidth(40000);
|
||||
self::assertEquals(40000, $testInstance->getLineWidth());
|
||||
|
||||
$testInstance->setLineWidth(1);
|
||||
self::assertEquals(12700, $testInstance->getLineWidth(), 'should enforce minimum width');
|
||||
}
|
||||
}
|
30
inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Chart/LayoutTest.php
vendored
Normal file
30
inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Chart/LayoutTest.php
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Chart;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Chart\Layout;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class LayoutTest extends TestCase
|
||||
{
|
||||
public function testSetLayoutTarget()
|
||||
{
|
||||
$LayoutTargetValue = 'String';
|
||||
|
||||
$testInstance = new Layout();
|
||||
|
||||
$result = $testInstance->setLayoutTarget($LayoutTargetValue);
|
||||
self::assertInstanceOf(Layout::class, $result);
|
||||
}
|
||||
|
||||
public function testGetLayoutTarget()
|
||||
{
|
||||
$LayoutTargetValue = 'String';
|
||||
|
||||
$testInstance = new Layout();
|
||||
$testInstance->setLayoutTarget($LayoutTargetValue);
|
||||
|
||||
$result = $testInstance->getLayoutTarget();
|
||||
self::assertEquals($LayoutTargetValue, $result);
|
||||
}
|
||||
}
|
127
inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Chart/LegendTest.php
vendored
Normal file
127
inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Chart/LegendTest.php
vendored
Normal file
@ -0,0 +1,127 @@
|
||||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Chart;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Chart\Legend;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class LegendTest extends TestCase
|
||||
{
|
||||
public function testSetPosition()
|
||||
{
|
||||
$positionValues = [
|
||||
Legend::POSITION_RIGHT,
|
||||
Legend::POSITION_LEFT,
|
||||
Legend::POSITION_TOP,
|
||||
Legend::POSITION_BOTTOM,
|
||||
Legend::POSITION_TOPRIGHT,
|
||||
];
|
||||
|
||||
$testInstance = new Legend();
|
||||
|
||||
foreach ($positionValues as $positionValue) {
|
||||
$result = $testInstance->setPosition($positionValue);
|
||||
self::assertTrue($result);
|
||||
}
|
||||
}
|
||||
|
||||
public function testSetInvalidPositionReturnsFalse()
|
||||
{
|
||||
$testInstance = new Legend();
|
||||
|
||||
$result = $testInstance->setPosition('BottomLeft');
|
||||
self::assertFalse($result);
|
||||
// Ensure that value is unchanged
|
||||
$result = $testInstance->getPosition();
|
||||
self::assertEquals(Legend::POSITION_RIGHT, $result);
|
||||
}
|
||||
|
||||
public function testGetPosition()
|
||||
{
|
||||
$PositionValue = Legend::POSITION_BOTTOM;
|
||||
|
||||
$testInstance = new Legend();
|
||||
$testInstance->setPosition($PositionValue);
|
||||
|
||||
$result = $testInstance->getPosition();
|
||||
self::assertEquals($PositionValue, $result);
|
||||
}
|
||||
|
||||
public function testSetPositionXL()
|
||||
{
|
||||
$positionValues = [
|
||||
Legend::XL_LEGEND_POSITION_BOTTOM,
|
||||
Legend::XL_LEGEND_POSITION_CORNER,
|
||||
Legend::XL_LEGEND_POSITION_CUSTOM,
|
||||
Legend::XL_LEGEND_POSITION_LEFT,
|
||||
Legend::XL_LEGEND_POSITION_RIGHT,
|
||||
Legend::XL_LEGEND_POSITION_TOP,
|
||||
];
|
||||
|
||||
$testInstance = new Legend();
|
||||
|
||||
foreach ($positionValues as $positionValue) {
|
||||
$result = $testInstance->setPositionXL($positionValue);
|
||||
self::assertTrue($result);
|
||||
}
|
||||
}
|
||||
|
||||
public function testSetInvalidXLPositionReturnsFalse()
|
||||
{
|
||||
$testInstance = new Legend();
|
||||
|
||||
$result = $testInstance->setPositionXL(999);
|
||||
self::assertFalse($result);
|
||||
// Ensure that value is unchanged
|
||||
$result = $testInstance->getPositionXL();
|
||||
self::assertEquals(Legend::XL_LEGEND_POSITION_RIGHT, $result);
|
||||
}
|
||||
|
||||
public function testGetPositionXL()
|
||||
{
|
||||
$PositionValue = Legend::XL_LEGEND_POSITION_CORNER;
|
||||
|
||||
$testInstance = new Legend();
|
||||
$testInstance->setPositionXL($PositionValue);
|
||||
|
||||
$result = $testInstance->getPositionXL();
|
||||
self::assertEquals($PositionValue, $result);
|
||||
}
|
||||
|
||||
public function testSetOverlay()
|
||||
{
|
||||
$overlayValues = [
|
||||
true,
|
||||
false,
|
||||
];
|
||||
|
||||
$testInstance = new Legend();
|
||||
|
||||
foreach ($overlayValues as $overlayValue) {
|
||||
$result = $testInstance->setOverlay($overlayValue);
|
||||
self::assertTrue($result);
|
||||
}
|
||||
}
|
||||
|
||||
public function testSetInvalidOverlayReturnsFalse()
|
||||
{
|
||||
$testInstance = new Legend();
|
||||
|
||||
$result = $testInstance->setOverlay('INVALID');
|
||||
self::assertFalse($result);
|
||||
|
||||
$result = $testInstance->getOverlay();
|
||||
self::assertFalse($result);
|
||||
}
|
||||
|
||||
public function testGetOverlay()
|
||||
{
|
||||
$OverlayValue = true;
|
||||
|
||||
$testInstance = new Legend();
|
||||
$testInstance->setOverlay($OverlayValue);
|
||||
|
||||
$result = $testInstance->getOverlay();
|
||||
self::assertEquals($OverlayValue, $result);
|
||||
}
|
||||
}
|
117
inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Collection/CellsTest.php
vendored
Normal file
117
inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Collection/CellsTest.php
vendored
Normal file
@ -0,0 +1,117 @@
|
||||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Collection;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Cell\Cell;
|
||||
use PhpOffice\PhpSpreadsheet\Collection\Cells;
|
||||
use PhpOffice\PhpSpreadsheet\Collection\Memory;
|
||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class CellsTest extends TestCase
|
||||
{
|
||||
public function testCollectionCell()
|
||||
{
|
||||
$spreadsheet = new Spreadsheet();
|
||||
$sheet = $spreadsheet->getActiveSheet();
|
||||
$collection = $sheet->getCellCollection();
|
||||
|
||||
// Assert empty state
|
||||
self::assertEquals([], $collection->getCoordinates(), 'cell list should be empty');
|
||||
self::assertEquals([], $collection->getSortedCoordinates(), 'sorted cell list should be empty');
|
||||
self::assertNull($collection->get('B2'), 'getting non-existing cell must return null');
|
||||
self::assertFalse($collection->has('B2'), 'non-existing cell should be non-existent');
|
||||
|
||||
// Add one cell
|
||||
$cell1 = $sheet->getCell('B2');
|
||||
self::assertSame($cell1, $collection->add('B2', $cell1), 'adding a cell should return the cell');
|
||||
|
||||
// Assert cell presence
|
||||
self::assertEquals(['B2'], $collection->getCoordinates(), 'cell list should contains the cell');
|
||||
self::assertEquals(['B2'], $collection->getSortedCoordinates(), 'sorted cell list contains the cell');
|
||||
self::assertSame($cell1, $collection->get('B2'), 'should get exact same object');
|
||||
self::assertTrue($collection->has('B2'), 'cell should exists');
|
||||
|
||||
// Add a second cell
|
||||
$cell2 = $sheet->getCell('A1');
|
||||
self::assertSame($cell2, $collection->add('A1', $cell2), 'adding a second cell should return the cell');
|
||||
self::assertEquals(['B2', 'A1'], $collection->getCoordinates(), 'cell list should contains the cell');
|
||||
self::assertEquals(['A1', 'B2'], $collection->getSortedCoordinates(), 'sorted cell list contains the cell');
|
||||
|
||||
// Assert collection copy
|
||||
$sheet2 = $spreadsheet->createSheet();
|
||||
$collection2 = $collection->cloneCellCollection($sheet2);
|
||||
self::assertTrue($collection2->has('A1'));
|
||||
$copiedCell2 = $collection2->get('A1');
|
||||
self::assertNotSame($cell2, $copiedCell2, 'copied cell should not be the same object any more');
|
||||
self::assertSame($collection2, $copiedCell2->getParent(), 'copied cell should be owned by the copied collection');
|
||||
self::assertSame('A1', $copiedCell2->getCoordinate(), 'copied cell should keep attributes');
|
||||
|
||||
// Assert deletion
|
||||
$collection->delete('B2');
|
||||
self::assertFalse($collection->has('B2'), 'cell should have been deleted');
|
||||
self::assertEquals(['A1'], $collection->getCoordinates(), 'cell list should contains the cell');
|
||||
|
||||
// Assert update
|
||||
$cell2 = $sheet->getCell('A1');
|
||||
self::assertSame($sheet->getCellCollection(), $collection);
|
||||
self::assertSame($cell2, $collection->update($cell2), 'should update existing cell');
|
||||
|
||||
$cell3 = $sheet->getCell('C3');
|
||||
self::assertSame($cell3, $collection->update($cell3), 'should silently add non-existing cell');
|
||||
self::assertEquals(['A1', 'C3'], $collection->getCoordinates(), 'cell list should contains the cell');
|
||||
}
|
||||
|
||||
public function testCacheLastCell()
|
||||
{
|
||||
$workbook = new Spreadsheet();
|
||||
$cells = ['A1', 'A2'];
|
||||
$sheet = $workbook->getActiveSheet();
|
||||
$sheet->setCellValue('A1', 1);
|
||||
$sheet->setCellValue('A2', 2);
|
||||
self::assertEquals($cells, $sheet->getCoordinates(), 'list should include last added cell');
|
||||
}
|
||||
|
||||
public function testCanGetCellAfterAnotherIsDeleted()
|
||||
{
|
||||
$workbook = new Spreadsheet();
|
||||
$sheet = $workbook->getActiveSheet();
|
||||
$collection = $sheet->getCellCollection();
|
||||
$sheet->setCellValue('A1', 1);
|
||||
$sheet->setCellValue('A2', 1);
|
||||
$collection->delete('A1');
|
||||
$sheet->setCellValue('A3', 1);
|
||||
self::assertNotNull($collection->get('A2'), 'should be able to get back the cell even when another cell was deleted while this one was the current one');
|
||||
}
|
||||
|
||||
public function testThrowsWhenCellCannotBeRetrievedFromCache()
|
||||
{
|
||||
$this->expectException(\PhpOffice\PhpSpreadsheet\Exception::class);
|
||||
|
||||
$collection = $this->getMockBuilder(Cells::class)
|
||||
->setConstructorArgs([new Worksheet(), new Memory()])
|
||||
->setMethods(['has'])
|
||||
->getMock();
|
||||
|
||||
$collection->method('has')
|
||||
->willReturn(true);
|
||||
|
||||
$collection->get('A2');
|
||||
}
|
||||
|
||||
public function testThrowsWhenCellCannotBeStoredInCache()
|
||||
{
|
||||
$this->expectException(\PhpOffice\PhpSpreadsheet\Exception::class);
|
||||
|
||||
$cache = $this->createMock(Memory::class);
|
||||
$cell = $this->createMock(Cell::class);
|
||||
$cache->method('set')
|
||||
->willReturn(false);
|
||||
|
||||
$collection = new Cells(new Worksheet(), $cache);
|
||||
|
||||
$collection->add('A1', $cell);
|
||||
$collection->add('A2', $cell);
|
||||
}
|
||||
}
|
82
inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Custom/ComplexAssert.php
vendored
Normal file
82
inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Custom/ComplexAssert.php
vendored
Normal file
@ -0,0 +1,82 @@
|
||||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Custom;
|
||||
|
||||
use Complex\Complex;
|
||||
|
||||
class ComplexAssert
|
||||
{
|
||||
private $errorMessage = '';
|
||||
|
||||
private function testExpectedExceptions($expected, $actual)
|
||||
{
|
||||
// Expecting an error, so we do a straight string comparison
|
||||
if ($expected === $actual) {
|
||||
return true;
|
||||
} elseif ($expected === INF && $actual === 'INF') {
|
||||
return true;
|
||||
}
|
||||
$this->errorMessage = 'Expected Error: ' . $actual . ' !== ' . $expected;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function adjustDelta($expected, $actual, $delta)
|
||||
{
|
||||
$adjustedDelta = $delta;
|
||||
|
||||
if (abs($actual) > 10 && abs($expected) > 10) {
|
||||
$variance = floor(log10(abs($expected)));
|
||||
$adjustedDelta *= pow(10, $variance);
|
||||
}
|
||||
|
||||
return $adjustedDelta > 1.0 ? 1.0 : $adjustedDelta;
|
||||
}
|
||||
|
||||
public function assertComplexEquals($expected, $actual, $delta = 0)
|
||||
{
|
||||
if ($expected === INF || $expected[0] === '#') {
|
||||
return $this->testExpectedExceptions($expected, $actual);
|
||||
}
|
||||
|
||||
$expectedComplex = new Complex($expected);
|
||||
$actualComplex = new Complex($actual);
|
||||
|
||||
if (!is_numeric($actualComplex->getReal()) || !is_numeric($expectedComplex->getReal())) {
|
||||
if ($actualComplex->getReal() !== $expectedComplex->getReal()) {
|
||||
$this->errorMessage = 'Mismatched String: ' . $actualComplex->getReal() . ' !== ' . $expectedComplex->getReal();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
$adjustedDelta = $this->adjustDelta($expectedComplex->getReal(), $actualComplex->getReal(), $delta);
|
||||
if (abs($actualComplex->getReal() - $expectedComplex->getReal()) > $adjustedDelta) {
|
||||
$this->errorMessage = 'Mismatched Real part: ' . $actualComplex->getReal() . ' != ' . $expectedComplex->getReal();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$adjustedDelta = $this->adjustDelta($expectedComplex->getImaginary(), $actualComplex->getImaginary(), $delta);
|
||||
if (abs($actualComplex->getImaginary() - $expectedComplex->getImaginary()) > $adjustedDelta) {
|
||||
$this->errorMessage = 'Mismatched Imaginary part: ' . $actualComplex->getImaginary() . ' != ' . $expectedComplex->getImaginary();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($actualComplex->getSuffix() !== $actualComplex->getSuffix()) {
|
||||
$this->errorMessage = 'Mismatched Suffix: ' . $actualComplex->getSuffix() . ' != ' . $expectedComplex->getSuffix();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getErrorMessage()
|
||||
{
|
||||
return $this->errorMessage;
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user