Merge branch 'master' into mpdfcache
This commit is contained in:
commit
a5b7b3074a
|
|
@ -124,6 +124,37 @@ jobs:
|
|||
- name: Code style with PHP_CodeSniffer
|
||||
run: ./vendor/bin/phpcs -q --report=checkstyle | cs2pr
|
||||
|
||||
versions:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Setup PHP, with composer and extensions
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: 7.4
|
||||
extensions: ctype, dom, gd, iconv, fileinfo, libxml, mbstring, simplexml, xml, xmlreader, xmlwriter, zip, zlib
|
||||
coverage: none
|
||||
tools: cs2pr
|
||||
|
||||
- name: Get composer cache directory
|
||||
id: composer-cache
|
||||
run: echo "::set-output name=dir::$(composer config cache-files-dir)"
|
||||
|
||||
- name: Cache composer dependencies
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ${{ steps.composer-cache.outputs.dir }}
|
||||
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
|
||||
restore-keys: ${{ runner.os }}-composer-
|
||||
|
||||
- name: Install dependencies
|
||||
run: composer install --no-progress --prefer-dist --optimize-autoloader
|
||||
|
||||
- name: Code Version Compatibility check with PHP_CodeSniffer
|
||||
run: ./vendor/bin/phpcs -q --report-width=200 --report=summary,full src/ --standard=PHPCompatibility --runtime-set testVersion 7.2-
|
||||
|
||||
phpstan:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
|
|
|
|||
10
CHANGELOG.md
10
CHANGELOG.md
|
|
@ -9,8 +9,13 @@ and this project adheres to [Semantic Versioning](https://semver.org).
|
|||
|
||||
### Added
|
||||
|
||||
- Implemented basic AutoFiltering for Ods Reader and Writer [PR #2053](https://github.com/PHPOffice/PhpSpreadsheet/pull/2053)
|
||||
- Implemented basic AutoFiltering for Gnumeric Reader [PR #2055](https://github.com/PHPOffice/PhpSpreadsheet/pull/2055)
|
||||
- Improved support for Row and Column ranges in formulae [Issue #1755](https://github.com/PHPOffice/PhpSpreadsheet/issues/1755) [PR #2028](https://github.com/PHPOffice/PhpSpreadsheet/pull/2028)
|
||||
- Implemented URLENCODE() Web Function
|
||||
- Implemented the CHITEST(), CHISQ.DIST() and CHISQ.INV() and equivalent Statistical functions, for both left- and right-tailed distributions.
|
||||
- Support for ActiveSheet and SelectedCells in the ODS Reader and Writer. [PR #1908](https://github.com/PHPOffice/PhpSpreadsheet/pull/1908)
|
||||
- Support for notContainsText Conditional Style in xlsx [Issue #984](https://github.com/PHPOffice/PhpSpreadsheet/issues/984)
|
||||
|
||||
### Changed
|
||||
|
||||
|
|
@ -18,14 +23,15 @@ and this project adheres to [Semantic Versioning](https://semver.org).
|
|||
|
||||
### Deprecated
|
||||
|
||||
- Nothing.
|
||||
- All Excel Function implementations in `Calculation\Database`, `Calculation\DateTime`, `Calculation\Engineering`, `Calculation\Financial`, `Calculation\Logical`, `Calculation\LookupRef`, `Calculation\MathTrig`, `Calculation\Statistical`, `Calculation\TextData` and `Calculation\Web` have been moved to dedicated classes for individual functions or groups of related functions. See the docblocks against all the deprecated methods for details of the new methods to call instead. At some point, these old classes will be deleted.
|
||||
|
||||
### Removed
|
||||
|
||||
- Nothing.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Correctly handle absolute A1 references when converting to R1C1 format [PR #2060](https://github.com/PHPOffice/PhpSpreadsheet/pull/2060)
|
||||
- Correct default fill style for conditional without a pattern defined [Issue #2035](https://github.com/PHPOffice/PhpSpreadsheet/issues/2035) [PR #2050](https://github.com/PHPOffice/PhpSpreadsheet/pull/2050)
|
||||
- Fixed issue where array key check for existince before accessing arrays in Xlsx.php. [PR #1970](https://github.com/PHPOffice/PhpSpreadsheet/pull/1970)
|
||||
- Fixed issue with quoted strings in number format mask rendered with toFormattedString() [Issue 1972#](https://github.com/PHPOffice/PhpSpreadsheet/issues/1972) [PR #1978](https://github.com/PHPOffice/PhpSpreadsheet/pull/1978)
|
||||
- Fixed issue with percentage formats in number format mask rendered with toFormattedString() [Issue 1929#](https://github.com/PHPOffice/PhpSpreadsheet/issues/1929) [PR #1928](https://github.com/PHPOffice/PhpSpreadsheet/pull/1928)
|
||||
|
|
|
|||
|
|
@ -53,7 +53,6 @@
|
|||
},
|
||||
"require": {
|
||||
"php": "^7.2 || ^8.0",
|
||||
"ext-simplexml": "*",
|
||||
"ext-ctype": "*",
|
||||
"ext-dom": "*",
|
||||
"ext-fileinfo": "*",
|
||||
|
|
@ -61,6 +60,7 @@
|
|||
"ext-iconv": "*",
|
||||
"ext-libxml": "*",
|
||||
"ext-mbstring": "*",
|
||||
"ext-simplexml": "*",
|
||||
"ext-xml": "*",
|
||||
"ext-xmlreader": "*",
|
||||
"ext-xmlwriter": "*",
|
||||
|
|
@ -75,6 +75,7 @@
|
|||
"psr/simple-cache": "^1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"dealerdirect/phpcodesniffer-composer-installer": "dev-master",
|
||||
"dompdf/dompdf": "^1.0",
|
||||
"friendsofphp/php-cs-fixer": "^2.18",
|
||||
"jpgraph/jpgraph": "^4.0",
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "3be2673a6367d296c616bf9c34b77953",
|
||||
"content-hash": "9158fcde13425499acaf0da201637737",
|
||||
"packages": [
|
||||
{
|
||||
"name": "ezyang/htmlpurifier",
|
||||
|
|
@ -802,6 +802,77 @@
|
|||
],
|
||||
"time": "2021-03-25T17:01:18+00:00"
|
||||
},
|
||||
{
|
||||
"name": "dealerdirect/phpcodesniffer-composer-installer",
|
||||
"version": "dev-master",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer.git",
|
||||
"reference": "c960cf4629fab7155caca18c038ca7257b7595e3"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Dealerdirect/phpcodesniffer-composer-installer/zipball/c960cf4629fab7155caca18c038ca7257b7595e3",
|
||||
"reference": "c960cf4629fab7155caca18c038ca7257b7595e3",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"composer-plugin-api": "^1.0 || ^2.0",
|
||||
"php": ">=5.3",
|
||||
"squizlabs/php_codesniffer": "^2.0 || ^3.0 || ^4.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"composer/composer": "*",
|
||||
"enlightn/security-checker": "^1.2",
|
||||
"phpcompatibility/php-compatibility": "^9.0"
|
||||
},
|
||||
"default-branch": true,
|
||||
"type": "composer-plugin",
|
||||
"extra": {
|
||||
"class": "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Franck Nijhof",
|
||||
"email": "franck.nijhof@dealerdirect.com",
|
||||
"homepage": "http://www.frenck.nl",
|
||||
"role": "Developer / IT Manager"
|
||||
}
|
||||
],
|
||||
"description": "PHP_CodeSniffer Standards Composer Installer Plugin",
|
||||
"homepage": "http://www.dealerdirect.com",
|
||||
"keywords": [
|
||||
"PHPCodeSniffer",
|
||||
"PHP_CodeSniffer",
|
||||
"code quality",
|
||||
"codesniffer",
|
||||
"composer",
|
||||
"installer",
|
||||
"phpcs",
|
||||
"plugin",
|
||||
"qa",
|
||||
"quality",
|
||||
"standard",
|
||||
"standards",
|
||||
"style guide",
|
||||
"stylecheck",
|
||||
"tests"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/dealerdirect/phpcodesniffer-composer-installer/issues",
|
||||
"source": "https://github.com/dealerdirect/phpcodesniffer-composer-installer"
|
||||
},
|
||||
"time": "2021-03-14T13:49:41+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/annotations",
|
||||
"version": "1.12.1",
|
||||
|
|
@ -5065,12 +5136,13 @@
|
|||
],
|
||||
"aliases": [],
|
||||
"minimum-stability": "stable",
|
||||
"stability-flags": [],
|
||||
"stability-flags": {
|
||||
"dealerdirect/phpcodesniffer-composer-installer": 20
|
||||
},
|
||||
"prefer-stable": false,
|
||||
"prefer-lowest": false,
|
||||
"platform": {
|
||||
"php": "^7.2 || ^8.0",
|
||||
"ext-simplexml": "*",
|
||||
"ext-ctype": "*",
|
||||
"ext-dom": "*",
|
||||
"ext-fileinfo": "*",
|
||||
|
|
@ -5078,6 +5150,7 @@
|
|||
"ext-iconv": "*",
|
||||
"ext-libxml": "*",
|
||||
"ext-mbstring": "*",
|
||||
"ext-simplexml": "*",
|
||||
"ext-xml": "*",
|
||||
"ext-xmlreader": "*",
|
||||
"ext-xmlwriter": "*",
|
||||
|
|
|
|||
|
|
@ -1220,13 +1220,13 @@
|
|||
</tr>
|
||||
<tr>
|
||||
<td style="padding-left: 1em;">Merged Cells</td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td style="text-align: center; color: green;">✔</td>
|
||||
<td style="text-align: center; color: green;">✔</td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td style="text-align: center; color: green;">✔</td>
|
||||
<td style="text-align: center; color: green;">✔</td>
|
||||
<td>N/A</td>
|
||||
<td>N/A</td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
|
|
@ -1313,13 +1313,13 @@
|
|||
<td style="text-align: center; color: orange;">●</td>
|
||||
<td style="text-align: center; color: orange;">●</td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td style="text-align: center; color: orange;">●</td>
|
||||
<td style="text-align: center; color: orange;">●</td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td style="text-align: center; color: orange;">●</td>
|
||||
<td style="text-align: center; color: orange;">●</td>
|
||||
<td></td>
|
||||
<td style="text-align: center; color: orange;">●</td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
|
|
|
|||
|
|
@ -340,141 +340,6 @@ parameters:
|
|||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/Database/DatabaseAbstract.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\DateTime\\:\\:NETWORKDAYS\\(\\) has parameter \\$dateArgs with no typehint specified\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/DateTime.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\DateTime\\:\\:WORKDAY\\(\\) has parameter \\$dateArgs with no typehint specified\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/DateTime.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#3 \\$subject of function str_replace expects array\\|string, string\\|null given\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/DateTimeExcel/DateValue.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$haystack of function strpos expects string, float\\|int\\|string given\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/DateTimeExcel/DateValue.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$PHPDateArray of static method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\DateTimeExcel\\\\DateValue\\:\\:finalResults\\(\\) expects array\\|false, array\\|bool given\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/DateTimeExcel/DateValue.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$testVal1 of static method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\DateTimeExcel\\\\Helpers\\:\\:adjustYear\\(\\) expects string, string\\|false given\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/DateTimeExcel/DateValue.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#2 \\$testVal2 of static method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\DateTimeExcel\\\\Helpers\\:\\:adjustYear\\(\\) expects string, string\\|false given\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/DateTimeExcel/DateValue.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$value of static method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\StringHelper\\:\\:testStringAsNumeric\\(\\) expects string, float\\|int\\|string given\\.$#"
|
||||
count: 2
|
||||
path: src/PhpSpreadsheet/Calculation/DateTimeExcel/Datefunc.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\DateTimeExcel\\\\Day\\:\\:weirdCondition\\(\\) has parameter \\$dateValue with no typehint specified\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/DateTimeExcel/Day.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\DateTimeExcel\\\\Helpers\\:\\:adjustDateByMonths\\(\\) has no return typehint specified\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/DateTimeExcel/Helpers.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\DateTimeExcel\\\\Helpers\\:\\:adjustDateByMonths\\(\\) has parameter \\$adjustmentMonths with no typehint specified\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/DateTimeExcel/Helpers.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\DateTimeExcel\\\\Helpers\\:\\:adjustDateByMonths\\(\\) has parameter \\$dateValue with no typehint specified\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/DateTimeExcel/Helpers.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$excelTimestamp of static method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Date\\:\\:excelToTimestamp\\(\\) expects float\\|int, bool\\|float given\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/DateTimeExcel/Helpers.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\DateTimeExcel\\\\Helpers\\:\\:validateNumericNull\\(\\) should return float\\|int but returns float\\|int\\|string\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/DateTimeExcel/Helpers.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\DateTimeExcel\\\\IsoWeekNum\\:\\:apparentBug\\(\\) has parameter \\$dateValue with no typehint specified\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/DateTimeExcel/IsoWeekNum.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\DateTimeExcel\\\\NetworkDays\\:\\:funcNetworkDays\\(\\) has parameter \\$dateArgs with no typehint specified\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/DateTimeExcel/NetworkDays.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\DateTimeExcel\\\\NetworkDays\\:\\:applySign\\(\\) has no return typehint specified\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/DateTimeExcel/NetworkDays.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\DateTimeExcel\\\\Time\\:\\:toIntWithNullBool\\(\\) has parameter \\$value with no typehint specified\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/DateTimeExcel/Time.php
|
||||
|
||||
-
|
||||
message: "#^Cannot access offset 0 on array\\<int, string\\>\\|false\\.$#"
|
||||
count: 3
|
||||
path: src/PhpSpreadsheet/Calculation/DateTimeExcel/TimeValue.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$var of function count expects array\\|Countable, array\\<int, string\\>\\|false given\\.$#"
|
||||
count: 2
|
||||
path: src/PhpSpreadsheet/Calculation/DateTimeExcel/TimeValue.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\DateTimeExcel\\\\WeekDay\\:\\:validateStyle\\(\\) has parameter \\$style with no typehint specified\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/DateTimeExcel/WeekDay.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\DateTimeExcel\\\\WorkDay\\:\\:funcWorkDay\\(\\) has parameter \\$dateArgs with no typehint specified\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/DateTimeExcel/WorkDay.php
|
||||
|
||||
-
|
||||
message: "#^Binary operation \"\\-\" between 7 and int\\|string results in an error\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/DateTimeExcel/WorkDay.php
|
||||
|
||||
-
|
||||
message: "#^Binary operation \"\\-\" between 7 and int\\<5, max\\>\\|string results in an error\\.$#"
|
||||
count: 2
|
||||
path: src/PhpSpreadsheet/Calculation/DateTimeExcel/WorkDay.php
|
||||
|
||||
-
|
||||
message: "#^Binary operation \"\\-\" between 4 and int\\<5, max\\>\\|string results in an error\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/DateTimeExcel/WorkDay.php
|
||||
|
||||
-
|
||||
message: "#^Binary operation \"\\-\" between int\\|string and int\\|string results in an error\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/DateTimeExcel/YearFrac.php
|
||||
|
||||
-
|
||||
message: "#^Binary operation \"\\*\" between 100 and int\\|string results in an error\\.$#"
|
||||
count: 2
|
||||
path: src/PhpSpreadsheet/Calculation/DateTimeExcel/YearFrac.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Engine\\\\Logger\\:\\:writeDebugLog\\(\\) has parameter \\$args with no typehint specified\\.$#"
|
||||
count: 1
|
||||
|
|
@ -960,16 +825,6 @@ parameters:
|
|||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/LookupRef.php
|
||||
|
||||
-
|
||||
message: "#^Call to function is_bool\\(\\) with float\\|int\\|\\(string&numeric\\) will always evaluate to false\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/LookupRef.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method getCell\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\|null\\.$#"
|
||||
count: 2
|
||||
path: src/PhpSpreadsheet/Calculation/LookupRef.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\LookupRef\\\\Address\\:\\:sheetName\\(\\) has no return typehint specified\\.$#"
|
||||
count: 1
|
||||
|
|
@ -1120,11 +975,6 @@ parameters:
|
|||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/LookupRef/LookupBase.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#3 \\$rowNum of static method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\LookupRef\\\\Matrix\\:\\:extractRowValue\\(\\) expects int, float\\|int\\<0, max\\>\\|string given\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/LookupRef/Matrix.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\LookupRef\\\\Matrix\\:\\:extractRowValue\\(\\) has no return typehint specified\\.$#"
|
||||
count: 1
|
||||
|
|
@ -1230,141 +1080,6 @@ parameters:
|
|||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/LookupRef/VLookup.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\MathTrig\\:\\:COMBIN\\(\\) should return int\\|string but returns float\\|int\\|string\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/MathTrig.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\MathTrig\\:\\:EVEN\\(\\) should return int\\|string but returns float\\|string\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/MathTrig.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\MathTrig\\:\\:FACT\\(\\) should return int\\|string but returns float\\|int\\|string\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/MathTrig.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\MathTrig\\:\\:FACTDOUBLE\\(\\) should return int\\|string but returns float\\|int\\|string\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/MathTrig.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\MathTrig\\:\\:MOD\\(\\) should return int\\|string but returns float\\|int\\|string\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/MathTrig.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\MathTrig\\:\\:ODD\\(\\) should return int\\|string but returns float\\|string\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/MathTrig.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\MathTrig\\:\\:SUMIFS\\(\\) should return float\\|string but returns float\\|string\\|null\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/MathTrig.php
|
||||
|
||||
-
|
||||
message: "#^Else branch is unreachable because ternary operator condition is always true\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/MathTrig/Arabic.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$number of function base_convert expects string, int\\<0, 9007199254740991\\> given\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/MathTrig/Base.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\MathTrig\\\\Helpers\\:\\:validateNumericNullBool\\(\\) should return float\\|int but returns float\\|int\\|string\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/MathTrig/Helpers.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\MathTrig\\\\Helpers\\:\\:validateNumericNullSubstitution\\(\\) should return float\\|int but returns float\\|int\\|string\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/MathTrig/Helpers.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\MathTrig\\\\Lcm\\:\\:factors\\(\\) has no return typehint specified\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/MathTrig/Lcm.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\MathTrig\\\\Lcm\\:\\:factors\\(\\) has parameter \\$value with no typehint specified\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/MathTrig/Lcm.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\MathTrig\\\\Roman\\:\\:romanCut\\(\\) has no return typehint specified\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/MathTrig/Roman.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\MathTrig\\\\Roman\\:\\:romanCut\\(\\) has parameter \\$n with no typehint specified\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/MathTrig/Roman.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\MathTrig\\\\Roman\\:\\:romanCut\\(\\) has parameter \\$num with no typehint specified\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/MathTrig/Roman.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#2 \\$precision of function round expects int, float\\|int given\\.$#"
|
||||
count: 2
|
||||
path: src/PhpSpreadsheet/Calculation/MathTrig/RoundDown.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#2 \\$precision of function round expects int, float\\|int given\\.$#"
|
||||
count: 2
|
||||
path: src/PhpSpreadsheet/Calculation/MathTrig/RoundUp.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\MathTrig\\\\Subtotal\\:\\:filterHiddenArgs\\(\\) has no return typehint specified\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/MathTrig/Subtotal.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\MathTrig\\\\Subtotal\\:\\:filterHiddenArgs\\(\\) has parameter \\$args with no typehint specified\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/MathTrig/Subtotal.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\MathTrig\\\\Subtotal\\:\\:filterHiddenArgs\\(\\) has parameter \\$cellReference with no typehint specified\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/MathTrig/Subtotal.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\MathTrig\\\\Subtotal\\:\\:filterFormulaArgs\\(\\) has no return typehint specified\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/MathTrig/Subtotal.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\MathTrig\\\\Subtotal\\:\\:filterFormulaArgs\\(\\) has parameter \\$args with no typehint specified\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/MathTrig/Subtotal.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\MathTrig\\\\Subtotal\\:\\:filterFormulaArgs\\(\\) has parameter \\$cellReference with no typehint specified\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/MathTrig/Subtotal.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$function of function call_user_func_array expects callable\\(\\)\\: mixed, array\\('PhpOffice…'\\|'PhpOffice…'\\|'PhpOffice…'\\|'PhpOffice…'\\|'PhpOffice…'\\|'PhpOffice…'\\|'PhpOffice…'\\|'PhpOffice…', string\\) given\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/MathTrig/Subtotal.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$str of function rtrim expects string, int given\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/MathTrig/Trunc.php
|
||||
|
||||
-
|
||||
message: "#^Binary operation \"\\-\" between float\\|int and float\\|string results in an error\\.$#"
|
||||
count: 4
|
||||
path: src/PhpSpreadsheet/Calculation/Statistical.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\:\\:MAXIFS\\(\\) should return float but returns float\\|string\\|null\\.$#"
|
||||
count: 1
|
||||
|
|
@ -2825,91 +2540,6 @@ parameters:
|
|||
count: 1
|
||||
path: src/PhpSpreadsheet/Reader/Csv/Delimiter.php
|
||||
|
||||
-
|
||||
message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Gnumeric\\:\\:\\$referenceHelper has no typehint specified\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Reader/Gnumeric.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$fp of function fread expects resource, resource\\|false given\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Reader/Gnumeric.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$fp of function fclose expects resource, resource\\|false given\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Reader/Gnumeric.php
|
||||
|
||||
-
|
||||
message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Gnumeric\\:\\:\\$mappings has no typehint specified\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Reader/Gnumeric.php
|
||||
|
||||
-
|
||||
message: "#^Offset 'No' does not exist on SimpleXMLElement\\|null\\.$#"
|
||||
count: 2
|
||||
path: src/PhpSpreadsheet/Reader/Gnumeric.php
|
||||
|
||||
-
|
||||
message: "#^Offset 'Unit' does not exist on SimpleXMLElement\\|null\\.$#"
|
||||
count: 2
|
||||
path: src/PhpSpreadsheet/Reader/Gnumeric.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method setWidth\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\ColumnDimension\\|null\\.$#"
|
||||
count: 3
|
||||
path: src/PhpSpreadsheet/Reader/Gnumeric.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method setVisible\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\ColumnDimension\\|null\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Reader/Gnumeric.php
|
||||
|
||||
-
|
||||
message: "#^Offset 'DefaultSizePts' does not exist on SimpleXMLElement\\|null\\.$#"
|
||||
count: 2
|
||||
path: src/PhpSpreadsheet/Reader/Gnumeric.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method setRowHeight\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\RowDimension\\|null\\.$#"
|
||||
count: 2
|
||||
path: src/PhpSpreadsheet/Reader/Gnumeric.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method setVisible\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\RowDimension\\|null\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Reader/Gnumeric.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Gnumeric\\:\\:parseBorderAttributes\\(\\) has no return typehint specified\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Reader/Gnumeric.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Gnumeric\\:\\:parseBorderAttributes\\(\\) has parameter \\$borderAttributes with no typehint specified\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Reader/Gnumeric.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Gnumeric\\:\\:parseRichText\\(\\) has no return typehint specified\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Reader/Gnumeric.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Gnumeric\\:\\:parseRichText\\(\\) has parameter \\$is with no typehint specified\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Reader/Gnumeric.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Gnumeric\\:\\:parseGnumericColour\\(\\) has no return typehint specified\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Reader/Gnumeric.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Gnumeric\\:\\:parseGnumericColour\\(\\) has parameter \\$gnmColour with no typehint specified\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Reader/Gnumeric.php
|
||||
|
||||
-
|
||||
message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Html\\:\\:\\$rowspan has no typehint specified\\.$#"
|
||||
count: 1
|
||||
|
|
@ -3025,16 +2655,6 @@ parameters:
|
|||
count: 1
|
||||
path: src/PhpSpreadsheet/Reader/Html.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method setRowHeight\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\RowDimension\\|null\\.$#"
|
||||
count: 4
|
||||
path: src/PhpSpreadsheet/Reader/Html.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method setWidth\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\ColumnDimension\\|null\\.$#"
|
||||
count: 3
|
||||
path: src/PhpSpreadsheet/Reader/Html.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#2 \\$styleValue of method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Html\\:\\:setBorderStyle\\(\\) expects string, string\\|null given\\.$#"
|
||||
count: 5
|
||||
|
|
@ -3120,21 +2740,6 @@ parameters:
|
|||
count: 1
|
||||
path: src/PhpSpreadsheet/Reader/Ods.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#3 \\$subject of function preg_replace expects array\\|string, string\\|null given\\.$#"
|
||||
count: 7
|
||||
path: src/PhpSpreadsheet/Reader/Ods.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Ods\\:\\:convertToExcelAddressValue\\(\\) should return string but returns string\\|null\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Reader/Ods.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#3 \\$formula of static method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:translateSeparator\\(\\) expects string, string\\|null given\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Reader/Ods.php
|
||||
|
||||
-
|
||||
message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Ods\\\\PageSettings\\:\\:\\$officeNs has no typehint specified\\.$#"
|
||||
count: 1
|
||||
|
|
@ -3285,11 +2890,6 @@ parameters:
|
|||
count: 3
|
||||
path: src/PhpSpreadsheet/Reader/Slk.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method setWidth\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\ColumnDimension\\|null\\.$#"
|
||||
count: 3
|
||||
path: src/PhpSpreadsheet/Reader/Slk.php
|
||||
|
||||
-
|
||||
message: "#^Call to an undefined method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\\\SpgrContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\\\SpgrContainer\\\\SpContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\\\BstoreContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\\\BstoreContainer\\\\BSE\\:\\:getDgContainer\\(\\)\\.$#"
|
||||
count: 1
|
||||
|
|
@ -3490,56 +3090,6 @@ parameters:
|
|||
count: 1
|
||||
path: src/PhpSpreadsheet/Reader/Xls.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method setWidth\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\ColumnDimension\\|null\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Reader/Xls.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method setVisible\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\ColumnDimension\\|null\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Reader/Xls.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method setOutlineLevel\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\ColumnDimension\\|null\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Reader/Xls.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method setCollapsed\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\ColumnDimension\\|null\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Reader/Xls.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method setXfIndex\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\ColumnDimension\\|null\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Reader/Xls.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method setRowHeight\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\RowDimension\\|null\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Reader/Xls.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method setOutlineLevel\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\RowDimension\\|null\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Reader/Xls.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method setCollapsed\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\RowDimension\\|null\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Reader/Xls.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method setVisible\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\RowDimension\\|null\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Reader/Xls.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method setXfIndex\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\RowDimension\\|null\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Reader/Xls.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xls\\:\\:includeCellRangeFiltered\\(\\) has no return typehint specified\\.$#"
|
||||
count: 1
|
||||
|
|
@ -3725,16 +3275,6 @@ parameters:
|
|||
count: 1
|
||||
path: src/PhpSpreadsheet/Reader/Xls/RC4.php
|
||||
|
||||
-
|
||||
message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xls\\\\Style\\\\Border\\:\\:\\$map has no typehint specified\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Reader/Xls/Style/Border.php
|
||||
|
||||
-
|
||||
message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xls\\\\Style\\\\FillPattern\\:\\:\\$map has no typehint specified\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Reader/Xls/Style/FillPattern.php
|
||||
|
||||
-
|
||||
message: "#^Cannot access property \\$Relationship on SimpleXMLElement\\|false\\.$#"
|
||||
count: 12
|
||||
|
|
@ -3940,31 +3480,6 @@ parameters:
|
|||
count: 1
|
||||
path: src/PhpSpreadsheet/Reader/Xlsx.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:readColor\\(\\) has no return typehint specified\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Reader/Xlsx.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:readColor\\(\\) has parameter \\$background with no typehint specified\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Reader/Xlsx.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:readColor\\(\\) has parameter \\$color with no typehint specified\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Reader/Xlsx.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$hex of static method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Color\\:\\:changeBrightness\\(\\) expects string, string\\|null given\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Reader/Xlsx.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$pValue of method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\:\\:setSize\\(\\) expects float, string given\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Reader/Xlsx.php
|
||||
|
||||
-
|
||||
message: "#^Cannot access property \\$r on SimpleXMLElement\\|null\\.$#"
|
||||
count: 2
|
||||
|
|
@ -4740,16 +4255,6 @@ parameters:
|
|||
count: 1
|
||||
path: src/PhpSpreadsheet/Reader/Xml.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method setWidth\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\ColumnDimension\\|null\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Reader/Xml.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method setRowHeight\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\RowDimension\\|null\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Reader/Xml.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#2 \\$cmp_function of function uksort expects callable\\(mixed, mixed\\)\\: int, array\\('self', 'cellReverseSort'\\) given\\.$#"
|
||||
count: 4
|
||||
|
|
@ -4760,61 +4265,11 @@ parameters:
|
|||
count: 4
|
||||
path: src/PhpSpreadsheet/ReferenceHelper.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#2 \\$pPassword of method PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\:\\:protectCells\\(\\) expects string, array given\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/ReferenceHelper.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$index of method PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\RowDimension\\:\\:setRowIndex\\(\\) expects int, string given\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/ReferenceHelper.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method getRowHeight\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\RowDimension\\|null\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/ReferenceHelper.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method setRowHeight\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\RowDimension\\|null\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/ReferenceHelper.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method getVisible\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\RowDimension\\|null\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/ReferenceHelper.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method setVisible\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\RowDimension\\|null\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/ReferenceHelper.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method getOutlineLevel\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\RowDimension\\|null\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/ReferenceHelper.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method setOutlineLevel\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\RowDimension\\|null\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/ReferenceHelper.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method getCollapsed\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\RowDimension\\|null\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/ReferenceHelper.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method setCollapsed\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\RowDimension\\|null\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/ReferenceHelper.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method setXfIndex\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\Cell\\|null\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/ReferenceHelper.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$columnIndex of static method PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\Coordinate\\:\\:stringFromColumnIndex\\(\\) expects int, float\\|int given\\.$#"
|
||||
count: 1
|
||||
|
|
@ -6230,36 +5685,6 @@ parameters:
|
|||
count: 1
|
||||
path: src/PhpSpreadsheet/Style/Style.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method getXfIndex\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\ColumnDimension\\|null\\.$#"
|
||||
count: 2
|
||||
path: src/PhpSpreadsheet/Style/Style.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method setXfIndex\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\ColumnDimension\\|null\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Style/Style.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method getXfIndex\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\RowDimension\\|null\\.$#"
|
||||
count: 3
|
||||
path: src/PhpSpreadsheet/Style/Style.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method setXfIndex\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\RowDimension\\|null\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Style/Style.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method getXfIndex\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\Cell\\|null\\.$#"
|
||||
count: 2
|
||||
path: src/PhpSpreadsheet/Style/Style.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method setXfIndex\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\Cell\\|null\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Style/Style.php
|
||||
|
||||
-
|
||||
message: "#^Result of && is always true\\.$#"
|
||||
count: 1
|
||||
|
|
@ -6350,11 +5775,6 @@ parameters:
|
|||
count: 2
|
||||
path: src/PhpSpreadsheet/Worksheet/AutoFilter.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method setVisible\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\RowDimension\\|null\\.$#"
|
||||
count: 2
|
||||
path: src/PhpSpreadsheet/Worksheet/AutoFilter.php
|
||||
|
||||
-
|
||||
message: "#^Cannot assign offset 'year' to array\\<string\\>\\|string\\.$#"
|
||||
count: 1
|
||||
|
|
@ -6630,11 +6050,6 @@ parameters:
|
|||
count: 1
|
||||
path: src/PhpSpreadsheet/Worksheet/Worksheet.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method setWidth\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\ColumnDimension\\|null\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Worksheet/Worksheet.php
|
||||
|
||||
-
|
||||
message: "#^If condition is always true\\.$#"
|
||||
count: 2
|
||||
|
|
@ -6650,26 +6065,11 @@ parameters:
|
|||
count: 1
|
||||
path: src/PhpSpreadsheet/Worksheet/Worksheet.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method setValue\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\Cell\\|null\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Worksheet/Worksheet.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method setValueExplicit\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\Cell\\|null\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Worksheet/Worksheet.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#2 \\$start of function substr expects int, int\\<0, max\\>\\|false given\\.$#"
|
||||
count: 2
|
||||
path: src/PhpSpreadsheet/Worksheet/Worksheet.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$pRow of method PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\:\\:getRowDimension\\(\\) expects int, string given\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Worksheet/Worksheet.php
|
||||
|
||||
-
|
||||
message: "#^Result of && is always true\\.$#"
|
||||
count: 1
|
||||
|
|
@ -7430,16 +6830,6 @@ parameters:
|
|||
count: 1
|
||||
path: src/PhpSpreadsheet/Writer/Xls/Worksheet.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#2 \\$height of method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xls\\\\Worksheet\\:\\:writeRow\\(\\) expects int, float given\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Writer/Xls/Worksheet.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#4 \\$hidden of method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xls\\\\Worksheet\\:\\:writeRow\\(\\) expects bool, string given\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Writer/Xls/Worksheet.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method getHashCode\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#"
|
||||
count: 1
|
||||
|
|
@ -7470,11 +6860,6 @@ parameters:
|
|||
count: 1
|
||||
path: src/PhpSpreadsheet/Writer/Xls/Worksheet.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$hexadecimal_number of function hexdec expects string, array given\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Writer/Xls/Worksheet.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$coordinates of static method PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\Coordinate\\:\\:indexesFromString\\(\\) expects string, string\\|null given\\.$#"
|
||||
count: 1
|
||||
|
|
@ -7575,26 +6960,6 @@ parameters:
|
|||
count: 1
|
||||
path: src/PhpSpreadsheet/Writer/Xls/Worksheet.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$value of static method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\StringHelper\\:\\:UTF8toBIFF8UnicodeLong\\(\\) expects string, string\\|null given\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Writer/Xls/Worksheet.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$fillType of static method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xls\\\\Xf\\:\\:mapFillType\\(\\) expects string, string\\|null given\\.$#"
|
||||
count: 2
|
||||
path: src/PhpSpreadsheet/Writer/Xls/Xf.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$hAlign of method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xls\\\\Xf\\:\\:mapHAlign\\(\\) expects string, string\\|null given\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Writer/Xls/Xf.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$vAlign of static method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xls\\\\Xf\\:\\:mapVAlign\\(\\) expects string, string\\|null given\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Writer/Xls/Xf.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$textRotation of static method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xls\\\\Xf\\:\\:mapTextRotation\\(\\) expects int, int\\|null given\\.$#"
|
||||
count: 1
|
||||
|
|
@ -8105,11 +7470,6 @@ parameters:
|
|||
count: 2
|
||||
path: src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, array given\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, array\\<string\\>\\|string given\\.$#"
|
||||
count: 2
|
||||
|
|
@ -8120,31 +7480,6 @@ parameters:
|
|||
count: 1
|
||||
path: src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method getCollapsed\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\RowDimension\\|null\\.$#"
|
||||
count: 2
|
||||
path: src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method getOutlineLevel\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\RowDimension\\|null\\.$#"
|
||||
count: 3
|
||||
path: src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method getRowHeight\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\RowDimension\\|null\\.$#"
|
||||
count: 3
|
||||
path: src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method getVisible\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\RowDimension\\|null\\.$#"
|
||||
count: 2
|
||||
path: src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method getXfIndex\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\RowDimension\\|null\\.$#"
|
||||
count: 3
|
||||
path: src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#2 \\$content of method XMLWriter\\:\\:writeElement\\(\\) expects string\\|null, int\\|string given\\.$#"
|
||||
count: 1
|
||||
|
|
@ -8165,21 +7500,6 @@ parameters:
|
|||
count: 1
|
||||
path: tests/PhpSpreadsheetTests/Calculation/Engine/RangeTest.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method setVisible\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\ColumnDimension\\|null\\.$#"
|
||||
count: 1
|
||||
path: tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SubTotalTest.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method setVisible\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\RowDimension\\|null\\.$#"
|
||||
count: 1
|
||||
path: tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SubTotalTest.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method setAutoSize\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\ColumnDimension\\|null\\.$#"
|
||||
count: 1
|
||||
path: tests/PhpSpreadsheetTests/Calculation/XlfnFunctionsTest.php
|
||||
|
||||
-
|
||||
message: "#^Call to static method PHPUnit\\\\Framework\\\\Assert\\:\\:assertSame\\(\\) with arguments PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\Cell, null and 'should get exact…' will always evaluate to false\\.$#"
|
||||
count: 1
|
||||
|
|
@ -8205,16 +7525,6 @@ parameters:
|
|||
count: 1
|
||||
path: tests/PhpSpreadsheetTests/Functional/ColumnWidthTest.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method setWidth\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\ColumnDimension\\|null\\.$#"
|
||||
count: 1
|
||||
path: tests/PhpSpreadsheetTests/Functional/ColumnWidthTest.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method getWidth\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\ColumnDimension\\|null\\.$#"
|
||||
count: 1
|
||||
path: tests/PhpSpreadsheetTests/Functional/ColumnWidthTest.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheetTests\\\\Functional\\\\CommentsTest\\:\\:testComments\\(\\) has parameter \\$format with no typehint specified\\.$#"
|
||||
count: 1
|
||||
|
|
@ -8225,11 +7535,6 @@ parameters:
|
|||
count: 2
|
||||
path: tests/PhpSpreadsheetTests/Functional/ConditionalStopIfTrueTest.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method setAutoSize\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\ColumnDimension\\|null\\.$#"
|
||||
count: 1
|
||||
path: tests/PhpSpreadsheetTests/Functional/ConditionalTextTest.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$im of function imagecolorallocate expects resource, resource\\|false given\\.$#"
|
||||
count: 1
|
||||
|
|
@ -8325,26 +7630,6 @@ parameters:
|
|||
count: 1
|
||||
path: tests/PhpSpreadsheetTests/Reader/CsvTest.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method getVisible\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\RowDimension\\|null\\.$#"
|
||||
count: 1
|
||||
path: tests/PhpSpreadsheetTests/Reader/Gnumeric/GnumericLoadTest.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method getRowHeight\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\RowDimension\\|null\\.$#"
|
||||
count: 2
|
||||
path: tests/PhpSpreadsheetTests/Reader/Html/HtmlTagsTest.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method getWidth\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\ColumnDimension\\|null\\.$#"
|
||||
count: 2
|
||||
path: tests/PhpSpreadsheetTests/Reader/Html/HtmlTest.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method getRowHeight\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\RowDimension\\|null\\.$#"
|
||||
count: 2
|
||||
path: tests/PhpSpreadsheetTests/Reader/Html/HtmlTest.php
|
||||
|
||||
-
|
||||
message: "#^Unreachable statement \\- code above always terminates\\.$#"
|
||||
count: 1
|
||||
|
|
@ -8435,26 +7720,6 @@ parameters:
|
|||
count: 1
|
||||
path: tests/PhpSpreadsheetTests/Reader/Xlsx/ConditionalFormattingDataBarXlsxTest.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method getRowHeight\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\RowDimension\\|null\\.$#"
|
||||
count: 1
|
||||
path: tests/PhpSpreadsheetTests/Reader/XlsxTest.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method getVisible\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\RowDimension\\|null\\.$#"
|
||||
count: 1
|
||||
path: tests/PhpSpreadsheetTests/Reader/XlsxTest.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method getWidth\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\ColumnDimension\\|null\\.$#"
|
||||
count: 1
|
||||
path: tests/PhpSpreadsheetTests/Reader/XlsxTest.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method getVisible\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\ColumnDimension\\|null\\.$#"
|
||||
count: 1
|
||||
path: tests/PhpSpreadsheetTests/Reader/XlsxTest.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheetTests\\\\Reader\\\\XlsxTest\\:\\:testStripsWhiteSpaceFromStyleString\\(\\) has parameter \\$string with no typehint specified\\.$#"
|
||||
count: 1
|
||||
|
|
@ -8610,21 +7875,6 @@ parameters:
|
|||
count: 1
|
||||
path: tests/PhpSpreadsheetTests/Writer/Html/ImagesRootTest.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method setVisible\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\ColumnDimension\\|null\\.$#"
|
||||
count: 2
|
||||
path: tests/PhpSpreadsheetTests/Writer/Html/VisibilityTest.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method setVisible\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\RowDimension\\|null\\.$#"
|
||||
count: 3
|
||||
path: tests/PhpSpreadsheetTests/Writer/Html/VisibilityTest.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method setRowHeight\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\RowDimension\\|null\\.$#"
|
||||
count: 1
|
||||
path: tests/PhpSpreadsheetTests/Writer/Html/VisibilityTest.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$options of static method PhpOffice\\\\PhpSpreadsheet\\\\Settings\\:\\:setLibXmlLoaderOptions\\(\\) expects int, null given\\.$#"
|
||||
count: 1
|
||||
|
|
|
|||
|
|
@ -38,7 +38,8 @@ $helper->write($spreadsheetFromCSV, __FILE__, ['Xlsx']);
|
|||
$filenameCSV = $helper->getFilename(__FILE__, 'csv');
|
||||
/** @var \PhpOffice\PhpSpreadsheet\Writer\Csv $writerCSV */
|
||||
$writerCSV = new CsvWriter($spreadsheetFromCSV);
|
||||
$writerCSV->setExcelCompatibility(true);
|
||||
//$writerCSV->setExcelCompatibility(true);
|
||||
$writerCSV->setUseBom(true); // because of non-ASCII chars
|
||||
|
||||
$callStartTime = microtime(true);
|
||||
$writerCSV->save($filenameCSV);
|
||||
|
|
|
|||
|
|
@ -30,6 +30,9 @@ class Calculation
|
|||
const CALCULATION_REGEXP_CELLREF = '((([^\s,!&%^\/\*\+<>=-]*)|(\'[^\']*\')|(\"[^\"]*\"))!)?\$?\b([a-z]{1,3})\$?(\d{1,7})(?![\w.])';
|
||||
// Cell reference (with or without a sheet reference) ensuring absolute/relative
|
||||
const CALCULATION_REGEXP_CELLREF_RELATIVE = '((([^\s\(,!&%^\/\*\+<>=-]*)|(\'[^\']*\')|(\"[^\"]*\"))!)?(\$?\b[a-z]{1,3})(\$?\d{1,7})(?![\w.])';
|
||||
const CALCULATION_REGEXP_COLUMN_RANGE = '(((([^\s\(,!&%^\/\*\+<>=-]*)|(\'[^\']*\')|(\"[^\"]*\"))!)?(\$?[a-z]{1,3})):(?![.*])';
|
||||
const CALCULATION_REGEXP_ROW_RANGE = '(((([^\s\(,!&%^\/\*\+<>=-]*)|(\'[^\']*\')|(\"[^\"]*\"))!)?(\$?[1-9][0-9]{0,6})):(?![.*])';
|
||||
// Cell reference (with or without a sheet reference) ensuring absolute/relative
|
||||
// Cell ranges ensuring absolute/relative
|
||||
const CALCULATION_REGEXP_COLUMNRANGE_RELATIVE = '(\$?[a-z]{1,3}):(\$?[a-z]{1,3})';
|
||||
const CALCULATION_REGEXP_ROWRANGE_RELATIVE = '(\$?\d{1,7}):(\$?\d{1,7})';
|
||||
|
|
@ -528,7 +531,7 @@ class Calculation
|
|||
],
|
||||
'CHOOSE' => [
|
||||
'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE,
|
||||
'functionCall' => [LookupRef::class, 'CHOOSE'],
|
||||
'functionCall' => [LookupRef\Selection::class, 'CHOOSE'],
|
||||
'argumentCount' => '2+',
|
||||
],
|
||||
'CLEAN' => [
|
||||
|
|
@ -755,17 +758,17 @@ class Calculation
|
|||
],
|
||||
'DATE' => [
|
||||
'category' => Category::CATEGORY_DATE_AND_TIME,
|
||||
'functionCall' => [DateTimeExcel\Datefunc::class, 'funcDate'],
|
||||
'functionCall' => [DateTimeExcel\Date::class, 'fromYMD'],
|
||||
'argumentCount' => '3',
|
||||
],
|
||||
'DATEDIF' => [
|
||||
'category' => Category::CATEGORY_DATE_AND_TIME,
|
||||
'functionCall' => [DateTimeExcel\DateDif::class, 'funcDateDif'],
|
||||
'functionCall' => [DateTimeExcel\Difference::class, 'interval'],
|
||||
'argumentCount' => '2,3',
|
||||
],
|
||||
'DATEVALUE' => [
|
||||
'category' => Category::CATEGORY_DATE_AND_TIME,
|
||||
'functionCall' => [DateTimeExcel\DateValue::class, 'funcDateValue'],
|
||||
'functionCall' => [DateTimeExcel\DateValue::class, 'fromString'],
|
||||
'argumentCount' => '1',
|
||||
],
|
||||
'DAVERAGE' => [
|
||||
|
|
@ -775,22 +778,22 @@ class Calculation
|
|||
],
|
||||
'DAY' => [
|
||||
'category' => Category::CATEGORY_DATE_AND_TIME,
|
||||
'functionCall' => [DateTimeExcel\Day::class, 'funcDay'],
|
||||
'functionCall' => [DateTimeExcel\DateParts::class, 'day'],
|
||||
'argumentCount' => '1',
|
||||
],
|
||||
'DAYS' => [
|
||||
'category' => Category::CATEGORY_DATE_AND_TIME,
|
||||
'functionCall' => [DateTimeExcel\Days::class, 'funcDays'],
|
||||
'functionCall' => [DateTimeExcel\Days::class, 'between'],
|
||||
'argumentCount' => '2',
|
||||
],
|
||||
'DAYS360' => [
|
||||
'category' => Category::CATEGORY_DATE_AND_TIME,
|
||||
'functionCall' => [DateTimeExcel\Days360::class, 'funcDays360'],
|
||||
'functionCall' => [DateTimeExcel\Days360::class, 'between'],
|
||||
'argumentCount' => '2,3',
|
||||
],
|
||||
'DB' => [
|
||||
'category' => Category::CATEGORY_FINANCIAL,
|
||||
'functionCall' => [Financial::class, 'DB'],
|
||||
'functionCall' => [Financial\Depreciation::class, 'DB'],
|
||||
'argumentCount' => '4,5',
|
||||
],
|
||||
'DBCS' => [
|
||||
|
|
@ -810,7 +813,7 @@ class Calculation
|
|||
],
|
||||
'DDB' => [
|
||||
'category' => Category::CATEGORY_FINANCIAL,
|
||||
'functionCall' => [Financial::class, 'DDB'],
|
||||
'functionCall' => [Financial\Depreciation::class, 'DDB'],
|
||||
'argumentCount' => '4,5',
|
||||
],
|
||||
'DEC2BIN' => [
|
||||
|
|
@ -845,7 +848,7 @@ class Calculation
|
|||
],
|
||||
'DEVSQ' => [
|
||||
'category' => Category::CATEGORY_STATISTICAL,
|
||||
'functionCall' => [Statistical::class, 'DEVSQ'],
|
||||
'functionCall' => [Statistical\Deviations::class, 'sumSquares'],
|
||||
'argumentCount' => '1+',
|
||||
],
|
||||
'DGET' => [
|
||||
|
|
@ -920,7 +923,7 @@ class Calculation
|
|||
],
|
||||
'EDATE' => [
|
||||
'category' => Category::CATEGORY_DATE_AND_TIME,
|
||||
'functionCall' => [DateTimeExcel\EDate::class, 'funcEDate'],
|
||||
'functionCall' => [DateTimeExcel\Month::class, 'adjust'],
|
||||
'argumentCount' => '2',
|
||||
],
|
||||
'EFFECT' => [
|
||||
|
|
@ -930,12 +933,12 @@ class Calculation
|
|||
],
|
||||
'ENCODEURL' => [
|
||||
'category' => Category::CATEGORY_WEB,
|
||||
'functionCall' => [Functions::class, 'DUMMY'],
|
||||
'functionCall' => [Web\Service::class, 'urlEncode'],
|
||||
'argumentCount' => '1',
|
||||
],
|
||||
'EOMONTH' => [
|
||||
'category' => Category::CATEGORY_DATE_AND_TIME,
|
||||
'functionCall' => [DateTimeExcel\EoMonth::class, 'funcEoMonth'],
|
||||
'functionCall' => [DateTimeExcel\Month::class, 'lastDay'],
|
||||
'argumentCount' => '2',
|
||||
],
|
||||
'ERF' => [
|
||||
|
|
@ -1115,7 +1118,7 @@ class Calculation
|
|||
],
|
||||
'FORMULATEXT' => [
|
||||
'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE,
|
||||
'functionCall' => [LookupRef::class, 'FORMULATEXT'],
|
||||
'functionCall' => [LookupRef\Formula::class, 'text'],
|
||||
'argumentCount' => '1',
|
||||
'passCellReference' => true,
|
||||
'passByReference' => [true],
|
||||
|
|
@ -1182,7 +1185,7 @@ class Calculation
|
|||
],
|
||||
'GAUSS' => [
|
||||
'category' => Category::CATEGORY_STATISTICAL,
|
||||
'functionCall' => [Statistical::class, 'GAUSS'],
|
||||
'functionCall' => [Statistical\Distributions\StandardNormal::class, 'gauss'],
|
||||
'argumentCount' => '1',
|
||||
],
|
||||
'GCD' => [
|
||||
|
|
@ -1192,7 +1195,7 @@ class Calculation
|
|||
],
|
||||
'GEOMEAN' => [
|
||||
'category' => Category::CATEGORY_STATISTICAL,
|
||||
'functionCall' => [Statistical::class, 'GEOMEAN'],
|
||||
'functionCall' => [Statistical\Averages\Mean::class, 'geometric'],
|
||||
'argumentCount' => '1+',
|
||||
],
|
||||
'GESTEP' => [
|
||||
|
|
@ -1212,7 +1215,7 @@ class Calculation
|
|||
],
|
||||
'HARMEAN' => [
|
||||
'category' => Category::CATEGORY_STATISTICAL,
|
||||
'functionCall' => [Statistical::class, 'HARMEAN'],
|
||||
'functionCall' => [Statistical\Averages\Mean::class, 'harmonic'],
|
||||
'argumentCount' => '1+',
|
||||
],
|
||||
'HEX2BIN' => [
|
||||
|
|
@ -1237,12 +1240,12 @@ class Calculation
|
|||
],
|
||||
'HOUR' => [
|
||||
'category' => Category::CATEGORY_DATE_AND_TIME,
|
||||
'functionCall' => [DateTimeExcel\Hour::class, 'funcHour'],
|
||||
'functionCall' => [DateTimeExcel\TimeParts::class, 'hour'],
|
||||
'argumentCount' => '1',
|
||||
],
|
||||
'HYPERLINK' => [
|
||||
'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE,
|
||||
'functionCall' => [LookupRef::class, 'HYPERLINK'],
|
||||
'functionCall' => [LookupRef\Hyperlink::class, 'set'],
|
||||
'argumentCount' => '1,2',
|
||||
'passCellReference' => true,
|
||||
],
|
||||
|
|
@ -1403,7 +1406,7 @@ class Calculation
|
|||
],
|
||||
'INDEX' => [
|
||||
'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE,
|
||||
'functionCall' => [LookupRef::class, 'INDEX'],
|
||||
'functionCall' => [LookupRef\Matrix::class, 'index'],
|
||||
'argumentCount' => '1-4',
|
||||
],
|
||||
'INDIRECT' => [
|
||||
|
|
@ -1501,7 +1504,7 @@ class Calculation
|
|||
],
|
||||
'ISOWEEKNUM' => [
|
||||
'category' => Category::CATEGORY_DATE_AND_TIME,
|
||||
'functionCall' => [DateTimeExcel\IsoWeekNum::class, 'funcIsoWeekNum'],
|
||||
'functionCall' => [DateTimeExcel\Week::class, 'isoWeekNumber'],
|
||||
'argumentCount' => '1',
|
||||
],
|
||||
'ISPMT' => [
|
||||
|
|
@ -1526,12 +1529,12 @@ class Calculation
|
|||
],
|
||||
'KURT' => [
|
||||
'category' => Category::CATEGORY_STATISTICAL,
|
||||
'functionCall' => [Statistical::class, 'KURT'],
|
||||
'functionCall' => [Statistical\Deviations::class, 'kurtosis'],
|
||||
'argumentCount' => '1+',
|
||||
],
|
||||
'LARGE' => [
|
||||
'category' => Category::CATEGORY_STATISTICAL,
|
||||
'functionCall' => [Statistical::class, 'LARGE'],
|
||||
'functionCall' => [Statistical\Size::class, 'large'],
|
||||
'argumentCount' => '2',
|
||||
],
|
||||
'LCM' => [
|
||||
|
|
@ -1681,7 +1684,7 @@ class Calculation
|
|||
],
|
||||
'MINUTE' => [
|
||||
'category' => Category::CATEGORY_DATE_AND_TIME,
|
||||
'functionCall' => [DateTimeExcel\Minute::class, 'funcMinute'],
|
||||
'functionCall' => [DateTimeExcel\TimeParts::class, 'minute'],
|
||||
'argumentCount' => '1',
|
||||
],
|
||||
'MINVERSE' => [
|
||||
|
|
@ -1721,7 +1724,7 @@ class Calculation
|
|||
],
|
||||
'MONTH' => [
|
||||
'category' => Category::CATEGORY_DATE_AND_TIME,
|
||||
'functionCall' => [DateTimeExcel\Month::class, 'funcMonth'],
|
||||
'functionCall' => [DateTimeExcel\DateParts::class, 'month'],
|
||||
'argumentCount' => '1',
|
||||
],
|
||||
'MROUND' => [
|
||||
|
|
@ -1761,7 +1764,7 @@ class Calculation
|
|||
],
|
||||
'NETWORKDAYS' => [
|
||||
'category' => Category::CATEGORY_DATE_AND_TIME,
|
||||
'functionCall' => [DateTimeExcel\NetworkDays::class, 'funcNetworkDays'],
|
||||
'functionCall' => [DateTimeExcel\NetworkDays::class, 'count'],
|
||||
'argumentCount' => '2-3',
|
||||
],
|
||||
'NETWORKDAYS.INTL' => [
|
||||
|
|
@ -1821,7 +1824,7 @@ class Calculation
|
|||
],
|
||||
'NOW' => [
|
||||
'category' => Category::CATEGORY_DATE_AND_TIME,
|
||||
'functionCall' => [DateTimeExcel\Now::class, 'funcNow'],
|
||||
'functionCall' => [DateTimeExcel\Current::class, 'now'],
|
||||
'argumentCount' => '0',
|
||||
],
|
||||
'NPER' => [
|
||||
|
|
@ -2068,7 +2071,7 @@ class Calculation
|
|||
],
|
||||
'RANK.EQ' => [
|
||||
'category' => Category::CATEGORY_STATISTICAL,
|
||||
'functionCall' => [Statistical::class, 'RANK'],
|
||||
'functionCall' => [Statistical\Percentiles::class, 'RANK'],
|
||||
'argumentCount' => '2,3',
|
||||
],
|
||||
'RATE' => [
|
||||
|
|
@ -2175,7 +2178,7 @@ class Calculation
|
|||
],
|
||||
'SECOND' => [
|
||||
'category' => Category::CATEGORY_DATE_AND_TIME,
|
||||
'functionCall' => [DateTimeExcel\Second::class, 'funcSecond'],
|
||||
'functionCall' => [DateTimeExcel\TimeParts::class, 'second'],
|
||||
'argumentCount' => '1',
|
||||
],
|
||||
'SEQUENCE' => [
|
||||
|
|
@ -2215,7 +2218,7 @@ class Calculation
|
|||
],
|
||||
'SKEW' => [
|
||||
'category' => Category::CATEGORY_STATISTICAL,
|
||||
'functionCall' => [Statistical::class, 'SKEW'],
|
||||
'functionCall' => [Statistical\Deviations::class, 'skew'],
|
||||
'argumentCount' => '1+',
|
||||
],
|
||||
'SKEW.P' => [
|
||||
|
|
@ -2235,7 +2238,7 @@ class Calculation
|
|||
],
|
||||
'SMALL' => [
|
||||
'category' => Category::CATEGORY_STATISTICAL,
|
||||
'functionCall' => [Statistical::class, 'SMALL'],
|
||||
'functionCall' => [Statistical\Size::class, 'small'],
|
||||
'argumentCount' => '2',
|
||||
],
|
||||
'SORT' => [
|
||||
|
|
@ -2260,7 +2263,7 @@ class Calculation
|
|||
],
|
||||
'STANDARDIZE' => [
|
||||
'category' => Category::CATEGORY_STATISTICAL,
|
||||
'functionCall' => [Statistical::class, 'STANDARDIZE'],
|
||||
'functionCall' => [Statistical\Standardize::class, 'execute'],
|
||||
'argumentCount' => '3',
|
||||
],
|
||||
'STDEV' => [
|
||||
|
|
@ -2285,12 +2288,12 @@ class Calculation
|
|||
],
|
||||
'STDEVP' => [
|
||||
'category' => Category::CATEGORY_STATISTICAL,
|
||||
'functionCall' => [Statistical::class, 'STDEVP'],
|
||||
'functionCall' => [Statistical\StandardDeviations::class, 'STDEVP'],
|
||||
'argumentCount' => '1+',
|
||||
],
|
||||
'STDEVPA' => [
|
||||
'category' => Category::CATEGORY_STATISTICAL,
|
||||
'functionCall' => [Statistical::class, 'STDEVPA'],
|
||||
'functionCall' => [Statistical\StandardDeviations::class, 'STDEVPA'],
|
||||
'argumentCount' => '1+',
|
||||
],
|
||||
'STEYX' => [
|
||||
|
|
@ -2416,17 +2419,17 @@ class Calculation
|
|||
],
|
||||
'TEXTJOIN' => [
|
||||
'category' => Category::CATEGORY_TEXT_AND_DATA,
|
||||
'functionCall' => [TextData::class, 'TEXTJOIN'],
|
||||
'functionCall' => [TextData\Concatenate::class, 'TEXTJOIN'],
|
||||
'argumentCount' => '3+',
|
||||
],
|
||||
'TIME' => [
|
||||
'category' => Category::CATEGORY_DATE_AND_TIME,
|
||||
'functionCall' => [DateTimeExcel\Time::class, 'funcTime'],
|
||||
'functionCall' => [DateTimeExcel\Time::class, 'fromHMS'],
|
||||
'argumentCount' => '3',
|
||||
],
|
||||
'TIMEVALUE' => [
|
||||
'category' => Category::CATEGORY_DATE_AND_TIME,
|
||||
'functionCall' => [DateTimeExcel\TimeValue::class, 'funcTimeValue'],
|
||||
'functionCall' => [DateTimeExcel\TimeValue::class, 'fromString'],
|
||||
'argumentCount' => '1',
|
||||
],
|
||||
'TINV' => [
|
||||
|
|
@ -2446,7 +2449,7 @@ class Calculation
|
|||
],
|
||||
'TODAY' => [
|
||||
'category' => Category::CATEGORY_DATE_AND_TIME,
|
||||
'functionCall' => [DateTimeExcel\Today::class, 'funcToday'],
|
||||
'functionCall' => [DateTimeExcel\Current::class, 'today'],
|
||||
'argumentCount' => '0',
|
||||
],
|
||||
'TRANSPOSE' => [
|
||||
|
|
@ -2466,7 +2469,7 @@ class Calculation
|
|||
],
|
||||
'TRIMMEAN' => [
|
||||
'category' => Category::CATEGORY_STATISTICAL,
|
||||
'functionCall' => [Statistical::class, 'TRIMMEAN'],
|
||||
'functionCall' => [Statistical\Averages\Mean::class, 'trim'],
|
||||
'argumentCount' => '2',
|
||||
],
|
||||
'TRUE' => [
|
||||
|
|
@ -2566,17 +2569,17 @@ class Calculation
|
|||
],
|
||||
'WEBSERVICE' => [
|
||||
'category' => Category::CATEGORY_WEB,
|
||||
'functionCall' => [Web::class, 'WEBSERVICE'],
|
||||
'functionCall' => [Web\Service::class, 'webService'],
|
||||
'argumentCount' => '1',
|
||||
],
|
||||
'WEEKDAY' => [
|
||||
'category' => Category::CATEGORY_DATE_AND_TIME,
|
||||
'functionCall' => [DateTimeExcel\WeekDay::class, 'funcWeekDay'],
|
||||
'functionCall' => [DateTimeExcel\Week::class, 'day'],
|
||||
'argumentCount' => '1,2',
|
||||
],
|
||||
'WEEKNUM' => [
|
||||
'category' => Category::CATEGORY_DATE_AND_TIME,
|
||||
'functionCall' => [DateTimeExcel\WeekNum::class, 'funcWeekNum'],
|
||||
'functionCall' => [DateTimeExcel\Week::class, 'number'],
|
||||
'argumentCount' => '1,2',
|
||||
],
|
||||
'WEIBULL' => [
|
||||
|
|
@ -2591,7 +2594,7 @@ class Calculation
|
|||
],
|
||||
'WORKDAY' => [
|
||||
'category' => Category::CATEGORY_DATE_AND_TIME,
|
||||
'functionCall' => [DateTimeExcel\WorkDay::class, 'funcWorkDay'],
|
||||
'functionCall' => [DateTimeExcel\WorkDay::class, 'date'],
|
||||
'argumentCount' => '2-3',
|
||||
],
|
||||
'WORKDAY.INTL' => [
|
||||
|
|
@ -2601,7 +2604,7 @@ class Calculation
|
|||
],
|
||||
'XIRR' => [
|
||||
'category' => Category::CATEGORY_FINANCIAL,
|
||||
'functionCall' => [Financial::class, 'XIRR'],
|
||||
'functionCall' => [Financial\CashFlow\Variable\NonPeriodic::class, 'rate'],
|
||||
'argumentCount' => '2,3',
|
||||
],
|
||||
'XLOOKUP' => [
|
||||
|
|
@ -2611,7 +2614,7 @@ class Calculation
|
|||
],
|
||||
'XNPV' => [
|
||||
'category' => Category::CATEGORY_FINANCIAL,
|
||||
'functionCall' => [Financial::class, 'XNPV'],
|
||||
'functionCall' => [Financial\CashFlow\Variable\NonPeriodic::class, 'presentValue'],
|
||||
'argumentCount' => '3',
|
||||
],
|
||||
'XMATCH' => [
|
||||
|
|
@ -2626,12 +2629,12 @@ class Calculation
|
|||
],
|
||||
'YEAR' => [
|
||||
'category' => Category::CATEGORY_DATE_AND_TIME,
|
||||
'functionCall' => [DateTimeExcel\Year::class, 'funcYear'],
|
||||
'functionCall' => [DateTimeExcel\DateParts::class, 'year'],
|
||||
'argumentCount' => '1',
|
||||
],
|
||||
'YEARFRAC' => [
|
||||
'category' => Category::CATEGORY_DATE_AND_TIME,
|
||||
'functionCall' => [DateTimeExcel\YearFrac::class, 'funcYearFrac'],
|
||||
'functionCall' => [DateTimeExcel\YearFrac::class, 'fraction'],
|
||||
'argumentCount' => '2,3',
|
||||
],
|
||||
'YIELD' => [
|
||||
|
|
@ -3798,6 +3801,8 @@ class Calculation
|
|||
|
||||
$regexpMatchString = '/^(' . self::CALCULATION_REGEXP_FUNCTION .
|
||||
'|' . self::CALCULATION_REGEXP_CELLREF .
|
||||
'|' . self::CALCULATION_REGEXP_COLUMN_RANGE .
|
||||
'|' . self::CALCULATION_REGEXP_ROW_RANGE .
|
||||
'|' . self::CALCULATION_REGEXP_NUMBER .
|
||||
'|' . self::CALCULATION_REGEXP_STRING .
|
||||
'|' . self::CALCULATION_REGEXP_OPENBRACE .
|
||||
|
|
@ -3866,7 +3871,8 @@ class Calculation
|
|||
$opCharacter .= $formula[++$index];
|
||||
}
|
||||
// Find out if we're currently at the beginning of a number, variable, cell reference, function, parenthesis or operand
|
||||
$isOperandOrFunction = preg_match($regexpMatchString, substr($formula, $index), $match);
|
||||
$isOperandOrFunction = (bool) preg_match($regexpMatchString, substr($formula, $index), $match);
|
||||
|
||||
if ($opCharacter == '-' && !$expectingOperator) { // Is it a negation instead of a minus?
|
||||
// Put a negation on the stack
|
||||
$stack->push('Unary Operator', '~', null, $currentCondition, $currentOnlyIf, $currentOnlyIfNot);
|
||||
|
|
@ -4038,6 +4044,7 @@ class Calculation
|
|||
$expectingOperand = false;
|
||||
$val = $match[1];
|
||||
$length = strlen($val);
|
||||
|
||||
if (preg_match('/^' . self::CALCULATION_REGEXP_FUNCTION . '$/miu', $val, $matches)) {
|
||||
$val = preg_replace('/\s/u', '', $val);
|
||||
if (isset(self::$phpSpreadsheetFunctions[strtoupper($matches[1])]) || isset(self::$controlFunctions[strtoupper($matches[1])])) { // it's a function
|
||||
|
|
@ -4074,7 +4081,7 @@ class Calculation
|
|||
// Should only be applied to the actual cell column, not the worksheet name
|
||||
// If the last entry on the stack was a : operator, then we have a cell range reference
|
||||
$testPrevOp = $stack->last(1);
|
||||
if ($testPrevOp !== null && $testPrevOp['value'] == ':') {
|
||||
if ($testPrevOp !== null && $testPrevOp['value'] === ':') {
|
||||
// If we have a worksheet reference, then we're playing with a 3D reference
|
||||
if ($matches[2] == '') {
|
||||
// Otherwise, we 'inherit' the worksheet reference from the start cell reference
|
||||
|
|
@ -4091,62 +4098,57 @@ class Calculation
|
|||
return $this->raiseFormulaError('3D Range references are not yet supported');
|
||||
}
|
||||
}
|
||||
} elseif (strpos($val, '!') === false && $pCellParent !== null) {
|
||||
$worksheet = $pCellParent->getTitle();
|
||||
$val = "'{$worksheet}'!{$val}";
|
||||
}
|
||||
|
||||
$outputItem = $stack->getStackItem('Cell Reference', $val, $val, $currentCondition, $currentOnlyIf, $currentOnlyIfNot);
|
||||
|
||||
$output[] = $outputItem;
|
||||
} else { // it's a variable, constant, string, number or boolean
|
||||
$localeConstant = false;
|
||||
$stackItemType = 'Value';
|
||||
$stackItemReference = null;
|
||||
|
||||
// If the last entry on the stack was a : operator, then we may have a row or column range reference
|
||||
$testPrevOp = $stack->last(1);
|
||||
if ($testPrevOp !== null && $testPrevOp['value'] === ':') {
|
||||
$stackItemType = 'Cell Reference';
|
||||
$startRowColRef = $output[count($output) - 1]['value'];
|
||||
[$rangeWS1, $startRowColRef] = Worksheet::extractSheetTitle($startRowColRef, true);
|
||||
$rangeSheetRef = $rangeWS1;
|
||||
if ($rangeWS1 != '') {
|
||||
if ($rangeWS1 !== '') {
|
||||
$rangeWS1 .= '!';
|
||||
}
|
||||
$rangeSheetRef = trim($rangeSheetRef, "'");
|
||||
[$rangeWS2, $val] = Worksheet::extractSheetTitle($val, true);
|
||||
if ($rangeWS2 != '') {
|
||||
if ($rangeWS2 !== '') {
|
||||
$rangeWS2 .= '!';
|
||||
} else {
|
||||
$rangeWS2 = $rangeWS1;
|
||||
}
|
||||
|
||||
$refSheet = $pCellParent;
|
||||
if ($pCellParent !== null && $rangeSheetRef !== $pCellParent->getTitle()) {
|
||||
if ($pCellParent !== null && $rangeSheetRef !== '' && $rangeSheetRef !== $pCellParent->getTitle()) {
|
||||
$refSheet = $pCellParent->getParent()->getSheetByName($rangeSheetRef);
|
||||
}
|
||||
if (
|
||||
(is_int($startRowColRef)) && (ctype_digit($val)) &&
|
||||
($startRowColRef <= 1048576) && ($val <= 1048576)
|
||||
) {
|
||||
// Row range
|
||||
$endRowColRef = ($refSheet !== null) ? $refSheet->getHighestColumn() : 'XFD'; // Max 16,384 columns for Excel2007
|
||||
$output[count($output) - 1]['value'] = $rangeWS1 . 'A' . $startRowColRef;
|
||||
$val = $rangeWS2 . $endRowColRef . $val;
|
||||
} elseif (
|
||||
(ctype_alpha($startRowColRef)) && (ctype_alpha($val)) &&
|
||||
(strlen($startRowColRef) <= 3) && (strlen($val) <= 3)
|
||||
) {
|
||||
// Column range
|
||||
$endRowColRef = ($refSheet !== null) ? $refSheet->getHighestRow() : 1048576; // Max 1,048,576 rows for Excel2007
|
||||
$output[count($output) - 1]['value'] = $rangeWS1 . strtoupper($startRowColRef) . '1';
|
||||
$val = $rangeWS2 . $val . $endRowColRef;
|
||||
}
|
||||
}
|
||||
|
||||
$localeConstant = false;
|
||||
$stackItemType = 'Value';
|
||||
$stackItemReference = null;
|
||||
if ($opCharacter == self::FORMULA_STRING_QUOTE) {
|
||||
if (ctype_digit($val) && $val <= 1048576) {
|
||||
// Row range
|
||||
$stackItemType = 'Row Reference';
|
||||
$endRowColRef = ($refSheet !== null) ? $refSheet->getHighestDataColumn($val) : 'XFD'; // Max 16,384 columns for Excel2007
|
||||
$val = "{$rangeWS2}{$endRowColRef}{$val}";
|
||||
} elseif (ctype_alpha($val) && strlen($val) <= 3) {
|
||||
// Column range
|
||||
$stackItemType = 'Column Reference';
|
||||
$endRowColRef = ($refSheet !== null) ? $refSheet->getHighestDataRow($val) : 1048576; // Max 1,048,576 rows for Excel2007
|
||||
$val = "{$rangeWS2}{$val}{$endRowColRef}";
|
||||
}
|
||||
$stackItemReference = $val;
|
||||
} elseif ($opCharacter == self::FORMULA_STRING_QUOTE) {
|
||||
// UnEscape any quotes within the string
|
||||
$val = self::wrapResult(str_replace('""', self::FORMULA_STRING_QUOTE, self::unwrapResult($val)));
|
||||
} elseif (is_numeric($val)) {
|
||||
if ((strpos($val, '.') !== false) || (stripos($val, 'e') !== false) || ($val > PHP_INT_MAX) || ($val < -PHP_INT_MAX)) {
|
||||
$val = (float) $val;
|
||||
} else {
|
||||
$val = (int) $val;
|
||||
}
|
||||
} elseif (isset(self::$excelConstants[trim(strtoupper($val))])) {
|
||||
$stackItemType = 'Constant';
|
||||
$excelConstant = trim(strtoupper($val));
|
||||
|
|
@ -4154,10 +4156,41 @@ class Calculation
|
|||
} elseif (($localeConstant = array_search(trim(strtoupper($val)), self::$localeBoolean)) !== false) {
|
||||
$stackItemType = 'Constant';
|
||||
$val = self::$excelConstants[$localeConstant];
|
||||
} elseif (
|
||||
preg_match('/^' . self::CALCULATION_REGEXP_ROW_RANGE . '/miu', substr($formula, $index), $rowRangeReference)
|
||||
) {
|
||||
$val = $rowRangeReference[1];
|
||||
$length = strlen($rowRangeReference[1]);
|
||||
$stackItemType = 'Row Reference';
|
||||
$column = 'A';
|
||||
if (($testPrevOp !== null && $testPrevOp['value'] === ':') && $pCellParent !== null) {
|
||||
$column = $pCellParent->getHighestDataColumn($val);
|
||||
}
|
||||
$val = "{$rowRangeReference[2]}{$column}{$rowRangeReference[7]}";
|
||||
$stackItemReference = $val;
|
||||
} elseif (
|
||||
preg_match('/^' . self::CALCULATION_REGEXP_COLUMN_RANGE . '/miu', substr($formula, $index), $columnRangeReference)
|
||||
) {
|
||||
$val = $columnRangeReference[1];
|
||||
$length = strlen($val);
|
||||
$stackItemType = 'Column Reference';
|
||||
$row = '1';
|
||||
if (($testPrevOp !== null && $testPrevOp['value'] === ':') && $pCellParent !== null) {
|
||||
$row = $pCellParent->getHighestDataRow($val);
|
||||
}
|
||||
$val = "{$val}{$row}";
|
||||
$stackItemReference = $val;
|
||||
} elseif (preg_match('/^' . self::CALCULATION_REGEXP_DEFINEDNAME . '.*/miu', $val, $match)) {
|
||||
$stackItemType = 'Defined Name';
|
||||
$stackItemReference = $val;
|
||||
} elseif (is_numeric($val)) {
|
||||
if ((strpos($val, '.') !== false) || (stripos($val, 'e') !== false) || ($val > PHP_INT_MAX) || ($val < -PHP_INT_MAX)) {
|
||||
$val = (float) $val;
|
||||
} else {
|
||||
$val = (int) $val;
|
||||
}
|
||||
}
|
||||
|
||||
$details = $stack->getStackItem($stackItemType, $val, $stackItemReference, $currentCondition, $currentOnlyIf, $currentOnlyIfNot);
|
||||
if ($localeConstant) {
|
||||
$details['localeValue'] = $localeConstant;
|
||||
|
|
@ -4431,6 +4464,7 @@ class Calculation
|
|||
} else {
|
||||
return $this->raiseFormulaError('Unable to access Cell Reference');
|
||||
}
|
||||
|
||||
$stack->push('Cell Reference', $cellValue, $cellRef);
|
||||
} else {
|
||||
$stack->push('Error', Functions::REF(), null);
|
||||
|
|
@ -4564,6 +4598,7 @@ class Calculation
|
|||
}
|
||||
} elseif (preg_match('/^' . self::CALCULATION_REGEXP_CELLREF . '$/i', $token, $matches)) {
|
||||
$cellRef = null;
|
||||
|
||||
if (isset($matches[8])) {
|
||||
if ($pCell === null) {
|
||||
// We can't access the range, so return a REF error
|
||||
|
|
@ -4596,7 +4631,7 @@ class Calculation
|
|||
}
|
||||
} else {
|
||||
if ($pCell === null) {
|
||||
// We can't access the cell, so return a REF error
|
||||
// We can't access the cell, so return a REF error
|
||||
$cellValue = Functions::REF();
|
||||
} else {
|
||||
$cellRef = $matches[6] . $matches[7];
|
||||
|
|
@ -4613,6 +4648,7 @@ class Calculation
|
|||
$cellValue = $this->extractCellRange($cellRef, $this->spreadsheet->getSheetByName($matches[2]), false);
|
||||
$pCell->attach($pCellParent);
|
||||
} else {
|
||||
$cellRef = ($cellSheet !== null) ? "{$matches[2]}!{$cellRef}" : $cellRef;
|
||||
$cellValue = null;
|
||||
}
|
||||
} else {
|
||||
|
|
@ -4631,7 +4667,8 @@ class Calculation
|
|||
}
|
||||
}
|
||||
}
|
||||
$stack->push('Value', $cellValue, $cellRef);
|
||||
|
||||
$stack->push('Cell Value', $cellValue, $cellRef);
|
||||
if (isset($storeKey)) {
|
||||
$branchStore[$storeKey] = $cellValue;
|
||||
}
|
||||
|
|
@ -5116,6 +5153,7 @@ class Calculation
|
|||
|
||||
if ($pSheet !== null) {
|
||||
$pSheetName = $pSheet->getTitle();
|
||||
|
||||
if (strpos($pRange, '!') !== false) {
|
||||
[$pSheetName, $pRange] = Worksheet::extractSheetTitle($pRange, true);
|
||||
$pSheet = $this->spreadsheet->getSheetByName($pSheetName);
|
||||
|
|
|
|||
|
|
@ -17,7 +17,8 @@ class Database
|
|||
*
|
||||
* @Deprecated 1.17.0
|
||||
*
|
||||
* @see Use the evaluate() method in the Database\DAverage class instead
|
||||
* @see Database\DAverage::evaluate()
|
||||
* Use the evaluate() method in the Database\DAverage class instead
|
||||
*
|
||||
* @param mixed[] $database The range of cells that makes up the list or database.
|
||||
* A database is a list of related data in which rows of related
|
||||
|
|
@ -52,7 +53,8 @@ class Database
|
|||
*
|
||||
* @Deprecated 1.17.0
|
||||
*
|
||||
* @see Use the evaluate() method in the Database\DCount class instead
|
||||
* @see Database\DCount::evaluate()
|
||||
* Use the evaluate() method in the Database\DCount class instead
|
||||
*
|
||||
* @param mixed[] $database The range of cells that makes up the list or database.
|
||||
* A database is a list of related data in which rows of related
|
||||
|
|
@ -89,7 +91,8 @@ class Database
|
|||
*
|
||||
* @Deprecated 1.17.0
|
||||
*
|
||||
* @see Use the evaluate() method in the Database\DCountA class instead
|
||||
* @see Database\DCountA::evaluate()
|
||||
* Use the evaluate() method in the Database\DCountA class instead
|
||||
*
|
||||
* @param mixed[] $database The range of cells that makes up the list or database.
|
||||
* A database is a list of related data in which rows of related
|
||||
|
|
@ -124,7 +127,8 @@ class Database
|
|||
*
|
||||
* @Deprecated 1.17.0
|
||||
*
|
||||
* @see Use the evaluate() method in the Database\DGet class instead
|
||||
* @see Database\DGet::evaluate()
|
||||
* Use the evaluate() method in the Database\DGet class instead
|
||||
*
|
||||
* @param mixed[] $database The range of cells that makes up the list or database.
|
||||
* A database is a list of related data in which rows of related
|
||||
|
|
@ -159,7 +163,8 @@ class Database
|
|||
*
|
||||
* @Deprecated 1.17.0
|
||||
*
|
||||
* @see Use the evaluate() method in the Database\DMax class instead
|
||||
* @see Database\DMax::evaluate()
|
||||
* Use the evaluate() method in the Database\DMax class instead
|
||||
*
|
||||
* @param mixed[] $database The range of cells that makes up the list or database.
|
||||
* A database is a list of related data in which rows of related
|
||||
|
|
@ -194,7 +199,8 @@ class Database
|
|||
*
|
||||
* @Deprecated 1.17.0
|
||||
*
|
||||
* @see Use the evaluate() method in the Database\DMin class instead
|
||||
* @see Database\DMin::evaluate()
|
||||
* Use the evaluate() method in the Database\DMin class instead
|
||||
*
|
||||
* @param mixed[] $database The range of cells that makes up the list or database.
|
||||
* A database is a list of related data in which rows of related
|
||||
|
|
@ -228,7 +234,8 @@ class Database
|
|||
*
|
||||
* @Deprecated 1.17.0
|
||||
*
|
||||
* @see Use the evaluate() method in the Database\DProduct class instead
|
||||
* @see Database\DProduct::evaluate()
|
||||
* Use the evaluate() method in the Database\DProduct class instead
|
||||
*
|
||||
* @param mixed[] $database The range of cells that makes up the list or database.
|
||||
* A database is a list of related data in which rows of related
|
||||
|
|
@ -263,7 +270,8 @@ class Database
|
|||
*
|
||||
* @Deprecated 1.17.0
|
||||
*
|
||||
* @see Use the evaluate() method in the Database\DStDev class instead
|
||||
* @see Database\DStDev::evaluate()
|
||||
* Use the evaluate() method in the Database\DStDev class instead
|
||||
*
|
||||
* @param mixed[] $database The range of cells that makes up the list or database.
|
||||
* A database is a list of related data in which rows of related
|
||||
|
|
@ -298,7 +306,8 @@ class Database
|
|||
*
|
||||
* @Deprecated 1.17.0
|
||||
*
|
||||
* @see Use the evaluate() method in the Database\DStDevP class instead
|
||||
* @see Database\DStDevP::evaluate()
|
||||
* Use the evaluate() method in the Database\DStDevP class instead
|
||||
*
|
||||
* @param mixed[] $database The range of cells that makes up the list or database.
|
||||
* A database is a list of related data in which rows of related
|
||||
|
|
@ -332,7 +341,8 @@ class Database
|
|||
*
|
||||
* @Deprecated 1.17.0
|
||||
*
|
||||
* @see Use the evaluate() method in the Database\DSum class instead
|
||||
* @see Database\DSum::evaluate()
|
||||
* Use the evaluate() method in the Database\DSum class instead
|
||||
*
|
||||
* @param mixed[] $database The range of cells that makes up the list or database.
|
||||
* A database is a list of related data in which rows of related
|
||||
|
|
@ -367,7 +377,8 @@ class Database
|
|||
*
|
||||
* @Deprecated 1.17.0
|
||||
*
|
||||
* @see Use the evaluate() method in the Database\DVar class instead
|
||||
* @see Database\DVar::evaluate()
|
||||
* Use the evaluate() method in the Database\DVar class instead
|
||||
*
|
||||
* @param mixed[] $database The range of cells that makes up the list or database.
|
||||
* A database is a list of related data in which rows of related
|
||||
|
|
@ -402,7 +413,8 @@ class Database
|
|||
*
|
||||
* @Deprecated 1.17.0
|
||||
*
|
||||
* @see Use the evaluate() method in the Database\DVarP class instead
|
||||
* @see Database\DVarP::evaluate()
|
||||
* Use the evaluate() method in the Database\DVarP class instead
|
||||
*
|
||||
* @param mixed[] $database The range of cells that makes up the list or database.
|
||||
* A database is a list of related data in which rows of related
|
||||
|
|
|
|||
|
|
@ -4,12 +4,18 @@ namespace PhpOffice\PhpSpreadsheet\Calculation;
|
|||
|
||||
use DateTimeInterface;
|
||||
|
||||
/**
|
||||
* @deprecated 1.18.0
|
||||
*/
|
||||
class DateTime
|
||||
{
|
||||
/**
|
||||
* Identify if a year is a leap year or not.
|
||||
*
|
||||
* @Deprecated 2.0.0 Use the method isLeapYear in the DateTimeExcel\Helpers class instead
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @See DateTimeExcel\Helpers::isLeapYear()
|
||||
* Use the isLeapYear method in the DateTimeExcel\Helpers class instead
|
||||
*
|
||||
* @param int|string $year The year to test
|
||||
*
|
||||
|
|
@ -23,7 +29,10 @@ class DateTime
|
|||
/**
|
||||
* getDateValue.
|
||||
*
|
||||
* @Deprecated 2.0.0 Use the method getDateValue in the DateTimeExcel\Helpers class instead
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @See DateTimeExcel\Helpers::getDateValue()
|
||||
* Use the getDateValue method in the DateTimeExcel\Helpers class instead
|
||||
*
|
||||
* @param mixed $dateValue
|
||||
*
|
||||
|
|
@ -49,17 +58,20 @@ class DateTime
|
|||
* NOTE: When used in a Cell Formula, MS Excel changes the cell format so that it matches the date
|
||||
* and time format of your regional settings. PhpSpreadsheet does not change cell formatting in this way.
|
||||
*
|
||||
* @Deprecated 2.0.0 Use the funcNow method in the DateTimeExcel\Now class instead
|
||||
*
|
||||
* Excel Function:
|
||||
* NOW()
|
||||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @See DateTimeExcel\Current::now()
|
||||
* Use the now method in the DateTimeExcel\Current class instead
|
||||
*
|
||||
* @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object,
|
||||
* depending on the value of the ReturnDateType flag
|
||||
*/
|
||||
public static function DATETIMENOW()
|
||||
{
|
||||
return DateTimeExcel\Now::funcNow();
|
||||
return DateTimeExcel\Current::now();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -73,17 +85,20 @@ class DateTime
|
|||
* NOTE: When used in a Cell Formula, MS Excel changes the cell format so that it matches the date
|
||||
* and time format of your regional settings. PhpSpreadsheet does not change cell formatting in this way.
|
||||
*
|
||||
* @Deprecated 2.0.0 Use the funcToday method in the DateTimeExcel\Today class instead
|
||||
*
|
||||
* Excel Function:
|
||||
* TODAY()
|
||||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @See DateTimeExcel\Current::today()
|
||||
* Use the today method in the DateTimeExcel\Current class instead
|
||||
*
|
||||
* @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object,
|
||||
* depending on the value of the ReturnDateType flag
|
||||
*/
|
||||
public static function DATENOW()
|
||||
{
|
||||
return DateTimeExcel\Today::funcToday();
|
||||
return DateTimeExcel\Current::today();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -94,11 +109,15 @@ class DateTime
|
|||
* NOTE: When used in a Cell Formula, MS Excel changes the cell format so that it matches the date
|
||||
* format of your regional settings. PhpSpreadsheet does not change cell formatting in this way.
|
||||
*
|
||||
* @Deprecated 2.0.0 Use the funcDate method in the DateTimeExcel\Date class instead
|
||||
*
|
||||
* Excel Function:
|
||||
* DATE(year,month,day)
|
||||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @See DateTimeExcel\Date::fromYMD()
|
||||
* Use the fromYMD method in the DateTimeExcel\Date class instead
|
||||
*
|
||||
* PhpSpreadsheet is a lot more forgiving than MS Excel when passing non numeric values to this function.
|
||||
* A Month name or abbreviation (English only at this point) such as 'January' or 'Jan' will still be accepted,
|
||||
* as will a day value with a suffix (e.g. '21st' rather than simply 21); again only English language.
|
||||
|
|
@ -139,7 +158,7 @@ class DateTime
|
|||
*/
|
||||
public static function DATE($year = 0, $month = 1, $day = 1)
|
||||
{
|
||||
return DateTimeExcel\Datefunc::funcDate($year, $month, $day);
|
||||
return DateTimeExcel\Date::fromYMD($year, $month, $day);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -150,11 +169,14 @@ class DateTime
|
|||
* NOTE: When used in a Cell Formula, MS Excel changes the cell format so that it matches the time
|
||||
* format of your regional settings. PhpSpreadsheet does not change cell formatting in this way.
|
||||
*
|
||||
* @Deprecated 2.0.0 Use the funcTime method in the DateTimeExcel\Time class instead
|
||||
*
|
||||
* Excel Function:
|
||||
* TIME(hour,minute,second)
|
||||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @See DateTimeExcel\Time::fromHMS()
|
||||
* Use the fromHMS method in the DateTimeExcel\Time class instead
|
||||
*
|
||||
* @param int $hour A number from 0 (zero) to 32767 representing the hour.
|
||||
* Any value greater than 23 will be divided by 24 and the remainder
|
||||
* will be treated as the hour value. For example, TIME(27,0,0) =
|
||||
|
|
@ -172,7 +194,7 @@ class DateTime
|
|||
*/
|
||||
public static function TIME($hour = 0, $minute = 0, $second = 0)
|
||||
{
|
||||
return DateTimeExcel\Time::funcTime($hour, $minute, $second);
|
||||
return DateTimeExcel\Time::fromHMS($hour, $minute, $second);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -185,11 +207,14 @@ class DateTime
|
|||
* NOTE: When used in a Cell Formula, MS Excel changes the cell format so that it matches the date
|
||||
* format of your regional settings. PhpSpreadsheet does not change cell formatting in this way.
|
||||
*
|
||||
* @Deprecated 2.0.0 Use the funcDateValue method in the DateTimeExcel\DateValue class instead
|
||||
*
|
||||
* Excel Function:
|
||||
* DATEVALUE(dateValue)
|
||||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @See DateTimeExcel\DateValue::fromString()
|
||||
* Use the fromString method in the DateTimeExcel\DateValue class instead
|
||||
*
|
||||
* @param string $dateValue Text that represents a date in a Microsoft Excel date format.
|
||||
* For example, "1/30/2008" or "30-Jan-2008" are text strings within
|
||||
* quotation marks that represent dates. Using the default date
|
||||
|
|
@ -204,7 +229,7 @@ class DateTime
|
|||
*/
|
||||
public static function DATEVALUE($dateValue)
|
||||
{
|
||||
return DateTimeExcel\DateValue::funcDateValue($dateValue);
|
||||
return DateTimeExcel\DateValue::fromString($dateValue);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -217,11 +242,14 @@ class DateTime
|
|||
* NOTE: When used in a Cell Formula, MS Excel changes the cell format so that it matches the time
|
||||
* format of your regional settings. PhpSpreadsheet does not change cell formatting in this way.
|
||||
*
|
||||
* @Deprecated 2.0.0 Use the funcTimeValue method in the DateTimeExcel\TimeValue class instead
|
||||
*
|
||||
* Excel Function:
|
||||
* TIMEVALUE(timeValue)
|
||||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @See DateTimeExcel\TimeValue::fromString()
|
||||
* Use the fromString method in the DateTimeExcel\TimeValue class instead
|
||||
*
|
||||
* @param string $timeValue A text string that represents a time in any one of the Microsoft
|
||||
* Excel time formats; for example, "6:45 PM" and "18:45" text strings
|
||||
* within quotation marks that represent time.
|
||||
|
|
@ -232,13 +260,19 @@ class DateTime
|
|||
*/
|
||||
public static function TIMEVALUE($timeValue)
|
||||
{
|
||||
return DateTimeExcel\TimeValue::funcTimeValue($timeValue);
|
||||
return DateTimeExcel\TimeValue::fromString($timeValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* DATEDIF.
|
||||
*
|
||||
* @Deprecated 2.0.0 Use the funcDateDif method in the DateTimeExcel\DateDif class instead
|
||||
* Excel Function:
|
||||
* DATEDIF(startdate, enddate, unit)
|
||||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @See DateTimeExcel\Difference::interval()
|
||||
* Use the interval method in the DateTimeExcel\Difference class instead
|
||||
*
|
||||
* @param mixed $startDate Excel date serial value, PHP date/time stamp, PHP DateTime object
|
||||
* or a standard date string
|
||||
|
|
@ -250,7 +284,7 @@ class DateTime
|
|||
*/
|
||||
public static function DATEDIF($startDate = 0, $endDate = 0, $unit = 'D')
|
||||
{
|
||||
return DateTimeExcel\DateDif::funcDateDif($startDate, $endDate, $unit);
|
||||
return DateTimeExcel\Difference::interval($startDate, $endDate, $unit);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -258,11 +292,14 @@ class DateTime
|
|||
*
|
||||
* Returns the number of days between two dates
|
||||
*
|
||||
* @Deprecated 2.0.0 Use the funcDays method in the DateTimeExcel\Days class instead
|
||||
*
|
||||
* Excel Function:
|
||||
* DAYS(endDate, startDate)
|
||||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @See DateTimeExcel\Days::between()
|
||||
* Use the between method in the DateTimeExcel\Days class instead
|
||||
*
|
||||
* @param DateTimeInterface|float|int|string $endDate Excel date serial value (float),
|
||||
* PHP date timestamp (integer), PHP DateTime object, or a standard date string
|
||||
* @param DateTimeInterface|float|int|string $startDate Excel date serial value (float),
|
||||
|
|
@ -272,7 +309,7 @@ class DateTime
|
|||
*/
|
||||
public static function DAYS($endDate = 0, $startDate = 0)
|
||||
{
|
||||
return DateTimeExcel\Days::funcDays($endDate, $startDate);
|
||||
return DateTimeExcel\Days::between($endDate, $startDate);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -282,11 +319,14 @@ class DateTime
|
|||
* which is used in some accounting calculations. Use this function to help compute payments if
|
||||
* your accounting system is based on twelve 30-day months.
|
||||
*
|
||||
* @Deprecated 2.0.0 Use the funcDays360 method in the DateTimeExcel\Days360 class instead
|
||||
*
|
||||
* Excel Function:
|
||||
* DAYS360(startDate,endDate[,method])
|
||||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @See DateTimeExcel\Days360::between()
|
||||
* Use the between method in the DateTimeExcel\Days360 class instead
|
||||
*
|
||||
* @param mixed $startDate Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard date string
|
||||
* @param mixed $endDate Excel date serial value (float), PHP date timestamp (integer),
|
||||
|
|
@ -307,7 +347,7 @@ class DateTime
|
|||
*/
|
||||
public static function DAYS360($startDate = 0, $endDate = 0, $method = false)
|
||||
{
|
||||
return DateTimeExcel\Days360::funcDays360($startDate, $endDate, $method);
|
||||
return DateTimeExcel\Days360::between($startDate, $endDate, $method);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -318,10 +358,14 @@ class DateTime
|
|||
* Use the YEARFRAC worksheet function to identify the proportion of a whole year's benefits or
|
||||
* obligations to assign to a specific term.
|
||||
*
|
||||
* @Deprecated 2.0.0 Use the funcYearFrac method in the DateTimeExcel\YearFrac class instead
|
||||
*
|
||||
* Excel Function:
|
||||
* YEARFRAC(startDate,endDate[,method])
|
||||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @See DateTimeExcel\YearFrac::fraction()
|
||||
* Use the fraction method in the DateTimeExcel\YearFrac class instead
|
||||
*
|
||||
* See https://lists.oasis-open.org/archives/office-formula/200806/msg00039.html
|
||||
* for description of algorithm used in Excel
|
||||
*
|
||||
|
|
@ -340,7 +384,7 @@ class DateTime
|
|||
*/
|
||||
public static function YEARFRAC($startDate = 0, $endDate = 0, $method = 0)
|
||||
{
|
||||
return DateTimeExcel\YearFrac::funcYearFrac($startDate, $endDate, $method);
|
||||
return DateTimeExcel\YearFrac::fraction($startDate, $endDate, $method);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -351,21 +395,25 @@ class DateTime
|
|||
* Use NETWORKDAYS to calculate employee benefits that accrue based on the number of days
|
||||
* worked during a specific term.
|
||||
*
|
||||
* @Deprecated 2.0.0 Use the funcNetworkDays method in the DateTimeExcel\NetworkDays class instead
|
||||
*
|
||||
* Excel Function:
|
||||
* NETWORKDAYS(startDate,endDate[,holidays[,holiday[,...]]])
|
||||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @See DateTimeExcel\NetworkDays::count()
|
||||
* Use the count method in the DateTimeExcel\NetworkDays class instead
|
||||
*
|
||||
* @param mixed $startDate Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard date string
|
||||
* @param mixed $endDate Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard date string
|
||||
* @param mixed $dateArgs
|
||||
*
|
||||
* @return int|string Interval between the dates
|
||||
*/
|
||||
public static function NETWORKDAYS($startDate, $endDate, ...$dateArgs)
|
||||
{
|
||||
return DateTimeExcel\NetworkDays::funcNetworkDays($startDate, $endDate, ...$dateArgs);
|
||||
return DateTimeExcel\NetworkDays::count($startDate, $endDate, ...$dateArgs);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -376,23 +424,27 @@ class DateTime
|
|||
* Use WORKDAY to exclude weekends or holidays when you calculate invoice due dates, expected
|
||||
* delivery times, or the number of days of work performed.
|
||||
*
|
||||
* @Deprecated 2.0.0 Use the funcWorkDay method in the DateTimeExcel\WorkDay class instead
|
||||
*
|
||||
* Excel Function:
|
||||
* WORKDAY(startDate,endDays[,holidays[,holiday[,...]]])
|
||||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @See DateTimeExcel\WorkDay::date()
|
||||
* Use the date method in the DateTimeExcel\WorkDay class instead
|
||||
*
|
||||
* @param mixed $startDate Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard date string
|
||||
* @param int $endDays The number of nonweekend and nonholiday days before or after
|
||||
* startDate. A positive value for days yields a future date; a
|
||||
* negative value yields a past date.
|
||||
* @param mixed $dateArgs
|
||||
*
|
||||
* @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object,
|
||||
* depending on the value of the ReturnDateType flag
|
||||
*/
|
||||
public static function WORKDAY($startDate, $endDays, ...$dateArgs)
|
||||
{
|
||||
return DateTimeExcel\WorkDay::funcWorkDay($startDate, $endDays, ...$dateArgs);
|
||||
return DateTimeExcel\WorkDay::date($startDate, $endDays, ...$dateArgs);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -401,11 +453,14 @@ class DateTime
|
|||
* Returns the day of the month, for a specified date. The day is given as an integer
|
||||
* ranging from 1 to 31.
|
||||
*
|
||||
* @Deprecated 2.0.0 Use the funcDay method in the DateTimeExcel\Day class instead
|
||||
*
|
||||
* Excel Function:
|
||||
* DAY(dateValue)
|
||||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @See DateTimeExcel\DateParts::day()
|
||||
* Use the day method in the DateTimeExcel\DateParts class instead
|
||||
*
|
||||
* @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard date string
|
||||
*
|
||||
|
|
@ -413,7 +468,7 @@ class DateTime
|
|||
*/
|
||||
public static function DAYOFMONTH($dateValue = 1)
|
||||
{
|
||||
return DateTimeExcel\Day::funcDay($dateValue);
|
||||
return DateTimeExcel\DateParts::day($dateValue);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -422,11 +477,14 @@ class DateTime
|
|||
* Returns the day of the week for a specified date. The day is given as an integer
|
||||
* ranging from 0 to 7 (dependent on the requested style).
|
||||
*
|
||||
* @Deprecated 2.0.0 Use the funcWeekDay method in the DateTimeExcel\WeekDay class instead
|
||||
*
|
||||
* Excel Function:
|
||||
* WEEKDAY(dateValue[,style])
|
||||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @See DateTimeExcel\Week::day()
|
||||
* Use the day method in the DateTimeExcel\Week class instead
|
||||
*
|
||||
* @param float|int|string $dateValue Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard date string
|
||||
* @param int $style A number that determines the type of return value
|
||||
|
|
@ -438,13 +496,13 @@ class DateTime
|
|||
*/
|
||||
public static function WEEKDAY($dateValue = 1, $style = 1)
|
||||
{
|
||||
return DateTimeExcel\WeekDay::funcWeekDay($dateValue, $style);
|
||||
return DateTimeExcel\Week::day($dateValue, $style);
|
||||
}
|
||||
|
||||
/**
|
||||
* STARTWEEK_SUNDAY.
|
||||
*
|
||||
* @Deprecated 2.0.0
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see Use DateTimeExcel\Constants\STARTWEEK_SUNDAY instead
|
||||
*/
|
||||
|
|
@ -453,7 +511,7 @@ class DateTime
|
|||
/**
|
||||
* STARTWEEK_MONDAY.
|
||||
*
|
||||
* @Deprecated 2.0.0
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see Use DateTimeExcel\Constants\STARTWEEK_MONDAY instead
|
||||
*/
|
||||
|
|
@ -462,7 +520,7 @@ class DateTime
|
|||
/**
|
||||
* STARTWEEK_MONDAY_ALT.
|
||||
*
|
||||
* @Deprecated 2.0.0
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see Use DateTimeExcel\Constants\STARTWEEK_MONDAY_ALT instead
|
||||
*/
|
||||
|
|
@ -471,7 +529,7 @@ class DateTime
|
|||
/**
|
||||
* STARTWEEK_TUESDAY.
|
||||
*
|
||||
* @Deprecated 2.0.0
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see Use DateTimeExcel\Constants\STARTWEEK_TUESDAY instead
|
||||
*/
|
||||
|
|
@ -480,7 +538,7 @@ class DateTime
|
|||
/**
|
||||
* STARTWEEK_WEDNESDAY.
|
||||
*
|
||||
* @Deprecated 2.0.0
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see Use DateTimeExcel\Constants\STARTWEEK_WEDNESDAY instead
|
||||
*/
|
||||
|
|
@ -489,7 +547,7 @@ class DateTime
|
|||
/**
|
||||
* STARTWEEK_THURSDAY.
|
||||
*
|
||||
* @Deprecated 2.0.0
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see Use DateTimeExcel\Constants\STARTWEEK_THURSDAY instead
|
||||
*/
|
||||
|
|
@ -498,7 +556,7 @@ class DateTime
|
|||
/**
|
||||
* STARTWEEK_FRIDAY.
|
||||
*
|
||||
* @Deprecated 2.0.0
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see Use DateTimeExcel\Constants\STARTWEEK_FRIDAY instead
|
||||
*/
|
||||
|
|
@ -507,7 +565,7 @@ class DateTime
|
|||
/**
|
||||
* STARTWEEK_SATURDAY.
|
||||
*
|
||||
* @Deprecated 2.0.0
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see Use DateTimeExcel\Constants\STARTWEEK_SATURDAY instead
|
||||
*/
|
||||
|
|
@ -516,7 +574,7 @@ class DateTime
|
|||
/**
|
||||
* STARTWEEK_SUNDAY_ALT.
|
||||
*
|
||||
* @Deprecated 2.0.0
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see Use DateTimeExcel\Constants\STARTWEEK_SUNDAY_ALT instead
|
||||
*/
|
||||
|
|
@ -525,7 +583,7 @@ class DateTime
|
|||
/**
|
||||
* DOW_SUNDAY.
|
||||
*
|
||||
* @Deprecated 2.0.0
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see Use DateTimeExcel\Constants\DOW_SUNDAY instead
|
||||
*/
|
||||
|
|
@ -534,7 +592,7 @@ class DateTime
|
|||
/**
|
||||
* DOW_MONDAY.
|
||||
*
|
||||
* @Deprecated 2.0.0
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see Use DateTimeExcel\Constants\DOW_MONDAY instead
|
||||
*/
|
||||
|
|
@ -543,7 +601,7 @@ class DateTime
|
|||
/**
|
||||
* DOW_TUESDAY.
|
||||
*
|
||||
* @Deprecated 2.0.0
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see Use DateTimeExcel\Constants\DOW_TUESDAY instead
|
||||
*/
|
||||
|
|
@ -552,7 +610,7 @@ class DateTime
|
|||
/**
|
||||
* DOW_WEDNESDAY.
|
||||
*
|
||||
* @Deprecated 2.0.0
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see Use DateTimeExcel\Constants\DOW_WEDNESDAY instead
|
||||
*/
|
||||
|
|
@ -561,7 +619,7 @@ class DateTime
|
|||
/**
|
||||
* DOW_THURSDAY.
|
||||
*
|
||||
* @Deprecated 2.0.0
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see Use DateTimeExcel\Constants\DOW_THURSDAY instead
|
||||
*/
|
||||
|
|
@ -570,7 +628,7 @@ class DateTime
|
|||
/**
|
||||
* DOW_FRIDAY.
|
||||
*
|
||||
* @Deprecated 2.0.0
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see Use DateTimeExcel\Constants\DOW_FRIDAY instead
|
||||
*/
|
||||
|
|
@ -579,7 +637,7 @@ class DateTime
|
|||
/**
|
||||
* DOW_SATURDAY.
|
||||
*
|
||||
* @Deprecated 2.0.0
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see Use DateTimeExcel\Constants\DOW_SATURDAY instead
|
||||
*/
|
||||
|
|
@ -588,7 +646,7 @@ class DateTime
|
|||
/**
|
||||
* STARTWEEK_MONDAY_ISO.
|
||||
*
|
||||
* @Deprecated 2.0.0
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see Use DateTimeExcel\Constants\STARTWEEK_MONDAY_ISO instead
|
||||
*/
|
||||
|
|
@ -597,7 +655,7 @@ class DateTime
|
|||
/**
|
||||
* METHODARR.
|
||||
*
|
||||
* @Deprecated 2.0.0
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see Use DateTimeExcel\Constants\METHODARR instead
|
||||
*/
|
||||
|
|
@ -624,11 +682,14 @@ class DateTime
|
|||
* three days or less in the first week of January, the WEEKNUM function returns week numbers
|
||||
* that are incorrect according to the European standard.
|
||||
*
|
||||
* @Deprecated 2.0.0 Use the funcWeekNum method in the DateTimeExcel\WeekNum class instead
|
||||
*
|
||||
* Excel Function:
|
||||
* WEEKNUM(dateValue[,style])
|
||||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @See DateTimeExcel\Week::number(()
|
||||
* Use the number method in the DateTimeExcel\Week class instead
|
||||
*
|
||||
* @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard date string
|
||||
* @param int $method Week begins on Sunday or Monday
|
||||
|
|
@ -647,7 +708,7 @@ class DateTime
|
|||
*/
|
||||
public static function WEEKNUM($dateValue = 1, $method = self::STARTWEEK_SUNDAY)
|
||||
{
|
||||
return DateTimeExcel\WeekNum::funcWeekNum($dateValue, $method);
|
||||
return DateTimeExcel\Week::number($dateValue, $method);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -655,11 +716,14 @@ class DateTime
|
|||
*
|
||||
* Returns the ISO 8601 week number of the year for a specified date.
|
||||
*
|
||||
* @Deprecated 2.0.0 Use the funcIsoWeeknum method in the DateTimeExcel\IsoWeekNum class instead
|
||||
*
|
||||
* Excel Function:
|
||||
* ISOWEEKNUM(dateValue)
|
||||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @See DateTimeExcel\Week::isoWeekNumber()
|
||||
* Use the isoWeekNumber method in the DateTimeExcel\Week class instead
|
||||
*
|
||||
* @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard date string
|
||||
*
|
||||
|
|
@ -667,7 +731,7 @@ class DateTime
|
|||
*/
|
||||
public static function ISOWEEKNUM($dateValue = 1)
|
||||
{
|
||||
return DateTimeExcel\IsoWeekNum::funcIsoWeekNum($dateValue);
|
||||
return DateTimeExcel\Week::isoWeekNumber($dateValue);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -676,11 +740,14 @@ class DateTime
|
|||
* Returns the month of a date represented by a serial number.
|
||||
* The month is given as an integer, ranging from 1 (January) to 12 (December).
|
||||
*
|
||||
* @Deprecated 2.0.0 Use the funcMonth method in the DateTimeExcel\Month class instead
|
||||
*
|
||||
* Excel Function:
|
||||
* MONTH(dateValue)
|
||||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @See DateTimeExcel\DateParts::month()
|
||||
* Use the month method in the DateTimeExcel\DateParts class instead
|
||||
*
|
||||
* @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard date string
|
||||
*
|
||||
|
|
@ -688,7 +755,7 @@ class DateTime
|
|||
*/
|
||||
public static function MONTHOFYEAR($dateValue = 1)
|
||||
{
|
||||
return DateTimeExcel\Month::funcMonth($dateValue);
|
||||
return DateTimeExcel\DateParts::month($dateValue);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -697,11 +764,14 @@ class DateTime
|
|||
* Returns the year corresponding to a date.
|
||||
* The year is returned as an integer in the range 1900-9999.
|
||||
*
|
||||
* @Deprecated 2.0.0 Use the funcYear method in the DateTimeExcel\Year class instead
|
||||
*
|
||||
* Excel Function:
|
||||
* YEAR(dateValue)
|
||||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @See DateTimeExcel\DateParts::year()
|
||||
* Use the ear method in the DateTimeExcel\DateParts class instead
|
||||
*
|
||||
* @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard date string
|
||||
*
|
||||
|
|
@ -709,7 +779,7 @@ class DateTime
|
|||
*/
|
||||
public static function YEAR($dateValue = 1)
|
||||
{
|
||||
return DateTimeExcel\Year::funcYear($dateValue);
|
||||
return DateTimeExcel\DateParts::year($dateValue);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -718,11 +788,14 @@ class DateTime
|
|||
* Returns the hour of a time value.
|
||||
* The hour is given as an integer, ranging from 0 (12:00 A.M.) to 23 (11:00 P.M.).
|
||||
*
|
||||
* @Deprecated 2.0.0 Use the funcHour method in the DateTimeExcel\Hour class instead
|
||||
*
|
||||
* Excel Function:
|
||||
* HOUR(timeValue)
|
||||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @See DateTimeExcel\TimeParts::hour()
|
||||
* Use the hour method in the DateTimeExcel\TimeParts class instead
|
||||
*
|
||||
* @param mixed $timeValue Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard time string
|
||||
*
|
||||
|
|
@ -730,7 +803,7 @@ class DateTime
|
|||
*/
|
||||
public static function HOUROFDAY($timeValue = 0)
|
||||
{
|
||||
return DateTimeExcel\Hour::funcHour($timeValue);
|
||||
return DateTimeExcel\TimeParts::hour($timeValue);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -739,11 +812,14 @@ class DateTime
|
|||
* Returns the minutes of a time value.
|
||||
* The minute is given as an integer, ranging from 0 to 59.
|
||||
*
|
||||
* @Deprecated 2.0.0 Use the funcMinute method in the DateTimeExcel\Minute class instead
|
||||
*
|
||||
* Excel Function:
|
||||
* MINUTE(timeValue)
|
||||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @See DateTimeExcel\TimeParts::minute()
|
||||
* Use the minute method in the DateTimeExcel\TimeParts class instead
|
||||
*
|
||||
* @param mixed $timeValue Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard time string
|
||||
*
|
||||
|
|
@ -751,7 +827,7 @@ class DateTime
|
|||
*/
|
||||
public static function MINUTE($timeValue = 0)
|
||||
{
|
||||
return DateTimeExcel\Minute::funcMinute($timeValue);
|
||||
return DateTimeExcel\TimeParts::minute($timeValue);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -760,11 +836,14 @@ class DateTime
|
|||
* Returns the seconds of a time value.
|
||||
* The second is given as an integer in the range 0 (zero) to 59.
|
||||
*
|
||||
* @Deprecated 2.0.0 Use the funcSecond method in the DateTimeExcel\Second class instead
|
||||
*
|
||||
* Excel Function:
|
||||
* SECOND(timeValue)
|
||||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @See DateTimeExcel\TimeParts::second()
|
||||
* Use the second method in the DateTimeExcel\TimeParts class instead
|
||||
*
|
||||
* @param mixed $timeValue Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard time string
|
||||
*
|
||||
|
|
@ -772,7 +851,7 @@ class DateTime
|
|||
*/
|
||||
public static function SECOND($timeValue = 0)
|
||||
{
|
||||
return DateTimeExcel\Second::funcSecond($timeValue);
|
||||
return DateTimeExcel\TimeParts::second($timeValue);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -783,11 +862,14 @@ class DateTime
|
|||
* Use EDATE to calculate maturity dates or due dates that fall on the same day of the month
|
||||
* as the date of issue.
|
||||
*
|
||||
* @Deprecated 2.0.0 Use the funcEDate method in the DateTimeExcel\EDate class instead
|
||||
*
|
||||
* Excel Function:
|
||||
* EDATE(dateValue,adjustmentMonths)
|
||||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @See DateTimeExcel\Month::adjust()
|
||||
* Use the adjust method in the DateTimeExcel\Edate class instead
|
||||
*
|
||||
* @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard date string
|
||||
* @param int $adjustmentMonths The number of months before or after start_date.
|
||||
|
|
@ -799,7 +881,7 @@ class DateTime
|
|||
*/
|
||||
public static function EDATE($dateValue = 1, $adjustmentMonths = 0)
|
||||
{
|
||||
return DateTimeExcel\EDate::funcEDate($dateValue, $adjustmentMonths);
|
||||
return DateTimeExcel\Month::adjust($dateValue, $adjustmentMonths);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -809,11 +891,14 @@ class DateTime
|
|||
* before or after start_date.
|
||||
* Use EOMONTH to calculate maturity dates or due dates that fall on the last day of the month.
|
||||
*
|
||||
* @Deprecated 2.0.0 Use the funcEoMonth method in the DateTimeExcel\EoMonth class instead
|
||||
*
|
||||
* Excel Function:
|
||||
* EOMONTH(dateValue,adjustmentMonths)
|
||||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @See DateTimeExcel\Month::lastDay()
|
||||
* Use the lastDay method in the DateTimeExcel\EoMonth class instead
|
||||
*
|
||||
* @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard date string
|
||||
* @param int $adjustmentMonths The number of months before or after start_date.
|
||||
|
|
@ -825,6 +910,6 @@ class DateTime
|
|||
*/
|
||||
public static function EOMONTH($dateValue = 1, $adjustmentMonths = 0)
|
||||
{
|
||||
return DateTimeExcel\EoMonth::funcEoMonth($dateValue, $adjustmentMonths);
|
||||
return DateTimeExcel\Month::lastDay($dateValue, $adjustmentMonths);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ class Constants
|
|||
const DOW_FRIDAY = 6;
|
||||
const DOW_SATURDAY = 7;
|
||||
const STARTWEEK_MONDAY_ISO = 21;
|
||||
|
||||
const METHODARR = [
|
||||
self::STARTWEEK_SUNDAY => self::DOW_SUNDAY,
|
||||
self::DOW_MONDAY,
|
||||
|
|
|
|||
|
|
@ -5,8 +5,33 @@ namespace PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel;
|
|||
use DateTimeImmutable;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
|
||||
class Now
|
||||
class Current
|
||||
{
|
||||
/**
|
||||
* DATENOW.
|
||||
*
|
||||
* Returns the current date.
|
||||
* The NOW function is useful when you need to display the current date and time on a worksheet or
|
||||
* calculate a value based on the current date and time, and have that value updated each time you
|
||||
* open the worksheet.
|
||||
*
|
||||
* NOTE: When used in a Cell Formula, MS Excel changes the cell format so that it matches the date
|
||||
* and time format of your regional settings. PhpSpreadsheet does not change cell formatting in this way.
|
||||
*
|
||||
* Excel Function:
|
||||
* TODAY()
|
||||
*
|
||||
* @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object,
|
||||
* depending on the value of the ReturnDateType flag
|
||||
*/
|
||||
public static function today()
|
||||
{
|
||||
$dti = new DateTimeImmutable();
|
||||
$dateArray = date_parse($dti->format('c'));
|
||||
|
||||
return is_array($dateArray) ? Helpers::returnIn3FormatsArray($dateArray, true) : Functions::VALUE();
|
||||
}
|
||||
|
||||
/**
|
||||
* DATETIMENOW.
|
||||
*
|
||||
|
|
@ -24,7 +49,7 @@ class Now
|
|||
* @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object,
|
||||
* depending on the value of the ReturnDateType flag
|
||||
*/
|
||||
public static function funcNow()
|
||||
public static function now()
|
||||
{
|
||||
$dti = new DateTimeImmutable();
|
||||
$dateArray = date_parse($dti->format('c'));
|
||||
|
|
@ -2,12 +2,12 @@
|
|||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel;
|
||||
|
||||
use Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\Date;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\Date as SharedDateHelper;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\StringHelper;
|
||||
|
||||
class Datefunc
|
||||
class Date
|
||||
{
|
||||
/**
|
||||
* DATE.
|
||||
|
|
@ -58,9 +58,9 @@ class Datefunc
|
|||
* @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object,
|
||||
* depending on the value of the ReturnDateType flag
|
||||
*/
|
||||
public static function funcDate($year, $month, $day)
|
||||
public static function fromYMD($year, $month, $day)
|
||||
{
|
||||
$baseYear = Date::getExcelCalendar();
|
||||
$baseYear = SharedDateHelper::getExcelCalendar();
|
||||
|
||||
try {
|
||||
$year = self::getYear($year, $baseYear);
|
||||
|
|
@ -72,7 +72,7 @@ class Datefunc
|
|||
}
|
||||
|
||||
// Execute function
|
||||
$excelDateValue = Date::formattedPHPToExcel($year, $month, $day);
|
||||
$excelDateValue = SharedDateHelper::formattedPHPToExcel($year, $month, $day);
|
||||
|
||||
return Helpers::returnIn3FormatsFloat($excelDateValue);
|
||||
}
|
||||
|
|
@ -85,7 +85,7 @@ class Datefunc
|
|||
private static function getYear($year, int $baseYear): int
|
||||
{
|
||||
$year = Functions::flattenSingleValue($year);
|
||||
$year = ($year !== null) ? StringHelper::testStringAsNumeric($year) : 0;
|
||||
$year = ($year !== null) ? StringHelper::testStringAsNumeric((string) $year) : 0;
|
||||
if (!is_numeric($year)) {
|
||||
throw new Exception(Functions::VALUE());
|
||||
}
|
||||
|
|
@ -102,7 +102,7 @@ class Datefunc
|
|||
$year += 1900;
|
||||
}
|
||||
|
||||
return $year;
|
||||
return (int) $year;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -115,10 +115,10 @@ class Datefunc
|
|||
$month = Functions::flattenSingleValue($month);
|
||||
|
||||
if (($month !== null) && (!is_numeric($month))) {
|
||||
$month = Date::monthStringToNumber($month);
|
||||
$month = SharedDateHelper::monthStringToNumber($month);
|
||||
}
|
||||
|
||||
$month = ($month !== null) ? StringHelper::testStringAsNumeric($month) : 0;
|
||||
$month = ($month !== null) ? StringHelper::testStringAsNumeric((string) $month) : 0;
|
||||
if (!is_numeric($month)) {
|
||||
throw new Exception(Functions::VALUE());
|
||||
}
|
||||
|
|
@ -136,10 +136,10 @@ class Datefunc
|
|||
$day = Functions::flattenSingleValue($day);
|
||||
|
||||
if (($day !== null) && (!is_numeric($day))) {
|
||||
$day = Date::dayStringToNumber($day);
|
||||
$day = SharedDateHelper::dayStringToNumber($day);
|
||||
}
|
||||
|
||||
$day = ($day !== null) ? StringHelper::testStringAsNumeric($day) : 0;
|
||||
$day = ($day !== null) ? StringHelper::testStringAsNumeric((string) $day) : 0;
|
||||
if (!is_numeric($day)) {
|
||||
throw new Exception(Functions::VALUE());
|
||||
}
|
||||
|
|
@ -0,0 +1,127 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\Date as SharedDateHelper;
|
||||
|
||||
class DateParts
|
||||
{
|
||||
/**
|
||||
* DAYOFMONTH.
|
||||
*
|
||||
* Returns the day of the month, for a specified date. The day is given as an integer
|
||||
* ranging from 1 to 31.
|
||||
*
|
||||
* Excel Function:
|
||||
* DAY(dateValue)
|
||||
*
|
||||
* @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard date string
|
||||
*
|
||||
* @return int|string Day of the month
|
||||
*/
|
||||
public static function day($dateValue)
|
||||
{
|
||||
$weirdResult = self::weirdCondition($dateValue);
|
||||
if ($weirdResult >= 0) {
|
||||
return $weirdResult;
|
||||
}
|
||||
|
||||
try {
|
||||
$dateValue = Helpers::getDateValue($dateValue);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
// Execute function
|
||||
$PHPDateObject = SharedDateHelper::excelToDateTimeObject($dateValue);
|
||||
|
||||
return (int) $PHPDateObject->format('j');
|
||||
}
|
||||
|
||||
/**
|
||||
* MONTHOFYEAR.
|
||||
*
|
||||
* Returns the month of a date represented by a serial number.
|
||||
* The month is given as an integer, ranging from 1 (January) to 12 (December).
|
||||
*
|
||||
* Excel Function:
|
||||
* MONTH(dateValue)
|
||||
*
|
||||
* @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard date string
|
||||
*
|
||||
* @return int|string Month of the year
|
||||
*/
|
||||
public static function month($dateValue)
|
||||
{
|
||||
try {
|
||||
$dateValue = Helpers::getDateValue($dateValue);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
if ($dateValue < 1 && SharedDateHelper::getExcelCalendar() === SharedDateHelper::CALENDAR_WINDOWS_1900) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Execute function
|
||||
$PHPDateObject = SharedDateHelper::excelToDateTimeObject($dateValue);
|
||||
|
||||
return (int) $PHPDateObject->format('n');
|
||||
}
|
||||
|
||||
/**
|
||||
* YEAR.
|
||||
*
|
||||
* Returns the year corresponding to a date.
|
||||
* The year is returned as an integer in the range 1900-9999.
|
||||
*
|
||||
* Excel Function:
|
||||
* YEAR(dateValue)
|
||||
*
|
||||
* @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard date string
|
||||
*
|
||||
* @return int|string Year
|
||||
*/
|
||||
public static function year($dateValue)
|
||||
{
|
||||
try {
|
||||
$dateValue = Helpers::getDateValue($dateValue);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
if ($dateValue < 1 && SharedDateHelper::getExcelCalendar() === SharedDateHelper::CALENDAR_WINDOWS_1900) {
|
||||
return 1900;
|
||||
}
|
||||
// Execute function
|
||||
$PHPDateObject = SharedDateHelper::excelToDateTimeObject($dateValue);
|
||||
|
||||
return (int) $PHPDateObject->format('Y');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard date string
|
||||
*/
|
||||
private static function weirdCondition($dateValue): int
|
||||
{
|
||||
// Excel does not treat 0 consistently for DAY vs. (MONTH or YEAR)
|
||||
if (SharedDateHelper::getExcelCalendar() === SharedDateHelper::CALENDAR_WINDOWS_1900 && Functions::getCompatibilityMode() == Functions::COMPATIBILITY_EXCEL) {
|
||||
if (is_bool($dateValue)) {
|
||||
return (int) $dateValue;
|
||||
}
|
||||
if ($dateValue === null) {
|
||||
return 0;
|
||||
}
|
||||
if (is_numeric($dateValue) && $dateValue < 1 && $dateValue >= 0) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
|
@ -4,7 +4,7 @@ namespace PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel;
|
|||
|
||||
use DateTimeImmutable;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\Date;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\Date as SharedDateHelper;
|
||||
|
||||
class DateValue
|
||||
{
|
||||
|
|
@ -33,13 +33,13 @@ class DateValue
|
|||
* @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object,
|
||||
* depending on the value of the ReturnDateType flag
|
||||
*/
|
||||
public static function funcDateValue($dateValue)
|
||||
public static function fromString($dateValue)
|
||||
{
|
||||
$dti = new DateTimeImmutable();
|
||||
$baseYear = Date::getExcelCalendar();
|
||||
$baseYear = SharedDateHelper::getExcelCalendar();
|
||||
$dateValue = trim(Functions::flattenSingleValue($dateValue), '"');
|
||||
// Strip any ordinals because they're allowed in Excel (English only)
|
||||
$dateValue = preg_replace('/(\d)(st|nd|rd|th)([ -\/])/Ui', '$1$3', $dateValue);
|
||||
$dateValue = preg_replace('/(\d)(st|nd|rd|th)([ -\/])/Ui', '$1$3', $dateValue) ?? '';
|
||||
// Convert separators (/ . or space) to hyphens (should also handle dot used for ordinals in some countries, e.g. Denmark, Germany)
|
||||
$dateValue = str_replace(['/', '.', '-', ' '], ' ', $dateValue);
|
||||
|
||||
|
|
@ -59,7 +59,7 @@ class DateValue
|
|||
}
|
||||
if (count($t1) === 1) {
|
||||
// We've been fed a time value without any date
|
||||
return ((strpos($t, ':') === false)) ? Functions::Value() : 0.0;
|
||||
return ((strpos((string) $t, ':') === false)) ? Functions::Value() : 0.0;
|
||||
}
|
||||
unset($t);
|
||||
|
||||
|
|
@ -105,7 +105,7 @@ class DateValue
|
|||
$testVal1 = strtok($dateValue, '- ');
|
||||
$testVal2 = strtok('- ');
|
||||
$testVal3 = strtok('- ') ?: $dti->format('Y');
|
||||
Helpers::adjustYear($testVal1, $testVal2, $testVal3);
|
||||
Helpers::adjustYear((string) $testVal1, (string) $testVal2, $testVal3);
|
||||
$PHPDateArray = date_parse($testVal1 . '-' . $testVal2 . '-' . $testVal3);
|
||||
if (($PHPDateArray === false) || ($PHPDateArray['error_count'] > 0)) {
|
||||
$PHPDateArray = date_parse($testVal2 . '-' . $testVal1 . '-' . $testVal3);
|
||||
|
|
@ -118,7 +118,7 @@ class DateValue
|
|||
/**
|
||||
* Final results.
|
||||
*
|
||||
* @param array|false $PHPDateArray
|
||||
* @param array|bool $PHPDateArray
|
||||
*
|
||||
* @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object,
|
||||
* depending on the value of the ReturnDateType flag
|
||||
|
|
@ -126,7 +126,7 @@ class DateValue
|
|||
private static function finalResults($PHPDateArray, DateTimeImmutable $dti, int $baseYear)
|
||||
{
|
||||
$retValue = Functions::Value();
|
||||
if (($PHPDateArray !== false) && ($PHPDateArray['error_count'] == 0)) {
|
||||
if (is_array($PHPDateArray) && $PHPDateArray['error_count'] == 0) {
|
||||
// Execute function
|
||||
Helpers::replaceIfEmpty($PHPDateArray['year'], $dti->format('Y'));
|
||||
if ($PHPDateArray['year'] < $baseYear) {
|
||||
|
|
|
|||
|
|
@ -1,61 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel;
|
||||
|
||||
use Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\Date;
|
||||
|
||||
class Day
|
||||
{
|
||||
/**
|
||||
* DAYOFMONTH.
|
||||
*
|
||||
* Returns the day of the month, for a specified date. The day is given as an integer
|
||||
* ranging from 1 to 31.
|
||||
*
|
||||
* Excel Function:
|
||||
* DAY(dateValue)
|
||||
*
|
||||
* @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard date string
|
||||
*
|
||||
* @return int|string Day of the month
|
||||
*/
|
||||
public static function funcDay($dateValue)
|
||||
{
|
||||
$weirdResult = self::weirdCondition($dateValue);
|
||||
if ($weirdResult >= 0) {
|
||||
return $weirdResult;
|
||||
}
|
||||
|
||||
try {
|
||||
$dateValue = Helpers::getDateValue($dateValue);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
// Execute function
|
||||
$PHPDateObject = Date::excelToDateTimeObject($dateValue);
|
||||
|
||||
return (int) $PHPDateObject->format('j');
|
||||
}
|
||||
|
||||
private static function weirdCondition($dateValue): int
|
||||
{
|
||||
// Excel does not treat 0 consistently for DAY vs. (MONTH or YEAR)
|
||||
if (Date::getExcelCalendar() === DATE::CALENDAR_WINDOWS_1900 && Functions::getCompatibilityMode() == Functions::COMPATIBILITY_EXCEL) {
|
||||
if (is_bool($dateValue)) {
|
||||
return (int) $dateValue;
|
||||
}
|
||||
if ($dateValue === null) {
|
||||
return 0;
|
||||
}
|
||||
if (is_numeric($dateValue) && $dateValue < 1 && $dateValue >= 0) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
|
@ -3,9 +3,9 @@
|
|||
namespace PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel;
|
||||
|
||||
use DateTimeInterface;
|
||||
use Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\Date;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\Date as SharedDateHelper;
|
||||
|
||||
class Days
|
||||
{
|
||||
|
|
@ -24,7 +24,7 @@ class Days
|
|||
*
|
||||
* @return int|string Number of days between start date and end date or an error
|
||||
*/
|
||||
public static function funcDays($endDate, $startDate)
|
||||
public static function between($endDate, $startDate)
|
||||
{
|
||||
try {
|
||||
$startDate = Helpers::getDateValue($startDate);
|
||||
|
|
@ -34,8 +34,8 @@ class Days
|
|||
}
|
||||
|
||||
// Execute function
|
||||
$PHPStartDateObject = Date::excelToDateTimeObject($startDate);
|
||||
$PHPEndDateObject = Date::excelToDateTimeObject($endDate);
|
||||
$PHPStartDateObject = SharedDateHelper::excelToDateTimeObject($startDate);
|
||||
$PHPEndDateObject = SharedDateHelper::excelToDateTimeObject($endDate);
|
||||
|
||||
$days = Functions::VALUE();
|
||||
$diff = $PHPStartDateObject->diff($PHPEndDateObject);
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ namespace PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel;
|
|||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\Date;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\Date as SharedDateHelper;
|
||||
|
||||
class Days360
|
||||
{
|
||||
|
|
@ -36,7 +36,7 @@ class Days360
|
|||
*
|
||||
* @return int|string Number of days between start date and end date
|
||||
*/
|
||||
public static function funcDays360($startDate = 0, $endDate = 0, $method = false)
|
||||
public static function between($startDate = 0, $endDate = 0, $method = false)
|
||||
{
|
||||
try {
|
||||
$startDate = Helpers::getDateValue($startDate);
|
||||
|
|
@ -50,12 +50,12 @@ class Days360
|
|||
}
|
||||
|
||||
// Execute function
|
||||
$PHPStartDateObject = Date::excelToDateTimeObject($startDate);
|
||||
$PHPStartDateObject = SharedDateHelper::excelToDateTimeObject($startDate);
|
||||
$startDay = $PHPStartDateObject->format('j');
|
||||
$startMonth = $PHPStartDateObject->format('n');
|
||||
$startYear = $PHPStartDateObject->format('Y');
|
||||
|
||||
$PHPEndDateObject = Date::excelToDateTimeObject($endDate);
|
||||
$PHPEndDateObject = SharedDateHelper::excelToDateTimeObject($endDate);
|
||||
$endDay = $PHPEndDateObject->format('j');
|
||||
$endMonth = $PHPEndDateObject->format('n');
|
||||
$endYear = $PHPEndDateObject->format('Y');
|
||||
|
|
|
|||
|
|
@ -4,11 +4,11 @@ namespace PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel;
|
|||
|
||||
use DateInterval;
|
||||
use DateTime;
|
||||
use Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\Date;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\Date as SharedDateHelper;
|
||||
|
||||
class DateDif
|
||||
class Difference
|
||||
{
|
||||
/**
|
||||
* DATEDIF.
|
||||
|
|
@ -21,7 +21,7 @@ class DateDif
|
|||
*
|
||||
* @return int|string Interval between the dates
|
||||
*/
|
||||
public static function funcDateDif($startDate, $endDate, $unit = 'D')
|
||||
public static function interval($startDate, $endDate, $unit = 'D')
|
||||
{
|
||||
try {
|
||||
$startDate = Helpers::getDateValue($startDate);
|
||||
|
|
@ -33,12 +33,12 @@ class DateDif
|
|||
}
|
||||
|
||||
// Execute function
|
||||
$PHPStartDateObject = Date::excelToDateTimeObject($startDate);
|
||||
$PHPStartDateObject = SharedDateHelper::excelToDateTimeObject($startDate);
|
||||
$startDays = (int) $PHPStartDateObject->format('j');
|
||||
$startMonths = (int) $PHPStartDateObject->format('n');
|
||||
$startYears = (int) $PHPStartDateObject->format('Y');
|
||||
|
||||
$PHPEndDateObject = Date::excelToDateTimeObject($endDate);
|
||||
$PHPEndDateObject = SharedDateHelper::excelToDateTimeObject($endDate);
|
||||
$endDays = (int) $PHPEndDateObject->format('j');
|
||||
$endMonths = (int) $PHPEndDateObject->format('n');
|
||||
$endYears = (int) $PHPEndDateObject->format('Y');
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel;
|
||||
|
||||
use Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\Date;
|
||||
|
||||
class EDate
|
||||
{
|
||||
/**
|
||||
* EDATE.
|
||||
*
|
||||
* Returns the serial number that represents the date that is the indicated number of months
|
||||
* before or after a specified date (the start_date).
|
||||
* Use EDATE to calculate maturity dates or due dates that fall on the same day of the month
|
||||
* as the date of issue.
|
||||
*
|
||||
* Excel Function:
|
||||
* EDATE(dateValue,adjustmentMonths)
|
||||
*
|
||||
* @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard date string
|
||||
* @param int $adjustmentMonths The number of months before or after start_date.
|
||||
* A positive value for months yields a future date;
|
||||
* a negative value yields a past date.
|
||||
*
|
||||
* @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object,
|
||||
* depending on the value of the ReturnDateType flag
|
||||
*/
|
||||
public static function funcEDate($dateValue, $adjustmentMonths)
|
||||
{
|
||||
try {
|
||||
$dateValue = Helpers::getDateValue($dateValue, false);
|
||||
$adjustmentMonths = Helpers::validateNumericNull($adjustmentMonths);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
$adjustmentMonths = floor($adjustmentMonths);
|
||||
|
||||
// Execute function
|
||||
$PHPDateObject = Helpers::adjustDateByMonths($dateValue, $adjustmentMonths);
|
||||
|
||||
return Helpers::returnIn3FormatsObject($PHPDateObject);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel;
|
||||
|
||||
use Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\Date;
|
||||
|
||||
class EoMonth
|
||||
{
|
||||
/**
|
||||
* EOMONTH.
|
||||
*
|
||||
* Returns the date value for the last day of the month that is the indicated number of months
|
||||
* before or after start_date.
|
||||
* Use EOMONTH to calculate maturity dates or due dates that fall on the last day of the month.
|
||||
*
|
||||
* Excel Function:
|
||||
* EOMONTH(dateValue,adjustmentMonths)
|
||||
*
|
||||
* @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard date string
|
||||
* @param int $adjustmentMonths The number of months before or after start_date.
|
||||
* A positive value for months yields a future date;
|
||||
* a negative value yields a past date.
|
||||
*
|
||||
* @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object,
|
||||
* depending on the value of the ReturnDateType flag
|
||||
*/
|
||||
public static function funcEoMonth($dateValue, $adjustmentMonths)
|
||||
{
|
||||
try {
|
||||
$dateValue = Helpers::getDateValue($dateValue, false);
|
||||
$adjustmentMonths = Helpers::validateNumericNull($adjustmentMonths);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
$adjustmentMonths = floor($adjustmentMonths);
|
||||
|
||||
// Execute function
|
||||
$PHPDateObject = Helpers::adjustDateByMonths($dateValue, $adjustmentMonths + 1);
|
||||
$adjustDays = (int) $PHPDateObject->format('d');
|
||||
$adjustDaysString = '-' . $adjustDays . ' days';
|
||||
$PHPDateObject->modify($adjustDaysString);
|
||||
|
||||
return Helpers::returnIn3FormatsObject($PHPDateObject);
|
||||
}
|
||||
}
|
||||
|
|
@ -5,7 +5,7 @@ namespace PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel;
|
|||
use DateTime;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\Date;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\Date as SharedDateHelper;
|
||||
|
||||
class Helpers
|
||||
{
|
||||
|
|
@ -31,7 +31,7 @@ class Helpers
|
|||
public static function getDateValue($dateValue, bool $allowBool = true): float
|
||||
{
|
||||
if (is_object($dateValue)) {
|
||||
$retval = Date::PHPToExcel($dateValue);
|
||||
$retval = SharedDateHelper::PHPToExcel($dateValue);
|
||||
if (is_bool($retval)) {
|
||||
throw new Exception(Functions::VALUE());
|
||||
}
|
||||
|
|
@ -43,7 +43,7 @@ class Helpers
|
|||
if (!is_numeric($dateValue)) {
|
||||
$saveReturnDateType = Functions::getReturnDateType();
|
||||
Functions::setReturnDateType(Functions::RETURNDATE_EXCEL);
|
||||
$dateValue = DateValue::funcDateValue($dateValue);
|
||||
$dateValue = DateValue::fromString($dateValue);
|
||||
Functions::setReturnDateType($saveReturnDateType);
|
||||
if (!is_numeric($dateValue)) {
|
||||
throw new Exception(Functions::VALUE());
|
||||
|
|
@ -67,16 +67,21 @@ class Helpers
|
|||
{
|
||||
$saveReturnDateType = Functions::getReturnDateType();
|
||||
Functions::setReturnDateType(Functions::RETURNDATE_EXCEL);
|
||||
$timeValue = TimeValue::funcTimeValue($timeValue);
|
||||
$timeValue = TimeValue::fromString($timeValue);
|
||||
Functions::setReturnDateType($saveReturnDateType);
|
||||
|
||||
return $timeValue;
|
||||
}
|
||||
|
||||
public static function adjustDateByMonths($dateValue = 0, $adjustmentMonths = 0)
|
||||
/**
|
||||
* Adjust date by given months.
|
||||
*
|
||||
* @param mixed $dateValue
|
||||
*/
|
||||
public static function adjustDateByMonths($dateValue = 0, float $adjustmentMonths = 0): DateTime
|
||||
{
|
||||
// Execute function
|
||||
$PHPDateObject = Date::excelToDateTimeObject($dateValue);
|
||||
$PHPDateObject = SharedDateHelper::excelToDateTimeObject($dateValue);
|
||||
$oMonth = (int) $PHPDateObject->format('m');
|
||||
$oYear = (int) $PHPDateObject->format('Y');
|
||||
|
||||
|
|
@ -144,7 +149,7 @@ class Helpers
|
|||
);
|
||||
}
|
||||
$excelDateValue =
|
||||
Date::formattedPHPToExcel(
|
||||
SharedDateHelper::formattedPHPToExcel(
|
||||
$dateArray['year'],
|
||||
$dateArray['month'],
|
||||
$dateArray['day'],
|
||||
|
|
@ -157,7 +162,7 @@ class Helpers
|
|||
}
|
||||
// RETURNDATE_UNIX_TIMESTAMP)
|
||||
|
||||
return (int) Date::excelToTimestamp($excelDateValue);
|
||||
return (int) SharedDateHelper::excelToTimestamp($excelDateValue);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -172,11 +177,11 @@ class Helpers
|
|||
return $excelDateValue;
|
||||
}
|
||||
if ($retType === Functions::RETURNDATE_UNIX_TIMESTAMP) {
|
||||
return (int) Date::excelToTimestamp($excelDateValue);
|
||||
return (int) SharedDateHelper::excelToTimestamp($excelDateValue);
|
||||
}
|
||||
// RETURNDATE_PHP_DATETIME_OBJECT
|
||||
|
||||
return Date::excelToDateTimeObject($excelDateValue);
|
||||
return SharedDateHelper::excelToDateTimeObject($excelDateValue);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -191,11 +196,13 @@ class Helpers
|
|||
return $PHPDateObject;
|
||||
}
|
||||
if ($retType === Functions::RETURNDATE_EXCEL) {
|
||||
return (float) Date::PHPToExcel($PHPDateObject);
|
||||
return (float) SharedDateHelper::PHPToExcel($PHPDateObject);
|
||||
}
|
||||
// RETURNDATE_UNIX_TIMESTAMP
|
||||
$stamp = SharedDateHelper::PHPToExcel($PHPDateObject);
|
||||
$stamp = is_bool($stamp) ? ((int) $stamp) : $stamp;
|
||||
|
||||
return (int) Date::excelToTimestamp(Date::PHPToExcel($PHPDateObject));
|
||||
return (int) SharedDateHelper::excelToTimestamp($stamp);
|
||||
}
|
||||
|
||||
private static function baseDate(): int
|
||||
|
|
@ -203,7 +210,7 @@ class Helpers
|
|||
if (Functions::getCompatibilityMode() === Functions::COMPATIBILITY_OPENOFFICE) {
|
||||
return 0;
|
||||
}
|
||||
if (Date::getExcelCalendar() === Date::CALENDAR_MAC_1904) {
|
||||
if (SharedDateHelper::getExcelCalendar() === SharedDateHelper::CALENDAR_MAC_1904) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -239,9 +246,12 @@ class Helpers
|
|||
if ($number === null) {
|
||||
return 0;
|
||||
}
|
||||
if (is_numeric($number)) {
|
||||
if (is_int($number)) {
|
||||
return $number;
|
||||
}
|
||||
if (is_numeric($number)) {
|
||||
return (float) $number;
|
||||
}
|
||||
|
||||
throw new Exception(Functions::VALUE());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,44 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel;
|
||||
|
||||
use Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\Date;
|
||||
|
||||
class Hour
|
||||
{
|
||||
/**
|
||||
* HOUROFDAY.
|
||||
*
|
||||
* Returns the hour of a time value.
|
||||
* The hour is given as an integer, ranging from 0 (12:00 A.M.) to 23 (11:00 P.M.).
|
||||
*
|
||||
* Excel Function:
|
||||
* HOUR(timeValue)
|
||||
*
|
||||
* @param mixed $timeValue Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard time string
|
||||
*
|
||||
* @return int|string Hour
|
||||
*/
|
||||
public static function funcHour($timeValue)
|
||||
{
|
||||
try {
|
||||
$timeValue = Functions::flattenSingleValue($timeValue);
|
||||
Helpers::nullFalseTrueToNumber($timeValue);
|
||||
if (!is_numeric($timeValue)) {
|
||||
$timeValue = Helpers::getTimeValue($timeValue);
|
||||
}
|
||||
Helpers::validateNotNegative($timeValue);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
// Execute function
|
||||
$timeValue = fmod($timeValue, 1);
|
||||
$timeValue = Date::excelToDateTimeObject($timeValue);
|
||||
|
||||
return (int) $timeValue->format('H');
|
||||
}
|
||||
}
|
||||
|
|
@ -1,55 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel;
|
||||
|
||||
use Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\Date;
|
||||
|
||||
class IsoWeekNum
|
||||
{
|
||||
/**
|
||||
* 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 funcIsoWeekNum($dateValue)
|
||||
{
|
||||
if (self::apparentBug($dateValue)) {
|
||||
return 52;
|
||||
}
|
||||
|
||||
try {
|
||||
$dateValue = Helpers::getDateValue($dateValue);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
// Execute function
|
||||
$PHPDateObject = Date::excelToDateTimeObject($dateValue);
|
||||
Helpers::silly1900($PHPDateObject);
|
||||
|
||||
return (int) $PHPDateObject->format('W');
|
||||
}
|
||||
|
||||
private static function apparentBug($dateValue): bool
|
||||
{
|
||||
if (Date::getExcelCalendar() !== DATE::CALENDAR_MAC_1904) {
|
||||
if (is_bool($dateValue)) {
|
||||
return true;
|
||||
}
|
||||
if (is_numeric($dateValue) && !((int) $dateValue)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel;
|
||||
|
||||
use Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\Date;
|
||||
|
||||
class Minute
|
||||
{
|
||||
/**
|
||||
* MINUTE.
|
||||
*
|
||||
* Returns the minutes of a time value.
|
||||
* The minute is given as an integer, ranging from 0 to 59.
|
||||
*
|
||||
* Excel Function:
|
||||
* MINUTE(timeValue)
|
||||
*
|
||||
* @param mixed $timeValue Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard time string
|
||||
*
|
||||
* @return int|string Minute
|
||||
*/
|
||||
public static function funcMinute($timeValue)
|
||||
{
|
||||
try {
|
||||
$timeValue = Functions::flattenSingleValue($timeValue);
|
||||
Helpers::nullFalseTrueToNumber($timeValue);
|
||||
if (!is_numeric($timeValue)) {
|
||||
$timeValue = Helpers::getTimeValue($timeValue);
|
||||
}
|
||||
Helpers::validateNotNegative($timeValue);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
// Execute function
|
||||
$timeValue = fmod($timeValue, 1);
|
||||
$timeValue = Date::excelToDateTimeObject($timeValue);
|
||||
|
||||
return (int) $timeValue->format('i');
|
||||
}
|
||||
}
|
||||
|
|
@ -2,39 +2,81 @@
|
|||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel;
|
||||
|
||||
use Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\Date;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
|
||||
|
||||
class Month
|
||||
{
|
||||
/**
|
||||
* MONTHOFYEAR.
|
||||
* EDATE.
|
||||
*
|
||||
* Returns the month of a date represented by a serial number.
|
||||
* The month is given as an integer, ranging from 1 (January) to 12 (December).
|
||||
* Returns the serial number that represents the date that is the indicated number of months
|
||||
* before or after a specified date (the start_date).
|
||||
* Use EDATE to calculate maturity dates or due dates that fall on the same day of the month
|
||||
* as the date of issue.
|
||||
*
|
||||
* Excel Function:
|
||||
* MONTH(dateValue)
|
||||
* EDATE(dateValue,adjustmentMonths)
|
||||
*
|
||||
* @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard date string
|
||||
* PHP DateTime object, or a standard date string
|
||||
* @param int $adjustmentMonths The number of months before or after start_date.
|
||||
* A positive value for months yields a future date;
|
||||
* a negative value yields a past date.
|
||||
*
|
||||
* @return int|string Month of the year
|
||||
* @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object,
|
||||
* depending on the value of the ReturnDateType flag
|
||||
*/
|
||||
public static function funcMonth($dateValue)
|
||||
public static function adjust($dateValue, $adjustmentMonths)
|
||||
{
|
||||
try {
|
||||
$dateValue = Helpers::getDateValue($dateValue);
|
||||
$dateValue = Helpers::getDateValue($dateValue, false);
|
||||
$adjustmentMonths = Helpers::validateNumericNull($adjustmentMonths);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
if ($dateValue < 1 && Date::getExcelCalendar() === DATE::CALENDAR_WINDOWS_1900) {
|
||||
return 1;
|
||||
}
|
||||
$adjustmentMonths = floor($adjustmentMonths);
|
||||
|
||||
// Execute function
|
||||
$PHPDateObject = Date::excelToDateTimeObject($dateValue);
|
||||
$PHPDateObject = Helpers::adjustDateByMonths($dateValue, $adjustmentMonths);
|
||||
|
||||
return (int) $PHPDateObject->format('n');
|
||||
return Helpers::returnIn3FormatsObject($PHPDateObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* EOMONTH.
|
||||
*
|
||||
* Returns the date value for the last day of the month that is the indicated number of months
|
||||
* before or after start_date.
|
||||
* Use EOMONTH to calculate maturity dates or due dates that fall on the last day of the month.
|
||||
*
|
||||
* Excel Function:
|
||||
* EOMONTH(dateValue,adjustmentMonths)
|
||||
*
|
||||
* @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard date string
|
||||
* @param int $adjustmentMonths The number of months before or after start_date.
|
||||
* A positive value for months yields a future date;
|
||||
* a negative value yields a past date.
|
||||
*
|
||||
* @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object,
|
||||
* depending on the value of the ReturnDateType flag
|
||||
*/
|
||||
public static function lastDay($dateValue, $adjustmentMonths)
|
||||
{
|
||||
try {
|
||||
$dateValue = Helpers::getDateValue($dateValue, false);
|
||||
$adjustmentMonths = Helpers::validateNumericNull($adjustmentMonths);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
$adjustmentMonths = floor($adjustmentMonths);
|
||||
|
||||
// Execute function
|
||||
$PHPDateObject = Helpers::adjustDateByMonths($dateValue, $adjustmentMonths + 1);
|
||||
$adjustDays = (int) $PHPDateObject->format('d');
|
||||
$adjustDaysString = '-' . $adjustDays . ' days';
|
||||
$PHPDateObject->modify($adjustDaysString);
|
||||
|
||||
return Helpers::returnIn3FormatsObject($PHPDateObject);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,9 +2,8 @@
|
|||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel;
|
||||
|
||||
use Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\Date;
|
||||
|
||||
class NetworkDays
|
||||
{
|
||||
|
|
@ -23,10 +22,11 @@ class NetworkDays
|
|||
* PHP DateTime object, or a standard date string
|
||||
* @param mixed $endDate Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard date string
|
||||
* @param mixed $dateArgs
|
||||
*
|
||||
* @return int|string Interval between the dates
|
||||
*/
|
||||
public static function funcNetworkDays($startDate, $endDate, ...$dateArgs)
|
||||
public static function count($startDate, $endDate, ...$dateArgs)
|
||||
{
|
||||
try {
|
||||
// Retrieve the mandatory start and end date that are referenced in the function definition
|
||||
|
|
@ -55,7 +55,7 @@ class NetworkDays
|
|||
$holidayCountedArray = [];
|
||||
foreach ($holidayArray as $holidayDate) {
|
||||
if (($holidayDate >= $startDate) && ($holidayDate <= $endDate)) {
|
||||
if ((WeekDay::funcWeekDay($holidayDate, 2) < 6) && (!in_array($holidayDate, $holidayCountedArray))) {
|
||||
if ((Week::day($holidayDate, 2) < 6) && (!in_array($holidayDate, $holidayCountedArray))) {
|
||||
--$partWeekDays;
|
||||
$holidayCountedArray[] = $holidayDate;
|
||||
}
|
||||
|
|
@ -67,7 +67,7 @@ class NetworkDays
|
|||
|
||||
private static function calcStartDow(float $startDate): int
|
||||
{
|
||||
$startDow = 6 - (int) WeekDay::funcWeekDay($startDate, 2);
|
||||
$startDow = 6 - (int) Week::day($startDate, 2);
|
||||
if ($startDow < 0) {
|
||||
$startDow = 5;
|
||||
}
|
||||
|
|
@ -77,7 +77,7 @@ class NetworkDays
|
|||
|
||||
private static function calcEndDow(float $endDate): int
|
||||
{
|
||||
$endDow = (int) WeekDay::funcWeekDay($endDate, 2);
|
||||
$endDow = (int) Week::day($endDate, 2);
|
||||
if ($endDow >= 6) {
|
||||
$endDow = 0;
|
||||
}
|
||||
|
|
@ -95,7 +95,7 @@ class NetworkDays
|
|||
return $partWeekDays;
|
||||
}
|
||||
|
||||
private static function applySign(int $result, float $sDate, float $eDate)
|
||||
private static function applySign(int $result, float $sDate, float $eDate): int
|
||||
{
|
||||
return ($sDate > $eDate) ? -$result : $result;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,44 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel;
|
||||
|
||||
use Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\Date;
|
||||
|
||||
class Second
|
||||
{
|
||||
/**
|
||||
* MINUTE.
|
||||
*
|
||||
* Returns the minutes of a time value.
|
||||
* The minute is given as an integer, ranging from 0 to 59.
|
||||
*
|
||||
* Excel Function:
|
||||
* MINUTE(timeValue)
|
||||
*
|
||||
* @param mixed $timeValue Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard time string
|
||||
*
|
||||
* @return int|string Minute
|
||||
*/
|
||||
public static function funcSecond($timeValue)
|
||||
{
|
||||
try {
|
||||
$timeValue = Functions::flattenSingleValue($timeValue);
|
||||
Helpers::nullFalseTrueToNumber($timeValue);
|
||||
if (!is_numeric($timeValue)) {
|
||||
$timeValue = Helpers::getTimeValue($timeValue);
|
||||
}
|
||||
Helpers::validateNotNegative($timeValue);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
// Execute function
|
||||
$timeValue = fmod($timeValue, 1);
|
||||
$timeValue = Date::excelToDateTimeObject($timeValue);
|
||||
|
||||
return (int) $timeValue->format('s');
|
||||
}
|
||||
}
|
||||
|
|
@ -5,7 +5,7 @@ namespace PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel;
|
|||
use DateTime;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\Date;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\Date as SharedDateHelper;
|
||||
|
||||
class Time
|
||||
{
|
||||
|
|
@ -20,14 +20,14 @@ class Time
|
|||
* Excel Function:
|
||||
* TIME(hour,minute,second)
|
||||
*
|
||||
* @param int $hour A number from 0 (zero) to 32767 representing the hour.
|
||||
* @param mixed $hour A number from 0 (zero) to 32767 representing the hour.
|
||||
* Any value greater than 23 will be divided by 24 and the remainder
|
||||
* will be treated as the hour value. For example, TIME(27,0,0) =
|
||||
* TIME(3,0,0) = .125 or 3:00 AM.
|
||||
* @param int $minute A number from 0 to 32767 representing the minute.
|
||||
* @param mixed $minute A number from 0 to 32767 representing the minute.
|
||||
* Any value greater than 59 will be converted to hours and minutes.
|
||||
* For example, TIME(0,750,0) = TIME(12,30,0) = .520833 or 12:30 PM.
|
||||
* @param int $second A number from 0 to 32767 representing the second.
|
||||
* @param mixed $second A number from 0 to 32767 representing the second.
|
||||
* Any value greater than 59 will be converted to hours, minutes,
|
||||
* and seconds. For example, TIME(0,0,2000) = TIME(0,33,22) = .023148
|
||||
* or 12:33:20 AM
|
||||
|
|
@ -35,7 +35,7 @@ class Time
|
|||
* @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object,
|
||||
* depending on the value of the ReturnDateType flag
|
||||
*/
|
||||
public static function funcTime($hour, $minute, $second)
|
||||
public static function fromHMS($hour, $minute, $second)
|
||||
{
|
||||
try {
|
||||
$hour = self::toIntWithNullBool($hour);
|
||||
|
|
@ -57,13 +57,13 @@ class Time
|
|||
// Execute function
|
||||
$retType = Functions::getReturnDateType();
|
||||
if ($retType === Functions::RETURNDATE_EXCEL) {
|
||||
$calendar = Date::getExcelCalendar();
|
||||
$date = (int) ($calendar !== Date::CALENDAR_WINDOWS_1900);
|
||||
$calendar = SharedDateHelper::getExcelCalendar();
|
||||
$date = (int) ($calendar !== SharedDateHelper::CALENDAR_WINDOWS_1900);
|
||||
|
||||
return (float) Date::formattedPHPToExcel($calendar, 1, $date, $hour, $minute, $second);
|
||||
return (float) SharedDateHelper::formattedPHPToExcel($calendar, 1, $date, $hour, $minute, $second);
|
||||
}
|
||||
if ($retType === Functions::RETURNDATE_UNIX_TIMESTAMP) {
|
||||
return (int) Date::excelToTimestamp(Date::formattedPHPToExcel(1970, 1, 1, $hour, $minute, $second)); // -2147468400; // -2147472000 + 3600
|
||||
return (int) SharedDateHelper::excelToTimestamp(SharedDateHelper::formattedPHPToExcel(1970, 1, 1, $hour, $minute, $second)); // -2147468400; // -2147472000 + 3600
|
||||
}
|
||||
// RETURNDATE_PHP_DATETIME_OBJECT
|
||||
// Hour has already been normalized (0-23) above
|
||||
|
|
@ -100,6 +100,9 @@ class Time
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $value expect int
|
||||
*/
|
||||
private static function toIntWithNullBool($value): int
|
||||
{
|
||||
$value = Functions::flattenSingleValue($value);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,112 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\Date as SharedDateHelper;
|
||||
|
||||
class TimeParts
|
||||
{
|
||||
/**
|
||||
* HOUROFDAY.
|
||||
*
|
||||
* Returns the hour of a time value.
|
||||
* The hour is given as an integer, ranging from 0 (12:00 A.M.) to 23 (11:00 P.M.).
|
||||
*
|
||||
* Excel Function:
|
||||
* HOUR(timeValue)
|
||||
*
|
||||
* @param mixed $timeValue Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard time string
|
||||
*
|
||||
* @return int|string Hour
|
||||
*/
|
||||
public static function hour($timeValue)
|
||||
{
|
||||
try {
|
||||
$timeValue = Functions::flattenSingleValue($timeValue);
|
||||
Helpers::nullFalseTrueToNumber($timeValue);
|
||||
if (!is_numeric($timeValue)) {
|
||||
$timeValue = Helpers::getTimeValue($timeValue);
|
||||
}
|
||||
Helpers::validateNotNegative($timeValue);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
// Execute function
|
||||
$timeValue = fmod($timeValue, 1);
|
||||
$timeValue = SharedDateHelper::excelToDateTimeObject($timeValue);
|
||||
|
||||
return (int) $timeValue->format('H');
|
||||
}
|
||||
|
||||
/**
|
||||
* MINUTE.
|
||||
*
|
||||
* Returns the minutes of a time value.
|
||||
* The minute is given as an integer, ranging from 0 to 59.
|
||||
*
|
||||
* Excel Function:
|
||||
* MINUTE(timeValue)
|
||||
*
|
||||
* @param mixed $timeValue Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard time string
|
||||
*
|
||||
* @return int|string Minute
|
||||
*/
|
||||
public static function minute($timeValue)
|
||||
{
|
||||
try {
|
||||
$timeValue = Functions::flattenSingleValue($timeValue);
|
||||
Helpers::nullFalseTrueToNumber($timeValue);
|
||||
if (!is_numeric($timeValue)) {
|
||||
$timeValue = Helpers::getTimeValue($timeValue);
|
||||
}
|
||||
Helpers::validateNotNegative($timeValue);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
// Execute function
|
||||
$timeValue = fmod($timeValue, 1);
|
||||
$timeValue = SharedDateHelper::excelToDateTimeObject($timeValue);
|
||||
|
||||
return (int) $timeValue->format('i');
|
||||
}
|
||||
|
||||
/**
|
||||
* SECOND.
|
||||
*
|
||||
* Returns the seconds of a time value.
|
||||
* The minute is given as an integer, ranging from 0 to 59.
|
||||
*
|
||||
* Excel Function:
|
||||
* SECOND(timeValue)
|
||||
*
|
||||
* @param mixed $timeValue Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard time string
|
||||
*
|
||||
* @return int|string Second
|
||||
*/
|
||||
public static function second($timeValue)
|
||||
{
|
||||
try {
|
||||
$timeValue = Functions::flattenSingleValue($timeValue);
|
||||
Helpers::nullFalseTrueToNumber($timeValue);
|
||||
if (!is_numeric($timeValue)) {
|
||||
$timeValue = Helpers::getTimeValue($timeValue);
|
||||
}
|
||||
Helpers::validateNotNegative($timeValue);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
// Execute function
|
||||
$timeValue = fmod($timeValue, 1);
|
||||
$timeValue = SharedDateHelper::excelToDateTimeObject($timeValue);
|
||||
|
||||
return (int) $timeValue->format('s');
|
||||
}
|
||||
}
|
||||
|
|
@ -4,7 +4,7 @@ namespace PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel;
|
|||
|
||||
use Datetime;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\Date;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\Date as SharedDateHelper;
|
||||
|
||||
class TimeValue
|
||||
{
|
||||
|
|
@ -29,12 +29,12 @@ class TimeValue
|
|||
* @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object,
|
||||
* depending on the value of the ReturnDateType flag
|
||||
*/
|
||||
public static function funcTimeValue($timeValue)
|
||||
public static function fromString($timeValue)
|
||||
{
|
||||
$timeValue = trim(Functions::flattenSingleValue($timeValue), '"');
|
||||
$timeValue = str_replace(['/', '.'], '-', $timeValue);
|
||||
|
||||
$arraySplit = preg_split('/[\/:\-\s]/', $timeValue);
|
||||
$arraySplit = preg_split('/[\/:\-\s]/', $timeValue) ?: [];
|
||||
if ((count($arraySplit) == 2 || count($arraySplit) == 3) && $arraySplit[0] > 24) {
|
||||
$arraySplit[0] = ($arraySplit[0] % 24);
|
||||
$timeValue = implode(':', $arraySplit);
|
||||
|
|
@ -44,13 +44,13 @@ class TimeValue
|
|||
$retValue = Functions::VALUE();
|
||||
if (($PHPDateArray !== false) && ($PHPDateArray['error_count'] == 0)) {
|
||||
// OpenOffice-specific code removed - it works just like Excel
|
||||
$excelDateValue = Date::formattedPHPToExcel(1900, 1, 1, $PHPDateArray['hour'], $PHPDateArray['minute'], $PHPDateArray['second']) - 1;
|
||||
$excelDateValue = SharedDateHelper::formattedPHPToExcel(1900, 1, 1, $PHPDateArray['hour'], $PHPDateArray['minute'], $PHPDateArray['second']) - 1;
|
||||
|
||||
$retType = Functions::getReturnDateType();
|
||||
if ($retType === Functions::RETURNDATE_EXCEL) {
|
||||
$retValue = (float) $excelDateValue;
|
||||
} elseif ($retType === Functions::RETURNDATE_UNIX_TIMESTAMP) {
|
||||
$retValue = (int) $phpDateValue = Date::excelToTimestamp($excelDateValue + 25569) - 3600;
|
||||
$retValue = (int) $phpDateValue = SharedDateHelper::excelToTimestamp($excelDateValue + 25569) - 3600;
|
||||
} else {
|
||||
$retValue = new DateTime('1900-01-01 ' . $PHPDateArray['hour'] . ':' . $PHPDateArray['minute'] . ':' . $PHPDateArray['second']);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,34 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel;
|
||||
|
||||
use DateTimeImmutable;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
|
||||
class Today
|
||||
{
|
||||
/**
|
||||
* DATENOW.
|
||||
*
|
||||
* Returns the current date.
|
||||
* The NOW function is useful when you need to display the current date and time on a worksheet or
|
||||
* calculate a value based on the current date and time, and have that value updated each time you
|
||||
* open the worksheet.
|
||||
*
|
||||
* NOTE: When used in a Cell Formula, MS Excel changes the cell format so that it matches the date
|
||||
* and time format of your regional settings. PhpSpreadsheet does not change cell formatting in this way.
|
||||
*
|
||||
* Excel Function:
|
||||
* TODAY()
|
||||
*
|
||||
* @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object,
|
||||
* depending on the value of the ReturnDateType flag
|
||||
*/
|
||||
public static function funcToday()
|
||||
{
|
||||
$dti = new DateTimeImmutable();
|
||||
$dateArray = date_parse($dti->format('c'));
|
||||
|
||||
return is_array($dateArray) ? Helpers::returnIn3FormatsArray($dateArray, true) : Functions::VALUE();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,254 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel;
|
||||
|
||||
use DateTime;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\Date as SharedDateHelper;
|
||||
|
||||
class Week
|
||||
{
|
||||
/**
|
||||
* WEEKNUM.
|
||||
*
|
||||
* Returns the week of the year for a specified date.
|
||||
* The WEEKNUM function considers the week containing January 1 to be the first week of the year.
|
||||
* However, there is a European standard that defines the first week as the one with the majority
|
||||
* of days (four or more) falling in the new year. This means that for years in which there are
|
||||
* three days or less in the first week of January, the WEEKNUM function returns week numbers
|
||||
* that are incorrect according to the European standard.
|
||||
*
|
||||
* Excel Function:
|
||||
* WEEKNUM(dateValue[,style])
|
||||
*
|
||||
* @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard date string
|
||||
* @param int $method Week begins on Sunday or Monday
|
||||
* 1 or omitted Week begins on Sunday.
|
||||
* 2 Week begins on Monday.
|
||||
* 11 Week begins on Monday.
|
||||
* 12 Week begins on Tuesday.
|
||||
* 13 Week begins on Wednesday.
|
||||
* 14 Week begins on Thursday.
|
||||
* 15 Week begins on Friday.
|
||||
* 16 Week begins on Saturday.
|
||||
* 17 Week begins on Sunday.
|
||||
* 21 ISO (Jan. 4 is week 1, begins on Monday).
|
||||
*
|
||||
* @return int|string Week Number
|
||||
*/
|
||||
public static function number($dateValue, $method = Constants::STARTWEEK_SUNDAY)
|
||||
{
|
||||
$origDateValueNull = empty($dateValue);
|
||||
|
||||
try {
|
||||
$method = self::validateMethod($method);
|
||||
if ($dateValue === null) { // boolean not allowed
|
||||
$dateValue = (SharedDateHelper::getExcelCalendar() === SharedDateHelper::CALENDAR_MAC_1904 || $method === Constants::DOW_SUNDAY) ? 0 : 1;
|
||||
}
|
||||
$dateValue = self::validateDateValue($dateValue);
|
||||
if (!$dateValue && self::buggyWeekNum1900($method)) {
|
||||
// This seems to be an additional Excel bug.
|
||||
return 0;
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
// Execute function
|
||||
$PHPDateObject = SharedDateHelper::excelToDateTimeObject($dateValue);
|
||||
if ($method == Constants::STARTWEEK_MONDAY_ISO) {
|
||||
Helpers::silly1900($PHPDateObject);
|
||||
|
||||
return (int) $PHPDateObject->format('W');
|
||||
}
|
||||
if (self::buggyWeekNum1904($method, $origDateValueNull, $PHPDateObject)) {
|
||||
return 0;
|
||||
}
|
||||
Helpers::silly1900($PHPDateObject, '+ 5 years'); // 1905 calendar matches
|
||||
$dayOfYear = (int) $PHPDateObject->format('z');
|
||||
$PHPDateObject->modify('-' . $dayOfYear . ' days');
|
||||
$firstDayOfFirstWeek = (int) $PHPDateObject->format('w');
|
||||
$daysInFirstWeek = (6 - $firstDayOfFirstWeek + $method) % 7;
|
||||
$daysInFirstWeek += 7 * !$daysInFirstWeek;
|
||||
$endFirstWeek = $daysInFirstWeek - 1;
|
||||
$weekOfYear = floor(($dayOfYear - $endFirstWeek + 13) / 7);
|
||||
|
||||
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 isoWeekNumber($dateValue)
|
||||
{
|
||||
if (self::apparentBug($dateValue)) {
|
||||
return 52;
|
||||
}
|
||||
|
||||
try {
|
||||
$dateValue = Helpers::getDateValue($dateValue);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
// Execute function
|
||||
$PHPDateObject = SharedDateHelper::excelToDateTimeObject($dateValue);
|
||||
Helpers::silly1900($PHPDateObject);
|
||||
|
||||
return (int) $PHPDateObject->format('W');
|
||||
}
|
||||
|
||||
/**
|
||||
* WEEKDAY.
|
||||
*
|
||||
* Returns the day of the week for a specified date. The day is given as an integer
|
||||
* ranging from 0 to 7 (dependent on the requested style).
|
||||
*
|
||||
* Excel Function:
|
||||
* WEEKDAY(dateValue[,style])
|
||||
*
|
||||
* @param null|float|int|string $dateValue Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard date string
|
||||
* @param mixed $style A number that determines the type of return value
|
||||
* 1 or omitted Numbers 1 (Sunday) through 7 (Saturday).
|
||||
* 2 Numbers 1 (Monday) through 7 (Sunday).
|
||||
* 3 Numbers 0 (Monday) through 6 (Sunday).
|
||||
*
|
||||
* @return int|string Day of the week value
|
||||
*/
|
||||
public static function day($dateValue, $style = 1)
|
||||
{
|
||||
try {
|
||||
$dateValue = Helpers::getDateValue($dateValue);
|
||||
$style = self::validateStyle($style);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
// Execute function
|
||||
$PHPDateObject = SharedDateHelper::excelToDateTimeObject($dateValue);
|
||||
Helpers::silly1900($PHPDateObject);
|
||||
$DoW = (int) $PHPDateObject->format('w');
|
||||
|
||||
switch ($style) {
|
||||
case 1:
|
||||
++$DoW;
|
||||
|
||||
break;
|
||||
case 2:
|
||||
$DoW = self::dow0Becomes7($DoW);
|
||||
|
||||
break;
|
||||
case 3:
|
||||
$DoW = self::dow0Becomes7($DoW) - 1;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return $DoW;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $style expect int
|
||||
*/
|
||||
private static function validateStyle($style): int
|
||||
{
|
||||
$style = Functions::flattenSingleValue($style);
|
||||
|
||||
if (!is_numeric($style)) {
|
||||
throw new Exception(Functions::VALUE());
|
||||
}
|
||||
$style = (int) $style;
|
||||
if (($style < 1) || ($style > 3)) {
|
||||
throw new Exception(Functions::NAN());
|
||||
}
|
||||
|
||||
return $style;
|
||||
}
|
||||
|
||||
private static function dow0Becomes7(int $DoW): int
|
||||
{
|
||||
return ($DoW === 0) ? 7 : $DoW;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard date string
|
||||
*/
|
||||
private static function apparentBug($dateValue): bool
|
||||
{
|
||||
if (SharedDateHelper::getExcelCalendar() !== SharedDateHelper::CALENDAR_MAC_1904) {
|
||||
if (is_bool($dateValue)) {
|
||||
return true;
|
||||
}
|
||||
if (is_numeric($dateValue) && !((int) $dateValue)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate dateValue parameter.
|
||||
*
|
||||
* @param mixed $dateValue
|
||||
*/
|
||||
private static function validateDateValue($dateValue): float
|
||||
{
|
||||
if (is_bool($dateValue)) {
|
||||
throw new Exception(Functions::VALUE());
|
||||
}
|
||||
|
||||
return Helpers::getDateValue($dateValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate method parameter.
|
||||
*
|
||||
* @param mixed $method
|
||||
*/
|
||||
private static function validateMethod($method): int
|
||||
{
|
||||
if ($method === null) {
|
||||
$method = Constants::STARTWEEK_SUNDAY;
|
||||
}
|
||||
$method = Functions::flattenSingleValue($method);
|
||||
if (!is_numeric($method)) {
|
||||
throw new Exception(Functions::VALUE());
|
||||
}
|
||||
|
||||
$method = (int) $method;
|
||||
if (!array_key_exists($method, Constants::METHODARR)) {
|
||||
throw new Exception(Functions::NAN());
|
||||
}
|
||||
$method = Constants::METHODARR[$method];
|
||||
|
||||
return $method;
|
||||
}
|
||||
|
||||
private static function buggyWeekNum1900(int $method): bool
|
||||
{
|
||||
return $method === Constants::DOW_SUNDAY && SharedDateHelper::getExcelCalendar() === SharedDateHelper::CALENDAR_WINDOWS_1900;
|
||||
}
|
||||
|
||||
private static function buggyWeekNum1904(int $method, bool $origNull, DateTime $dateObject): bool
|
||||
{
|
||||
// This appears to be another Excel bug.
|
||||
|
||||
return $method === Constants::DOW_SUNDAY && SharedDateHelper::getExcelCalendar() === SharedDateHelper::CALENDAR_MAC_1904 &&
|
||||
!$origNull && $dateObject->format('Y-m-d') === '1904-01-01';
|
||||
}
|
||||
}
|
||||
|
|
@ -1,80 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\Date;
|
||||
|
||||
class WeekDay
|
||||
{
|
||||
/**
|
||||
* WEEKDAY.
|
||||
*
|
||||
* Returns the day of the week for a specified date. The day is given as an integer
|
||||
* ranging from 0 to 7 (dependent on the requested style).
|
||||
*
|
||||
* Excel Function:
|
||||
* WEEKDAY(dateValue[,style])
|
||||
*
|
||||
* @param null|float|int|string $dateValue Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard date string
|
||||
* @param int $style A number that determines the type of return value
|
||||
* 1 or omitted Numbers 1 (Sunday) through 7 (Saturday).
|
||||
* 2 Numbers 1 (Monday) through 7 (Sunday).
|
||||
* 3 Numbers 0 (Monday) through 6 (Sunday).
|
||||
*
|
||||
* @return int|string Day of the week value
|
||||
*/
|
||||
public static function funcWeekDay($dateValue, $style = 1)
|
||||
{
|
||||
try {
|
||||
$dateValue = Helpers::getDateValue($dateValue);
|
||||
$style = self::validateStyle($style);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
// Execute function
|
||||
$PHPDateObject = Date::excelToDateTimeObject($dateValue);
|
||||
Helpers::silly1900($PHPDateObject);
|
||||
$DoW = (int) $PHPDateObject->format('w');
|
||||
|
||||
switch ($style) {
|
||||
case 1:
|
||||
++$DoW;
|
||||
|
||||
break;
|
||||
case 2:
|
||||
$DoW = self::dow0Becomes7($DoW);
|
||||
|
||||
break;
|
||||
case 3:
|
||||
$DoW = self::dow0Becomes7($DoW) - 1;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return $DoW;
|
||||
}
|
||||
|
||||
private static function validateStyle($style): int
|
||||
{
|
||||
$style = Functions::flattenSingleValue($style);
|
||||
|
||||
if (!is_numeric($style)) {
|
||||
throw new Exception(Functions::VALUE());
|
||||
}
|
||||
$style = (int) $style;
|
||||
if (($style < 1) || ($style > 3)) {
|
||||
throw new Exception(Functions::NAN());
|
||||
}
|
||||
|
||||
return $style;
|
||||
}
|
||||
|
||||
private static function dow0Becomes7(int $DoW): int
|
||||
{
|
||||
return ($DoW === 0) ? 7 : $DoW;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,130 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel;
|
||||
|
||||
use DateTime;
|
||||
use Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\Date;
|
||||
|
||||
class WeekNum
|
||||
{
|
||||
/**
|
||||
* WEEKNUM.
|
||||
*
|
||||
* Returns the week of the year for a specified date.
|
||||
* The WEEKNUM function considers the week containing January 1 to be the first week of the year.
|
||||
* However, there is a European standard that defines the first week as the one with the majority
|
||||
* of days (four or more) falling in the new year. This means that for years in which there are
|
||||
* three days or less in the first week of January, the WEEKNUM function returns week numbers
|
||||
* that are incorrect according to the European standard.
|
||||
*
|
||||
* Excel Function:
|
||||
* WEEKNUM(dateValue[,style])
|
||||
*
|
||||
* @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard date string
|
||||
* @param int $method Week begins on Sunday or Monday
|
||||
* 1 or omitted Week begins on Sunday.
|
||||
* 2 Week begins on Monday.
|
||||
* 11 Week begins on Monday.
|
||||
* 12 Week begins on Tuesday.
|
||||
* 13 Week begins on Wednesday.
|
||||
* 14 Week begins on Thursday.
|
||||
* 15 Week begins on Friday.
|
||||
* 16 Week begins on Saturday.
|
||||
* 17 Week begins on Sunday.
|
||||
* 21 ISO (Jan. 4 is week 1, begins on Monday).
|
||||
*
|
||||
* @return int|string Week Number
|
||||
*/
|
||||
public static function funcWeekNum($dateValue, $method = Constants::STARTWEEK_SUNDAY)
|
||||
{
|
||||
$origDateValueNull = empty($dateValue);
|
||||
|
||||
try {
|
||||
$method = self::validateMethod($method);
|
||||
if ($dateValue === null) { // boolean not allowed
|
||||
$dateValue = (Date::getExcelCalendar() === DATE::CALENDAR_MAC_1904 || $method === Constants::DOW_SUNDAY) ? 0 : 1;
|
||||
}
|
||||
$dateValue = self::validateDateValue($dateValue);
|
||||
if (!$dateValue && self::buggyWeekNum1900($method)) {
|
||||
// This seems to be an additional Excel bug.
|
||||
return 0;
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
// Execute function
|
||||
$PHPDateObject = Date::excelToDateTimeObject($dateValue);
|
||||
if ($method == Constants::STARTWEEK_MONDAY_ISO) {
|
||||
Helpers::silly1900($PHPDateObject);
|
||||
|
||||
return (int) $PHPDateObject->format('W');
|
||||
}
|
||||
if (self::buggyWeekNum1904($method, $origDateValueNull, $PHPDateObject)) {
|
||||
return 0;
|
||||
}
|
||||
Helpers::silly1900($PHPDateObject, '+ 5 years'); // 1905 calendar matches
|
||||
$dayOfYear = (int) $PHPDateObject->format('z');
|
||||
$PHPDateObject->modify('-' . $dayOfYear . ' days');
|
||||
$firstDayOfFirstWeek = (int) $PHPDateObject->format('w');
|
||||
$daysInFirstWeek = (6 - $firstDayOfFirstWeek + $method) % 7;
|
||||
$daysInFirstWeek += 7 * !$daysInFirstWeek;
|
||||
$endFirstWeek = $daysInFirstWeek - 1;
|
||||
$weekOfYear = floor(($dayOfYear - $endFirstWeek + 13) / 7);
|
||||
|
||||
return (int) $weekOfYear;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate dateValue parameter.
|
||||
*
|
||||
* @param mixed $dateValue
|
||||
*/
|
||||
private static function validateDateValue($dateValue): float
|
||||
{
|
||||
if (is_bool($dateValue)) {
|
||||
throw new Exception(Functions::VALUE());
|
||||
}
|
||||
|
||||
return Helpers::getDateValue($dateValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate method parameter.
|
||||
*
|
||||
* @param mixed $method
|
||||
*/
|
||||
private static function validateMethod($method): int
|
||||
{
|
||||
if ($method === null) {
|
||||
$method = Constants::STARTWEEK_SUNDAY;
|
||||
}
|
||||
$method = Functions::flattenSingleValue($method);
|
||||
if (!is_numeric($method)) {
|
||||
throw new Exception(Functions::VALUE());
|
||||
}
|
||||
|
||||
$method = (int) $method;
|
||||
if (!array_key_exists($method, Constants::METHODARR)) {
|
||||
throw new Exception(Functions::NAN());
|
||||
}
|
||||
$method = Constants::METHODARR[$method];
|
||||
|
||||
return $method;
|
||||
}
|
||||
|
||||
private static function buggyWeekNum1900(int $method): bool
|
||||
{
|
||||
return $method === Constants::DOW_SUNDAY && Date::getExcelCalendar() === Date::CALENDAR_WINDOWS_1900;
|
||||
}
|
||||
|
||||
private static function buggyWeekNum1904(int $method, bool $origNull, DateTime $dateObject): bool
|
||||
{
|
||||
// This appears to be another Excel bug.
|
||||
|
||||
return $method === Constants::DOW_SUNDAY && Date::getExcelCalendar() === Date::CALENDAR_MAC_1904 && !$origNull && $dateObject->format('Y-m-d') === '1904-01-01';
|
||||
}
|
||||
}
|
||||
|
|
@ -2,9 +2,8 @@
|
|||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel;
|
||||
|
||||
use Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\Date;
|
||||
|
||||
class WorkDay
|
||||
{
|
||||
|
|
@ -24,11 +23,12 @@ class WorkDay
|
|||
* @param int $endDays The number of nonweekend and nonholiday days before or after
|
||||
* startDate. A positive value for days yields a future date; a
|
||||
* negative value yields a past date.
|
||||
* @param mixed $dateArgs
|
||||
*
|
||||
* @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object,
|
||||
* depending on the value of the ReturnDateType flag
|
||||
*/
|
||||
public static function funcWorkDay($startDate, $endDays, ...$dateArgs)
|
||||
public static function date($startDate, $endDays, ...$dateArgs)
|
||||
{
|
||||
// Retrieve the mandatory start date and days that are referenced in the function definition
|
||||
try {
|
||||
|
|
@ -65,8 +65,8 @@ class WorkDay
|
|||
{
|
||||
// Adjust the start date if it falls over a weekend
|
||||
|
||||
$startDoW = WeekDay::funcWeekDay($startDate, 3);
|
||||
if (WeekDay::funcWeekDay($startDate, 3) >= 5) {
|
||||
$startDoW = self::getWeekDay($startDate, 3);
|
||||
if (self::getWeekDay($startDate, 3) >= 5) {
|
||||
$startDate += 7 - $startDoW;
|
||||
--$endDays;
|
||||
}
|
||||
|
|
@ -77,7 +77,7 @@ class WorkDay
|
|||
while ($endDays > 0) {
|
||||
++$endDate;
|
||||
// Adjust the calculated end date if it falls over a weekend
|
||||
$endDow = WeekDay::funcWeekDay($endDate, 3);
|
||||
$endDow = self::getWeekDay($endDate, 3);
|
||||
if ($endDow >= 5) {
|
||||
$endDate += 7 - $endDow;
|
||||
}
|
||||
|
|
@ -96,7 +96,7 @@ class WorkDay
|
|||
{
|
||||
$holidayCountedArray = $holidayDates = [];
|
||||
foreach ($holidayArray as $holidayDate) {
|
||||
if (WeekDay::funcWeekDay($holidayDate, 3) < 5) {
|
||||
if (self::getWeekDay($holidayDate, 3) < 5) {
|
||||
$holidayDates[] = $holidayDate;
|
||||
}
|
||||
}
|
||||
|
|
@ -109,7 +109,7 @@ class WorkDay
|
|||
}
|
||||
}
|
||||
// Adjust the calculated end date if it falls over a weekend
|
||||
$endDoW = WeekDay::funcWeekDay($endDate, 3);
|
||||
$endDoW = self::getWeekDay($endDate, 3);
|
||||
if ($endDoW >= 5) {
|
||||
$endDate += 7 - $endDoW;
|
||||
}
|
||||
|
|
@ -127,9 +127,8 @@ class WorkDay
|
|||
{
|
||||
// Adjust the start date if it falls over a weekend
|
||||
|
||||
$startDoW = WeekDay::funcWeekDay($startDate, 3);
|
||||
if (WeekDay::funcWeekDay($startDate, 3) >= 5) {
|
||||
// @phpstan-ignore-next-line
|
||||
$startDoW = self::getWeekDay($startDate, 3);
|
||||
if (self::getWeekDay($startDate, 3) >= 5) {
|
||||
$startDate += -$startDoW + 4;
|
||||
++$endDays;
|
||||
}
|
||||
|
|
@ -140,7 +139,7 @@ class WorkDay
|
|||
while ($endDays < 0) {
|
||||
--$endDate;
|
||||
// Adjust the calculated end date if it falls over a weekend
|
||||
$endDow = WeekDay::funcWeekDay($endDate, 3);
|
||||
$endDow = self::getWeekDay($endDate, 3);
|
||||
if ($endDow >= 5) {
|
||||
$endDate += 4 - $endDow;
|
||||
}
|
||||
|
|
@ -159,7 +158,7 @@ class WorkDay
|
|||
{
|
||||
$holidayCountedArray = $holidayDates = [];
|
||||
foreach ($holidayArray as $holidayDate) {
|
||||
if (WeekDay::funcWeekDay($holidayDate, 3) < 5) {
|
||||
if (self::getWeekDay($holidayDate, 3) < 5) {
|
||||
$holidayDates[] = $holidayDate;
|
||||
}
|
||||
}
|
||||
|
|
@ -172,13 +171,19 @@ class WorkDay
|
|||
}
|
||||
}
|
||||
// Adjust the calculated end date if it falls over a weekend
|
||||
$endDoW = WeekDay::funcWeekDay($endDate, 3);
|
||||
$endDoW = self::getWeekDay($endDate, 3);
|
||||
if ($endDoW >= 5) {
|
||||
// @phpstan-ignore-next-line
|
||||
$endDate += -$endDoW + 4;
|
||||
}
|
||||
}
|
||||
|
||||
return $endDate;
|
||||
}
|
||||
|
||||
private static function getWeekDay(float $date, int $wd): int
|
||||
{
|
||||
$result = Week::day($date, $wd);
|
||||
|
||||
return is_string($result) ? -1 : $result;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,40 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel;
|
||||
|
||||
use Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\Date;
|
||||
|
||||
class Year
|
||||
{
|
||||
/**
|
||||
* YEAR.
|
||||
*
|
||||
* Returns the year corresponding to a date.
|
||||
* The year is returned as an integer in the range 1900-9999.
|
||||
*
|
||||
* Excel Function:
|
||||
* YEAR(dateValue)
|
||||
*
|
||||
* @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard date string
|
||||
*
|
||||
* @return int|string Year
|
||||
*/
|
||||
public static function funcYear($dateValue)
|
||||
{
|
||||
try {
|
||||
$dateValue = Helpers::getDateValue($dateValue);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
if ($dateValue < 1 && Date::getExcelCalendar() === DATE::CALENDAR_WINDOWS_1900) {
|
||||
return 1900;
|
||||
}
|
||||
// Execute function
|
||||
$PHPDateObject = Date::excelToDateTimeObject($dateValue);
|
||||
|
||||
return (int) $PHPDateObject->format('Y');
|
||||
}
|
||||
}
|
||||
|
|
@ -2,9 +2,9 @@
|
|||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel;
|
||||
|
||||
use Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\Date;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\Date as SharedDateHelper;
|
||||
|
||||
class YearFrac
|
||||
{
|
||||
|
|
@ -34,7 +34,7 @@ class YearFrac
|
|||
*
|
||||
* @return float|string fraction of the year, or a string containing an error
|
||||
*/
|
||||
public static function funcYearFrac($startDate, $endDate, $method = 0)
|
||||
public static function fraction($startDate, $endDate, $method = 0)
|
||||
{
|
||||
try {
|
||||
$method = (int) Helpers::validateNumericNull($method);
|
||||
|
|
@ -50,15 +50,15 @@ class YearFrac
|
|||
|
||||
switch ($method) {
|
||||
case 0:
|
||||
return Days360::funcDays360($startDate, $endDate) / 360;
|
||||
return Days360::between($startDate, $endDate) / 360;
|
||||
case 1:
|
||||
return self::method1($startDate, $endDate);
|
||||
case 2:
|
||||
return DateDif::funcDateDif($startDate, $endDate) / 360;
|
||||
return Difference::interval($startDate, $endDate) / 360;
|
||||
case 3:
|
||||
return DateDif::funcDateDif($startDate, $endDate) / 365;
|
||||
return Difference::interval($startDate, $endDate) / 365;
|
||||
case 4:
|
||||
return Days360::funcDays360($startDate, $endDate, true) / 360;
|
||||
return Days360::between($startDate, $endDate, true) / 360;
|
||||
}
|
||||
|
||||
return Functions::NAN();
|
||||
|
|
@ -72,9 +72,9 @@ class YearFrac
|
|||
*/
|
||||
private static function excelBug(float $sDate, $startDate, $endDate, int $method): float
|
||||
{
|
||||
if (Functions::getCompatibilityMode() !== Functions::COMPATIBILITY_OPENOFFICE && Date::getExcelCalendar() !== Date::CALENDAR_MAC_1904) {
|
||||
if (Functions::getCompatibilityMode() !== Functions::COMPATIBILITY_OPENOFFICE && SharedDateHelper::getExcelCalendar() !== SharedDateHelper::CALENDAR_MAC_1904) {
|
||||
if ($endDate === null && $startDate !== null) {
|
||||
if (Month::funcMonth($sDate) == 12 && Day::funcDay($sDate) === 31 && $method === 0) {
|
||||
if (DateParts::month($sDate) == 12 && DateParts::day($sDate) === 31 && $method === 0) {
|
||||
$sDate += 2;
|
||||
} else {
|
||||
++$sDate;
|
||||
|
|
@ -87,14 +87,14 @@ class YearFrac
|
|||
|
||||
private static function method1(float $startDate, float $endDate): float
|
||||
{
|
||||
$days = DateDif::funcDateDif($startDate, $endDate);
|
||||
$startYear = Year::funcYear($startDate);
|
||||
$endYear = Year::funcYear($endDate);
|
||||
$days = Difference::interval($startDate, $endDate);
|
||||
$startYear = (int) DateParts::year($startDate);
|
||||
$endYear = (int) DateParts::year($endDate);
|
||||
$years = $endYear - $startYear + 1;
|
||||
$startMonth = Month::funcMonth($startDate);
|
||||
$startDay = Day::funcDay($startDate);
|
||||
$endMonth = Month::funcMonth($endDate);
|
||||
$endDay = Day::funcDay($endDate);
|
||||
$startMonth = (int) DateParts::month($startDate);
|
||||
$startDay = (int) DateParts::day($startDate);
|
||||
$endMonth = (int) DateParts::month($endDate);
|
||||
$endDay = (int) DateParts::day($endDate);
|
||||
$startMonthDay = 100 * $startMonth + $startDay;
|
||||
$endMonthDay = 100 * $endMonth + $endDay;
|
||||
if ($years == 1) {
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ class Amortization
|
|||
return $e->getMessage();
|
||||
}
|
||||
|
||||
$yearFrac = DateTimeExcel\YearFrac::funcYearFrac($purchased, $firstPeriod, $basis);
|
||||
$yearFrac = DateTimeExcel\YearFrac::fraction($purchased, $firstPeriod, $basis);
|
||||
if (is_string($yearFrac)) {
|
||||
return $yearFrac;
|
||||
}
|
||||
|
|
@ -160,8 +160,8 @@ class Amortization
|
|||
$fOneRate = $cost * $rate;
|
||||
$fCostDelta = $cost - $salvage;
|
||||
// Note, quirky variation for leap years on the YEARFRAC for this function
|
||||
$purchasedYear = DateTimeExcel\Year::funcYear($purchased);
|
||||
$yearFrac = DateTimeExcel\YearFrac::funcYearFrac($purchased, $firstPeriod, $basis);
|
||||
$purchasedYear = DateTimeExcel\DateParts::year($purchased);
|
||||
$yearFrac = DateTimeExcel\YearFrac::fraction($purchased, $firstPeriod, $basis);
|
||||
if (is_string($yearFrac)) {
|
||||
return $yearFrac;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -196,10 +196,9 @@ class NonPeriodic
|
|||
return $e->getMessage();
|
||||
}
|
||||
if ($date0 > $datei) {
|
||||
/** @phpstan-ignore-next-line */
|
||||
$dif = $ordered ? Functions::NAN() : -DateTimeExcel\DateDif::funcDateDif($datei, $date0, 'd');
|
||||
$dif = $ordered ? Functions::NAN() : -((int) DateTimeExcel\Difference::interval($datei, $date0, 'd'));
|
||||
} else {
|
||||
$dif = DateTimeExcel\DateDif::funcDateDif($date0, $datei, 'd');
|
||||
$dif = DateTimeExcel\Difference::interval($date0, $datei, 'd');
|
||||
}
|
||||
if (!is_numeric($dif)) {
|
||||
return $dif;
|
||||
|
|
|
|||
|
|
@ -63,17 +63,17 @@ class Coupons
|
|||
return $e->getMessage();
|
||||
}
|
||||
|
||||
$daysPerYear = Helpers::daysPerYear(DateTimeExcel\Year::funcYear($settlement), $basis);
|
||||
$daysPerYear = Helpers::daysPerYear(DateTimeExcel\DateParts::year($settlement), $basis);
|
||||
if (is_string($daysPerYear)) {
|
||||
return Functions::VALUE();
|
||||
}
|
||||
$prev = self::couponFirstPeriodDate($settlement, $maturity, $frequency, self::PERIOD_DATE_PREVIOUS);
|
||||
|
||||
if ($basis === FinancialConstants::BASIS_DAYS_PER_YEAR_ACTUAL) {
|
||||
return abs(DateTimeExcel\Days::funcDays($prev, $settlement));
|
||||
return abs((float) DateTimeExcel\Days::between($prev, $settlement));
|
||||
}
|
||||
|
||||
return DateTimeExcel\YearFrac::funcYearFrac($prev, $settlement, $basis) * $daysPerYear;
|
||||
return DateTimeExcel\YearFrac::fraction($prev, $settlement, $basis) * $daysPerYear;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -133,7 +133,7 @@ class Coupons
|
|||
case FinancialConstants::BASIS_DAYS_PER_YEAR_ACTUAL:
|
||||
// Actual/actual
|
||||
if ($frequency == FinancialConstants::FREQUENCY_ANNUAL) {
|
||||
$daysPerYear = Helpers::daysPerYear(DateTimeExcel\Year::funcYear($settlement), $basis);
|
||||
$daysPerYear = Helpers::daysPerYear(DateTimeExcel\DateParts::year($settlement), $basis);
|
||||
|
||||
return $daysPerYear / $frequency;
|
||||
}
|
||||
|
|
@ -197,7 +197,7 @@ class Coupons
|
|||
return $e->getMessage();
|
||||
}
|
||||
|
||||
$daysPerYear = Helpers::daysPerYear(DateTimeExcel\Year::funcYear($settlement), $basis);
|
||||
$daysPerYear = Helpers::daysPerYear(DateTimeExcel\DateParts::year($settlement), $basis);
|
||||
$next = self::couponFirstPeriodDate($settlement, $maturity, $frequency, self::PERIOD_DATE_NEXT);
|
||||
|
||||
if ($basis === FinancialConstants::BASIS_DAYS_PER_YEAR_NASD) {
|
||||
|
|
@ -208,7 +208,7 @@ class Coupons
|
|||
}
|
||||
}
|
||||
|
||||
return DateTimeExcel\YearFrac::funcYearFrac($settlement, $next, $basis) * $daysPerYear;
|
||||
return DateTimeExcel\YearFrac::fraction($settlement, $next, $basis) * $daysPerYear;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -316,7 +316,7 @@ class Coupons
|
|||
return $e->getMessage();
|
||||
}
|
||||
|
||||
$yearsBetweenSettlementAndMaturity = DateTimeExcel\YearFrac::funcYearFrac(
|
||||
$yearsBetweenSettlementAndMaturity = DateTimeExcel\YearFrac::fraction(
|
||||
$settlement,
|
||||
$maturity,
|
||||
FinancialConstants::BASIS_DAYS_PER_YEAR_NASD
|
||||
|
|
|
|||
|
|
@ -78,12 +78,12 @@ class AccruedInterest
|
|||
return $e->getMessage();
|
||||
}
|
||||
|
||||
$daysBetweenIssueAndSettlement = YearFrac::funcYearFrac($issue, $settlement, $basis);
|
||||
$daysBetweenIssueAndSettlement = YearFrac::fraction($issue, $settlement, $basis);
|
||||
if (!is_numeric($daysBetweenIssueAndSettlement)) {
|
||||
// return date error
|
||||
return $daysBetweenIssueAndSettlement;
|
||||
}
|
||||
$daysBetweenFirstInterestAndSettlement = YearFrac::funcYearFrac($firstInterest, $settlement, $basis);
|
||||
$daysBetweenFirstInterestAndSettlement = YearFrac::fraction($firstInterest, $settlement, $basis);
|
||||
if (!is_numeric($daysBetweenFirstInterestAndSettlement)) {
|
||||
// return date error
|
||||
return $daysBetweenFirstInterestAndSettlement;
|
||||
|
|
@ -140,7 +140,7 @@ class AccruedInterest
|
|||
return $e->getMessage();
|
||||
}
|
||||
|
||||
$daysBetweenIssueAndSettlement = YearFrac::funcYearFrac($issue, $settlement, $basis);
|
||||
$daysBetweenIssueAndSettlement = YearFrac::fraction($issue, $settlement, $basis);
|
||||
if (!is_numeric($daysBetweenIssueAndSettlement)) {
|
||||
// return date error
|
||||
return $daysBetweenIssueAndSettlement;
|
||||
|
|
|
|||
|
|
@ -134,7 +134,7 @@ class Price
|
|||
return $e->getMessage();
|
||||
}
|
||||
|
||||
$daysBetweenSettlementAndMaturity = DateTimeExcel\YearFrac::funcYearFrac($settlement, $maturity, $basis);
|
||||
$daysBetweenSettlementAndMaturity = DateTimeExcel\YearFrac::fraction($settlement, $maturity, $basis);
|
||||
if (!is_numeric($daysBetweenSettlementAndMaturity)) {
|
||||
// return date error
|
||||
return $daysBetweenSettlementAndMaturity;
|
||||
|
|
@ -194,23 +194,23 @@ class Price
|
|||
return $e->getMessage();
|
||||
}
|
||||
|
||||
$daysPerYear = Helpers::daysPerYear(DateTimeExcel\Year::funcYear($settlement), $basis);
|
||||
$daysPerYear = Helpers::daysPerYear(DateTimeExcel\DateParts::year($settlement), $basis);
|
||||
if (!is_numeric($daysPerYear)) {
|
||||
return $daysPerYear;
|
||||
}
|
||||
$daysBetweenIssueAndSettlement = DateTimeExcel\YearFrac::funcYearFrac($issue, $settlement, $basis);
|
||||
$daysBetweenIssueAndSettlement = DateTimeExcel\YearFrac::fraction($issue, $settlement, $basis);
|
||||
if (!is_numeric($daysBetweenIssueAndSettlement)) {
|
||||
// return date error
|
||||
return $daysBetweenIssueAndSettlement;
|
||||
}
|
||||
$daysBetweenIssueAndSettlement *= $daysPerYear;
|
||||
$daysBetweenIssueAndMaturity = DateTimeExcel\YearFrac::funcYearFrac($issue, $maturity, $basis);
|
||||
$daysBetweenIssueAndMaturity = DateTimeExcel\YearFrac::fraction($issue, $maturity, $basis);
|
||||
if (!is_numeric($daysBetweenIssueAndMaturity)) {
|
||||
// return date error
|
||||
return $daysBetweenIssueAndMaturity;
|
||||
}
|
||||
$daysBetweenIssueAndMaturity *= $daysPerYear;
|
||||
$daysBetweenSettlementAndMaturity = DateTimeExcel\YearFrac::funcYearFrac($settlement, $maturity, $basis);
|
||||
$daysBetweenSettlementAndMaturity = DateTimeExcel\YearFrac::fraction($settlement, $maturity, $basis);
|
||||
if (!is_numeric($daysBetweenSettlementAndMaturity)) {
|
||||
// return date error
|
||||
return $daysBetweenSettlementAndMaturity;
|
||||
|
|
@ -272,7 +272,7 @@ class Price
|
|||
if ($investment <= 0) {
|
||||
return Functions::NAN();
|
||||
}
|
||||
$daysBetweenSettlementAndMaturity = DateTimeExcel\YearFrac::funcYearFrac($settlement, $maturity, $basis);
|
||||
$daysBetweenSettlementAndMaturity = DateTimeExcel\YearFrac::fraction($settlement, $maturity, $basis);
|
||||
if (!is_numeric($daysBetweenSettlementAndMaturity)) {
|
||||
// return date error
|
||||
return $daysBetweenSettlementAndMaturity;
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ class Rates
|
|||
return Functions::NAN();
|
||||
}
|
||||
|
||||
$daysBetweenSettlementAndMaturity = DateTimeExcel\YearFrac::funcYearFrac($settlement, $maturity, $basis);
|
||||
$daysBetweenSettlementAndMaturity = DateTimeExcel\YearFrac::fraction($settlement, $maturity, $basis);
|
||||
if (!is_numeric($daysBetweenSettlementAndMaturity)) {
|
||||
// return date error
|
||||
return $daysBetweenSettlementAndMaturity;
|
||||
|
|
@ -126,7 +126,7 @@ class Rates
|
|||
return Functions::NAN();
|
||||
}
|
||||
|
||||
$daysBetweenSettlementAndMaturity = DateTimeExcel\YearFrac::funcYearFrac($settlement, $maturity, $basis);
|
||||
$daysBetweenSettlementAndMaturity = DateTimeExcel\YearFrac::fraction($settlement, $maturity, $basis);
|
||||
if (!is_numeric($daysBetweenSettlementAndMaturity)) {
|
||||
// return date error
|
||||
return $daysBetweenSettlementAndMaturity;
|
||||
|
|
|
|||
|
|
@ -57,11 +57,11 @@ class Yields
|
|||
return $e->getMessage();
|
||||
}
|
||||
|
||||
$daysPerYear = Helpers::daysPerYear(DateTimeExcel\Year::funcYear($settlement), $basis);
|
||||
$daysPerYear = Helpers::daysPerYear(DateTimeExcel\DateParts::year($settlement), $basis);
|
||||
if (!is_numeric($daysPerYear)) {
|
||||
return $daysPerYear;
|
||||
}
|
||||
$daysBetweenSettlementAndMaturity = DateTimeExcel\YearFrac::funcYearFrac($settlement, $maturity, $basis);
|
||||
$daysBetweenSettlementAndMaturity = DateTimeExcel\YearFrac::fraction($settlement, $maturity, $basis);
|
||||
if (!is_numeric($daysBetweenSettlementAndMaturity)) {
|
||||
// return date error
|
||||
return $daysBetweenSettlementAndMaturity;
|
||||
|
|
@ -122,23 +122,23 @@ class Yields
|
|||
return $e->getMessage();
|
||||
}
|
||||
|
||||
$daysPerYear = Helpers::daysPerYear(DateTimeExcel\Year::funcYear($settlement), $basis);
|
||||
$daysPerYear = Helpers::daysPerYear(DateTimeExcel\DateParts::year($settlement), $basis);
|
||||
if (!is_numeric($daysPerYear)) {
|
||||
return $daysPerYear;
|
||||
}
|
||||
$daysBetweenIssueAndSettlement = DateTimeExcel\YearFrac::funcYearFrac($issue, $settlement, $basis);
|
||||
$daysBetweenIssueAndSettlement = DateTimeExcel\YearFrac::fraction($issue, $settlement, $basis);
|
||||
if (!is_numeric($daysBetweenIssueAndSettlement)) {
|
||||
// return date error
|
||||
return $daysBetweenIssueAndSettlement;
|
||||
}
|
||||
$daysBetweenIssueAndSettlement *= $daysPerYear;
|
||||
$daysBetweenIssueAndMaturity = DateTimeExcel\YearFrac::funcYearFrac($issue, $maturity, $basis);
|
||||
$daysBetweenIssueAndMaturity = DateTimeExcel\YearFrac::fraction($issue, $maturity, $basis);
|
||||
if (!is_numeric($daysBetweenIssueAndMaturity)) {
|
||||
// return date error
|
||||
return $daysBetweenIssueAndMaturity;
|
||||
}
|
||||
$daysBetweenIssueAndMaturity *= $daysPerYear;
|
||||
$daysBetweenSettlementAndMaturity = DateTimeExcel\YearFrac::funcYearFrac($settlement, $maturity, $basis);
|
||||
$daysBetweenSettlementAndMaturity = DateTimeExcel\YearFrac::fraction($settlement, $maturity, $basis);
|
||||
if (!is_numeric($daysBetweenSettlementAndMaturity)) {
|
||||
// return date error
|
||||
return $daysBetweenSettlementAndMaturity;
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ class TreasuryBill
|
|||
|
||||
$daysBetweenSettlementAndMaturity = $maturity - $settlement;
|
||||
$daysPerYear = Helpers::daysPerYear(
|
||||
DateTimeExcel\Year::funcYear($maturity),
|
||||
DateTimeExcel\DateParts::year($maturity),
|
||||
FinancialConstants::BASIS_DAYS_PER_YEAR_ACTUAL
|
||||
);
|
||||
|
||||
|
|
@ -88,7 +88,7 @@ class TreasuryBill
|
|||
|
||||
$daysBetweenSettlementAndMaturity = $maturity - $settlement;
|
||||
$daysPerYear = Helpers::daysPerYear(
|
||||
DateTimeExcel\Year::funcYear($maturity),
|
||||
DateTimeExcel\DateParts::year($maturity),
|
||||
FinancialConstants::BASIS_DAYS_PER_YEAR_ACTUAL
|
||||
);
|
||||
|
||||
|
|
@ -134,7 +134,7 @@ class TreasuryBill
|
|||
|
||||
$daysBetweenSettlementAndMaturity = $maturity - $settlement;
|
||||
$daysPerYear = Helpers::daysPerYear(
|
||||
DateTimeExcel\Year::funcYear($maturity),
|
||||
DateTimeExcel\DateParts::year($maturity),
|
||||
FinancialConstants::BASIS_DAYS_PER_YEAR_ACTUAL
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,9 @@ use PhpOffice\PhpSpreadsheet\Calculation\LookupRef\VLookup;
|
|||
use PhpOffice\PhpSpreadsheet\Cell\Cell;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
||||
|
||||
/**
|
||||
* @deprecated 1.18.0
|
||||
*/
|
||||
class LookupRef
|
||||
{
|
||||
/**
|
||||
|
|
@ -25,7 +28,8 @@ class LookupRef
|
|||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see Use the cell() method in the LookupRef\Address class instead
|
||||
* @see LookupRef\Address::cell()
|
||||
* Use the cell() method in the LookupRef\Address class instead
|
||||
*
|
||||
* @param mixed $row Row number to use in the cell reference
|
||||
* @param mixed $column Column number to use in the cell reference
|
||||
|
|
@ -61,11 +65,12 @@ class LookupRef
|
|||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see Use the COLUMN() method in the LookupRef\RowColumnInformation class instead
|
||||
* @see LookupRef\RowColumnInformation::COLUMN()
|
||||
* Use the COLUMN() method in the LookupRef\RowColumnInformation class instead
|
||||
*
|
||||
* @param null|array|string $cellAddress A reference to a range of cells for which you want the column numbers
|
||||
*
|
||||
* @return int|int[]
|
||||
* @return int|int[]|string
|
||||
*/
|
||||
public static function COLUMN($cellAddress = null, ?Cell $cell = null)
|
||||
{
|
||||
|
|
@ -82,7 +87,8 @@ class LookupRef
|
|||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see Use the COLUMNS() method in the LookupRef\RowColumnInformation class instead
|
||||
* @see LookupRef\RowColumnInformation::COLUMNS()
|
||||
* Use the COLUMNS() method in the LookupRef\RowColumnInformation class instead
|
||||
*
|
||||
* @param null|array|string $cellAddress An array or array formula, or a reference to a range of cells
|
||||
* for which you want the number of columns
|
||||
|
|
@ -109,7 +115,8 @@ class LookupRef
|
|||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see Use the ROW() method in the LookupRef\RowColumnInformation class instead
|
||||
* @see LookupRef\RowColumnInformation::ROW()
|
||||
* Use the ROW() method in the LookupRef\RowColumnInformation class instead
|
||||
*
|
||||
* @param null|array|string $cellAddress A reference to a range of cells for which you want the row numbers
|
||||
*
|
||||
|
|
@ -130,7 +137,8 @@ class LookupRef
|
|||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see Use the ROWS() method in the LookupRef\RowColumnInformation class instead
|
||||
* @see LookupRef\RowColumnInformation::ROWS()
|
||||
* Use the ROWS() method in the LookupRef\RowColumnInformation class instead
|
||||
*
|
||||
* @param null|array|string $cellAddress An array or array formula, or a reference to a range of cells
|
||||
* for which you want the number of rows
|
||||
|
|
@ -148,29 +156,20 @@ class LookupRef
|
|||
* Excel Function:
|
||||
* =HYPERLINK(linkURL,displayName)
|
||||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see LookupRef\Hyperlink::set()
|
||||
* Use the set() method in the LookupRef\Hyperlink class instead
|
||||
*
|
||||
* @param mixed $linkURL Expect string. Value to check, is also the value returned when no error
|
||||
* @param mixed $displayName Expect string. Value to return when testValue is an error condition
|
||||
* @param Cell $pCell The cell to set the hyperlink in
|
||||
*
|
||||
* @return mixed The value of $displayName (or $linkURL if $displayName was blank)
|
||||
* @return string The value of $displayName (or $linkURL if $displayName was blank)
|
||||
*/
|
||||
public static function HYPERLINK($linkURL = '', $displayName = null, ?Cell $pCell = null)
|
||||
{
|
||||
$linkURL = ($linkURL === null) ? '' : Functions::flattenSingleValue($linkURL);
|
||||
$displayName = ($displayName === null) ? '' : Functions::flattenSingleValue($displayName);
|
||||
|
||||
if ((!is_object($pCell)) || (trim($linkURL) == '')) {
|
||||
return Functions::REF();
|
||||
}
|
||||
|
||||
if ((is_object($displayName)) || trim($displayName) == '') {
|
||||
$displayName = $linkURL;
|
||||
}
|
||||
|
||||
$pCell->getHyperlink()->setUrl($linkURL);
|
||||
$pCell->getHyperlink()->setTooltip($displayName);
|
||||
|
||||
return $displayName;
|
||||
return LookupRef\Hyperlink::set($linkURL, $displayName, $pCell);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -184,7 +183,8 @@ class LookupRef
|
|||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see Use the INDIRECT() method in the LookupRef\Indirect class instead
|
||||
* @see LookupRef\Indirect::INDIRECT()
|
||||
* Use the INDIRECT() method in the LookupRef\Indirect class instead
|
||||
*
|
||||
* NOTE - INDIRECT() does not yet support the optional a1 parameter introduced in Excel 2010
|
||||
*
|
||||
|
|
@ -192,8 +192,6 @@ class LookupRef
|
|||
* @param Cell $pCell The current cell (containing this formula)
|
||||
*
|
||||
* @return array|string An array containing a cell or range of cells, or a string on error
|
||||
*
|
||||
* @TODO Support for the optional a1 parameter introduced in Excel 2010
|
||||
*/
|
||||
public static function INDIRECT($cellAddress, Cell $pCell)
|
||||
{
|
||||
|
|
@ -212,7 +210,8 @@ class LookupRef
|
|||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see Use the OFFSET() method in the LookupRef\Offset class instead
|
||||
* @see LookupRef\Offset::OFFSET()
|
||||
* Use the OFFSET() method in the LookupRef\Offset class instead
|
||||
*
|
||||
* @param null|string $cellAddress The reference from which you want to base the offset.
|
||||
* Reference must refer to a cell or range of adjacent cells;
|
||||
|
|
@ -248,31 +247,16 @@ class LookupRef
|
|||
* Excel Function:
|
||||
* =CHOOSE(index_num, value1, [value2], ...)
|
||||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see LookupRef\Selection::choose()
|
||||
* Use the choose() method in the LookupRef\Selection class instead
|
||||
*
|
||||
* @return mixed The selected value
|
||||
*/
|
||||
public static function CHOOSE(...$chooseArgs)
|
||||
{
|
||||
$chosenEntry = Functions::flattenArray(array_shift($chooseArgs));
|
||||
$entryCount = count($chooseArgs) - 1;
|
||||
|
||||
if (is_array($chosenEntry)) {
|
||||
$chosenEntry = array_shift($chosenEntry);
|
||||
}
|
||||
if ((is_numeric($chosenEntry)) && (!is_bool($chosenEntry))) {
|
||||
--$chosenEntry;
|
||||
} else {
|
||||
return Functions::VALUE();
|
||||
}
|
||||
$chosenEntry = floor($chosenEntry);
|
||||
if (($chosenEntry < 0) || ($chosenEntry > $entryCount)) {
|
||||
return Functions::VALUE();
|
||||
}
|
||||
|
||||
if (is_array($chooseArgs[$chosenEntry])) {
|
||||
return Functions::flattenArray($chooseArgs[$chosenEntry]);
|
||||
}
|
||||
|
||||
return $chooseArgs[$chosenEntry];
|
||||
return LookupRef\Selection::choose(...$chooseArgs);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -285,7 +269,8 @@ class LookupRef
|
|||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see Use the MATCH() method in the LookupRef\ExcelMatch class instead
|
||||
* @see LookupRef\ExcelMatch::MATCH()
|
||||
* Use the MATCH() method in the LookupRef\ExcelMatch class instead
|
||||
*
|
||||
* @param mixed $lookupValue The value that you want to match in lookup_array
|
||||
* @param mixed $lookupArray The range of cells being searched
|
||||
|
|
@ -309,7 +294,8 @@ class LookupRef
|
|||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see Use the index() method in the LookupRef\Matrix class instead
|
||||
* @see LookupRef\Matrix::index()
|
||||
* Use the index() method in the LookupRef\Matrix class instead
|
||||
*
|
||||
* @param mixed $rowNum The row in the array or range from which to return a value.
|
||||
* If row_num is omitted, column_num is required.
|
||||
|
|
@ -329,7 +315,8 @@ class LookupRef
|
|||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see Use the transpose() method in the LookupRef\Matrix class instead
|
||||
* @see LookupRef\Matrix::transpose()
|
||||
* Use the transpose() method in the LookupRef\Matrix class instead
|
||||
*
|
||||
* @param array $matrixData A matrix of values
|
||||
*
|
||||
|
|
@ -350,7 +337,8 @@ class LookupRef
|
|||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see Use the lookup() method in the LookupRef\VLookup class instead
|
||||
* @see LookupRef\VLookup::lookup()
|
||||
* Use the lookup() method in the LookupRef\VLookup class instead
|
||||
*
|
||||
* @param mixed $lookup_value The value that you want to match in lookup_array
|
||||
* @param mixed $lookup_array The range of cells being searched
|
||||
|
|
@ -372,7 +360,8 @@ class LookupRef
|
|||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see Use the lookup() method in the LookupRef\HLookup class instead
|
||||
* @see LookupRef\HLookup::lookup()
|
||||
* Use the lookup() method in the LookupRef\HLookup class instead
|
||||
*
|
||||
* @param mixed $lookup_value The value that you want to match in lookup_array
|
||||
* @param mixed $lookup_array The range of cells being searched
|
||||
|
|
@ -393,7 +382,8 @@ class LookupRef
|
|||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see Use the lookup() method in the LookupRef\Lookup class instead
|
||||
* @see LookupRef\Lookup::lookup()
|
||||
* Use the lookup() method in the LookupRef\Lookup class instead
|
||||
*
|
||||
* @param mixed $lookup_value The value that you want to match in lookup_array
|
||||
* @param mixed $lookup_vector The range of cells being searched
|
||||
|
|
@ -409,6 +399,11 @@ class LookupRef
|
|||
/**
|
||||
* FORMULATEXT.
|
||||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see LookupRef\Formula::text()
|
||||
* Use the text() method in the LookupRef\Formula class instead
|
||||
*
|
||||
* @param mixed $cellReference The cell to check
|
||||
* @param Cell $pCell The current cell (containing this formula)
|
||||
*
|
||||
|
|
@ -416,22 +411,6 @@ class LookupRef
|
|||
*/
|
||||
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();
|
||||
return LookupRef\Formula::text($cellReference, $pCell);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\LookupRef;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
use PhpOffice\PhpSpreadsheet\Cell\Cell;
|
||||
|
||||
class Formula
|
||||
{
|
||||
/**
|
||||
* FORMULATEXT.
|
||||
*
|
||||
* @param mixed $cellReference The cell to check
|
||||
* @param Cell $pCell The current cell (containing this formula)
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function text($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 === null ||
|
||||
!$worksheet->cellExists($cellReference) ||
|
||||
!$worksheet->getCell($cellReference)->isFormula()
|
||||
) {
|
||||
return Functions::NA();
|
||||
}
|
||||
|
||||
return $worksheet->getCell($cellReference)->getValue();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\LookupRef;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
use PhpOffice\PhpSpreadsheet\Cell\Cell;
|
||||
|
||||
class Hyperlink
|
||||
{
|
||||
/**
|
||||
* HYPERLINK.
|
||||
*
|
||||
* Excel Function:
|
||||
* =HYPERLINK(linkURL, [displayName])
|
||||
*
|
||||
* @param mixed $linkURL Expect string. Value to check, is also the value returned when no error
|
||||
* @param mixed $displayName Expect string. Value to return when testValue is an error condition
|
||||
* @param Cell $pCell The cell to set the hyperlink in
|
||||
*
|
||||
* @return mixed The value of $displayName (or $linkURL if $displayName was blank)
|
||||
*/
|
||||
public static function set($linkURL = '', $displayName = null, ?Cell $pCell = null)
|
||||
{
|
||||
$linkURL = ($linkURL === null) ? '' : Functions::flattenSingleValue($linkURL);
|
||||
$displayName = ($displayName === null) ? '' : Functions::flattenSingleValue($displayName);
|
||||
|
||||
if ((!is_object($pCell)) || (trim($linkURL) == '')) {
|
||||
return Functions::REF();
|
||||
}
|
||||
|
||||
if ((is_object($displayName)) || trim($displayName) == '') {
|
||||
$displayName = $linkURL;
|
||||
}
|
||||
|
||||
$pCell->getHyperlink()->setUrl($linkURL);
|
||||
$pCell->getHyperlink()->setTooltip($displayName);
|
||||
|
||||
return $displayName;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\LookupRef;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
|
||||
class LookupRefValidations
|
||||
{
|
||||
/**
|
||||
* @param mixed $value
|
||||
*/
|
||||
public static function validateInt($value): int
|
||||
{
|
||||
if (!is_numeric($value)) {
|
||||
if (Functions::isError($value)) {
|
||||
throw new Exception($value);
|
||||
}
|
||||
|
||||
throw new Exception(Functions::VALUE());
|
||||
}
|
||||
|
||||
return (int) floor((float) $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $value
|
||||
*/
|
||||
public static function validatePositiveInt($value, bool $allowZero = true): int
|
||||
{
|
||||
$value = self::validateInt($value);
|
||||
|
||||
if (($allowZero === false && $value <= 0) || $value < 0) {
|
||||
throw new Exception(Functions::VALUE());
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\LookupRef;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
|
||||
class Matrix
|
||||
|
|
@ -39,7 +40,7 @@ class Matrix
|
|||
* Uses an index to choose a value from a reference or array
|
||||
*
|
||||
* Excel Function:
|
||||
* =INDEX(range_array, row_num, [column_num])
|
||||
* =INDEX(range_array, row_num, [column_num], [area_num])
|
||||
*
|
||||
* @param mixed $matrix A range of cells or an array constant
|
||||
* @param mixed $rowNum The row in the array or range from which to return a value.
|
||||
|
|
@ -47,15 +48,20 @@ class Matrix
|
|||
* @param mixed $columnNum The column in the array or range from which to return a value.
|
||||
* If column_num is omitted, row_num is required.
|
||||
*
|
||||
* TODO Provide support for area_num, currently not supported
|
||||
*
|
||||
* @return mixed the value of a specified cell or array of cells
|
||||
*/
|
||||
public static function index($matrix, $rowNum = 0, $columnNum = 0)
|
||||
{
|
||||
$rowNum = Functions::flattenSingleValue($rowNum);
|
||||
$columnNum = Functions::flattenSingleValue($columnNum);
|
||||
$rowNum = ($rowNum === null) ? 0 : Functions::flattenSingleValue($rowNum);
|
||||
$columnNum = ($columnNum === null) ? 0 : Functions::flattenSingleValue($columnNum);
|
||||
|
||||
if (!is_numeric($rowNum) || !is_numeric($columnNum) || ($rowNum < 0) || ($columnNum < 0)) {
|
||||
return Functions::VALUE();
|
||||
try {
|
||||
$rowNum = LookupRefValidations::validatePositiveInt($rowNum);
|
||||
$columnNum = LookupRefValidations::validatePositiveInt($columnNum);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
if (!is_array($matrix) || ($rowNum > count($matrix))) {
|
||||
|
|
@ -69,12 +75,12 @@ class Matrix
|
|||
return Functions::REF();
|
||||
}
|
||||
|
||||
if ($columnNum == 0) {
|
||||
if ($columnNum === 0) {
|
||||
return self::extractRowValue($matrix, $rowKeys, $rowNum);
|
||||
}
|
||||
|
||||
$columnNum = $columnKeys[--$columnNum];
|
||||
if ($rowNum == 0) {
|
||||
if ($rowNum === 0) {
|
||||
return array_map(
|
||||
function ($value) {
|
||||
return [$value];
|
||||
|
|
@ -89,7 +95,7 @@ class Matrix
|
|||
|
||||
private static function extractRowValue(array $matrix, array $rowKeys, int $rowNum)
|
||||
{
|
||||
if ($rowNum == 0) {
|
||||
if ($rowNum === 0) {
|
||||
return $matrix;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\LookupRef;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
|
||||
class Selection
|
||||
{
|
||||
/**
|
||||
* CHOOSE.
|
||||
*
|
||||
* Uses lookup_value to return a value from the list of value arguments.
|
||||
* Use CHOOSE to select one of up to 254 values based on the lookup_value.
|
||||
*
|
||||
* Excel Function:
|
||||
* =CHOOSE(index_num, value1, [value2], ...)
|
||||
*
|
||||
* @param mixed ...$chooseArgs Data values
|
||||
*
|
||||
* @return mixed The selected value
|
||||
*/
|
||||
public static function choose(...$chooseArgs)
|
||||
{
|
||||
$chosenEntry = Functions::flattenArray(array_shift($chooseArgs));
|
||||
$entryCount = count($chooseArgs) - 1;
|
||||
|
||||
if (is_array($chosenEntry)) {
|
||||
$chosenEntry = array_shift($chosenEntry);
|
||||
}
|
||||
if (is_numeric($chosenEntry)) {
|
||||
--$chosenEntry;
|
||||
} else {
|
||||
return Functions::VALUE();
|
||||
}
|
||||
$chosenEntry = floor($chosenEntry);
|
||||
if (($chosenEntry < 0) || ($chosenEntry > $entryCount)) {
|
||||
return Functions::VALUE();
|
||||
}
|
||||
|
||||
if (is_array($chooseArgs[$chosenEntry])) {
|
||||
return Functions::flattenArray($chooseArgs[$chosenEntry]);
|
||||
}
|
||||
|
||||
return $chooseArgs[$chosenEntry];
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,9 @@
|
|||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation;
|
||||
|
||||
/**
|
||||
* @deprecated 1.18.0
|
||||
*/
|
||||
class MathTrig
|
||||
{
|
||||
/**
|
||||
|
|
@ -124,7 +127,7 @@ class MathTrig
|
|||
* @param int $numObjs Number of different objects
|
||||
* @param int $numInSet Number of objects in each combination
|
||||
*
|
||||
* @return int|string Number of combinations, or a string containing an error
|
||||
* @return float|int|string Number of combinations, or a string containing an error
|
||||
*/
|
||||
public static function COMBIN($numObjs, $numInSet)
|
||||
{
|
||||
|
|
@ -150,7 +153,7 @@ class MathTrig
|
|||
*
|
||||
* @param float $number Number to round
|
||||
*
|
||||
* @return int|string Rounded Number, or a string containing an error
|
||||
* @return float|int|string Rounded Number, or a string containing an error
|
||||
*/
|
||||
public static function EVEN($number)
|
||||
{
|
||||
|
|
@ -186,7 +189,7 @@ class MathTrig
|
|||
*
|
||||
* @param float $factVal Factorial Value
|
||||
*
|
||||
* @return int|string Factorial, or a string containing an error
|
||||
* @return float|int|string Factorial, or a string containing an error
|
||||
*/
|
||||
public static function FACT($factVal)
|
||||
{
|
||||
|
|
@ -208,7 +211,7 @@ class MathTrig
|
|||
*
|
||||
* @param float $factVal Factorial Value
|
||||
*
|
||||
* @return int|string Double Factorial, or a string containing an error
|
||||
* @return float|int|string Double Factorial, or a string containing an error
|
||||
*/
|
||||
public static function FACTDOUBLE($factVal)
|
||||
{
|
||||
|
|
@ -452,7 +455,7 @@ class MathTrig
|
|||
* @param int $a Dividend
|
||||
* @param int $b Divisor
|
||||
*
|
||||
* @return int|string Remainder, or a string containing an error
|
||||
* @return float|int|string Remainder, or a string containing an error
|
||||
*/
|
||||
public static function MOD($a = 1, $b = 1)
|
||||
{
|
||||
|
|
@ -510,7 +513,7 @@ class MathTrig
|
|||
*
|
||||
* @param float $number Number to round
|
||||
*
|
||||
* @return int|string Rounded Number, or a string containing an error
|
||||
* @return float|int|string Rounded Number, or a string containing an error
|
||||
*/
|
||||
public static function ODD($number)
|
||||
{
|
||||
|
|
@ -822,7 +825,7 @@ class MathTrig
|
|||
*
|
||||
* @param mixed $args Data values
|
||||
*
|
||||
* @return float|string
|
||||
* @return null|float|string
|
||||
*/
|
||||
public static function SUMIFS(...$args)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -47,11 +47,19 @@ class Arabic
|
|||
return $sum;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $value
|
||||
*/
|
||||
private static function mollifyScrutinizer($value): array
|
||||
{
|
||||
return is_array($value) ? $value : [];
|
||||
}
|
||||
|
||||
private static function strSplit(string $roman): array
|
||||
{
|
||||
$rslt = str_split($roman);
|
||||
|
||||
return is_array($rslt) ? $rslt : [];
|
||||
return self::mollifyScrutinizer($rslt);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ class Base
|
|||
return Functions::NAN(); // Numeric range constraints
|
||||
}
|
||||
|
||||
$outcome = strtoupper((string) base_convert($number, 10, $radix));
|
||||
$outcome = strtoupper((string) base_convert((string) $number, 10, $radix));
|
||||
if ($minLength !== null) {
|
||||
$outcome = str_pad($outcome, (int) $minLength, '0', STR_PAD_LEFT); // String padding
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ class Helpers
|
|||
return (int) $number;
|
||||
}
|
||||
if (is_numeric($number)) {
|
||||
return $number;
|
||||
return 0 + $number;
|
||||
}
|
||||
|
||||
throw new Exception(Functions::VALUE());
|
||||
|
|
@ -55,7 +55,7 @@ class Helpers
|
|||
return $substitute;
|
||||
}
|
||||
if (is_numeric($number)) {
|
||||
return $number;
|
||||
return 0 + $number;
|
||||
}
|
||||
|
||||
throw new Exception(Functions::VALUE());
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ class Lcm
|
|||
//
|
||||
// Private method to return an array of the factors of the input value
|
||||
//
|
||||
private static function factors($value)
|
||||
private static function factors(float $value): array
|
||||
{
|
||||
$startVal = floor(sqrt($value));
|
||||
|
||||
|
|
|
|||
|
|
@ -776,19 +776,14 @@ class Roman
|
|||
const MAX_ROMAN_VALUE = 3999;
|
||||
const MAX_ROMAN_STYLE = 4;
|
||||
|
||||
private static function romanCut($num, $n)
|
||||
{
|
||||
return ($num - ($num % $n)) / $n;
|
||||
}
|
||||
|
||||
private static function valueOk(int $aValue, int $style): string
|
||||
{
|
||||
$origValue = $aValue;
|
||||
$m = self::romanCut($aValue, 1000);
|
||||
$m = \intdiv($aValue, 1000);
|
||||
$aValue %= 1000;
|
||||
$c = self::romanCut($aValue, 100);
|
||||
$c = \intdiv($aValue, 100);
|
||||
$aValue %= 100;
|
||||
$t = self::romanCut($aValue, 10);
|
||||
$t = \intdiv($aValue, 10);
|
||||
$aValue %= 10;
|
||||
$result = self::THOUSANDS[$m] . self::HUNDREDS[$c] . self::TENS[$t] . self::ONES[$aValue];
|
||||
if ($style > 0) {
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ class RoundDown
|
|||
{
|
||||
try {
|
||||
$number = Helpers::validateNumericNullBool($number);
|
||||
$digits = Helpers::validateNumericNullSubstitution($digits, null);
|
||||
$digits = (int) Helpers::validateNumericNullSubstitution($digits, null);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ class RoundUp
|
|||
{
|
||||
try {
|
||||
$number = Helpers::validateNumericNullBool($number);
|
||||
$digits = Helpers::validateNumericNullSubstitution($digits, null);
|
||||
$digits = (int) Helpers::validateNumericNullSubstitution($digits, null);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,11 @@ use PhpOffice\PhpSpreadsheet\Calculation\Statistical;
|
|||
|
||||
class Subtotal
|
||||
{
|
||||
protected static function filterHiddenArgs($cellReference, $args)
|
||||
/**
|
||||
* @param mixed $cellReference
|
||||
* @param mixed $args
|
||||
*/
|
||||
protected static function filterHiddenArgs($cellReference, $args): array
|
||||
{
|
||||
return array_filter(
|
||||
$args,
|
||||
|
|
@ -21,7 +25,11 @@ class Subtotal
|
|||
);
|
||||
}
|
||||
|
||||
protected static function filterFormulaArgs($cellReference, $args)
|
||||
/**
|
||||
* @param mixed $cellReference
|
||||
* @param mixed $args
|
||||
*/
|
||||
protected static function filterFormulaArgs($cellReference, $args): array
|
||||
{
|
||||
return array_filter(
|
||||
$args,
|
||||
|
|
@ -42,6 +50,7 @@ class Subtotal
|
|||
);
|
||||
}
|
||||
|
||||
/** @var callable[] */
|
||||
private const CALL_FUNCTIONS = [
|
||||
1 => [Statistical\Averages::class, 'AVERAGE'],
|
||||
[Statistical\Counts::class, 'COUNT'], // 2
|
||||
|
|
@ -67,7 +76,7 @@ class Subtotal
|
|||
* 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
|
||||
* in hidden rows
|
||||
* @param mixed[] $args A mixed data series of values
|
||||
*
|
||||
* @return float|string
|
||||
|
|
@ -91,7 +100,10 @@ class Subtotal
|
|||
|
||||
$aArgs = self::filterFormulaArgs($cellReference, $aArgs);
|
||||
if (array_key_exists($subtotal, self::CALL_FUNCTIONS)) {
|
||||
return call_user_func_array(self::CALL_FUNCTIONS[$subtotal], $aArgs);
|
||||
/** @var callable */
|
||||
$call = self::CALL_FUNCTIONS[$subtotal];
|
||||
|
||||
return call_user_func_array($call, $aArgs);
|
||||
}
|
||||
|
||||
return Functions::VALUE();
|
||||
|
|
|
|||
|
|
@ -50,15 +50,21 @@ class Sum
|
|||
public static function funcSumNoStrings(...$args)
|
||||
{
|
||||
$returnValue = 0;
|
||||
|
||||
// Loop through the arguments
|
||||
foreach (Functions::flattenArray($args) as $arg) {
|
||||
$aArgs = Functions::flattenArrayIndexed($args);
|
||||
foreach ($aArgs as $k => $arg) {
|
||||
// Is it a numeric value?
|
||||
if (is_numeric($arg)) {
|
||||
if (is_numeric($arg) || empty($arg)) {
|
||||
if (is_string($arg)) {
|
||||
$arg = (int) $arg;
|
||||
}
|
||||
$returnValue += $arg;
|
||||
} elseif (is_bool($arg)) {
|
||||
$returnValue += (int) $arg;
|
||||
} elseif (Functions::isError($arg)) {
|
||||
return $arg;
|
||||
} else {
|
||||
// ignore non-numerics from cell, but fail as literals (except null)
|
||||
} elseif ($arg !== null && !Functions::isCellValue($k)) {
|
||||
return Functions::VALUE();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ class Trunc
|
|||
// Truncate
|
||||
$adjust = 10 ** $digits;
|
||||
|
||||
if (($digits > 0) && (rtrim((int) ((abs($value) - abs((int) $value)) * $adjust), '0') < $adjust / 10)) {
|
||||
if (($digits > 0) && (rtrim((string) (int) ((abs($value) - abs((int) $value)) * $adjust), '0') < $adjust / 10)) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,12 +13,14 @@ use PhpOffice\PhpSpreadsheet\Calculation\Statistical\StandardDeviations;
|
|||
use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Trends;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Variances;
|
||||
|
||||
/**
|
||||
* @deprecated 1.18.0
|
||||
*/
|
||||
class Statistical
|
||||
{
|
||||
const LOG_GAMMA_X_MAX_VALUE = 2.55e305;
|
||||
const EPS = 2.22e-16;
|
||||
const MAX_VALUE = 1.2e308;
|
||||
const MAX_ITERATIONS = 256;
|
||||
const SQRT2PI = 2.5066282746310005024157652848110452530069867406099;
|
||||
|
||||
/**
|
||||
|
|
@ -428,48 +430,18 @@ class Statistical
|
|||
* Excel Function:
|
||||
* DEVSQ(value1[,value2[, ...]])
|
||||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see Statistical\Deviations::sumSquares()
|
||||
* Use the sumSquares() method in the Statistical\Deviations class instead
|
||||
*
|
||||
* @param mixed ...$args Data values
|
||||
*
|
||||
* @return float|string
|
||||
*/
|
||||
public static function DEVSQ(...$args)
|
||||
{
|
||||
$aArgs = Functions::flattenArrayIndexed($args);
|
||||
|
||||
// Return value
|
||||
$returnValue = null;
|
||||
|
||||
$aMean = Averages::average($aArgs);
|
||||
if ($aMean != Functions::DIV0()) {
|
||||
$aCount = -1;
|
||||
foreach ($aArgs as $k => $arg) {
|
||||
// Is it a numeric value?
|
||||
if (
|
||||
(is_bool($arg)) &&
|
||||
((!Functions::isCellValue($k)) ||
|
||||
(Functions::getCompatibilityMode() == Functions::COMPATIBILITY_OPENOFFICE))
|
||||
) {
|
||||
$arg = (int) $arg;
|
||||
}
|
||||
if ((is_numeric($arg)) && (!is_string($arg))) {
|
||||
if ($returnValue === null) {
|
||||
$returnValue = ($arg - $aMean) ** 2;
|
||||
} else {
|
||||
$returnValue += ($arg - $aMean) ** 2;
|
||||
}
|
||||
++$aCount;
|
||||
}
|
||||
}
|
||||
|
||||
// Return
|
||||
if ($returnValue === null) {
|
||||
return Functions::NAN();
|
||||
}
|
||||
|
||||
return $returnValue;
|
||||
}
|
||||
|
||||
return Functions::NA();
|
||||
return Statistical\Deviations::sumSquares(...$args);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -671,18 +643,18 @@ class Statistical
|
|||
* Calculates the probability that a member of a standard normal population will fall between
|
||||
* the mean and z standard deviations from the mean.
|
||||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see Statistical\Distributions\StandardNormal::gauss()
|
||||
* Use the gauss() method in the Statistical\Distributions\StandardNormal class instead
|
||||
*
|
||||
* @param float $value
|
||||
*
|
||||
* @return float|string The result, or a string containing an error
|
||||
*/
|
||||
public static function GAUSS($value)
|
||||
{
|
||||
$value = Functions::flattenSingleValue($value);
|
||||
if (!is_numeric($value)) {
|
||||
return Functions::VALUE();
|
||||
}
|
||||
|
||||
return Statistical\Distributions\Normal::distribution($value, 0, 1, true) - 0.5;
|
||||
return Statistical\Distributions\StandardNormal::gauss($value);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -695,23 +667,18 @@ class Statistical
|
|||
* Excel Function:
|
||||
* GEOMEAN(value1[,value2[, ...]])
|
||||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see Statistical\Averages\Mean::geometric()
|
||||
* Use the geometric() method in the Statistical\Averages\Mean class instead
|
||||
*
|
||||
* @param mixed ...$args Data values
|
||||
*
|
||||
* @return float|string
|
||||
*/
|
||||
public static function GEOMEAN(...$args)
|
||||
{
|
||||
$aArgs = Functions::flattenArray($args);
|
||||
|
||||
$aMean = MathTrig\Product::evaluate($aArgs);
|
||||
if (is_numeric($aMean) && ($aMean > 0)) {
|
||||
$aCount = Counts::COUNT($aArgs);
|
||||
if (Minimum::MIN($aArgs) > 0) {
|
||||
return $aMean ** (1 / $aCount);
|
||||
}
|
||||
}
|
||||
|
||||
return Functions::NAN();
|
||||
return Statistical\Averages\Mean::geometric(...$args);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -745,38 +712,18 @@ class Statistical
|
|||
* Excel Function:
|
||||
* HARMEAN(value1[,value2[, ...]])
|
||||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see Statistical\Averages\Mean::harmonic()
|
||||
* Use the harmonic() method in the Statistical\Averages\Mean class instead
|
||||
*
|
||||
* @param mixed ...$args Data values
|
||||
*
|
||||
* @return float|string
|
||||
*/
|
||||
public static function HARMEAN(...$args)
|
||||
{
|
||||
// Return value
|
||||
$returnValue = 0;
|
||||
|
||||
// Loop through arguments
|
||||
$aArgs = Functions::flattenArray($args);
|
||||
if (Minimum::MIN($aArgs) < 0) {
|
||||
return Functions::NAN();
|
||||
}
|
||||
$aCount = 0;
|
||||
foreach ($aArgs as $arg) {
|
||||
// Is it a numeric value?
|
||||
if ((is_numeric($arg)) && (!is_string($arg))) {
|
||||
if ($arg <= 0) {
|
||||
return Functions::NAN();
|
||||
}
|
||||
$returnValue += (1 / $arg);
|
||||
++$aCount;
|
||||
}
|
||||
}
|
||||
|
||||
// Return
|
||||
if ($aCount > 0) {
|
||||
return 1 / ($returnValue / $aCount);
|
||||
}
|
||||
|
||||
return Functions::NA();
|
||||
return Statistical\Averages\Mean::harmonic(...$args);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -835,40 +782,18 @@ class Statistical
|
|||
* kurtosis indicates a relatively peaked distribution. Negative kurtosis indicates a
|
||||
* relatively flat distribution.
|
||||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see Statistical\Deviations::kurtosis()
|
||||
* Use the kurtosis() method in the Statistical\Deviations class instead
|
||||
*
|
||||
* @param array ...$args Data Series
|
||||
*
|
||||
* @return float|string
|
||||
*/
|
||||
public static function KURT(...$args)
|
||||
{
|
||||
$aArgs = Functions::flattenArrayIndexed($args);
|
||||
$mean = Averages::average($aArgs);
|
||||
$stdDev = StandardDeviations::STDEV($aArgs);
|
||||
|
||||
if ($stdDev > 0) {
|
||||
$count = $summer = 0;
|
||||
// Loop through arguments
|
||||
foreach ($aArgs as $k => $arg) {
|
||||
if (
|
||||
(is_bool($arg)) &&
|
||||
(!Functions::isMatrixValue($k))
|
||||
) {
|
||||
} else {
|
||||
// Is it a numeric value?
|
||||
if ((is_numeric($arg)) && (!is_string($arg))) {
|
||||
$summer += (($arg - $mean) / $stdDev) ** 4;
|
||||
++$count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Return
|
||||
if ($count > 3) {
|
||||
return $summer * ($count * ($count + 1) / (($count - 1) * ($count - 2) * ($count - 3))) - (3 * ($count - 1) ** 2 / (($count - 2) * ($count - 3)));
|
||||
}
|
||||
}
|
||||
|
||||
return Functions::DIV0();
|
||||
return Statistical\Deviations::kurtosis(...$args);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -880,37 +805,18 @@ class Statistical
|
|||
* Excel Function:
|
||||
* LARGE(value1[,value2[, ...]],entry)
|
||||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see Statistical\Size::large()
|
||||
* Use the large() method in the Statistical\Size class instead
|
||||
*
|
||||
* @param mixed $args Data values
|
||||
*
|
||||
* @return float|string The result, or a string containing an error
|
||||
*/
|
||||
public static function LARGE(...$args)
|
||||
{
|
||||
$aArgs = Functions::flattenArray($args);
|
||||
$entry = array_pop($aArgs);
|
||||
|
||||
if ((is_numeric($entry)) && (!is_string($entry))) {
|
||||
$entry = (int) floor($entry);
|
||||
|
||||
// Calculate
|
||||
$mArgs = [];
|
||||
foreach ($aArgs as $arg) {
|
||||
// Is it a numeric value?
|
||||
if ((is_numeric($arg)) && (!is_string($arg))) {
|
||||
$mArgs[] = $arg;
|
||||
}
|
||||
}
|
||||
$count = Counts::COUNT($mArgs);
|
||||
--$entry;
|
||||
if (($entry < 0) || ($entry >= $count) || ($count == 0)) {
|
||||
return Functions::NAN();
|
||||
}
|
||||
rsort($mArgs);
|
||||
|
||||
return $mArgs[$entry];
|
||||
}
|
||||
|
||||
return Functions::VALUE();
|
||||
return Statistical\Size::large(...$args);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1503,40 +1409,18 @@ class Statistical
|
|||
* asymmetric tail extending toward more positive values. Negative skewness indicates a
|
||||
* distribution with an asymmetric tail extending toward more negative values.
|
||||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see Statistical\Deviations::skew()
|
||||
* Use the skew() method in the Statistical\Deviations class instead
|
||||
*
|
||||
* @param array ...$args Data Series
|
||||
*
|
||||
* @return float|string The result, or a string containing an error
|
||||
*/
|
||||
public static function SKEW(...$args)
|
||||
{
|
||||
$aArgs = Functions::flattenArrayIndexed($args);
|
||||
$mean = Averages::average($aArgs);
|
||||
$stdDev = StandardDeviations::STDEV($aArgs);
|
||||
|
||||
if ($stdDev === 0.0 || is_string($stdDev)) {
|
||||
return Functions::DIV0();
|
||||
}
|
||||
|
||||
$count = $summer = 0;
|
||||
// Loop through arguments
|
||||
foreach ($aArgs as $k => $arg) {
|
||||
if ((is_bool($arg)) && (!Functions::isMatrixValue($k))) {
|
||||
} elseif (!is_numeric($arg)) {
|
||||
return Functions::VALUE();
|
||||
} else {
|
||||
// Is it a numeric value?
|
||||
if ((is_numeric($arg)) && (!is_string($arg))) {
|
||||
$summer += (($arg - $mean) / $stdDev) ** 3;
|
||||
++$count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($count > 2) {
|
||||
return $summer * ($count / (($count - 1) * ($count - 2)));
|
||||
}
|
||||
|
||||
return Functions::DIV0();
|
||||
return Statistical\Deviations::skew(...$args);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1568,38 +1452,18 @@ class Statistical
|
|||
* Excel Function:
|
||||
* SMALL(value1[,value2[, ...]],entry)
|
||||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see Statistical\Size::small()
|
||||
* Use the small() method in the Statistical\Size class instead
|
||||
*
|
||||
* @param mixed $args Data values
|
||||
*
|
||||
* @return float|string The result, or a string containing an error
|
||||
*/
|
||||
public static function SMALL(...$args)
|
||||
{
|
||||
$aArgs = Functions::flattenArray($args);
|
||||
|
||||
// Calculate
|
||||
$entry = array_pop($aArgs);
|
||||
|
||||
if ((is_numeric($entry)) && (!is_string($entry))) {
|
||||
$entry = (int) floor($entry);
|
||||
|
||||
$mArgs = [];
|
||||
foreach ($aArgs as $arg) {
|
||||
// Is it a numeric value?
|
||||
if ((is_numeric($arg)) && (!is_string($arg))) {
|
||||
$mArgs[] = $arg;
|
||||
}
|
||||
}
|
||||
$count = Counts::COUNT($mArgs);
|
||||
--$entry;
|
||||
if (($entry < 0) || ($entry >= $count) || ($count == 0)) {
|
||||
return Functions::NAN();
|
||||
}
|
||||
sort($mArgs);
|
||||
|
||||
return $mArgs[$entry];
|
||||
}
|
||||
|
||||
return Functions::VALUE();
|
||||
return Statistical\Size::small(...$args);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1607,6 +1471,11 @@ class Statistical
|
|||
*
|
||||
* Returns a normalized value from a distribution characterized by mean and standard_dev.
|
||||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see Statistical\Standardize::execute()
|
||||
* Use the execute() method in the Statistical\Standardize class instead
|
||||
*
|
||||
* @param float $value Value to normalize
|
||||
* @param float $mean Mean Value
|
||||
* @param float $stdDev Standard Deviation
|
||||
|
|
@ -1615,19 +1484,7 @@ class Statistical
|
|||
*/
|
||||
public static function STANDARDIZE($value, $mean, $stdDev)
|
||||
{
|
||||
$value = Functions::flattenSingleValue($value);
|
||||
$mean = Functions::flattenSingleValue($mean);
|
||||
$stdDev = Functions::flattenSingleValue($stdDev);
|
||||
|
||||
if ((is_numeric($value)) && (is_numeric($mean)) && (is_numeric($stdDev))) {
|
||||
if ($stdDev <= 0) {
|
||||
return Functions::NAN();
|
||||
}
|
||||
|
||||
return ($value - $mean) / $stdDev;
|
||||
}
|
||||
|
||||
return Functions::VALUE();
|
||||
return Statistical\Standardize::execute($value, $mean, $stdDev);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1812,42 +1669,18 @@ class Statistical
|
|||
* Excel Function:
|
||||
* TRIMEAN(value1[,value2[, ...]], $discard)
|
||||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
*@see Statistical\Averages\Mean::trim()
|
||||
* Use the trim() method in the Statistical\Averages\Mean class instead
|
||||
*
|
||||
* @param mixed $args Data values
|
||||
*
|
||||
* @return float|string
|
||||
*/
|
||||
public static function TRIMMEAN(...$args)
|
||||
{
|
||||
$aArgs = Functions::flattenArray($args);
|
||||
|
||||
// Calculate
|
||||
$percent = array_pop($aArgs);
|
||||
|
||||
if ((is_numeric($percent)) && (!is_string($percent))) {
|
||||
if (($percent < 0) || ($percent > 1)) {
|
||||
return Functions::NAN();
|
||||
}
|
||||
|
||||
$mArgs = [];
|
||||
foreach ($aArgs as $arg) {
|
||||
// Is it a numeric value?
|
||||
if ((is_numeric($arg)) && (!is_string($arg))) {
|
||||
$mArgs[] = $arg;
|
||||
}
|
||||
}
|
||||
|
||||
$discard = floor(Counts::COUNT($mArgs) * $percent / 2);
|
||||
sort($mArgs);
|
||||
|
||||
for ($i = 0; $i < $discard; ++$i) {
|
||||
array_pop($mArgs);
|
||||
array_shift($mArgs);
|
||||
}
|
||||
|
||||
return Averages::average($mArgs);
|
||||
}
|
||||
|
||||
return Functions::VALUE();
|
||||
return Statistical\Averages\Mean::trim(...$args);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1860,12 +1693,12 @@ class Statistical
|
|||
*
|
||||
* @Deprecated 1.17.0
|
||||
*
|
||||
*@see Statistical\Variances::VAR()
|
||||
* Use the VAR() method in the Statistical\Variances class instead
|
||||
*
|
||||
* @param mixed ...$args Data values
|
||||
*
|
||||
* @return float|string (string if result is an error)
|
||||
*
|
||||
*@see Statistical\Variances::VAR()
|
||||
* Use the VAR() method in the Statistical\Variances class instead
|
||||
*/
|
||||
public static function VARFunc(...$args)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -0,0 +1,131 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\Statistical\Averages;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Averages;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Counts;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Minimum;
|
||||
|
||||
class Mean
|
||||
{
|
||||
/**
|
||||
* GEOMEAN.
|
||||
*
|
||||
* Returns the geometric mean of an array or range of positive data. For example, you
|
||||
* can use GEOMEAN to calculate average growth rate given compound interest with
|
||||
* variable rates.
|
||||
*
|
||||
* Excel Function:
|
||||
* GEOMEAN(value1[,value2[, ...]])
|
||||
*
|
||||
* @param mixed ...$args Data values
|
||||
*
|
||||
* @return float|string
|
||||
*/
|
||||
public static function geometric(...$args)
|
||||
{
|
||||
$aArgs = Functions::flattenArray($args);
|
||||
|
||||
$aMean = MathTrig\Product::evaluate($aArgs);
|
||||
if (is_numeric($aMean) && ($aMean > 0)) {
|
||||
$aCount = Counts::COUNT($aArgs);
|
||||
if (Minimum::MIN($aArgs) > 0) {
|
||||
return $aMean ** (1 / $aCount);
|
||||
}
|
||||
}
|
||||
|
||||
return Functions::NAN();
|
||||
}
|
||||
|
||||
/**
|
||||
* HARMEAN.
|
||||
*
|
||||
* Returns the harmonic mean of a data set. The harmonic mean is the reciprocal of the
|
||||
* arithmetic mean of reciprocals.
|
||||
*
|
||||
* Excel Function:
|
||||
* HARMEAN(value1[,value2[, ...]])
|
||||
*
|
||||
* @param mixed ...$args Data values
|
||||
*
|
||||
* @return float|string
|
||||
*/
|
||||
public static function harmonic(...$args)
|
||||
{
|
||||
// Loop through arguments
|
||||
$aArgs = Functions::flattenArray($args);
|
||||
if (Minimum::MIN($aArgs) < 0) {
|
||||
return Functions::NAN();
|
||||
}
|
||||
|
||||
$returnValue = 0;
|
||||
$aCount = 0;
|
||||
foreach ($aArgs as $arg) {
|
||||
// Is it a numeric value?
|
||||
if ((is_numeric($arg)) && (!is_string($arg))) {
|
||||
if ($arg <= 0) {
|
||||
return Functions::NAN();
|
||||
}
|
||||
$returnValue += (1 / $arg);
|
||||
++$aCount;
|
||||
}
|
||||
}
|
||||
|
||||
// Return
|
||||
if ($aCount > 0) {
|
||||
return 1 / ($returnValue / $aCount);
|
||||
}
|
||||
|
||||
return Functions::NA();
|
||||
}
|
||||
|
||||
/**
|
||||
* TRIMMEAN.
|
||||
*
|
||||
* Returns the mean of the interior of a data set. TRIMMEAN calculates the mean
|
||||
* taken by excluding a percentage of data points from the top and bottom tails
|
||||
* of a data set.
|
||||
*
|
||||
* Excel Function:
|
||||
* TRIMEAN(value1[,value2[, ...]], $discard)
|
||||
*
|
||||
* @param mixed $args Data values
|
||||
*
|
||||
* @return float|string
|
||||
*/
|
||||
public static function trim(...$args)
|
||||
{
|
||||
$aArgs = Functions::flattenArray($args);
|
||||
|
||||
// Calculate
|
||||
$percent = array_pop($aArgs);
|
||||
|
||||
if ((is_numeric($percent)) && (!is_string($percent))) {
|
||||
if (($percent < 0) || ($percent > 1)) {
|
||||
return Functions::NAN();
|
||||
}
|
||||
|
||||
$mArgs = [];
|
||||
foreach ($aArgs as $arg) {
|
||||
// Is it a numeric value?
|
||||
if ((is_numeric($arg)) && (!is_string($arg))) {
|
||||
$mArgs[] = $arg;
|
||||
}
|
||||
}
|
||||
|
||||
$discard = floor(Counts::COUNT($mArgs) * $percent / 2);
|
||||
sort($mArgs);
|
||||
|
||||
for ($i = 0; $i < $discard; ++$i) {
|
||||
array_pop($mArgs);
|
||||
array_shift($mArgs);
|
||||
}
|
||||
|
||||
return Averages::average($mArgs);
|
||||
}
|
||||
|
||||
return Functions::VALUE();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,141 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\Statistical;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
|
||||
class Deviations
|
||||
{
|
||||
/**
|
||||
* DEVSQ.
|
||||
*
|
||||
* Returns the sum of squares of deviations of data points from their sample mean.
|
||||
*
|
||||
* Excel Function:
|
||||
* DEVSQ(value1[,value2[, ...]])
|
||||
*
|
||||
* @param mixed ...$args Data values
|
||||
*
|
||||
* @return float|string
|
||||
*/
|
||||
public static function sumSquares(...$args)
|
||||
{
|
||||
$aArgs = Functions::flattenArrayIndexed($args);
|
||||
|
||||
$aMean = Averages::average($aArgs);
|
||||
if (!is_numeric($aMean)) {
|
||||
return Functions::NAN();
|
||||
}
|
||||
|
||||
// Return value
|
||||
$returnValue = 0.0;
|
||||
$aCount = -1;
|
||||
foreach ($aArgs as $k => $arg) {
|
||||
// Is it a numeric value?
|
||||
if (
|
||||
(is_bool($arg)) &&
|
||||
((!Functions::isCellValue($k)) ||
|
||||
(Functions::getCompatibilityMode() == Functions::COMPATIBILITY_OPENOFFICE))
|
||||
) {
|
||||
$arg = (int) $arg;
|
||||
}
|
||||
if ((is_numeric($arg)) && (!is_string($arg))) {
|
||||
$returnValue += ($arg - $aMean) ** 2;
|
||||
++$aCount;
|
||||
}
|
||||
}
|
||||
|
||||
return $aCount === 0 ? Functions::VALUE() : $returnValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* KURT.
|
||||
*
|
||||
* Returns the kurtosis of a data set. Kurtosis characterizes the relative peakedness
|
||||
* or flatness of a distribution compared with the normal distribution. Positive
|
||||
* kurtosis indicates a relatively peaked distribution. Negative kurtosis indicates a
|
||||
* relatively flat distribution.
|
||||
*
|
||||
* @param array ...$args Data Series
|
||||
*
|
||||
* @return float|string
|
||||
*/
|
||||
public static function kurtosis(...$args)
|
||||
{
|
||||
$aArgs = Functions::flattenArrayIndexed($args);
|
||||
$mean = Averages::average($aArgs);
|
||||
if (!is_numeric($mean)) {
|
||||
return Functions::DIV0();
|
||||
}
|
||||
$stdDev = StandardDeviations::STDEV($aArgs);
|
||||
|
||||
if ($stdDev > 0) {
|
||||
$count = $summer = 0;
|
||||
|
||||
foreach ($aArgs as $k => $arg) {
|
||||
if ((is_bool($arg)) && (!Functions::isMatrixValue($k))) {
|
||||
} else {
|
||||
// Is it a numeric value?
|
||||
if ((is_numeric($arg)) && (!is_string($arg))) {
|
||||
$summer += (($arg - $mean) / $stdDev) ** 4;
|
||||
++$count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($count > 3) {
|
||||
return $summer * ($count * ($count + 1) /
|
||||
(($count - 1) * ($count - 2) * ($count - 3))) - (3 * ($count - 1) ** 2 /
|
||||
(($count - 2) * ($count - 3)));
|
||||
}
|
||||
}
|
||||
|
||||
return Functions::DIV0();
|
||||
}
|
||||
|
||||
/**
|
||||
* SKEW.
|
||||
*
|
||||
* Returns the skewness of a distribution. Skewness characterizes the degree of asymmetry
|
||||
* of a distribution around its mean. Positive skewness indicates a distribution with an
|
||||
* asymmetric tail extending toward more positive values. Negative skewness indicates a
|
||||
* distribution with an asymmetric tail extending toward more negative values.
|
||||
*
|
||||
* @param array ...$args Data Series
|
||||
*
|
||||
* @return float|string The result, or a string containing an error
|
||||
*/
|
||||
public static function skew(...$args)
|
||||
{
|
||||
$aArgs = Functions::flattenArrayIndexed($args);
|
||||
$mean = Averages::average($aArgs);
|
||||
if (!is_numeric($mean)) {
|
||||
return Functions::DIV0();
|
||||
}
|
||||
$stdDev = StandardDeviations::STDEV($aArgs);
|
||||
if ($stdDev === 0.0 || is_string($stdDev)) {
|
||||
return Functions::DIV0();
|
||||
}
|
||||
|
||||
$count = $summer = 0;
|
||||
// Loop through arguments
|
||||
foreach ($aArgs as $k => $arg) {
|
||||
if ((is_bool($arg)) && (!Functions::isMatrixValue($k))) {
|
||||
} elseif (!is_numeric($arg)) {
|
||||
return Functions::VALUE();
|
||||
} else {
|
||||
// Is it a numeric value?
|
||||
if ((is_numeric($arg)) && (!is_string($arg))) {
|
||||
$summer += (($arg - $mean) / $stdDev) ** 3;
|
||||
++$count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($count > 2) {
|
||||
return $summer * ($count / (($count - 1) * ($count - 2)));
|
||||
}
|
||||
|
||||
return Functions::DIV0();
|
||||
}
|
||||
}
|
||||
|
|
@ -55,6 +55,26 @@ class StandardNormal
|
|||
return Normal::inverse($value, 0, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* GAUSS.
|
||||
*
|
||||
* Calculates the probability that a member of a standard normal population will fall between
|
||||
* the mean and z standard deviations from the mean.
|
||||
*
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return float|string The result, or a string containing an error
|
||||
*/
|
||||
public static function gauss($value)
|
||||
{
|
||||
$value = Functions::flattenSingleValue($value);
|
||||
if (!is_numeric($value)) {
|
||||
return Functions::VALUE();
|
||||
}
|
||||
|
||||
return self::distribution($value, true) - 0.5;
|
||||
}
|
||||
|
||||
/**
|
||||
* ZTEST.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -0,0 +1,96 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\Statistical;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
|
||||
class Size
|
||||
{
|
||||
/**
|
||||
* LARGE.
|
||||
*
|
||||
* Returns the nth largest value in a data set. You can use this function to
|
||||
* select a value based on its relative standing.
|
||||
*
|
||||
* Excel Function:
|
||||
* LARGE(value1[,value2[, ...]],entry)
|
||||
*
|
||||
* @param mixed $args Data values
|
||||
*
|
||||
* @return float|string The result, or a string containing an error
|
||||
*/
|
||||
public static function large(...$args)
|
||||
{
|
||||
$aArgs = Functions::flattenArray($args);
|
||||
$entry = array_pop($aArgs);
|
||||
|
||||
if ((is_numeric($entry)) && (!is_string($entry))) {
|
||||
$entry = (int) floor($entry);
|
||||
|
||||
$mArgs = self::filter($aArgs);
|
||||
$count = Counts::COUNT($mArgs);
|
||||
--$entry;
|
||||
if (($entry < 0) || ($entry >= $count) || ($count == 0)) {
|
||||
return Functions::NAN();
|
||||
}
|
||||
rsort($mArgs);
|
||||
|
||||
return $mArgs[$entry];
|
||||
}
|
||||
|
||||
return Functions::VALUE();
|
||||
}
|
||||
|
||||
/**
|
||||
* SMALL.
|
||||
*
|
||||
* Returns the nth smallest value in a data set. You can use this function to
|
||||
* select a value based on its relative standing.
|
||||
*
|
||||
* Excel Function:
|
||||
* SMALL(value1[,value2[, ...]],entry)
|
||||
*
|
||||
* @param mixed $args Data values
|
||||
*
|
||||
* @return float|string The result, or a string containing an error
|
||||
*/
|
||||
public static function small(...$args)
|
||||
{
|
||||
$aArgs = Functions::flattenArray($args);
|
||||
|
||||
$entry = array_pop($aArgs);
|
||||
|
||||
if ((is_numeric($entry)) && (!is_string($entry))) {
|
||||
$entry = (int) floor($entry);
|
||||
|
||||
$mArgs = self::filter($aArgs);
|
||||
$count = Counts::COUNT($mArgs);
|
||||
--$entry;
|
||||
if (($entry < 0) || ($entry >= $count) || ($count == 0)) {
|
||||
return Functions::NAN();
|
||||
}
|
||||
sort($mArgs);
|
||||
|
||||
return $mArgs[$entry];
|
||||
}
|
||||
|
||||
return Functions::VALUE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed[] $args Data values
|
||||
*/
|
||||
protected static function filter(array $args): array
|
||||
{
|
||||
$mArgs = [];
|
||||
|
||||
foreach ($args as $arg) {
|
||||
// Is it a numeric value?
|
||||
if ((is_numeric($arg)) && (!is_string($arg))) {
|
||||
$mArgs[] = $arg;
|
||||
}
|
||||
}
|
||||
|
||||
return $mArgs;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\Statistical;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
|
||||
class Standardize extends StatisticalValidations
|
||||
{
|
||||
/**
|
||||
* STANDARDIZE.
|
||||
*
|
||||
* Returns a normalized value from a distribution characterized by mean and standard_dev.
|
||||
*
|
||||
* @param float $value Value to normalize
|
||||
* @param float $mean Mean Value
|
||||
* @param float $stdDev Standard Deviation
|
||||
*
|
||||
* @return float|string Standardized value, or a string containing an error
|
||||
*/
|
||||
public static function execute($value, $mean, $stdDev)
|
||||
{
|
||||
$value = Functions::flattenSingleValue($value);
|
||||
$mean = Functions::flattenSingleValue($mean);
|
||||
$stdDev = Functions::flattenSingleValue($stdDev);
|
||||
|
||||
try {
|
||||
$value = self::validateFloat($value);
|
||||
$mean = self::validateFloat($mean);
|
||||
$stdDev = self::validateFloat($stdDev);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
if ($stdDev <= 0) {
|
||||
return Functions::NAN();
|
||||
}
|
||||
|
||||
return ($value - $mean) / $stdDev;
|
||||
}
|
||||
}
|
||||
|
|
@ -98,7 +98,7 @@ class Format
|
|||
$format = Functions::flattenSingleValue($format);
|
||||
|
||||
if ((is_string($value)) && (!is_numeric($value)) && Date::isDateTimeFormatCode($format)) {
|
||||
$value = DateTimeExcel\DateValue::funcDateValue($value);
|
||||
$value = DateTimeExcel\DateValue::fromString($value);
|
||||
}
|
||||
|
||||
return (string) NumberFormat::toFormattedString($value, $format);
|
||||
|
|
@ -129,14 +129,14 @@ class Format
|
|||
Functions::setReturnDateType(Functions::RETURNDATE_EXCEL);
|
||||
|
||||
if (strpos($value, ':') !== false) {
|
||||
$timeValue = DateTimeExcel\TimeValue::funcTimeValue($value);
|
||||
$timeValue = DateTimeExcel\TimeValue::fromString($value);
|
||||
if ($timeValue !== Functions::VALUE()) {
|
||||
Functions::setReturnDateType($dateSetting);
|
||||
|
||||
return $timeValue;
|
||||
}
|
||||
}
|
||||
$dateValue = DateTimeExcel\DateValue::funcDateValue($value);
|
||||
$dateValue = DateTimeExcel\DateValue::fromString($value);
|
||||
if ($dateValue !== Functions::VALUE()) {
|
||||
Functions::setReturnDateType($dateSetting);
|
||||
|
||||
|
|
|
|||
|
|
@ -2,9 +2,9 @@
|
|||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Settings;
|
||||
use Psr\Http\Client\ClientExceptionInterface;
|
||||
|
||||
/**
|
||||
* @deprecated 1.18.0
|
||||
*/
|
||||
class Web
|
||||
{
|
||||
/**
|
||||
|
|
@ -15,39 +15,13 @@ class Web
|
|||
* Excel Function:
|
||||
* Webservice(url)
|
||||
*
|
||||
* @see Web\Service::webService()
|
||||
* Use the webService() method in the Web\Service class instead
|
||||
*
|
||||
* @return string the output resulting from a call to the webservice
|
||||
*/
|
||||
public static function WEBSERVICE(string $url)
|
||||
{
|
||||
$url = trim($url);
|
||||
if (strlen($url) > 2048) {
|
||||
return Functions::VALUE(); // Invalid URL length
|
||||
}
|
||||
|
||||
if (!preg_match('/^http[s]?:\/\//', $url)) {
|
||||
return Functions::VALUE(); // Invalid protocol
|
||||
}
|
||||
|
||||
// Get results from the the webservice
|
||||
$client = Settings::getHttpClient();
|
||||
$requestFactory = Settings::getRequestFactory();
|
||||
$request = $requestFactory->createRequest('GET', $url);
|
||||
|
||||
try {
|
||||
$response = $client->sendRequest($request);
|
||||
} catch (ClientExceptionInterface $e) {
|
||||
return Functions::VALUE(); // cURL error
|
||||
}
|
||||
|
||||
if ($response->getStatusCode() != 200) {
|
||||
return Functions::VALUE(); // cURL error
|
||||
}
|
||||
|
||||
$output = $response->getBody()->getContents();
|
||||
if (strlen($output) > 32767) {
|
||||
return Functions::VALUE(); // Output not a string or too long
|
||||
}
|
||||
|
||||
return $output;
|
||||
return Web\Service::webService($url);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,75 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\Web;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
use PhpOffice\PhpSpreadsheet\Settings;
|
||||
use Psr\Http\Client\ClientExceptionInterface;
|
||||
|
||||
class Service
|
||||
{
|
||||
/**
|
||||
* WEBSERVICE.
|
||||
*
|
||||
* Returns data from a web service on the Internet or Intranet.
|
||||
*
|
||||
* Excel Function:
|
||||
* Webservice(url)
|
||||
*
|
||||
* @return string the output resulting from a call to the webservice
|
||||
*/
|
||||
public static function webService(string $url)
|
||||
{
|
||||
$url = trim($url);
|
||||
if (strlen($url) > 2048) {
|
||||
return Functions::VALUE(); // Invalid URL length
|
||||
}
|
||||
|
||||
if (!preg_match('/^http[s]?:\/\//', $url)) {
|
||||
return Functions::VALUE(); // Invalid protocol
|
||||
}
|
||||
|
||||
// Get results from the the webservice
|
||||
$client = Settings::getHttpClient();
|
||||
$requestFactory = Settings::getRequestFactory();
|
||||
$request = $requestFactory->createRequest('GET', $url);
|
||||
|
||||
try {
|
||||
$response = $client->sendRequest($request);
|
||||
} catch (ClientExceptionInterface $e) {
|
||||
return Functions::VALUE(); // cURL error
|
||||
}
|
||||
|
||||
if ($response->getStatusCode() != 200) {
|
||||
return Functions::VALUE(); // cURL error
|
||||
}
|
||||
|
||||
$output = $response->getBody()->getContents();
|
||||
if (strlen($output) > 32767) {
|
||||
return Functions::VALUE(); // Output not a string or too long
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* URLENCODE.
|
||||
*
|
||||
* Returns data from a web service on the Internet or Intranet.
|
||||
*
|
||||
* Excel Function:
|
||||
* urlEncode(text)
|
||||
*
|
||||
* @param mixed $text
|
||||
*
|
||||
* @return string the url encoded output
|
||||
*/
|
||||
public static function urlEncode($text)
|
||||
{
|
||||
if (!is_string($text)) {
|
||||
return Functions::VALUE();
|
||||
}
|
||||
|
||||
return str_replace('+', '%20', urlencode($text));
|
||||
}
|
||||
}
|
||||
|
|
@ -47,6 +47,7 @@ DVARP = BDVARP ## Calcule la variance pour l’ensemble d’une population d
|
|||
DATE = DATE ## Renvoie le numéro de série d’une date précise.
|
||||
DATEVALUE = DATEVAL ## Convertit une date représentée sous forme de texte en numéro de série.
|
||||
DAY = JOUR ## Convertit un numéro de série en jour du mois.
|
||||
DAYS = JOURS ## Calcule le nombre de jours qui séparent deux dates.
|
||||
DAYS360 = JOURS360 ## Calcule le nombre de jours qui séparent deux dates sur la base d’une année de 360 jours.
|
||||
EDATE = MOIS.DECALER ## Renvoie le numéro séquentiel de la date qui représente une date spécifiée (l’argument date_départ), corrigée en plus ou en moins du nombre de mois indiqué.
|
||||
EOMONTH = FIN.MOIS ## Renvoie le numéro séquentiel de la date du dernier jour du mois précédant ou suivant la date_départ du nombre de mois indiqué.
|
||||
|
|
|
|||
|
|
@ -102,14 +102,23 @@ class AddressHelper
|
|||
?int $currentRowNumber = null,
|
||||
?int $currentColumnNumber = null
|
||||
): string {
|
||||
$validityCheck = preg_match('/^\$?([A-Z]{1,3})\$?(\d{1,7})$/i', $address, $cellReference);
|
||||
$validityCheck = preg_match(Coordinate::A1_COORDINATE_REGEX, $address, $cellReference);
|
||||
|
||||
if ($validityCheck === 0) {
|
||||
throw new Exception('Invalid A1-format Cell Reference');
|
||||
}
|
||||
|
||||
$columnId = Coordinate::columnIndexFromString($cellReference[1]);
|
||||
$rowId = (int) $cellReference[2];
|
||||
$columnId = Coordinate::columnIndexFromString($cellReference['col_ref']);
|
||||
if ($cellReference['absolute_col'] === '$') {
|
||||
// Column must be absolute address
|
||||
$currentColumnNumber = null;
|
||||
}
|
||||
|
||||
$rowId = (int) $cellReference['row_ref'];
|
||||
if ($cellReference['absolute_row'] === '$') {
|
||||
// Row must be absolute address
|
||||
$currentRowNumber = null;
|
||||
}
|
||||
|
||||
if ($currentRowNumber !== null) {
|
||||
if ($rowId === $currentRowNumber) {
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@ use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
|||
*/
|
||||
abstract class Coordinate
|
||||
{
|
||||
public const A1_COORDINATE_REGEX = '/^(?<absolute_col>\$?)(?<col_ref>[A-Z]{1,3})(?<absolute_row>\$?)(?<row_ref>\d{1,7})$/i';
|
||||
|
||||
/**
|
||||
* Default range variable constant.
|
||||
*
|
||||
|
|
@ -29,8 +31,8 @@ abstract class Coordinate
|
|||
*/
|
||||
public static function coordinateFromString($pCoordinateString)
|
||||
{
|
||||
if (preg_match('/^([$]?[A-Z]{1,3})([$]?\\d{1,7})$/', $pCoordinateString, $matches)) {
|
||||
return [$matches[1], $matches[2]];
|
||||
if (preg_match(self::A1_COORDINATE_REGEX, $pCoordinateString, $matches)) {
|
||||
return [$matches['absolute_col'] . $matches['col_ref'], $matches['absolute_row'] . $matches['row_ref']];
|
||||
} elseif (self::coordinateIsRange($pCoordinateString)) {
|
||||
throw new Exception('Cell coordinate string can not be a range of cells');
|
||||
} elseif ($pCoordinateString == '') {
|
||||
|
|
|
|||
|
|
@ -7,25 +7,32 @@ use PhpOffice\PhpSpreadsheet\Cell\DataType;
|
|||
use PhpOffice\PhpSpreadsheet\DefinedName;
|
||||
use PhpOffice\PhpSpreadsheet\Reader\Gnumeric\PageSetup;
|
||||
use PhpOffice\PhpSpreadsheet\Reader\Gnumeric\Properties;
|
||||
use PhpOffice\PhpSpreadsheet\Reader\Gnumeric\Styles;
|
||||
use PhpOffice\PhpSpreadsheet\Reader\Security\XmlScanner;
|
||||
use PhpOffice\PhpSpreadsheet\ReferenceHelper;
|
||||
use PhpOffice\PhpSpreadsheet\RichText\RichText;
|
||||
use PhpOffice\PhpSpreadsheet\Settings;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\Date;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\File;
|
||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
use PhpOffice\PhpSpreadsheet\Style\Alignment;
|
||||
use PhpOffice\PhpSpreadsheet\Style\Border;
|
||||
use PhpOffice\PhpSpreadsheet\Style\Borders;
|
||||
use PhpOffice\PhpSpreadsheet\Style\Fill;
|
||||
use PhpOffice\PhpSpreadsheet\Style\Font;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
||||
use SimpleXMLElement;
|
||||
use XMLReader;
|
||||
|
||||
class Gnumeric extends BaseReader
|
||||
{
|
||||
private const UOM_CONVERSION_POINTS_TO_CENTIMETERS = 0.03527777778;
|
||||
const NAMESPACE_GNM = 'http://www.gnumeric.org/v10.dtd'; // gmr in old sheets
|
||||
|
||||
const NAMESPACE_XSI = 'http://www.w3.org/2001/XMLSchema-instance';
|
||||
|
||||
const NAMESPACE_OFFICE = 'urn:oasis:names:tc:opendocument:xmlns:office:1.0';
|
||||
|
||||
const NAMESPACE_XLINK = 'http://www.w3.org/1999/xlink';
|
||||
|
||||
const NAMESPACE_DC = 'http://purl.org/dc/elements/1.1/';
|
||||
|
||||
const NAMESPACE_META = 'urn:oasis:names:tc:opendocument:xmlns:meta:1.0';
|
||||
|
||||
const NAMESPACE_OOO = 'http://openoffice.org/2004/office';
|
||||
|
||||
/**
|
||||
* Shared Expressions.
|
||||
|
|
@ -41,15 +48,22 @@ class Gnumeric extends BaseReader
|
|||
*/
|
||||
private $spreadsheet;
|
||||
|
||||
/** @var ReferenceHelper */
|
||||
private $referenceHelper;
|
||||
|
||||
/**
|
||||
* Namespace shared across all functions.
|
||||
* It is 'gnm', except for really old sheets which use 'gmr'.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $gnm = 'gnm';
|
||||
/** @var array */
|
||||
public static $mappings = [
|
||||
'dataType' => [
|
||||
'10' => DataType::TYPE_NULL,
|
||||
'20' => DataType::TYPE_BOOL,
|
||||
'30' => DataType::TYPE_NUMERIC, // Integer doesn't exist in Excel
|
||||
'40' => DataType::TYPE_NUMERIC, // Float
|
||||
'50' => DataType::TYPE_ERROR,
|
||||
'60' => DataType::TYPE_STRING,
|
||||
//'70': // Cell Range
|
||||
//'80': // Array
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
* Create a new Gnumeric.
|
||||
|
|
@ -77,16 +91,20 @@ class Gnumeric extends BaseReader
|
|||
if (function_exists('gzread')) {
|
||||
// Read signature data (first 3 bytes)
|
||||
$fh = fopen($pFilename, 'rb');
|
||||
$data = fread($fh, 2);
|
||||
fclose($fh);
|
||||
if ($fh !== false) {
|
||||
$data = fread($fh, 2);
|
||||
fclose($fh);
|
||||
}
|
||||
}
|
||||
|
||||
return $data == chr(0x1F) . chr(0x8B);
|
||||
return $data === chr(0x1F) . chr(0x8B);
|
||||
}
|
||||
|
||||
private static function matchXml(string $name, string $field): bool
|
||||
private static function matchXml(XMLReader $xml, string $expectedLocalName): bool
|
||||
{
|
||||
return 1 === preg_match("/^(gnm|gmr):$field$/", $name);
|
||||
return $xml->namespaceURI === self::NAMESPACE_GNM
|
||||
&& $xml->localName === $expectedLocalName
|
||||
&& $xml->nodeType === XMLReader::ELEMENT;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -106,10 +124,10 @@ class Gnumeric extends BaseReader
|
|||
|
||||
$worksheetNames = [];
|
||||
while ($xml->read()) {
|
||||
if (self::matchXml($xml->name, 'SheetName') && $xml->nodeType == XMLReader::ELEMENT) {
|
||||
if (self::matchXml($xml, 'SheetName')) {
|
||||
$xml->read(); // Move onto the value node
|
||||
$worksheetNames[] = (string) $xml->value;
|
||||
} elseif (self::matchXml($xml->name, 'Sheets')) {
|
||||
} elseif (self::matchXml($xml, 'Sheets')) {
|
||||
// break out of the loop once we've got our sheet names rather than parse the entire file
|
||||
break;
|
||||
}
|
||||
|
|
@ -135,7 +153,7 @@ class Gnumeric extends BaseReader
|
|||
|
||||
$worksheetInfo = [];
|
||||
while ($xml->read()) {
|
||||
if (self::matchXml($xml->name, 'Sheet') && $xml->nodeType == XMLReader::ELEMENT) {
|
||||
if (self::matchXml($xml, 'Sheet')) {
|
||||
$tmpInfo = [
|
||||
'worksheetName' => '',
|
||||
'lastColumnLetter' => 'A',
|
||||
|
|
@ -145,20 +163,18 @@ class Gnumeric extends BaseReader
|
|||
];
|
||||
|
||||
while ($xml->read()) {
|
||||
if ($xml->nodeType == XMLReader::ELEMENT) {
|
||||
if (self::matchXml($xml->name, 'Name')) {
|
||||
$xml->read(); // Move onto the value node
|
||||
$tmpInfo['worksheetName'] = (string) $xml->value;
|
||||
} elseif (self::matchXml($xml->name, 'MaxCol')) {
|
||||
$xml->read(); // Move onto the value node
|
||||
$tmpInfo['lastColumnIndex'] = (int) $xml->value;
|
||||
$tmpInfo['totalColumns'] = (int) $xml->value + 1;
|
||||
} elseif (self::matchXml($xml->name, 'MaxRow')) {
|
||||
$xml->read(); // Move onto the value node
|
||||
$tmpInfo['totalRows'] = (int) $xml->value + 1;
|
||||
if (self::matchXml($xml, 'Name')) {
|
||||
$xml->read(); // Move onto the value node
|
||||
$tmpInfo['worksheetName'] = (string) $xml->value;
|
||||
} elseif (self::matchXml($xml, 'MaxCol')) {
|
||||
$xml->read(); // Move onto the value node
|
||||
$tmpInfo['lastColumnIndex'] = (int) $xml->value;
|
||||
$tmpInfo['totalColumns'] = (int) $xml->value + 1;
|
||||
} elseif (self::matchXml($xml, 'MaxRow')) {
|
||||
$xml->read(); // Move onto the value node
|
||||
$tmpInfo['totalRows'] = (int) $xml->value + 1;
|
||||
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
$tmpInfo['lastColumnLetter'] = Coordinate::stringFromColumnIndex($tmpInfo['lastColumnIndex'] + 1);
|
||||
|
|
@ -188,94 +204,34 @@ class Gnumeric extends BaseReader
|
|||
return $data;
|
||||
}
|
||||
|
||||
private static $mappings = [
|
||||
'borderStyle' => [
|
||||
'0' => Border::BORDER_NONE,
|
||||
'1' => Border::BORDER_THIN,
|
||||
'2' => Border::BORDER_MEDIUM,
|
||||
'3' => Border::BORDER_SLANTDASHDOT,
|
||||
'4' => Border::BORDER_DASHED,
|
||||
'5' => Border::BORDER_THICK,
|
||||
'6' => Border::BORDER_DOUBLE,
|
||||
'7' => Border::BORDER_DOTTED,
|
||||
'8' => Border::BORDER_MEDIUMDASHED,
|
||||
'9' => Border::BORDER_DASHDOT,
|
||||
'10' => Border::BORDER_MEDIUMDASHDOT,
|
||||
'11' => Border::BORDER_DASHDOTDOT,
|
||||
'12' => Border::BORDER_MEDIUMDASHDOTDOT,
|
||||
'13' => Border::BORDER_MEDIUMDASHDOTDOT,
|
||||
],
|
||||
'dataType' => [
|
||||
'10' => DataType::TYPE_NULL,
|
||||
'20' => DataType::TYPE_BOOL,
|
||||
'30' => DataType::TYPE_NUMERIC, // Integer doesn't exist in Excel
|
||||
'40' => DataType::TYPE_NUMERIC, // Float
|
||||
'50' => DataType::TYPE_ERROR,
|
||||
'60' => DataType::TYPE_STRING,
|
||||
//'70': // Cell Range
|
||||
//'80': // Array
|
||||
],
|
||||
'fillType' => [
|
||||
'1' => Fill::FILL_SOLID,
|
||||
'2' => Fill::FILL_PATTERN_DARKGRAY,
|
||||
'3' => Fill::FILL_PATTERN_MEDIUMGRAY,
|
||||
'4' => Fill::FILL_PATTERN_LIGHTGRAY,
|
||||
'5' => Fill::FILL_PATTERN_GRAY125,
|
||||
'6' => Fill::FILL_PATTERN_GRAY0625,
|
||||
'7' => Fill::FILL_PATTERN_DARKHORIZONTAL, // horizontal stripe
|
||||
'8' => Fill::FILL_PATTERN_DARKVERTICAL, // vertical stripe
|
||||
'9' => Fill::FILL_PATTERN_DARKDOWN, // diagonal stripe
|
||||
'10' => Fill::FILL_PATTERN_DARKUP, // reverse diagonal stripe
|
||||
'11' => Fill::FILL_PATTERN_DARKGRID, // diagoanl crosshatch
|
||||
'12' => Fill::FILL_PATTERN_DARKTRELLIS, // thick diagonal crosshatch
|
||||
'13' => Fill::FILL_PATTERN_LIGHTHORIZONTAL,
|
||||
'14' => Fill::FILL_PATTERN_LIGHTVERTICAL,
|
||||
'15' => Fill::FILL_PATTERN_LIGHTUP,
|
||||
'16' => Fill::FILL_PATTERN_LIGHTDOWN,
|
||||
'17' => Fill::FILL_PATTERN_LIGHTGRID, // thin horizontal crosshatch
|
||||
'18' => Fill::FILL_PATTERN_LIGHTTRELLIS, // thin diagonal crosshatch
|
||||
],
|
||||
'horizontal' => [
|
||||
'1' => Alignment::HORIZONTAL_GENERAL,
|
||||
'2' => Alignment::HORIZONTAL_LEFT,
|
||||
'4' => Alignment::HORIZONTAL_RIGHT,
|
||||
'8' => Alignment::HORIZONTAL_CENTER,
|
||||
'16' => Alignment::HORIZONTAL_CENTER_CONTINUOUS,
|
||||
'32' => Alignment::HORIZONTAL_JUSTIFY,
|
||||
'64' => Alignment::HORIZONTAL_CENTER_CONTINUOUS,
|
||||
],
|
||||
'underline' => [
|
||||
'1' => Font::UNDERLINE_SINGLE,
|
||||
'2' => Font::UNDERLINE_DOUBLE,
|
||||
'3' => Font::UNDERLINE_SINGLEACCOUNTING,
|
||||
'4' => Font::UNDERLINE_DOUBLEACCOUNTING,
|
||||
],
|
||||
'vertical' => [
|
||||
'1' => Alignment::VERTICAL_TOP,
|
||||
'2' => Alignment::VERTICAL_BOTTOM,
|
||||
'4' => Alignment::VERTICAL_CENTER,
|
||||
'8' => Alignment::VERTICAL_JUSTIFY,
|
||||
],
|
||||
];
|
||||
|
||||
public static function gnumericMappings(): array
|
||||
{
|
||||
return self::$mappings;
|
||||
return array_merge(self::$mappings, Styles::$mappings);
|
||||
}
|
||||
|
||||
private function processComments(SimpleXMLElement $sheet): void
|
||||
{
|
||||
if ((!$this->readDataOnly) && (isset($sheet->Objects))) {
|
||||
foreach ($sheet->Objects->children($this->gnm, true) as $key => $comment) {
|
||||
foreach ($sheet->Objects->children(self::NAMESPACE_GNM) as $key => $comment) {
|
||||
$commentAttributes = $comment->attributes();
|
||||
// Only comment objects are handled at the moment
|
||||
if ($commentAttributes->Text) {
|
||||
$this->spreadsheet->getActiveSheet()->getComment((string) $commentAttributes->ObjectBound)->setAuthor((string) $commentAttributes->Author)->setText($this->parseRichText((string) $commentAttributes->Text));
|
||||
$this->spreadsheet->getActiveSheet()->getComment((string) $commentAttributes->ObjectBound)
|
||||
->setAuthor((string) $commentAttributes->Author)
|
||||
->setText($this->parseRichText((string) $commentAttributes->Text));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $value
|
||||
*/
|
||||
private static function testSimpleXml($value): SimpleXMLElement
|
||||
{
|
||||
return ($value instanceof SimpleXMLElement) ? $value : new SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?><root></root>');
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads Spreadsheet from file.
|
||||
*
|
||||
|
|
@ -304,12 +260,10 @@ class Gnumeric extends BaseReader
|
|||
$gFileData = $this->gzfileGetContents($pFilename);
|
||||
|
||||
$xml2 = simplexml_load_string($this->securityScanner->scan($gFileData), 'SimpleXMLElement', Settings::getLibXmlLoaderOptions());
|
||||
$xml = ($xml2 !== false) ? $xml2 : new SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?><root></root>');
|
||||
$namespacesMeta = $xml->getNamespaces(true);
|
||||
$this->gnm = array_key_exists('gmr', $namespacesMeta) ? 'gmr' : 'gnm';
|
||||
$xml = self::testSimpleXml($xml2);
|
||||
|
||||
$gnmXML = $xml->children($namespacesMeta[$this->gnm]);
|
||||
(new Properties($this->spreadsheet))->readProperties($xml, $gnmXML, $namespacesMeta);
|
||||
$gnmXML = $xml->children(self::NAMESPACE_GNM);
|
||||
(new Properties($this->spreadsheet))->readProperties($xml, $gnmXML);
|
||||
|
||||
$worksheetID = 0;
|
||||
foreach ($gnmXML->Sheets->Sheet as $sheet) {
|
||||
|
|
@ -329,7 +283,7 @@ class Gnumeric extends BaseReader
|
|||
$this->spreadsheet->getActiveSheet()->setTitle($worksheetName, false, false);
|
||||
|
||||
if (!$this->readDataOnly) {
|
||||
(new PageSetup($this->spreadsheet, $this->gnm))
|
||||
(new PageSetup($this->spreadsheet))
|
||||
->printInformation($sheet)
|
||||
->sheetMargins($sheet);
|
||||
}
|
||||
|
|
@ -382,90 +336,22 @@ class Gnumeric extends BaseReader
|
|||
if (array_key_exists($vtype, self::$mappings['dataType'])) {
|
||||
$type = self::$mappings['dataType'][$vtype];
|
||||
}
|
||||
if ($vtype == '20') { // Boolean
|
||||
if ($vtype === '20') { // Boolean
|
||||
$cell = $cell == 'TRUE';
|
||||
}
|
||||
}
|
||||
$this->spreadsheet->getActiveSheet()->getCell($column . $row)->setValueExplicit((string) $cell, $type);
|
||||
}
|
||||
|
||||
$this->processComments($sheet);
|
||||
|
||||
foreach ($sheet->Styles->StyleRegion as $styleRegion) {
|
||||
$styleAttributes = $styleRegion->attributes();
|
||||
if (
|
||||
($styleAttributes['startRow'] <= $maxRow) &&
|
||||
($styleAttributes['startCol'] <= $maxCol)
|
||||
) {
|
||||
$startColumn = Coordinate::stringFromColumnIndex((int) $styleAttributes['startCol'] + 1);
|
||||
$startRow = $styleAttributes['startRow'] + 1;
|
||||
|
||||
$endColumn = ($styleAttributes['endCol'] > $maxCol) ? $maxCol : (int) $styleAttributes['endCol'];
|
||||
$endColumn = Coordinate::stringFromColumnIndex($endColumn + 1);
|
||||
|
||||
$endRow = 1 + (($styleAttributes['endRow'] > $maxRow) ? $maxRow : (int) $styleAttributes['endRow']);
|
||||
$cellRange = $startColumn . $startRow . ':' . $endColumn . $endRow;
|
||||
|
||||
$styleAttributes = $styleRegion->Style->attributes();
|
||||
|
||||
$styleArray = [];
|
||||
// We still set the number format mask for date/time values, even if readDataOnly is true
|
||||
$formatCode = (string) $styleAttributes['Format'];
|
||||
if (Date::isDateTimeFormatCode($formatCode)) {
|
||||
$styleArray['numberFormat']['formatCode'] = $formatCode;
|
||||
}
|
||||
if (!$this->readDataOnly) {
|
||||
// If readDataOnly is false, we set all formatting information
|
||||
$styleArray['numberFormat']['formatCode'] = $formatCode;
|
||||
|
||||
self::addStyle2($styleArray, 'alignment', 'horizontal', $styleAttributes['HAlign']);
|
||||
self::addStyle2($styleArray, 'alignment', 'vertical', $styleAttributes['VAlign']);
|
||||
$styleArray['alignment']['wrapText'] = $styleAttributes['WrapText'] == '1';
|
||||
$styleArray['alignment']['textRotation'] = $this->calcRotation($styleAttributes);
|
||||
$styleArray['alignment']['shrinkToFit'] = $styleAttributes['ShrinkToFit'] == '1';
|
||||
$styleArray['alignment']['indent'] = ((int) ($styleAttributes['Indent']) > 0) ? $styleAttributes['indent'] : 0;
|
||||
|
||||
$this->addColors($styleArray, $styleAttributes);
|
||||
|
||||
$fontAttributes = $styleRegion->Style->Font->attributes();
|
||||
$styleArray['font']['name'] = (string) $styleRegion->Style->Font;
|
||||
$styleArray['font']['size'] = (int) ($fontAttributes['Unit']);
|
||||
$styleArray['font']['bold'] = $fontAttributes['Bold'] == '1';
|
||||
$styleArray['font']['italic'] = $fontAttributes['Italic'] == '1';
|
||||
$styleArray['font']['strikethrough'] = $fontAttributes['StrikeThrough'] == '1';
|
||||
self::addStyle2($styleArray, 'font', 'underline', $fontAttributes['Underline']);
|
||||
|
||||
switch ($fontAttributes['Script']) {
|
||||
case '1':
|
||||
$styleArray['font']['superscript'] = true;
|
||||
|
||||
break;
|
||||
case '-1':
|
||||
$styleArray['font']['subscript'] = true;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (isset($styleRegion->Style->StyleBorder)) {
|
||||
$srssb = $styleRegion->Style->StyleBorder;
|
||||
$this->addBorderStyle($srssb, $styleArray, 'top');
|
||||
$this->addBorderStyle($srssb, $styleArray, 'bottom');
|
||||
$this->addBorderStyle($srssb, $styleArray, 'left');
|
||||
$this->addBorderStyle($srssb, $styleArray, 'right');
|
||||
$this->addBorderDiagonal($srssb, $styleArray);
|
||||
}
|
||||
if (isset($styleRegion->Style->HyperLink)) {
|
||||
// TO DO
|
||||
$hyperlink = $styleRegion->Style->HyperLink->attributes();
|
||||
}
|
||||
}
|
||||
$this->spreadsheet->getActiveSheet()->getStyle($cellRange)->applyFromArray($styleArray);
|
||||
}
|
||||
if ($sheet->Styles !== null) {
|
||||
(new Styles($this->spreadsheet, $this->readDataOnly))->read($sheet, $maxRow, $maxCol);
|
||||
}
|
||||
|
||||
$this->processComments($sheet);
|
||||
$this->processColumnWidths($sheet, $maxCol);
|
||||
$this->processRowHeights($sheet, $maxRow);
|
||||
$this->processMergedCells($sheet);
|
||||
$this->processAutofilter($sheet);
|
||||
|
||||
++$worksheetID;
|
||||
}
|
||||
|
|
@ -476,32 +362,10 @@ class Gnumeric extends BaseReader
|
|||
return $this->spreadsheet;
|
||||
}
|
||||
|
||||
private function addBorderDiagonal(SimpleXMLElement $srssb, array &$styleArray): void
|
||||
{
|
||||
if (isset($srssb->Diagonal, $srssb->{'Rev-Diagonal'})) {
|
||||
$styleArray['borders']['diagonal'] = self::parseBorderAttributes($srssb->Diagonal->attributes());
|
||||
$styleArray['borders']['diagonalDirection'] = Borders::DIAGONAL_BOTH;
|
||||
} elseif (isset($srssb->Diagonal)) {
|
||||
$styleArray['borders']['diagonal'] = self::parseBorderAttributes($srssb->Diagonal->attributes());
|
||||
$styleArray['borders']['diagonalDirection'] = Borders::DIAGONAL_UP;
|
||||
} elseif (isset($srssb->{'Rev-Diagonal'})) {
|
||||
$styleArray['borders']['diagonal'] = self::parseBorderAttributes($srssb->{'Rev-Diagonal'}->attributes());
|
||||
$styleArray['borders']['diagonalDirection'] = Borders::DIAGONAL_DOWN;
|
||||
}
|
||||
}
|
||||
|
||||
private function addBorderStyle(SimpleXMLElement $srssb, array &$styleArray, string $direction): void
|
||||
{
|
||||
$ucDirection = ucfirst($direction);
|
||||
if (isset($srssb->$ucDirection)) {
|
||||
$styleArray['borders'][$direction] = self::parseBorderAttributes($srssb->$ucDirection->attributes());
|
||||
}
|
||||
}
|
||||
|
||||
private function processMergedCells(SimpleXMLElement $sheet): void
|
||||
private function processMergedCells(?SimpleXMLElement $sheet): void
|
||||
{
|
||||
// Handle Merged Cells in this worksheet
|
||||
if (isset($sheet->MergedRegions)) {
|
||||
if ($sheet !== null && isset($sheet->MergedRegions)) {
|
||||
foreach ($sheet->MergedRegions->Merge as $mergeCells) {
|
||||
if (strpos($mergeCells, ':') !== false) {
|
||||
$this->spreadsheet->getActiveSheet()->mergeCells($mergeCells);
|
||||
|
|
@ -510,92 +374,144 @@ class Gnumeric extends BaseReader
|
|||
}
|
||||
}
|
||||
|
||||
private function processColumnLoop(int $c, int $maxCol, SimpleXMLElement $columnOverride, float $defaultWidth): int
|
||||
private function processAutofilter(?SimpleXMLElement $sheet): void
|
||||
{
|
||||
$columnAttributes = $columnOverride->attributes();
|
||||
if ($sheet !== null && isset($sheet->Filters)) {
|
||||
foreach ($sheet->Filters->Filter as $autofilter) {
|
||||
if ($autofilter !== null) {
|
||||
$attributes = $autofilter->attributes();
|
||||
if (isset($attributes['Area'])) {
|
||||
$this->spreadsheet->getActiveSheet()->setAutoFilter((string) $attributes['Area']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function setColumnWidth(int $whichColumn, float $defaultWidth): void
|
||||
{
|
||||
$columnDimension = $this->spreadsheet->getActiveSheet()->getColumnDimension(Coordinate::stringFromColumnIndex($whichColumn + 1));
|
||||
if ($columnDimension !== null) {
|
||||
$columnDimension->setWidth($defaultWidth);
|
||||
}
|
||||
}
|
||||
|
||||
private function setColumnInvisible(int $whichColumn): void
|
||||
{
|
||||
$columnDimension = $this->spreadsheet->getActiveSheet()->getColumnDimension(Coordinate::stringFromColumnIndex($whichColumn + 1));
|
||||
if ($columnDimension !== null) {
|
||||
$columnDimension->setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
private function processColumnLoop(int $whichColumn, int $maxCol, SimpleXMLElement $columnOverride, float $defaultWidth): int
|
||||
{
|
||||
$columnAttributes = self::testSimpleXml($columnOverride->attributes());
|
||||
$column = $columnAttributes['No'];
|
||||
$columnWidth = ((float) $columnAttributes['Unit']) / 5.4;
|
||||
$hidden = (isset($columnAttributes['Hidden'])) && ((string) $columnAttributes['Hidden'] == '1');
|
||||
$columnCount = (int) ($columnAttributes['Count'] ?? 1);
|
||||
while ($c < $column) {
|
||||
$this->spreadsheet->getActiveSheet()->getColumnDimension(Coordinate::stringFromColumnIndex($c + 1))->setWidth($defaultWidth);
|
||||
++$c;
|
||||
while ($whichColumn < $column) {
|
||||
$this->setColumnWidth($whichColumn, $defaultWidth);
|
||||
++$whichColumn;
|
||||
}
|
||||
while (($c < ($column + $columnCount)) && ($c <= $maxCol)) {
|
||||
$this->spreadsheet->getActiveSheet()->getColumnDimension(Coordinate::stringFromColumnIndex($c + 1))->setWidth($columnWidth);
|
||||
while (($whichColumn < ($column + $columnCount)) && ($whichColumn <= $maxCol)) {
|
||||
$this->setColumnWidth($whichColumn, $columnWidth);
|
||||
if ($hidden) {
|
||||
$this->spreadsheet->getActiveSheet()->getColumnDimension(Coordinate::stringFromColumnIndex($c + 1))->setVisible(false);
|
||||
$this->setColumnInvisible($whichColumn);
|
||||
}
|
||||
++$c;
|
||||
++$whichColumn;
|
||||
}
|
||||
|
||||
return $c;
|
||||
return $whichColumn;
|
||||
}
|
||||
|
||||
private function processColumnWidths(SimpleXMLElement $sheet, int $maxCol): void
|
||||
private function processColumnWidths(?SimpleXMLElement $sheet, int $maxCol): void
|
||||
{
|
||||
if ((!$this->readDataOnly) && (isset($sheet->Cols))) {
|
||||
if ((!$this->readDataOnly) && $sheet !== null && (isset($sheet->Cols))) {
|
||||
// Column Widths
|
||||
$defaultWidth = 0;
|
||||
$columnAttributes = $sheet->Cols->attributes();
|
||||
$defaultWidth = $columnAttributes['DefaultSizePts'] / 5.4;
|
||||
$c = 0;
|
||||
foreach ($sheet->Cols->ColInfo as $columnOverride) {
|
||||
$c = $this->processColumnLoop($c, $maxCol, $columnOverride, $defaultWidth);
|
||||
if ($columnAttributes !== null) {
|
||||
$defaultWidth = $columnAttributes['DefaultSizePts'] / 5.4;
|
||||
}
|
||||
while ($c <= $maxCol) {
|
||||
$this->spreadsheet->getActiveSheet()->getColumnDimension(Coordinate::stringFromColumnIndex($c + 1))->setWidth($defaultWidth);
|
||||
++$c;
|
||||
$whichColumn = 0;
|
||||
foreach ($sheet->Cols->ColInfo as $columnOverride) {
|
||||
$whichColumn = $this->processColumnLoop($whichColumn, $maxCol, $columnOverride, $defaultWidth);
|
||||
}
|
||||
while ($whichColumn <= $maxCol) {
|
||||
$this->setColumnWidth($whichColumn, $defaultWidth);
|
||||
++$whichColumn;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function processRowLoop(int $r, int $maxRow, SimpleXMLElement $rowOverride, float $defaultHeight): int
|
||||
private function setRowHeight(int $whichRow, float $defaultHeight): void
|
||||
{
|
||||
$rowAttributes = $rowOverride->attributes();
|
||||
$rowDimension = $this->spreadsheet->getActiveSheet()->getRowDimension($whichRow);
|
||||
if ($rowDimension !== null) {
|
||||
$rowDimension->setRowHeight($defaultHeight);
|
||||
}
|
||||
}
|
||||
|
||||
private function setRowInvisible(int $whichRow): void
|
||||
{
|
||||
$rowDimension = $this->spreadsheet->getActiveSheet()->getRowDimension($whichRow);
|
||||
if ($rowDimension !== null) {
|
||||
$rowDimension->setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
private function processRowLoop(int $whichRow, int $maxRow, SimpleXMLElement $rowOverride, float $defaultHeight): int
|
||||
{
|
||||
$rowAttributes = self::testSimpleXml($rowOverride->attributes());
|
||||
$row = $rowAttributes['No'];
|
||||
$rowHeight = (float) $rowAttributes['Unit'];
|
||||
$hidden = (isset($rowAttributes['Hidden'])) && ((string) $rowAttributes['Hidden'] == '1');
|
||||
$rowCount = (int) ($rowAttributes['Count'] ?? 1);
|
||||
while ($r < $row) {
|
||||
++$r;
|
||||
$this->spreadsheet->getActiveSheet()->getRowDimension($r)->setRowHeight($defaultHeight);
|
||||
while ($whichRow < $row) {
|
||||
++$whichRow;
|
||||
$this->setRowHeight($whichRow, $defaultHeight);
|
||||
}
|
||||
while (($r < ($row + $rowCount)) && ($r < $maxRow)) {
|
||||
++$r;
|
||||
$this->spreadsheet->getActiveSheet()->getRowDimension($r)->setRowHeight($rowHeight);
|
||||
while (($whichRow < ($row + $rowCount)) && ($whichRow < $maxRow)) {
|
||||
++$whichRow;
|
||||
$this->setRowHeight($whichRow, $rowHeight);
|
||||
if ($hidden) {
|
||||
$this->spreadsheet->getActiveSheet()->getRowDimension($r)->setVisible(false);
|
||||
$this->setRowInvisible($whichRow);
|
||||
}
|
||||
}
|
||||
|
||||
return $r;
|
||||
return $whichRow;
|
||||
}
|
||||
|
||||
private function processRowHeights(SimpleXMLElement $sheet, int $maxRow): void
|
||||
private function processRowHeights(?SimpleXMLElement $sheet, int $maxRow): void
|
||||
{
|
||||
if ((!$this->readDataOnly) && (isset($sheet->Rows))) {
|
||||
if ((!$this->readDataOnly) && $sheet !== null && (isset($sheet->Rows))) {
|
||||
// Row Heights
|
||||
$defaultHeight = 0;
|
||||
$rowAttributes = $sheet->Rows->attributes();
|
||||
$defaultHeight = (float) $rowAttributes['DefaultSizePts'];
|
||||
$r = 0;
|
||||
if ($rowAttributes !== null) {
|
||||
$defaultHeight = (float) $rowAttributes['DefaultSizePts'];
|
||||
}
|
||||
$whichRow = 0;
|
||||
|
||||
foreach ($sheet->Rows->RowInfo as $rowOverride) {
|
||||
$r = $this->processRowLoop($r, $maxRow, $rowOverride, $defaultHeight);
|
||||
$whichRow = $this->processRowLoop($whichRow, $maxRow, $rowOverride, $defaultHeight);
|
||||
}
|
||||
// never executed, I can't figure out any circumstances
|
||||
// under which it would be executed, and, even if
|
||||
// such exist, I'm not convinced this is needed.
|
||||
//while ($r < $maxRow) {
|
||||
// ++$r;
|
||||
// $this->spreadsheet->getActiveSheet()->getRowDimension($r)->setRowHeight($defaultHeight);
|
||||
//while ($whichRow < $maxRow) {
|
||||
// ++$whichRow;
|
||||
// $this->spreadsheet->getActiveSheet()->getRowDimension($whichRow)->setRowHeight($defaultHeight);
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
private function processDefinedNames(SimpleXMLElement $gnmXML): void
|
||||
private function processDefinedNames(?SimpleXMLElement $gnmXML): void
|
||||
{
|
||||
// Loop through definedNames (global named ranges)
|
||||
if (isset($gnmXML->Names)) {
|
||||
if ($gnmXML !== null && isset($gnmXML->Names)) {
|
||||
foreach ($gnmXML->Names->Name as $definedName) {
|
||||
$name = (string) $definedName->name;
|
||||
$value = (string) $definedName->value;
|
||||
|
|
@ -614,77 +530,11 @@ class Gnumeric extends BaseReader
|
|||
}
|
||||
}
|
||||
|
||||
private function calcRotation(SimpleXMLElement $styleAttributes): int
|
||||
{
|
||||
$rotation = (int) $styleAttributes->Rotation;
|
||||
if ($rotation >= 270 && $rotation <= 360) {
|
||||
$rotation -= 360;
|
||||
}
|
||||
$rotation = (abs($rotation) > 90) ? 0 : $rotation;
|
||||
|
||||
return $rotation;
|
||||
}
|
||||
|
||||
private static function addStyle(array &$styleArray, string $key, string $value): void
|
||||
{
|
||||
if (array_key_exists($value, self::$mappings[$key])) {
|
||||
$styleArray[$key] = self::$mappings[$key][$value];
|
||||
}
|
||||
}
|
||||
|
||||
private static function addStyle2(array &$styleArray, string $key1, string $key, string $value): void
|
||||
{
|
||||
if (array_key_exists($value, self::$mappings[$key])) {
|
||||
$styleArray[$key1][$key] = self::$mappings[$key][$value];
|
||||
}
|
||||
}
|
||||
|
||||
private static function parseBorderAttributes($borderAttributes)
|
||||
{
|
||||
$styleArray = [];
|
||||
if (isset($borderAttributes['Color'])) {
|
||||
$styleArray['color']['rgb'] = self::parseGnumericColour($borderAttributes['Color']);
|
||||
}
|
||||
|
||||
self::addStyle($styleArray, 'borderStyle', $borderAttributes['Style']);
|
||||
|
||||
return $styleArray;
|
||||
}
|
||||
|
||||
private function parseRichText($is)
|
||||
private function parseRichText(string $is): RichText
|
||||
{
|
||||
$value = new RichText();
|
||||
$value->createText($is);
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
private static function parseGnumericColour($gnmColour)
|
||||
{
|
||||
[$gnmR, $gnmG, $gnmB] = explode(':', $gnmColour);
|
||||
$gnmR = substr(str_pad($gnmR, 4, '0', STR_PAD_RIGHT), 0, 2);
|
||||
$gnmG = substr(str_pad($gnmG, 4, '0', STR_PAD_RIGHT), 0, 2);
|
||||
$gnmB = substr(str_pad($gnmB, 4, '0', STR_PAD_RIGHT), 0, 2);
|
||||
|
||||
return $gnmR . $gnmG . $gnmB;
|
||||
}
|
||||
|
||||
private function addColors(array &$styleArray, SimpleXMLElement $styleAttributes): void
|
||||
{
|
||||
$RGB = self::parseGnumericColour($styleAttributes['Fore']);
|
||||
$styleArray['font']['color']['rgb'] = $RGB;
|
||||
$RGB = self::parseGnumericColour($styleAttributes['Back']);
|
||||
$shade = (string) $styleAttributes['Shade'];
|
||||
if (($RGB != '000000') || ($shade != '0')) {
|
||||
$RGB2 = self::parseGnumericColour($styleAttributes['PatternColor']);
|
||||
if ($shade == '1') {
|
||||
$styleArray['fill']['startColor']['rgb'] = $RGB;
|
||||
$styleArray['fill']['endColor']['rgb'] = $RGB2;
|
||||
} else {
|
||||
$styleArray['fill']['endColor']['rgb'] = $RGB;
|
||||
$styleArray['fill']['startColor']['rgb'] = $RGB2;
|
||||
}
|
||||
self::addStyle2($styleArray, 'fill', 'fillType', $shade);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace PhpOffice\PhpSpreadsheet\Reader\Gnumeric;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Reader\Gnumeric;
|
||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\PageMargins;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\PageSetup as WorksheetPageSetup;
|
||||
|
|
@ -14,15 +15,9 @@ class PageSetup
|
|||
*/
|
||||
private $spreadsheet;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $gnm;
|
||||
|
||||
public function __construct(Spreadsheet $spreadsheet, string $gnm)
|
||||
public function __construct(Spreadsheet $spreadsheet)
|
||||
{
|
||||
$this->spreadsheet = $spreadsheet;
|
||||
$this->gnm = $gnm;
|
||||
}
|
||||
|
||||
public function printInformation(SimpleXMLElement $sheet): self
|
||||
|
|
@ -68,7 +63,7 @@ class PageSetup
|
|||
|
||||
private function buildMarginSet(SimpleXMLElement $sheet, array $marginSet): array
|
||||
{
|
||||
foreach ($sheet->PrintInformation->Margins->children($this->gnm, true) as $key => $margin) {
|
||||
foreach ($sheet->PrintInformation->Margins->children(Gnumeric::NAMESPACE_GNM) as $key => $margin) {
|
||||
$marginAttributes = $margin->attributes();
|
||||
$marginSize = ($marginAttributes['Points']) ?? 72; // Default is 72pt
|
||||
// Convert value in points to inches
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace PhpOffice\PhpSpreadsheet\Reader\Gnumeric;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Reader\Gnumeric;
|
||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
use SimpleXMLElement;
|
||||
|
||||
|
|
@ -91,74 +92,72 @@ class Properties
|
|||
}
|
||||
}
|
||||
|
||||
private function docPropertiesMeta(SimpleXMLElement $officePropertyMeta, array $namespacesMeta): void
|
||||
private function docPropertiesMeta(SimpleXMLElement $officePropertyMeta): void
|
||||
{
|
||||
$docProps = $this->spreadsheet->getProperties();
|
||||
foreach ($officePropertyMeta as $propertyName => $propertyValue) {
|
||||
if ($propertyValue === null) {
|
||||
continue;
|
||||
}
|
||||
if ($propertyValue !== null) {
|
||||
$attributes = $propertyValue->attributes(Gnumeric::NAMESPACE_META);
|
||||
$propertyValue = trim((string) $propertyValue);
|
||||
switch ($propertyName) {
|
||||
case 'keyword':
|
||||
$docProps->setKeywords($propertyValue);
|
||||
|
||||
$attributes = $propertyValue->attributes($namespacesMeta['meta']);
|
||||
$propertyValue = trim((string) $propertyValue);
|
||||
switch ($propertyName) {
|
||||
case 'keyword':
|
||||
$docProps->setKeywords($propertyValue);
|
||||
break;
|
||||
case 'initial-creator':
|
||||
$docProps->setCreator($propertyValue);
|
||||
$docProps->setLastModifiedBy($propertyValue);
|
||||
|
||||
break;
|
||||
case 'initial-creator':
|
||||
$docProps->setCreator($propertyValue);
|
||||
$docProps->setLastModifiedBy($propertyValue);
|
||||
break;
|
||||
case 'creation-date':
|
||||
$creationDate = strtotime($propertyValue);
|
||||
$creationDate = $creationDate === false ? time() : $creationDate;
|
||||
$docProps->setCreated($creationDate);
|
||||
$docProps->setModified($creationDate);
|
||||
|
||||
break;
|
||||
case 'creation-date':
|
||||
$creationDate = strtotime($propertyValue);
|
||||
$creationDate = $creationDate === false ? time() : $creationDate;
|
||||
$docProps->setCreated($creationDate);
|
||||
$docProps->setModified($creationDate);
|
||||
break;
|
||||
case 'user-defined':
|
||||
[, $attrName] = explode(':', $attributes['name']);
|
||||
$this->userDefinedProperties($attrName, $propertyValue);
|
||||
|
||||
break;
|
||||
case 'user-defined':
|
||||
[, $attrName] = explode(':', $attributes['name']);
|
||||
switch ($attrName) {
|
||||
case 'publisher':
|
||||
$docProps->setCompany($propertyValue);
|
||||
|
||||
break;
|
||||
case 'category':
|
||||
$docProps->setCategory($propertyValue);
|
||||
|
||||
break;
|
||||
case 'manager':
|
||||
$docProps->setManager($propertyValue);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function readProperties(SimpleXMLElement $xml, SimpleXMLElement $gnmXML, array $namespacesMeta): void
|
||||
private function userDefinedProperties(string $attrName, string $propertyValue): void
|
||||
{
|
||||
if (isset($namespacesMeta['office'])) {
|
||||
$officeXML = $xml->children($namespacesMeta['office']);
|
||||
$docProps = $this->spreadsheet->getProperties();
|
||||
switch ($attrName) {
|
||||
case 'publisher':
|
||||
$docProps->setCompany($propertyValue);
|
||||
|
||||
break;
|
||||
case 'category':
|
||||
$docProps->setCategory($propertyValue);
|
||||
|
||||
break;
|
||||
case 'manager':
|
||||
$docProps->setManager($propertyValue);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public function readProperties(SimpleXMLElement $xml, SimpleXMLElement $gnmXML): void
|
||||
{
|
||||
$officeXML = $xml->children(Gnumeric::NAMESPACE_OFFICE);
|
||||
if (!empty($officeXML)) {
|
||||
$officeDocXML = $officeXML->{'document-meta'};
|
||||
$officeDocMetaXML = $officeDocXML->meta;
|
||||
|
||||
foreach ($officeDocMetaXML as $officePropertyData) {
|
||||
$officePropertyDC = [];
|
||||
if (isset($namespacesMeta['dc'])) {
|
||||
$officePropertyDC = $officePropertyData->children($namespacesMeta['dc']);
|
||||
}
|
||||
$officePropertyDC = $officePropertyData->children(Gnumeric::NAMESPACE_DC);
|
||||
$this->docPropertiesDC($officePropertyDC);
|
||||
|
||||
$officePropertyMeta = [];
|
||||
if (isset($namespacesMeta['meta'])) {
|
||||
$officePropertyMeta = $officePropertyData->children($namespacesMeta['meta']);
|
||||
}
|
||||
$this->docPropertiesMeta($officePropertyMeta, $namespacesMeta);
|
||||
$officePropertyMeta = $officePropertyData->children(Gnumeric::NAMESPACE_META);
|
||||
$this->docPropertiesMeta($officePropertyMeta);
|
||||
}
|
||||
} elseif (isset($gnmXML->Summary)) {
|
||||
$this->docPropertiesOld($gnmXML);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,282 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Reader\Gnumeric;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\Date;
|
||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
use PhpOffice\PhpSpreadsheet\Style\Alignment;
|
||||
use PhpOffice\PhpSpreadsheet\Style\Border;
|
||||
use PhpOffice\PhpSpreadsheet\Style\Borders;
|
||||
use PhpOffice\PhpSpreadsheet\Style\Fill;
|
||||
use PhpOffice\PhpSpreadsheet\Style\Font;
|
||||
use SimpleXMLElement;
|
||||
|
||||
class Styles
|
||||
{
|
||||
/**
|
||||
* @var Spreadsheet
|
||||
*/
|
||||
private $spreadsheet;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $readDataOnly = false;
|
||||
|
||||
/** @var array */
|
||||
public static $mappings = [
|
||||
'borderStyle' => [
|
||||
'0' => Border::BORDER_NONE,
|
||||
'1' => Border::BORDER_THIN,
|
||||
'2' => Border::BORDER_MEDIUM,
|
||||
'3' => Border::BORDER_SLANTDASHDOT,
|
||||
'4' => Border::BORDER_DASHED,
|
||||
'5' => Border::BORDER_THICK,
|
||||
'6' => Border::BORDER_DOUBLE,
|
||||
'7' => Border::BORDER_DOTTED,
|
||||
'8' => Border::BORDER_MEDIUMDASHED,
|
||||
'9' => Border::BORDER_DASHDOT,
|
||||
'10' => Border::BORDER_MEDIUMDASHDOT,
|
||||
'11' => Border::BORDER_DASHDOTDOT,
|
||||
'12' => Border::BORDER_MEDIUMDASHDOTDOT,
|
||||
'13' => Border::BORDER_MEDIUMDASHDOTDOT,
|
||||
],
|
||||
'fillType' => [
|
||||
'1' => Fill::FILL_SOLID,
|
||||
'2' => Fill::FILL_PATTERN_DARKGRAY,
|
||||
'3' => Fill::FILL_PATTERN_MEDIUMGRAY,
|
||||
'4' => Fill::FILL_PATTERN_LIGHTGRAY,
|
||||
'5' => Fill::FILL_PATTERN_GRAY125,
|
||||
'6' => Fill::FILL_PATTERN_GRAY0625,
|
||||
'7' => Fill::FILL_PATTERN_DARKHORIZONTAL, // horizontal stripe
|
||||
'8' => Fill::FILL_PATTERN_DARKVERTICAL, // vertical stripe
|
||||
'9' => Fill::FILL_PATTERN_DARKDOWN, // diagonal stripe
|
||||
'10' => Fill::FILL_PATTERN_DARKUP, // reverse diagonal stripe
|
||||
'11' => Fill::FILL_PATTERN_DARKGRID, // diagoanl crosshatch
|
||||
'12' => Fill::FILL_PATTERN_DARKTRELLIS, // thick diagonal crosshatch
|
||||
'13' => Fill::FILL_PATTERN_LIGHTHORIZONTAL,
|
||||
'14' => Fill::FILL_PATTERN_LIGHTVERTICAL,
|
||||
'15' => Fill::FILL_PATTERN_LIGHTUP,
|
||||
'16' => Fill::FILL_PATTERN_LIGHTDOWN,
|
||||
'17' => Fill::FILL_PATTERN_LIGHTGRID, // thin horizontal crosshatch
|
||||
'18' => Fill::FILL_PATTERN_LIGHTTRELLIS, // thin diagonal crosshatch
|
||||
],
|
||||
'horizontal' => [
|
||||
'1' => Alignment::HORIZONTAL_GENERAL,
|
||||
'2' => Alignment::HORIZONTAL_LEFT,
|
||||
'4' => Alignment::HORIZONTAL_RIGHT,
|
||||
'8' => Alignment::HORIZONTAL_CENTER,
|
||||
'16' => Alignment::HORIZONTAL_CENTER_CONTINUOUS,
|
||||
'32' => Alignment::HORIZONTAL_JUSTIFY,
|
||||
'64' => Alignment::HORIZONTAL_CENTER_CONTINUOUS,
|
||||
],
|
||||
'underline' => [
|
||||
'1' => Font::UNDERLINE_SINGLE,
|
||||
'2' => Font::UNDERLINE_DOUBLE,
|
||||
'3' => Font::UNDERLINE_SINGLEACCOUNTING,
|
||||
'4' => Font::UNDERLINE_DOUBLEACCOUNTING,
|
||||
],
|
||||
'vertical' => [
|
||||
'1' => Alignment::VERTICAL_TOP,
|
||||
'2' => Alignment::VERTICAL_BOTTOM,
|
||||
'4' => Alignment::VERTICAL_CENTER,
|
||||
'8' => Alignment::VERTICAL_JUSTIFY,
|
||||
],
|
||||
];
|
||||
|
||||
public function __construct(Spreadsheet $spreadsheet, bool $readDataOnly)
|
||||
{
|
||||
$this->spreadsheet = $spreadsheet;
|
||||
$this->readDataOnly = $readDataOnly;
|
||||
}
|
||||
|
||||
public function read(SimpleXMLElement $sheet, int $maxRow, int $maxCol): void
|
||||
{
|
||||
if ($sheet->Styles->StyleRegion !== null) {
|
||||
$this->readStyles($sheet->Styles->StyleRegion, $maxRow, $maxCol);
|
||||
}
|
||||
}
|
||||
|
||||
private function readStyles(SimpleXMLElement $styleRegion, int $maxRow, int $maxCol): void
|
||||
{
|
||||
foreach ($styleRegion as $style) {
|
||||
if ($style === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$styleAttributes = $style->attributes();
|
||||
if ($styleAttributes !== null && ($styleAttributes['startRow'] <= $maxRow) && ($styleAttributes['startCol'] <= $maxCol)) {
|
||||
$cellRange = $this->readStyleRange($styleAttributes, $maxCol, $maxRow);
|
||||
|
||||
$styleAttributes = $style->Style->attributes();
|
||||
|
||||
$styleArray = [];
|
||||
// We still set the number format mask for date/time values, even if readDataOnly is true
|
||||
// so that we can identify whether a float is a float or a date value
|
||||
$formatCode = (string) $styleAttributes['Format'];
|
||||
if (Date::isDateTimeFormatCode($formatCode)) {
|
||||
$styleArray['numberFormat']['formatCode'] = $formatCode;
|
||||
}
|
||||
if ($this->readDataOnly === false && $styleAttributes !== null) {
|
||||
// If readDataOnly is false, we set all formatting information
|
||||
$styleArray['numberFormat']['formatCode'] = $formatCode;
|
||||
$styleArray = $this->readStyle($styleArray, $styleAttributes, $style);
|
||||
}
|
||||
$this->spreadsheet->getActiveSheet()->getStyle($cellRange)->applyFromArray($styleArray);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function addBorderDiagonal(SimpleXMLElement $srssb, array &$styleArray): void
|
||||
{
|
||||
if (isset($srssb->Diagonal, $srssb->{'Rev-Diagonal'})) {
|
||||
$styleArray['borders']['diagonal'] = self::parseBorderAttributes($srssb->Diagonal->attributes());
|
||||
$styleArray['borders']['diagonalDirection'] = Borders::DIAGONAL_BOTH;
|
||||
} elseif (isset($srssb->Diagonal)) {
|
||||
$styleArray['borders']['diagonal'] = self::parseBorderAttributes($srssb->Diagonal->attributes());
|
||||
$styleArray['borders']['diagonalDirection'] = Borders::DIAGONAL_UP;
|
||||
} elseif (isset($srssb->{'Rev-Diagonal'})) {
|
||||
$styleArray['borders']['diagonal'] = self::parseBorderAttributes($srssb->{'Rev-Diagonal'}->attributes());
|
||||
$styleArray['borders']['diagonalDirection'] = Borders::DIAGONAL_DOWN;
|
||||
}
|
||||
}
|
||||
|
||||
private function addBorderStyle(SimpleXMLElement $srssb, array &$styleArray, string $direction): void
|
||||
{
|
||||
$ucDirection = ucfirst($direction);
|
||||
if (isset($srssb->$ucDirection)) {
|
||||
$styleArray['borders'][$direction] = self::parseBorderAttributes($srssb->$ucDirection->attributes());
|
||||
}
|
||||
}
|
||||
|
||||
private function calcRotation(SimpleXMLElement $styleAttributes): int
|
||||
{
|
||||
$rotation = (int) $styleAttributes->Rotation;
|
||||
if ($rotation >= 270 && $rotation <= 360) {
|
||||
$rotation -= 360;
|
||||
}
|
||||
$rotation = (abs($rotation) > 90) ? 0 : $rotation;
|
||||
|
||||
return $rotation;
|
||||
}
|
||||
|
||||
private static function addStyle(array &$styleArray, string $key, string $value): void
|
||||
{
|
||||
if (array_key_exists($value, self::$mappings[$key])) {
|
||||
$styleArray[$key] = self::$mappings[$key][$value];
|
||||
}
|
||||
}
|
||||
|
||||
private static function addStyle2(array &$styleArray, string $key1, string $key, string $value): void
|
||||
{
|
||||
if (array_key_exists($value, self::$mappings[$key])) {
|
||||
$styleArray[$key1][$key] = self::$mappings[$key][$value];
|
||||
}
|
||||
}
|
||||
|
||||
private static function parseBorderAttributes(?SimpleXMLElement $borderAttributes): array
|
||||
{
|
||||
$styleArray = [];
|
||||
if ($borderAttributes !== null) {
|
||||
if (isset($borderAttributes['Color'])) {
|
||||
$styleArray['color']['rgb'] = self::parseGnumericColour($borderAttributes['Color']);
|
||||
}
|
||||
|
||||
self::addStyle($styleArray, 'borderStyle', $borderAttributes['Style']);
|
||||
}
|
||||
|
||||
return $styleArray;
|
||||
}
|
||||
|
||||
private static function parseGnumericColour(string $gnmColour): string
|
||||
{
|
||||
[$gnmR, $gnmG, $gnmB] = explode(':', $gnmColour);
|
||||
$gnmR = substr(str_pad($gnmR, 4, '0', STR_PAD_RIGHT), 0, 2);
|
||||
$gnmG = substr(str_pad($gnmG, 4, '0', STR_PAD_RIGHT), 0, 2);
|
||||
$gnmB = substr(str_pad($gnmB, 4, '0', STR_PAD_RIGHT), 0, 2);
|
||||
|
||||
return $gnmR . $gnmG . $gnmB;
|
||||
}
|
||||
|
||||
private function addColors(array &$styleArray, SimpleXMLElement $styleAttributes): void
|
||||
{
|
||||
$RGB = self::parseGnumericColour($styleAttributes['Fore']);
|
||||
$styleArray['font']['color']['rgb'] = $RGB;
|
||||
$RGB = self::parseGnumericColour($styleAttributes['Back']);
|
||||
$shade = (string) $styleAttributes['Shade'];
|
||||
if (($RGB !== '000000') || ($shade !== '0')) {
|
||||
$RGB2 = self::parseGnumericColour($styleAttributes['PatternColor']);
|
||||
if ($shade === '1') {
|
||||
$styleArray['fill']['startColor']['rgb'] = $RGB;
|
||||
$styleArray['fill']['endColor']['rgb'] = $RGB2;
|
||||
} else {
|
||||
$styleArray['fill']['endColor']['rgb'] = $RGB;
|
||||
$styleArray['fill']['startColor']['rgb'] = $RGB2;
|
||||
}
|
||||
self::addStyle2($styleArray, 'fill', 'fillType', $shade);
|
||||
}
|
||||
}
|
||||
|
||||
private function readStyleRange(SimpleXMLElement $styleAttributes, int $maxCol, int $maxRow): string
|
||||
{
|
||||
$startColumn = Coordinate::stringFromColumnIndex((int) $styleAttributes['startCol'] + 1);
|
||||
$startRow = $styleAttributes['startRow'] + 1;
|
||||
|
||||
$endColumn = ($styleAttributes['endCol'] > $maxCol) ? $maxCol : (int) $styleAttributes['endCol'];
|
||||
$endColumn = Coordinate::stringFromColumnIndex($endColumn + 1);
|
||||
|
||||
$endRow = 1 + (($styleAttributes['endRow'] > $maxRow) ? $maxRow : (int) $styleAttributes['endRow']);
|
||||
$cellRange = $startColumn . $startRow . ':' . $endColumn . $endRow;
|
||||
|
||||
return $cellRange;
|
||||
}
|
||||
|
||||
private function readStyle(array $styleArray, SimpleXMLElement $styleAttributes, SimpleXMLElement $style): array
|
||||
{
|
||||
self::addStyle2($styleArray, 'alignment', 'horizontal', $styleAttributes['HAlign']);
|
||||
self::addStyle2($styleArray, 'alignment', 'vertical', $styleAttributes['VAlign']);
|
||||
$styleArray['alignment']['wrapText'] = $styleAttributes['WrapText'] == '1';
|
||||
$styleArray['alignment']['textRotation'] = $this->calcRotation($styleAttributes);
|
||||
$styleArray['alignment']['shrinkToFit'] = $styleAttributes['ShrinkToFit'] == '1';
|
||||
$styleArray['alignment']['indent'] = ((int) ($styleAttributes['Indent']) > 0) ? $styleAttributes['indent'] : 0;
|
||||
|
||||
$this->addColors($styleArray, $styleAttributes);
|
||||
|
||||
$fontAttributes = $style->Style->Font->attributes();
|
||||
if ($fontAttributes !== null) {
|
||||
$styleArray['font']['name'] = (string) $style->Style->Font;
|
||||
$styleArray['font']['size'] = (int) ($fontAttributes['Unit']);
|
||||
$styleArray['font']['bold'] = $fontAttributes['Bold'] == '1';
|
||||
$styleArray['font']['italic'] = $fontAttributes['Italic'] == '1';
|
||||
$styleArray['font']['strikethrough'] = $fontAttributes['StrikeThrough'] == '1';
|
||||
self::addStyle2($styleArray, 'font', 'underline', $fontAttributes['Underline']);
|
||||
|
||||
switch ($fontAttributes['Script']) {
|
||||
case '1':
|
||||
$styleArray['font']['superscript'] = true;
|
||||
|
||||
break;
|
||||
case '-1':
|
||||
$styleArray['font']['subscript'] = true;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($style->Style->StyleBorder)) {
|
||||
$srssb = $style->Style->StyleBorder;
|
||||
$this->addBorderStyle($srssb, $styleArray, 'top');
|
||||
$this->addBorderStyle($srssb, $styleArray, 'bottom');
|
||||
$this->addBorderStyle($srssb, $styleArray, 'left');
|
||||
$this->addBorderStyle($srssb, $styleArray, 'right');
|
||||
$this->addBorderDiagonal($srssb, $styleArray);
|
||||
}
|
||||
if (isset($style->Style->HyperLink)) {
|
||||
// TO DO
|
||||
$hyperlink = $style->Style->HyperLink->attributes();
|
||||
}
|
||||
|
||||
return $styleArray;
|
||||
}
|
||||
}
|
||||
|
|
@ -220,13 +220,13 @@ class Html extends BaseReader
|
|||
/**
|
||||
* Set input encoding.
|
||||
*
|
||||
* @deprecated no use is made of this property
|
||||
*
|
||||
* @param string $pValue Input encoding, eg: 'ANSI'
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @deprecated no use is made of this property
|
||||
*/
|
||||
public function setInputEncoding($pValue)
|
||||
{
|
||||
|
|
@ -238,11 +238,11 @@ class Html extends BaseReader
|
|||
/**
|
||||
* Get input encoding.
|
||||
*
|
||||
* @deprecated no use is made of this property
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @deprecated no use is made of this property
|
||||
*/
|
||||
public function getInputEncoding()
|
||||
{
|
||||
|
|
@ -469,7 +469,7 @@ class Html extends BaseReader
|
|||
if ($child->nodeName === 'table') {
|
||||
$this->flushCell($sheet, $column, $row, $cellContent);
|
||||
$column = $this->setTableStartColumn($column);
|
||||
if ($this->tableLevel > 1) {
|
||||
if ($this->tableLevel > 1 && $row > 1) {
|
||||
--$row;
|
||||
}
|
||||
$this->processDomElement($child, $sheet, $row, $column, $cellContent);
|
||||
|
|
@ -620,7 +620,7 @@ class Html extends BaseReader
|
|||
$cellContent .= $domText;
|
||||
}
|
||||
// but if we have a rich text run instead, we need to append it correctly
|
||||
// TODO
|
||||
// TODO
|
||||
} elseif ($child instanceof DOMElement) {
|
||||
$this->processDomElementBody($sheet, $row, $column, $cellContent, $child);
|
||||
}
|
||||
|
|
@ -878,14 +878,14 @@ class Html extends BaseReader
|
|||
|
||||
case 'width':
|
||||
$sheet->getColumnDimension($column)->setWidth(
|
||||
str_replace('px', '', $styleValue)
|
||||
(float) str_replace(['px', 'pt'], '', $styleValue)
|
||||
);
|
||||
|
||||
break;
|
||||
|
||||
case 'height':
|
||||
$sheet->getRowDimension($row)->setRowHeight(
|
||||
str_replace('px', '', $styleValue)
|
||||
(float) str_replace(['px', 'pt'], '', $styleValue)
|
||||
);
|
||||
|
||||
break;
|
||||
|
|
@ -922,8 +922,8 @@ class Html extends BaseReader
|
|||
}
|
||||
|
||||
/**
|
||||
* @param string $column
|
||||
* @param int $row
|
||||
* @param string $column
|
||||
* @param int $row
|
||||
*/
|
||||
private function insertImage(Worksheet $sheet, $column, $row, array $attributes): void
|
||||
{
|
||||
|
|
@ -990,7 +990,7 @@ class Html extends BaseReader
|
|||
/**
|
||||
* Map html border style to PhpSpreadsheet border style.
|
||||
*
|
||||
* @param string $style
|
||||
* @param string $style
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
|
|
@ -1009,7 +1009,15 @@ class Html extends BaseReader
|
|||
$borderStyle = Border::BORDER_NONE;
|
||||
$color = null;
|
||||
} else {
|
||||
[, $borderStyle, $color] = explode(' ', $styleValue);
|
||||
$borderArray = explode(' ', $styleValue);
|
||||
$borderCount = count($borderArray);
|
||||
if ($borderCount >= 3) {
|
||||
$borderStyle = $borderArray[1];
|
||||
$color = $borderArray[2];
|
||||
} else {
|
||||
$borderStyle = $borderArray[0];
|
||||
$color = $borderArray[1] ?? null;
|
||||
}
|
||||
}
|
||||
|
||||
$cellStyle->applyFromArray([
|
||||
|
|
|
|||
|
|
@ -11,8 +11,9 @@ use DOMNode;
|
|||
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
|
||||
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
|
||||
use PhpOffice\PhpSpreadsheet\Cell\DataType;
|
||||
use PhpOffice\PhpSpreadsheet\DefinedName;
|
||||
use PhpOffice\PhpSpreadsheet\Reader\Exception as ReaderException;
|
||||
use PhpOffice\PhpSpreadsheet\Reader\Ods\AutoFilter;
|
||||
use PhpOffice\PhpSpreadsheet\Reader\Ods\DefinedNames;
|
||||
use PhpOffice\PhpSpreadsheet\Reader\Ods\PageSettings;
|
||||
use PhpOffice\PhpSpreadsheet\Reader\Ods\Properties as DocumentProperties;
|
||||
use PhpOffice\PhpSpreadsheet\Reader\Security\XmlScanner;
|
||||
|
|
@ -22,7 +23,6 @@ use PhpOffice\PhpSpreadsheet\Shared\Date;
|
|||
use PhpOffice\PhpSpreadsheet\Shared\File;
|
||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
||||
use Throwable;
|
||||
use XMLReader;
|
||||
use ZipArchive;
|
||||
|
|
@ -304,8 +304,10 @@ class Ods extends BaseReader
|
|||
|
||||
$pageSettings->readStyleCrossReferences($dom);
|
||||
|
||||
// Content
|
||||
$autoFilterReader = new AutoFilter($spreadsheet, $tableNs);
|
||||
$definedNameReader = new DefinedNames($spreadsheet, $tableNs);
|
||||
|
||||
// Content
|
||||
$spreadsheets = $dom->getElementsByTagNameNS($officeNs, 'body')
|
||||
->item(0)
|
||||
->getElementsByTagNameNS($officeNs, 'spreadsheet');
|
||||
|
|
@ -642,8 +644,8 @@ class Ods extends BaseReader
|
|||
++$worksheetID;
|
||||
}
|
||||
|
||||
$this->readDefinedRanges($spreadsheet, $workbookData, $tableNs);
|
||||
$this->readDefinedExpressions($spreadsheet, $workbookData, $tableNs);
|
||||
$autoFilterReader->read($workbookData);
|
||||
$definedNameReader->read($workbookData);
|
||||
}
|
||||
$spreadsheet->setActiveSheetIndex(0);
|
||||
|
||||
|
|
@ -771,26 +773,6 @@ class Ods extends BaseReader
|
|||
return $value;
|
||||
}
|
||||
|
||||
private function convertToExcelAddressValue(string $openOfficeAddress): string
|
||||
{
|
||||
$excelAddress = $openOfficeAddress;
|
||||
|
||||
// Cell range 3-d reference
|
||||
// As we don't support 3-d ranges, we're just going to take a quick and dirty approach
|
||||
// and assume that the second worksheet reference is the same as the first
|
||||
$excelAddress = preg_replace('/\$?([^\.]+)\.([^\.]+):\$?([^\.]+)\.([^\.]+)/miu', '$1!$2:$4', $excelAddress);
|
||||
// Cell range reference in another sheet
|
||||
$excelAddress = preg_replace('/\$?([^\.]+)\.([^\.]+):\.([^\.]+)/miu', '$1!$2:$3', $excelAddress);
|
||||
// Cell reference in another sheet
|
||||
$excelAddress = preg_replace('/\$?([^\.]+)\.([^\.]+)/miu', '$1!$2', $excelAddress);
|
||||
// Cell range reference
|
||||
$excelAddress = preg_replace('/\.([^\.]+):\.([^\.]+)/miu', '$1:$2', $excelAddress);
|
||||
// Simple cell reference
|
||||
$excelAddress = preg_replace('/\.([^\.]+)/miu', '$1', $excelAddress);
|
||||
|
||||
return $excelAddress;
|
||||
}
|
||||
|
||||
private function convertToExcelFormulaValue(string $openOfficeFormula): string
|
||||
{
|
||||
$temp = explode('"', $openOfficeFormula);
|
||||
|
|
@ -801,11 +783,13 @@ class Ods extends BaseReader
|
|||
// Cell range reference in another sheet
|
||||
$value = preg_replace('/\[\$?([^\.]+)\.([^\.]+):\.([^\.]+)\]/miu', '$1!$2:$3', $value);
|
||||
// Cell reference in another sheet
|
||||
$value = preg_replace('/\[\$?([^\.]+)\.([^\.]+)\]/miu', '$1!$2', $value);
|
||||
$value = preg_replace('/\[\$?([^\.]+)\.([^\.]+)\]/miu', '$1!$2', $value ?? '');
|
||||
// Cell range reference
|
||||
$value = preg_replace('/\[\.([^\.]+):\.([^\.]+)\]/miu', '$1:$2', $value);
|
||||
$value = preg_replace('/\[\.([^\.]+):\.([^\.]+)\]/miu', '$1:$2', $value ?? '');
|
||||
// Simple cell reference
|
||||
$value = preg_replace('/\[\.([^\.]+)\]/miu', '$1', $value);
|
||||
$value = preg_replace('/\[\.([^\.]+)\]/miu', '$1', $value ?? '');
|
||||
// Convert references to defined names/formulae
|
||||
$value = str_replace('$$', '', $value ?? '');
|
||||
|
||||
$value = Calculation::translateSeparator(';', ',', $value, $inBraces);
|
||||
}
|
||||
|
|
@ -816,53 +800,4 @@ class Ods extends BaseReader
|
|||
|
||||
return $excelFormula;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read any Named Ranges that are defined in this spreadsheet.
|
||||
*/
|
||||
private function readDefinedRanges(Spreadsheet $spreadsheet, DOMElement $workbookData, string $tableNs): void
|
||||
{
|
||||
$namedRanges = $workbookData->getElementsByTagNameNS($tableNs, 'named-range');
|
||||
foreach ($namedRanges as $definedNameElement) {
|
||||
$definedName = $definedNameElement->getAttributeNS($tableNs, 'name');
|
||||
$baseAddress = $definedNameElement->getAttributeNS($tableNs, 'base-cell-address');
|
||||
$range = $definedNameElement->getAttributeNS($tableNs, 'cell-range-address');
|
||||
|
||||
$baseAddress = $this->convertToExcelAddressValue($baseAddress);
|
||||
$range = $this->convertToExcelAddressValue($range);
|
||||
|
||||
$this->addDefinedName($spreadsheet, $baseAddress, $definedName, $range);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read any Named Formulae that are defined in this spreadsheet.
|
||||
*/
|
||||
private function readDefinedExpressions(Spreadsheet $spreadsheet, DOMElement $workbookData, string $tableNs): void
|
||||
{
|
||||
$namedExpressions = $workbookData->getElementsByTagNameNS($tableNs, 'named-expression');
|
||||
foreach ($namedExpressions as $definedNameElement) {
|
||||
$definedName = $definedNameElement->getAttributeNS($tableNs, 'name');
|
||||
$baseAddress = $definedNameElement->getAttributeNS($tableNs, 'base-cell-address');
|
||||
$expression = $definedNameElement->getAttributeNS($tableNs, 'expression');
|
||||
|
||||
$baseAddress = $this->convertToExcelAddressValue($baseAddress);
|
||||
$expression = $this->convertToExcelFormulaValue($expression);
|
||||
|
||||
$this->addDefinedName($spreadsheet, $baseAddress, $definedName, $expression);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Assess scope and store the Defined Name.
|
||||
*/
|
||||
private function addDefinedName(Spreadsheet $spreadsheet, string $baseAddress, string $definedName, string $value): void
|
||||
{
|
||||
[$sheetReference] = Worksheet::extractSheetTitle($baseAddress, true);
|
||||
$worksheet = $spreadsheet->getSheetByName($sheetReference);
|
||||
// Worksheet might still be null if we're only loading selected sheets rather than the full spreadsheet
|
||||
if ($worksheet !== null) {
|
||||
$spreadsheet->addDefinedName(DefinedName::createInstance((string) $definedName, $worksheet, $value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,45 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Reader\Ods;
|
||||
|
||||
use DOMElement;
|
||||
use DOMNode;
|
||||
|
||||
class AutoFilter extends BaseReader
|
||||
{
|
||||
public function read(DOMElement $workbookData): void
|
||||
{
|
||||
$this->readAutoFilters($workbookData);
|
||||
}
|
||||
|
||||
protected function readAutoFilters(DOMElement $workbookData): void
|
||||
{
|
||||
$databases = $workbookData->getElementsByTagNameNS($this->tableNs, 'database-ranges');
|
||||
|
||||
foreach ($databases as $autofilters) {
|
||||
foreach ($autofilters->childNodes as $autofilter) {
|
||||
$autofilterRange = $this->getAttributeValue($autofilter, 'target-range-address');
|
||||
if ($autofilterRange !== null) {
|
||||
$baseAddress = $this->convertToExcelAddressValue($autofilterRange);
|
||||
$this->spreadsheet->getActiveSheet()->setAutoFilter($baseAddress);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function getAttributeValue(?DOMNode $node, string $attributeName): ?string
|
||||
{
|
||||
if ($node !== null && $node->attributes !== null) {
|
||||
$attribute = $node->attributes->getNamedItemNS(
|
||||
$this->tableNs,
|
||||
$attributeName
|
||||
);
|
||||
|
||||
if ($attribute !== null) {
|
||||
return $attribute->nodeValue;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Reader\Ods;
|
||||
|
||||
use DOMElement;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
|
||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
|
||||
abstract class BaseReader
|
||||
{
|
||||
/**
|
||||
* @var Spreadsheet
|
||||
*/
|
||||
protected $spreadsheet;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $tableNs;
|
||||
|
||||
public function __construct(Spreadsheet $spreadsheet, string $tableNs)
|
||||
{
|
||||
$this->spreadsheet = $spreadsheet;
|
||||
$this->tableNs = $tableNs;
|
||||
}
|
||||
|
||||
abstract public function read(DOMElement $workbookData): void;
|
||||
|
||||
protected function convertToExcelAddressValue(string $openOfficeAddress): string
|
||||
{
|
||||
$excelAddress = $openOfficeAddress;
|
||||
|
||||
// Cell range 3-d reference
|
||||
// As we don't support 3-d ranges, we're just going to take a quick and dirty approach
|
||||
// and assume that the second worksheet reference is the same as the first
|
||||
$excelAddress = preg_replace('/\$?([^\.]+)\.([^\.]+):\$?([^\.]+)\.([^\.]+)/miu', '$1!$2:$4', $excelAddress);
|
||||
// Cell range reference in another sheet
|
||||
$excelAddress = preg_replace('/\$?([^\.]+)\.([^\.]+):\.([^\.]+)/miu', '$1!$2:$3', $excelAddress ?? '');
|
||||
// Cell reference in another sheet
|
||||
$excelAddress = preg_replace('/\$?([^\.]+)\.([^\.]+)/miu', '$1!$2', $excelAddress ?? '');
|
||||
// Cell range reference
|
||||
$excelAddress = preg_replace('/\.([^\.]+):\.([^\.]+)/miu', '$1:$2', $excelAddress ?? '');
|
||||
// Simple cell reference
|
||||
$excelAddress = preg_replace('/\.([^\.]+)/miu', '$1', $excelAddress ?? '');
|
||||
|
||||
return $excelAddress ?? '';
|
||||
}
|
||||
|
||||
protected function convertToExcelFormulaValue(string $openOfficeFormula): string
|
||||
{
|
||||
$temp = explode('"', $openOfficeFormula);
|
||||
$tKey = false;
|
||||
foreach ($temp as &$value) {
|
||||
// @var string $value
|
||||
// Only replace in alternate array entries (i.e. non-quoted blocks)
|
||||
if ($tKey = !$tKey) {
|
||||
// Cell range reference in another sheet
|
||||
$value = preg_replace('/\[\$?([^\.]+)\.([^\.]+):\.([^\.]+)\]/miu', '$1!$2:$3', $value);
|
||||
// Cell reference in another sheet
|
||||
$value = preg_replace('/\[\$?([^\.]+)\.([^\.]+)\]/miu', '$1!$2', $value ?? '');
|
||||
// Cell range reference
|
||||
$value = preg_replace('/\[\.([^\.]+):\.([^\.]+)\]/miu', '$1:$2', $value ?? '');
|
||||
// Simple cell reference
|
||||
$value = preg_replace('/\[\.([^\.]+)\]/miu', '$1', $value ?? '');
|
||||
// Convert references to defined names/formulae
|
||||
$value = str_replace('$$', '', $value ?? '');
|
||||
|
||||
$value = Calculation::translateSeparator(';', ',', $value, $inBraces);
|
||||
}
|
||||
}
|
||||
|
||||
// Then rebuild the formula string
|
||||
$excelFormula = implode('"', $temp);
|
||||
|
||||
return $excelFormula;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Reader\Ods;
|
||||
|
||||
use DOMElement;
|
||||
use PhpOffice\PhpSpreadsheet\DefinedName;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
||||
|
||||
class DefinedNames extends BaseReader
|
||||
{
|
||||
public function read(DOMElement $workbookData): void
|
||||
{
|
||||
$this->readDefinedRanges($workbookData);
|
||||
$this->readDefinedExpressions($workbookData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read any Named Ranges that are defined in this spreadsheet.
|
||||
*/
|
||||
protected function readDefinedRanges(DOMElement $workbookData): void
|
||||
{
|
||||
$namedRanges = $workbookData->getElementsByTagNameNS($this->tableNs, 'named-range');
|
||||
foreach ($namedRanges as $definedNameElement) {
|
||||
$definedName = $definedNameElement->getAttributeNS($this->tableNs, 'name');
|
||||
$baseAddress = $definedNameElement->getAttributeNS($this->tableNs, 'base-cell-address');
|
||||
$range = $definedNameElement->getAttributeNS($this->tableNs, 'cell-range-address');
|
||||
|
||||
$baseAddress = $this->convertToExcelAddressValue($baseAddress);
|
||||
$range = $this->convertToExcelAddressValue($range);
|
||||
|
||||
$this->addDefinedName($baseAddress, $definedName, $range);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read any Named Formulae that are defined in this spreadsheet.
|
||||
*/
|
||||
protected function readDefinedExpressions(DOMElement $workbookData): void
|
||||
{
|
||||
$namedExpressions = $workbookData->getElementsByTagNameNS($this->tableNs, 'named-expression');
|
||||
foreach ($namedExpressions as $definedNameElement) {
|
||||
$definedName = $definedNameElement->getAttributeNS($this->tableNs, 'name');
|
||||
$baseAddress = $definedNameElement->getAttributeNS($this->tableNs, 'base-cell-address');
|
||||
$expression = $definedNameElement->getAttributeNS($this->tableNs, 'expression');
|
||||
|
||||
$baseAddress = $this->convertToExcelAddressValue($baseAddress);
|
||||
$expression = substr($expression, strpos($expression, ':=') + 1);
|
||||
$expression = $this->convertToExcelFormulaValue($expression);
|
||||
|
||||
$this->addDefinedName($baseAddress, $definedName, $expression);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Assess scope and store the Defined Name.
|
||||
*/
|
||||
private function addDefinedName(string $baseAddress, string $definedName, string $value): void
|
||||
{
|
||||
[$sheetReference] = Worksheet::extractSheetTitle($baseAddress, true);
|
||||
$worksheet = $this->spreadsheet->getSheetByName($sheetReference);
|
||||
// Worksheet might still be null if we're only loading selected sheets rather than the full spreadsheet
|
||||
if ($worksheet !== null) {
|
||||
$this->spreadsheet->addDefinedName(DefinedName::createInstance((string) $definedName, $worksheet, $value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -7,6 +7,7 @@ use PhpOffice\PhpSpreadsheet\Cell\DataType;
|
|||
use PhpOffice\PhpSpreadsheet\Cell\DataValidation;
|
||||
use PhpOffice\PhpSpreadsheet\Exception as PhpSpreadsheetException;
|
||||
use PhpOffice\PhpSpreadsheet\NamedRange;
|
||||
use PhpOffice\PhpSpreadsheet\Reader\Xls\Style\CellFont;
|
||||
use PhpOffice\PhpSpreadsheet\RichText\RichText;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\CodePage;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\Date;
|
||||
|
|
@ -2067,39 +2068,11 @@ class Xls extends BaseReader
|
|||
|
||||
// offset: 8; size: 2; escapement type
|
||||
$escapement = self::getUInt2d($recordData, 8);
|
||||
switch ($escapement) {
|
||||
case 0x0001:
|
||||
$objFont->setSuperscript(true);
|
||||
|
||||
break;
|
||||
case 0x0002:
|
||||
$objFont->setSubscript(true);
|
||||
|
||||
break;
|
||||
}
|
||||
CellFont::escapement($objFont, $escapement);
|
||||
|
||||
// offset: 10; size: 1; underline type
|
||||
$underlineType = ord($recordData[10]);
|
||||
switch ($underlineType) {
|
||||
case 0x00:
|
||||
break; // no underline
|
||||
case 0x01:
|
||||
$objFont->setUnderline(Font::UNDERLINE_SINGLE);
|
||||
|
||||
break;
|
||||
case 0x02:
|
||||
$objFont->setUnderline(Font::UNDERLINE_DOUBLE);
|
||||
|
||||
break;
|
||||
case 0x21:
|
||||
$objFont->setUnderline(Font::UNDERLINE_SINGLEACCOUNTING);
|
||||
|
||||
break;
|
||||
case 0x22:
|
||||
$objFont->setUnderline(Font::UNDERLINE_DOUBLEACCOUNTING);
|
||||
|
||||
break;
|
||||
}
|
||||
CellFont::underline($objFont, $underlineType);
|
||||
|
||||
// offset: 11; size: 1; font family
|
||||
// offset: 12; size: 1; character set
|
||||
|
|
@ -2219,68 +2192,15 @@ class Xls extends BaseReader
|
|||
// offset: 6; size: 1; Alignment and text break
|
||||
// bit 2-0, mask 0x07; horizontal alignment
|
||||
$horAlign = (0x07 & ord($recordData[6])) >> 0;
|
||||
switch ($horAlign) {
|
||||
case 0:
|
||||
$objStyle->getAlignment()->setHorizontal(Alignment::HORIZONTAL_GENERAL);
|
||||
Xls\Style\CellAlignment::horizontal($objStyle->getAlignment(), $horAlign);
|
||||
|
||||
break;
|
||||
case 1:
|
||||
$objStyle->getAlignment()->setHorizontal(Alignment::HORIZONTAL_LEFT);
|
||||
|
||||
break;
|
||||
case 2:
|
||||
$objStyle->getAlignment()->setHorizontal(Alignment::HORIZONTAL_CENTER);
|
||||
|
||||
break;
|
||||
case 3:
|
||||
$objStyle->getAlignment()->setHorizontal(Alignment::HORIZONTAL_RIGHT);
|
||||
|
||||
break;
|
||||
case 4:
|
||||
$objStyle->getAlignment()->setHorizontal(Alignment::HORIZONTAL_FILL);
|
||||
|
||||
break;
|
||||
case 5:
|
||||
$objStyle->getAlignment()->setHorizontal(Alignment::HORIZONTAL_JUSTIFY);
|
||||
|
||||
break;
|
||||
case 6:
|
||||
$objStyle->getAlignment()->setHorizontal(Alignment::HORIZONTAL_CENTER_CONTINUOUS);
|
||||
|
||||
break;
|
||||
}
|
||||
// bit 3, mask 0x08; wrap text
|
||||
$wrapText = (0x08 & ord($recordData[6])) >> 3;
|
||||
switch ($wrapText) {
|
||||
case 0:
|
||||
$objStyle->getAlignment()->setWrapText(false);
|
||||
Xls\Style\CellAlignment::wrap($objStyle->getAlignment(), $wrapText);
|
||||
|
||||
break;
|
||||
case 1:
|
||||
$objStyle->getAlignment()->setWrapText(true);
|
||||
|
||||
break;
|
||||
}
|
||||
// bit 6-4, mask 0x70; vertical alignment
|
||||
$vertAlign = (0x70 & ord($recordData[6])) >> 4;
|
||||
switch ($vertAlign) {
|
||||
case 0:
|
||||
$objStyle->getAlignment()->setVertical(Alignment::VERTICAL_TOP);
|
||||
|
||||
break;
|
||||
case 1:
|
||||
$objStyle->getAlignment()->setVertical(Alignment::VERTICAL_CENTER);
|
||||
|
||||
break;
|
||||
case 2:
|
||||
$objStyle->getAlignment()->setVertical(Alignment::VERTICAL_BOTTOM);
|
||||
|
||||
break;
|
||||
case 3:
|
||||
$objStyle->getAlignment()->setVertical(Alignment::VERTICAL_JUSTIFY);
|
||||
|
||||
break;
|
||||
}
|
||||
Xls\Style\CellAlignment::vertical($objStyle->getAlignment(), $vertAlign);
|
||||
|
||||
if ($this->version == self::XLS_BIFF8) {
|
||||
// offset: 7; size: 1; XF_ROTATION: Text rotation angle
|
||||
|
|
@ -3634,7 +3554,7 @@ class Xls extends BaseReader
|
|||
$level = (0x0700 & self::getUInt2d($recordData, 8)) >> 8;
|
||||
|
||||
// bit: 12; mask: 0x1000; 1 = collapsed
|
||||
$isCollapsed = (0x1000 & self::getUInt2d($recordData, 8)) >> 12;
|
||||
$isCollapsed = (bool) ((0x1000 & self::getUInt2d($recordData, 8)) >> 12);
|
||||
|
||||
// offset: 10; size: 2; not used
|
||||
|
||||
|
|
@ -3704,7 +3624,7 @@ class Xls extends BaseReader
|
|||
$this->phpSheet->getRowDimension($r + 1)->setOutlineLevel($level);
|
||||
|
||||
// bit: 4; mask: 0x00000010; 1 = outline group start or ends here... and is collapsed
|
||||
$isCollapsed = (0x00000010 & self::getInt4d($recordData, 12)) >> 4;
|
||||
$isCollapsed = (bool) ((0x00000010 & self::getInt4d($recordData, 12)) >> 4);
|
||||
$this->phpSheet->getRowDimension($r + 1)->setCollapsed($isCollapsed);
|
||||
|
||||
// bit: 5; mask: 0x00000020; 1 = row is hidden
|
||||
|
|
|
|||
|
|
@ -5,62 +5,62 @@ namespace PhpOffice\PhpSpreadsheet\Reader\Xls\Color;
|
|||
class BIFF8
|
||||
{
|
||||
protected static $map = [
|
||||
0x08 => '000000',
|
||||
0x09 => 'FFFFFF',
|
||||
0x0A => 'FF0000',
|
||||
0x0B => '00FF00',
|
||||
0x0C => '0000FF',
|
||||
0x0D => 'FFFF00',
|
||||
0x0E => 'FF00FF',
|
||||
0x0F => '00FFFF',
|
||||
0x10 => '800000',
|
||||
0x11 => '008000',
|
||||
0x12 => '000080',
|
||||
0x13 => '808000',
|
||||
0x14 => '800080',
|
||||
0x15 => '008080',
|
||||
0x16 => 'C0C0C0',
|
||||
0x17 => '808080',
|
||||
0x18 => '9999FF',
|
||||
0x19 => '993366',
|
||||
0x1A => 'FFFFCC',
|
||||
0x1B => 'CCFFFF',
|
||||
0x1C => '660066',
|
||||
0x1D => 'FF8080',
|
||||
0x1E => '0066CC',
|
||||
0x1F => 'CCCCFF',
|
||||
0x20 => '000080',
|
||||
0x21 => 'FF00FF',
|
||||
0x22 => 'FFFF00',
|
||||
0x23 => '00FFFF',
|
||||
0x24 => '800080',
|
||||
0x25 => '800000',
|
||||
0x26 => '008080',
|
||||
0x27 => '0000FF',
|
||||
0x28 => '00CCFF',
|
||||
0x29 => 'CCFFFF',
|
||||
0x2A => 'CCFFCC',
|
||||
0x2B => 'FFFF99',
|
||||
0x2C => '99CCFF',
|
||||
0x2D => 'FF99CC',
|
||||
0x2E => 'CC99FF',
|
||||
0x2F => 'FFCC99',
|
||||
0x30 => '3366FF',
|
||||
0x31 => '33CCCC',
|
||||
0x32 => '99CC00',
|
||||
0x33 => 'FFCC00',
|
||||
0x34 => 'FF9900',
|
||||
0x35 => 'FF6600',
|
||||
0x36 => '666699',
|
||||
0x37 => '969696',
|
||||
0x38 => '003366',
|
||||
0x39 => '339966',
|
||||
0x3A => '003300',
|
||||
0x3B => '333300',
|
||||
0x3C => '993300',
|
||||
0x3D => '993366',
|
||||
0x3E => '333399',
|
||||
0x3F => '333333',
|
||||
'000000' => 0x08,
|
||||
'FFFFFF' => 0x09,
|
||||
'FF0000' => 0x0A,
|
||||
'00FF00' => 0x0B,
|
||||
'0000FF' => 0x0C,
|
||||
'FFFF00' => 0x0D,
|
||||
'FF00FF' => 0x0E,
|
||||
'00FFFF' => 0x0F,
|
||||
'800000' => 0x10,
|
||||
'008000' => 0x11,
|
||||
'000080' => 0x12,
|
||||
'808000' => 0x13,
|
||||
'800080' => 0x14,
|
||||
'008080' => 0x15,
|
||||
'C0C0C0' => 0x16,
|
||||
'808080' => 0x17,
|
||||
'9999FF' => 0x18,
|
||||
'993366' => 0x19,
|
||||
'FFFFCC' => 0x1A,
|
||||
'CCFFFF' => 0x1B,
|
||||
'660066' => 0x1C,
|
||||
'FF8080' => 0x1D,
|
||||
'0066CC' => 0x1E,
|
||||
'CCCCFF' => 0x1F,
|
||||
// '000080' => 0x20,
|
||||
// 'FF00FF' => 0x21,
|
||||
// 'FFFF00' => 0x22,
|
||||
// '00FFFF' => 0x23,
|
||||
// '800080' => 0x24,
|
||||
// '800000' => 0x25,
|
||||
// '008080' => 0x26,
|
||||
// '0000FF' => 0x27,
|
||||
'00CCFF' => 0x28,
|
||||
// 'CCFFFF' => 0x29,
|
||||
'CCFFCC' => 0x2A,
|
||||
'FFFF99' => 0x2B,
|
||||
'99CCFF' => 0x2C,
|
||||
'FF99CC' => 0x2D,
|
||||
'CC99FF' => 0x2E,
|
||||
'FFCC99' => 0x2F,
|
||||
'3366FF' => 0x30,
|
||||
'33CCCC' => 0x31,
|
||||
'99CC00' => 0x32,
|
||||
'FFCC00' => 0x33,
|
||||
'FF9900' => 0x34,
|
||||
'FF6600' => 0x35,
|
||||
'666699' => 0x36,
|
||||
'969696' => 0x37,
|
||||
'003366' => 0x38,
|
||||
'339966' => 0x39,
|
||||
'003300' => 0x3A,
|
||||
'333300' => 0x3B,
|
||||
'993300' => 0x3C,
|
||||
// '993366' => 0x3D,
|
||||
'333399' => 0x3E,
|
||||
'333333' => 0x3F,
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -6,7 +6,10 @@ use PhpOffice\PhpSpreadsheet\Style\Border as StyleBorder;
|
|||
|
||||
class Border
|
||||
{
|
||||
protected static $map = [
|
||||
/**
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected static $borderStyleMap = [
|
||||
0x00 => StyleBorder::BORDER_NONE,
|
||||
0x01 => StyleBorder::BORDER_THIN,
|
||||
0x02 => StyleBorder::BORDER_MEDIUM,
|
||||
|
|
@ -23,18 +26,10 @@ class Border
|
|||
0x0D => StyleBorder::BORDER_SLANTDASHDOT,
|
||||
];
|
||||
|
||||
/**
|
||||
* Map border style
|
||||
* OpenOffice documentation: 2.5.11.
|
||||
*
|
||||
* @param int $index
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function lookup($index)
|
||||
public static function lookup(int $index): string
|
||||
{
|
||||
if (isset(self::$map[$index])) {
|
||||
return self::$map[$index];
|
||||
if (isset(self::$borderStyleMap[$index])) {
|
||||
return self::$borderStyleMap[$index];
|
||||
}
|
||||
|
||||
return StyleBorder::BORDER_NONE;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Reader\Xls\Style;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Style\Alignment;
|
||||
|
||||
class CellAlignment
|
||||
{
|
||||
/**
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected static $horizontalAlignmentMap = [
|
||||
0 => Alignment::HORIZONTAL_GENERAL,
|
||||
1 => Alignment::HORIZONTAL_LEFT,
|
||||
2 => Alignment::HORIZONTAL_CENTER,
|
||||
3 => Alignment::HORIZONTAL_RIGHT,
|
||||
4 => Alignment::HORIZONTAL_FILL,
|
||||
5 => Alignment::HORIZONTAL_JUSTIFY,
|
||||
6 => Alignment::HORIZONTAL_CENTER_CONTINUOUS,
|
||||
];
|
||||
|
||||
/**
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected static $verticalAlignmentMap = [
|
||||
0 => Alignment::VERTICAL_TOP,
|
||||
1 => Alignment::VERTICAL_CENTER,
|
||||
2 => Alignment::VERTICAL_BOTTOM,
|
||||
3 => Alignment::VERTICAL_JUSTIFY,
|
||||
];
|
||||
|
||||
public static function horizontal(Alignment $alignment, int $horizontal): void
|
||||
{
|
||||
if (array_key_exists($horizontal, self::$horizontalAlignmentMap)) {
|
||||
$alignment->setHorizontal(self::$horizontalAlignmentMap[$horizontal]);
|
||||
}
|
||||
}
|
||||
|
||||
public static function vertical(Alignment $alignment, int $vertical): void
|
||||
{
|
||||
if (array_key_exists($vertical, self::$verticalAlignmentMap)) {
|
||||
$alignment->setVertical(self::$verticalAlignmentMap[$vertical]);
|
||||
}
|
||||
}
|
||||
|
||||
public static function wrap(Alignment $alignment, int $wrap): void
|
||||
{
|
||||
$alignment->setWrapText((bool) $wrap);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Reader\Xls\Style;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Style\Font;
|
||||
|
||||
class CellFont
|
||||
{
|
||||
public static function escapement(Font $font, int $escapement): void
|
||||
{
|
||||
switch ($escapement) {
|
||||
case 0x0001:
|
||||
$font->setSuperscript(true);
|
||||
|
||||
break;
|
||||
case 0x0002:
|
||||
$font->setSubscript(true);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected static $underlineMap = [
|
||||
0x01 => Font::UNDERLINE_SINGLE,
|
||||
0x02 => Font::UNDERLINE_DOUBLE,
|
||||
0x21 => Font::UNDERLINE_SINGLEACCOUNTING,
|
||||
0x22 => Font::UNDERLINE_DOUBLEACCOUNTING,
|
||||
];
|
||||
|
||||
public static function underline(Font $font, int $underline): void
|
||||
{
|
||||
if (array_key_exists($underline, self::$underlineMap)) {
|
||||
$font->setUnderline(self::$underlineMap[$underline]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6,7 +6,10 @@ use PhpOffice\PhpSpreadsheet\Style\Fill;
|
|||
|
||||
class FillPattern
|
||||
{
|
||||
protected static $map = [
|
||||
/**
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected static $fillPatternMap = [
|
||||
0x00 => Fill::FILL_NONE,
|
||||
0x01 => Fill::FILL_SOLID,
|
||||
0x02 => Fill::FILL_PATTERN_MEDIUMGRAY,
|
||||
|
|
@ -38,8 +41,8 @@ class FillPattern
|
|||
*/
|
||||
public static function lookup($index)
|
||||
{
|
||||
if (isset(self::$map[$index])) {
|
||||
return self::$map[$index];
|
||||
if (isset(self::$fillPatternMap[$index])) {
|
||||
return self::$fillPatternMap[$index];
|
||||
}
|
||||
|
||||
return Fill::FILL_NONE;
|
||||
|
|
|
|||
|
|
@ -27,12 +27,8 @@ use PhpOffice\PhpSpreadsheet\Shared\File;
|
|||
use PhpOffice\PhpSpreadsheet\Shared\Font;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\StringHelper;
|
||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
use PhpOffice\PhpSpreadsheet\Style\Border;
|
||||
use PhpOffice\PhpSpreadsheet\Style\Borders;
|
||||
use PhpOffice\PhpSpreadsheet\Style\Color;
|
||||
use PhpOffice\PhpSpreadsheet\Style\Fill;
|
||||
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
|
||||
use PhpOffice\PhpSpreadsheet\Style\Protection;
|
||||
use PhpOffice\PhpSpreadsheet\Style\Style;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\HeaderFooterDrawing;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
||||
|
|
@ -634,6 +630,12 @@ class Xlsx extends BaseReader
|
|||
}
|
||||
|
||||
if ($xmlSheet) {
|
||||
// Setting Conditional Styles adjusts selected cells, so we need to execute this
|
||||
// before reading the sheet view data to get the actual selected cells
|
||||
if (!$this->readDataOnly && $xmlSheet->conditionalFormatting) {
|
||||
(new ConditionalStyles($docSheet, $xmlSheet, $dxfs))->load();
|
||||
}
|
||||
|
||||
if (isset($xmlSheet->sheetViews, $xmlSheet->sheetViews->sheetView)) {
|
||||
$sheetViews = new SheetViews($xmlSheet->sheetViews->sheetView, $docSheet);
|
||||
$sheetViews->load();
|
||||
|
|
@ -767,10 +769,6 @@ class Xlsx extends BaseReader
|
|||
}
|
||||
}
|
||||
|
||||
if (!$this->readDataOnly && $xmlSheet && $xmlSheet->conditionalFormatting) {
|
||||
(new ConditionalStyles($docSheet, $xmlSheet, $dxfs))->load();
|
||||
}
|
||||
|
||||
$aKeys = ['sheet', 'objects', 'scenarios', 'formatCells', 'formatColumns', 'formatRows', 'insertColumns', 'insertRows', 'insertHyperlinks', 'deleteColumns', 'deleteRows', 'selectLockedCells', 'sort', 'autoFilter', 'pivotTables', 'selectUnlockedCells'];
|
||||
if (!$this->readDataOnly && $xmlSheet && $xmlSheet->sheetProtection) {
|
||||
foreach ($aKeys as $key) {
|
||||
|
|
@ -1570,31 +1568,6 @@ class Xlsx extends BaseReader
|
|||
return $excel;
|
||||
}
|
||||
|
||||
private static function readColor($color, $background = false)
|
||||
{
|
||||
if (isset($color['rgb'])) {
|
||||
return (string) $color['rgb'];
|
||||
} elseif (isset($color['indexed'])) {
|
||||
return Color::indexedColor($color['indexed'] - 7, $background)->getARGB();
|
||||
} elseif (isset($color['theme'])) {
|
||||
if (self::$theme !== null) {
|
||||
$returnColour = self::$theme->getColourByIndex((int) $color['theme']);
|
||||
if (isset($color['tint'])) {
|
||||
$tintAdjust = (float) $color['tint'];
|
||||
$returnColour = Color::changeBrightness($returnColour, $tintAdjust);
|
||||
}
|
||||
|
||||
return 'FF' . $returnColour;
|
||||
}
|
||||
}
|
||||
|
||||
if ($background) {
|
||||
return 'FFFFFFFF';
|
||||
}
|
||||
|
||||
return 'FF000000';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param SimpleXMLElement|stdClass $style
|
||||
*/
|
||||
|
|
@ -1604,134 +1577,33 @@ class Xlsx extends BaseReader
|
|||
|
||||
// font
|
||||
if (isset($style->font)) {
|
||||
$docStyle->getFont()->setName((string) $style->font->name['val']);
|
||||
$docStyle->getFont()->setSize((string) $style->font->sz['val']);
|
||||
if (isset($style->font->b)) {
|
||||
$docStyle->getFont()->setBold(!isset($style->font->b['val']) || self::boolean((string) $style->font->b['val']));
|
||||
}
|
||||
if (isset($style->font->i)) {
|
||||
$docStyle->getFont()->setItalic(!isset($style->font->i['val']) || self::boolean((string) $style->font->i['val']));
|
||||
}
|
||||
if (isset($style->font->strike)) {
|
||||
$docStyle->getFont()->setStrikethrough(!isset($style->font->strike['val']) || self::boolean((string) $style->font->strike['val']));
|
||||
}
|
||||
$docStyle->getFont()->getColor()->setARGB(self::readColor($style->font->color));
|
||||
|
||||
if (isset($style->font->u) && !isset($style->font->u['val'])) {
|
||||
$docStyle->getFont()->setUnderline(\PhpOffice\PhpSpreadsheet\Style\Font::UNDERLINE_SINGLE);
|
||||
} elseif (isset($style->font->u, $style->font->u['val'])) {
|
||||
$docStyle->getFont()->setUnderline((string) $style->font->u['val']);
|
||||
}
|
||||
|
||||
if (isset($style->font->vertAlign, $style->font->vertAlign['val'])) {
|
||||
$vertAlign = strtolower((string) $style->font->vertAlign['val']);
|
||||
if ($vertAlign == 'superscript') {
|
||||
$docStyle->getFont()->setSuperscript(true);
|
||||
}
|
||||
if ($vertAlign == 'subscript') {
|
||||
$docStyle->getFont()->setSubscript(true);
|
||||
}
|
||||
}
|
||||
Styles::readFontStyle($docStyle->getFont(), $style->font);
|
||||
}
|
||||
|
||||
// fill
|
||||
if (isset($style->fill)) {
|
||||
if ($style->fill->gradientFill) {
|
||||
/** @var SimpleXMLElement $gradientFill */
|
||||
$gradientFill = $style->fill->gradientFill[0];
|
||||
if (!empty($gradientFill['type'])) {
|
||||
$docStyle->getFill()->setFillType((string) $gradientFill['type']);
|
||||
}
|
||||
$docStyle->getFill()->setRotation((float) ($gradientFill['degree']));
|
||||
$gradientFill->registerXPathNamespace('sml', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main');
|
||||
$docStyle->getFill()->getStartColor()->setARGB(self::readColor(self::getArrayItem($gradientFill->xpath('sml:stop[@position=0]'))->color));
|
||||
$docStyle->getFill()->getEndColor()->setARGB(self::readColor(self::getArrayItem($gradientFill->xpath('sml:stop[@position=1]'))->color));
|
||||
} elseif ($style->fill->patternFill) {
|
||||
$patternType = (string) $style->fill->patternFill['patternType'] != '' ? (string) $style->fill->patternFill['patternType'] : Fill::FILL_NONE;
|
||||
$docStyle->getFill()->setFillType($patternType);
|
||||
if ($style->fill->patternFill->fgColor) {
|
||||
$docStyle->getFill()->getStartColor()->setARGB(self::readColor($style->fill->patternFill->fgColor, true));
|
||||
}
|
||||
if ($style->fill->patternFill->bgColor) {
|
||||
$docStyle->getFill()->getEndColor()->setARGB(self::readColor($style->fill->patternFill->bgColor, true));
|
||||
}
|
||||
}
|
||||
Styles::readFillStyle($docStyle->getFill(), $style->fill);
|
||||
}
|
||||
|
||||
// border
|
||||
if (isset($style->border)) {
|
||||
$diagonalUp = self::boolean((string) $style->border['diagonalUp']);
|
||||
$diagonalDown = self::boolean((string) $style->border['diagonalDown']);
|
||||
if (!$diagonalUp && !$diagonalDown) {
|
||||
$docStyle->getBorders()->setDiagonalDirection(Borders::DIAGONAL_NONE);
|
||||
} elseif ($diagonalUp && !$diagonalDown) {
|
||||
$docStyle->getBorders()->setDiagonalDirection(Borders::DIAGONAL_UP);
|
||||
} elseif (!$diagonalUp && $diagonalDown) {
|
||||
$docStyle->getBorders()->setDiagonalDirection(Borders::DIAGONAL_DOWN);
|
||||
} else {
|
||||
$docStyle->getBorders()->setDiagonalDirection(Borders::DIAGONAL_BOTH);
|
||||
}
|
||||
self::readBorder($docStyle->getBorders()->getLeft(), $style->border->left);
|
||||
self::readBorder($docStyle->getBorders()->getRight(), $style->border->right);
|
||||
self::readBorder($docStyle->getBorders()->getTop(), $style->border->top);
|
||||
self::readBorder($docStyle->getBorders()->getBottom(), $style->border->bottom);
|
||||
self::readBorder($docStyle->getBorders()->getDiagonal(), $style->border->diagonal);
|
||||
Styles::readBorderStyle($docStyle->getBorders(), $style->border);
|
||||
}
|
||||
|
||||
// alignment
|
||||
if (isset($style->alignment)) {
|
||||
$docStyle->getAlignment()->setHorizontal((string) $style->alignment['horizontal']);
|
||||
$docStyle->getAlignment()->setVertical((string) $style->alignment['vertical']);
|
||||
|
||||
$textRotation = 0;
|
||||
if ((int) $style->alignment['textRotation'] <= 90) {
|
||||
$textRotation = (int) $style->alignment['textRotation'];
|
||||
} elseif ((int) $style->alignment['textRotation'] > 90) {
|
||||
$textRotation = 90 - (int) $style->alignment['textRotation'];
|
||||
}
|
||||
|
||||
$docStyle->getAlignment()->setTextRotation((int) $textRotation);
|
||||
$docStyle->getAlignment()->setWrapText(self::boolean((string) $style->alignment['wrapText']));
|
||||
$docStyle->getAlignment()->setShrinkToFit(self::boolean((string) $style->alignment['shrinkToFit']));
|
||||
$docStyle->getAlignment()->setIndent((int) ((string) $style->alignment['indent']) > 0 ? (int) ((string) $style->alignment['indent']) : 0);
|
||||
$docStyle->getAlignment()->setReadOrder((int) ((string) $style->alignment['readingOrder']) > 0 ? (int) ((string) $style->alignment['readingOrder']) : 0);
|
||||
Styles::readAlignmentStyle($docStyle->getAlignment(), $style->alignment);
|
||||
}
|
||||
|
||||
// protection
|
||||
if (isset($style->protection)) {
|
||||
if (isset($style->protection['locked'])) {
|
||||
if (self::boolean((string) $style->protection['locked'])) {
|
||||
$docStyle->getProtection()->setLocked(Protection::PROTECTION_PROTECTED);
|
||||
} else {
|
||||
$docStyle->getProtection()->setLocked(Protection::PROTECTION_UNPROTECTED);
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($style->protection['hidden'])) {
|
||||
if (self::boolean((string) $style->protection['hidden'])) {
|
||||
$docStyle->getProtection()->setHidden(Protection::PROTECTION_PROTECTED);
|
||||
} else {
|
||||
$docStyle->getProtection()->setHidden(Protection::PROTECTION_UNPROTECTED);
|
||||
}
|
||||
}
|
||||
Styles::readProtectionLocked($docStyle, $style->protection);
|
||||
Styles::readProtectionHidden($docStyle, $style->protection);
|
||||
}
|
||||
|
||||
// top-level style settings
|
||||
if (isset($style->quotePrefix)) {
|
||||
$docStyle->setQuotePrefix($style->quotePrefix);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param SimpleXMLElement $eleBorder
|
||||
*/
|
||||
private static function readBorder(Border $docBorder, $eleBorder): void
|
||||
{
|
||||
if (isset($eleBorder['style'])) {
|
||||
$docBorder->setBorderStyle((string) $eleBorder['style']);
|
||||
}
|
||||
if (isset($eleBorder->color)) {
|
||||
$docBorder->getColor()->setARGB(self::readColor($eleBorder->color));
|
||||
$docStyle->setQuotePrefix((bool) $style->quotePrefix);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1763,7 +1635,7 @@ class Xlsx extends BaseReader
|
|||
$objText->getFont()->setSize((float) $run->rPr->sz['val']);
|
||||
}
|
||||
if (isset($run->rPr->color)) {
|
||||
$objText->getFont()->setColor(new Color(self::readColor($run->rPr->color)));
|
||||
$objText->getFont()->setColor(new Color(Styles::readColor($run->rPr->color)));
|
||||
}
|
||||
if (
|
||||
(isset($run->rPr->b['val']) && self::boolean((string) $run->rPr->b['val'])) ||
|
||||
|
|
@ -1949,11 +1821,17 @@ class Xlsx extends BaseReader
|
|||
}
|
||||
|
||||
if ($xmlWorkbook->workbookProtection['revisionsPassword']) {
|
||||
$excel->getSecurity()->setRevisionsPassword((string) $xmlWorkbook->workbookProtection['revisionsPassword'], true);
|
||||
$excel->getSecurity()->setRevisionsPassword(
|
||||
(string) $xmlWorkbook->workbookProtection['revisionsPassword'],
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
if ($xmlWorkbook->workbookProtection['workbookPassword']) {
|
||||
$excel->getSecurity()->setWorkbookPassword((string) $xmlWorkbook->workbookProtection['workbookPassword'], true);
|
||||
$excel->getSecurity()->setWorkbookPassword(
|
||||
(string) $xmlWorkbook->workbookProtection['workbookPassword'],
|
||||
true
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
namespace PhpOffice\PhpSpreadsheet\Reader\Xlsx;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Style\Color;
|
||||
use PhpOffice\PhpSpreadsheet\Style\Conditional;
|
||||
use PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\ConditionalDataBar;
|
||||
use PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\ConditionalFormattingRuleExtension;
|
||||
|
|
@ -39,15 +38,7 @@ class ConditionalStyles
|
|||
$conditionals = [];
|
||||
foreach ($xmlSheet->conditionalFormatting as $conditional) {
|
||||
foreach ($conditional->cfRule as $cfRule) {
|
||||
if (
|
||||
((string) $cfRule['type'] == Conditional::CONDITION_NONE
|
||||
|| (string) $cfRule['type'] == Conditional::CONDITION_CELLIS
|
||||
|| (string) $cfRule['type'] == Conditional::CONDITION_CONTAINSTEXT
|
||||
|| (string) $cfRule['type'] == Conditional::CONDITION_CONTAINSBLANKS
|
||||
|| (string) $cfRule['type'] == Conditional::CONDITION_NOTCONTAINSBLANKS
|
||||
|| (string) $cfRule['type'] == Conditional::CONDITION_EXPRESSION)
|
||||
&& isset($this->dxfs[(int) ($cfRule['dxfId'])])
|
||||
) {
|
||||
if (Conditional::isValidConditionType((string) $cfRule['type']) && isset($this->dxfs[(int) ($cfRule['dxfId'])])) {
|
||||
$conditionals[(string) $conditional['sqref']][(int) ($cfRule['priority'])] = $cfRule;
|
||||
} elseif ((string) $cfRule['type'] == Conditional::CONDITION_DATABAR) {
|
||||
$conditionals[(string) $conditional['sqref']][(int) ($cfRule['priority'])] = $cfRule;
|
||||
|
|
@ -98,7 +89,9 @@ class ConditionalStyles
|
|||
}
|
||||
|
||||
if (isset($cfRule->dataBar)) {
|
||||
$objConditional->setDataBar($this->readDataBarOfConditionalRule($cfRule, $conditionalFormattingRuleExtensions));
|
||||
$objConditional->setDataBar(
|
||||
$this->readDataBarOfConditionalRule($cfRule, $conditionalFormattingRuleExtensions)
|
||||
);
|
||||
} else {
|
||||
$objConditional->setStyle(clone $this->dxfs[(int) ($cfRule['dxfId'])]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,11 +40,14 @@ class Styles extends BaseParserClass
|
|||
$this->cellStyles = $cellStyles;
|
||||
}
|
||||
|
||||
private static function readFontStyle(Font $fontStyle, SimpleXMLElement $fontStyleXml): void
|
||||
public static function readFontStyle(Font $fontStyle, SimpleXMLElement $fontStyleXml): void
|
||||
{
|
||||
$fontStyle->setName((string) $fontStyleXml->name['val']);
|
||||
$fontStyle->setSize((float) $fontStyleXml->sz['val']);
|
||||
|
||||
if (isset($fontStyleXml->name, $fontStyleXml->name['val'])) {
|
||||
$fontStyle->setName((string) $fontStyleXml->name['val']);
|
||||
}
|
||||
if (isset($fontStyleXml->sz, $fontStyleXml->sz['val'])) {
|
||||
$fontStyle->setSize((float) $fontStyleXml->sz['val']);
|
||||
}
|
||||
if (isset($fontStyleXml->b)) {
|
||||
$fontStyle->setBold(!isset($fontStyleXml->b['val']) || self::boolean((string) $fontStyleXml->b['val']));
|
||||
}
|
||||
|
|
@ -52,7 +55,9 @@ class Styles extends BaseParserClass
|
|||
$fontStyle->setItalic(!isset($fontStyleXml->i['val']) || self::boolean((string) $fontStyleXml->i['val']));
|
||||
}
|
||||
if (isset($fontStyleXml->strike)) {
|
||||
$fontStyle->setStrikethrough(!isset($fontStyleXml->strike['val']) || self::boolean((string) $fontStyleXml->strike['val']));
|
||||
$fontStyle->setStrikethrough(
|
||||
!isset($fontStyleXml->strike['val']) || self::boolean((string) $fontStyleXml->strike['val'])
|
||||
);
|
||||
}
|
||||
$fontStyle->getColor()->setARGB(self::readColor($fontStyleXml->color));
|
||||
|
||||
|
|
@ -66,8 +71,7 @@ class Styles extends BaseParserClass
|
|||
$verticalAlign = strtolower((string) $fontStyleXml->vertAlign['val']);
|
||||
if ($verticalAlign === 'superscript') {
|
||||
$fontStyle->setSuperscript(true);
|
||||
}
|
||||
if ($verticalAlign === 'subscript') {
|
||||
} elseif ($verticalAlign === 'subscript') {
|
||||
$fontStyle->setSubscript(true);
|
||||
}
|
||||
}
|
||||
|
|
@ -84,7 +88,7 @@ class Styles extends BaseParserClass
|
|||
}
|
||||
}
|
||||
|
||||
private static function readFillStyle(Fill $fillStyle, SimpleXMLElement $fillStyleXml): void
|
||||
public static function readFillStyle(Fill $fillStyle, SimpleXMLElement $fillStyleXml): void
|
||||
{
|
||||
if ($fillStyleXml->gradientFill) {
|
||||
/** @var SimpleXMLElement $gradientFill */
|
||||
|
|
@ -94,23 +98,32 @@ class Styles extends BaseParserClass
|
|||
}
|
||||
$fillStyle->setRotation((float) ($gradientFill['degree']));
|
||||
$gradientFill->registerXPathNamespace('sml', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main');
|
||||
$fillStyle->getStartColor()->setARGB(self::readColor(self::getArrayItem($gradientFill->xpath('sml:stop[@position=0]'))->color));
|
||||
$fillStyle->getEndColor()->setARGB(self::readColor(self::getArrayItem($gradientFill->xpath('sml:stop[@position=1]'))->color));
|
||||
$fillStyle->getStartColor()->setARGB(
|
||||
self::readColor(self::getArrayItem($gradientFill->xpath('sml:stop[@position=0]'))->color)
|
||||
);
|
||||
$fillStyle->getEndColor()->setARGB(
|
||||
self::readColor(self::getArrayItem($gradientFill->xpath('sml:stop[@position=1]'))->color)
|
||||
);
|
||||
} elseif ($fillStyleXml->patternFill) {
|
||||
$patternType = (string) $fillStyleXml->patternFill['patternType'] != '' ? (string) $fillStyleXml->patternFill['patternType'] : Fill::FILL_NONE;
|
||||
$fillStyle->setFillType($patternType);
|
||||
$defaultFillStyle = Fill::FILL_NONE;
|
||||
if ($fillStyleXml->patternFill->fgColor) {
|
||||
$fillStyle->getStartColor()->setARGB(self::readColor($fillStyleXml->patternFill->fgColor, true));
|
||||
} else {
|
||||
$fillStyle->getStartColor()->setARGB('FF000000');
|
||||
$defaultFillStyle = Fill::FILL_SOLID;
|
||||
}
|
||||
if ($fillStyleXml->patternFill->bgColor) {
|
||||
$fillStyle->getEndColor()->setARGB(self::readColor($fillStyleXml->patternFill->bgColor, true));
|
||||
$defaultFillStyle = Fill::FILL_SOLID;
|
||||
}
|
||||
|
||||
$patternType = (string) $fillStyleXml->patternFill['patternType'] != ''
|
||||
? (string) $fillStyleXml->patternFill['patternType']
|
||||
: $defaultFillStyle;
|
||||
|
||||
$fillStyle->setFillType($patternType);
|
||||
}
|
||||
}
|
||||
|
||||
private static function readBorderStyle(Borders $borderStyle, SimpleXMLElement $borderStyleXml): void
|
||||
public static function readBorderStyle(Borders $borderStyle, SimpleXMLElement $borderStyleXml): void
|
||||
{
|
||||
$diagonalUp = self::boolean((string) $borderStyleXml['diagonalUp']);
|
||||
$diagonalDown = self::boolean((string) $borderStyleXml['diagonalDown']);
|
||||
|
|
@ -141,7 +154,7 @@ class Styles extends BaseParserClass
|
|||
}
|
||||
}
|
||||
|
||||
private static function readAlignmentStyle(Alignment $alignment, SimpleXMLElement $alignmentXml): void
|
||||
public static function readAlignmentStyle(Alignment $alignment, SimpleXMLElement $alignmentXml): void
|
||||
{
|
||||
$alignment->setHorizontal((string) $alignmentXml['horizontal']);
|
||||
$alignment->setVertical((string) $alignmentXml['vertical']);
|
||||
|
|
@ -156,8 +169,12 @@ class Styles extends BaseParserClass
|
|||
$alignment->setTextRotation((int) $textRotation);
|
||||
$alignment->setWrapText(self::boolean((string) $alignmentXml['wrapText']));
|
||||
$alignment->setShrinkToFit(self::boolean((string) $alignmentXml['shrinkToFit']));
|
||||
$alignment->setIndent((int) ((string) $alignmentXml['indent']) > 0 ? (int) ((string) $alignmentXml['indent']) : 0);
|
||||
$alignment->setReadOrder((int) ((string) $alignmentXml['readingOrder']) > 0 ? (int) ((string) $alignmentXml['readingOrder']) : 0);
|
||||
$alignment->setIndent(
|
||||
(int) ((string) $alignmentXml['indent']) > 0 ? (int) ((string) $alignmentXml['indent']) : 0
|
||||
);
|
||||
$alignment->setReadOrder(
|
||||
(int) ((string) $alignmentXml['readingOrder']) > 0 ? (int) ((string) $alignmentXml['readingOrder']) : 0
|
||||
);
|
||||
}
|
||||
|
||||
private function readStyle(Style $docStyle, $style): void
|
||||
|
|
@ -186,8 +203,8 @@ class Styles extends BaseParserClass
|
|||
|
||||
// protection
|
||||
if (isset($style->protection)) {
|
||||
$this->readProtectionLocked($docStyle, $style);
|
||||
$this->readProtectionHidden($docStyle, $style);
|
||||
self::readProtectionLocked($docStyle, $style);
|
||||
self::readProtectionHidden($docStyle, $style);
|
||||
}
|
||||
|
||||
// top-level style settings
|
||||
|
|
@ -196,7 +213,7 @@ class Styles extends BaseParserClass
|
|||
}
|
||||
}
|
||||
|
||||
private function readProtectionLocked(Style $docStyle, $style): void
|
||||
public static function readProtectionLocked(Style $docStyle, $style): void
|
||||
{
|
||||
if (isset($style->protection['locked'])) {
|
||||
if (self::boolean((string) $style->protection['locked'])) {
|
||||
|
|
@ -207,7 +224,7 @@ class Styles extends BaseParserClass
|
|||
}
|
||||
}
|
||||
|
||||
private function readProtectionHidden(Style $docStyle, $style): void
|
||||
public static function readProtectionHidden(Style $docStyle, $style): void
|
||||
{
|
||||
if (isset($style->protection['hidden'])) {
|
||||
if (self::boolean((string) $style->protection['hidden'])) {
|
||||
|
|
@ -218,7 +235,7 @@ class Styles extends BaseParserClass
|
|||
}
|
||||
}
|
||||
|
||||
private static function readColor($color, $background = false)
|
||||
public static function readColor($color, $background = false)
|
||||
{
|
||||
if (isset($color['rgb'])) {
|
||||
return (string) $color['rgb'];
|
||||
|
|
|
|||
|
|
@ -284,7 +284,7 @@ class Xml extends BaseReader
|
|||
$worksheet_ss = self::getAttributes($worksheet, $namespaces['ss']);
|
||||
|
||||
if (
|
||||
(isset($this->loadSheetsOnly)) && (isset($worksheet_ss['Name'])) &&
|
||||
isset($this->loadSheetsOnly, $worksheet_ss['Name']) &&
|
||||
(!in_array($worksheet_ss['Name'], $this->loadSheetsOnly))
|
||||
) {
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -437,14 +437,14 @@ class Date
|
|||
return false;
|
||||
}
|
||||
|
||||
$dateValueNew = DateTimeExcel\DateValue::funcDateValue($dateValue);
|
||||
$dateValueNew = DateTimeExcel\DateValue::fromString($dateValue);
|
||||
|
||||
if ($dateValueNew === Functions::VALUE()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (strpos($dateValue, ':') !== false) {
|
||||
$timeValue = DateTimeExcel\TimeValue::funcTimeValue($dateValue);
|
||||
$timeValue = DateTimeExcel\TimeValue::fromString($dateValue);
|
||||
if ($timeValue === Functions::VALUE()) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,18 @@ class Conditional implements IComparable
|
|||
const CONDITION_CONTAINSBLANKS = 'containsBlanks';
|
||||
const CONDITION_NOTCONTAINSBLANKS = 'notContainsBlanks';
|
||||
const CONDITION_DATABAR = 'dataBar';
|
||||
const CONDITION_NOTCONTAINSTEXT = 'notContainsText';
|
||||
|
||||
private const CONDITION_TYPES = [
|
||||
self::CONDITION_CELLIS,
|
||||
self::CONDITION_CONTAINSBLANKS,
|
||||
self::CONDITION_CONTAINSTEXT,
|
||||
self::CONDITION_DATABAR,
|
||||
self::CONDITION_EXPRESSION,
|
||||
self::CONDITION_NONE,
|
||||
self::CONDITION_NOTCONTAINSBLANKS,
|
||||
self::CONDITION_NOTCONTAINSTEXT,
|
||||
];
|
||||
|
||||
// Operator types
|
||||
const OPERATOR_NONE = '';
|
||||
|
|
@ -300,4 +312,12 @@ class Conditional implements IComparable
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify if param is valid condition type.
|
||||
*/
|
||||
public static function isValidConditionType(string $type): bool
|
||||
{
|
||||
return in_array($type, self::CONDITION_TYPES);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Style\Conditional;
|
||||
use SimpleXMLElement;
|
||||
|
||||
class ConditionalFormattingRuleExtension
|
||||
|
|
@ -62,19 +63,23 @@ class ConditionalFormattingRuleExtension
|
|||
$conditionalFormattingRuleExtensionXml = $extLst->ext;
|
||||
}
|
||||
}
|
||||
|
||||
if ($conditionalFormattingRuleExtensionXml) {
|
||||
$ns = $conditionalFormattingRuleExtensionXml->getNamespaces(true);
|
||||
$extFormattingsXml = $conditionalFormattingRuleExtensionXml->children($ns['x14']);
|
||||
|
||||
foreach ($extFormattingsXml->children($ns['x14']) as $extFormattingXml) {
|
||||
$extCfRuleXml = $extFormattingXml->cfRule;
|
||||
if (((string) $extCfRuleXml->attributes()->type) !== Conditional::CONDITION_DATABAR) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$extFormattingRuleObj = new self((string) $extCfRuleXml->attributes()->id);
|
||||
$extFormattingRuleObj->setSqref((string) $extFormattingXml->children($ns['xm'])->sqref);
|
||||
$conditionalFormattingRuleExtensions[$extFormattingRuleObj->getId()] = $extFormattingRuleObj;
|
||||
|
||||
$extDataBarObj = new ConditionalDataBarExtension();
|
||||
$extFormattingRuleObj->setDataBarExt($extDataBarObj);
|
||||
|
||||
$dataBarXml = $extCfRuleXml->dataBar;
|
||||
self::parseExtDataBarAttributesFromXml($extDataBarObj, $dataBarXml);
|
||||
self::parseExtDataBarElementChildrenFromXml($extDataBarObj, $dataBarXml, $ns);
|
||||
|
|
@ -85,8 +90,10 @@ class ConditionalFormattingRuleExtension
|
|||
return $conditionalFormattingRuleExtensions;
|
||||
}
|
||||
|
||||
private static function parseExtDataBarAttributesFromXml(ConditionalDataBarExtension $extDataBarObj, SimpleXMLElement $dataBarXml): void
|
||||
{
|
||||
private static function parseExtDataBarAttributesFromXml(
|
||||
ConditionalDataBarExtension $extDataBarObj,
|
||||
SimpleXMLElement $dataBarXml
|
||||
): void {
|
||||
$dataBarAttribute = $dataBarXml->attributes();
|
||||
if ($dataBarAttribute->minLength) {
|
||||
$extDataBarObj->setMinLength((int) $dataBarAttribute->minLength);
|
||||
|
|
|
|||
|
|
@ -130,7 +130,7 @@ class Formatter
|
|||
|
||||
// In Excel formats, "_" is used to add spacing,
|
||||
// The following character indicates the size of the spacing, which we can't do in HTML, so we just use a standard space
|
||||
$format = preg_replace('/_/ui', ' ', $format);
|
||||
$format = preg_replace('/_.?/ui', ' ', $format);
|
||||
|
||||
// Let's begin inspecting the format and converting the value to a formatted string
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
namespace PhpOffice\PhpSpreadsheet\Style\NumberFormat;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Shared\StringHelper;
|
||||
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
|
||||
|
||||
class NumberFormatter
|
||||
{
|
||||
|
|
@ -145,7 +146,6 @@ class NumberFormatter
|
|||
$format = preg_replace('/0,+/', '0', $format);
|
||||
$format = preg_replace('/#,+/', '#', $format);
|
||||
}
|
||||
|
||||
if (preg_match('/#?.*\?\/\?/', $format, $m)) {
|
||||
if ($value != (int) $value) {
|
||||
$value = FractionFormatter::format($value, $format);
|
||||
|
|
@ -163,7 +163,12 @@ class NumberFormatter
|
|||
$n = '/\\[[^\\]]+\\]/';
|
||||
$m = preg_replace($n, '', $format);
|
||||
if (preg_match(self::NUMBER_REGEX, $m, $matches)) {
|
||||
// There are placeholders for digits, so inject digits from the value into the mask
|
||||
$value = self::formatStraightNumericValue($value, $format, $matches, $useThousands);
|
||||
} elseif ($format !== NumberFormat::FORMAT_GENERAL) {
|
||||
// Yes, I know that this is basically just a hack;
|
||||
// if there's no placeholders for digits, just return the format mask "as is"
|
||||
$value = str_replace('?', '', $format ?? '');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -472,7 +472,7 @@ class AutoFilter
|
|||
$val = $maxVal = null;
|
||||
|
||||
$ruleValues = [];
|
||||
$baseDate = DateTimeExcel\Now::funcNow();
|
||||
$baseDate = DateTimeExcel\Current::now();
|
||||
// Calculate start/end dates for the required date range based on current date
|
||||
switch ($dynamicRuleType) {
|
||||
case AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTWEEK:
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue