Merge branch 'master' into htmledit
This commit is contained in:
commit
360c8d8284
|
@ -38,7 +38,7 @@ jobs:
|
|||
- php ocular.phar code-coverage:upload --format=php-clover tests/coverage-clover.xml
|
||||
|
||||
- stage: API documentations
|
||||
if: tag is present AND branch = master
|
||||
if: branch = master
|
||||
php: 7.4
|
||||
before_script:
|
||||
- curl -LO https://github.com/phpDocumentor/phpDocumentor/releases/download/v3.0.0-rc/phpDocumentor.phar
|
||||
|
|
|
@ -5,12 +5,13 @@ All notable changes to this project will be documented in this file.
|
|||
The format is based on [Keep a Changelog](https://keepachangelog.com)
|
||||
and this project adheres to [Semantic Versioning](https://semver.org).
|
||||
|
||||
## [Unreleased]
|
||||
## [1.13.0] - 2020-05-31
|
||||
|
||||
### Added
|
||||
|
||||
- Support writing to streams in all writers [#1292](https://github.com/PHPOffice/PhpSpreadsheet/issues/1292)
|
||||
- Support CSV files with data wrapping a lot of lines [#1468](https://github.com/PHPOffice/PhpSpreadsheet/pull/1468)
|
||||
- Support protection of worksheet by a specific hash algorithm [#1485](https://github.com/PHPOffice/PhpSpreadsheet/pull/1485)
|
||||
|
||||
### Fixed
|
||||
|
||||
|
@ -21,6 +22,8 @@ and this project adheres to [Semantic Versioning](https://semver.org).
|
|||
- Several improvements in HTML writer [#1464](https://github.com/PHPOffice/PhpSpreadsheet/pull/1464)
|
||||
- Fix incorrect behaviour when saving XLSX file with drawings [#1462](https://github.com/PHPOffice/PhpSpreadsheet/pull/1462),
|
||||
- Fix Crash while trying setting a cell the value "123456\n" [#1476](https://github.com/PHPOffice/PhpSpreadsheet/pull/1481)
|
||||
- Improved DATEDIF() function and reduced errors for Y and YM units [#1466](https://github.com/PHPOffice/PhpSpreadsheet/pull/1466)
|
||||
- Stricter typing for mergeCells [#1494](https://github.com/PHPOffice/PhpSpreadsheet/pull/1494)
|
||||
|
||||
### Changed
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ When you make use of any of the worksheet protection features (e.g. cell
|
|||
range protection, prohibiting deleting rows, ...), make sure you enable
|
||||
worksheet security. This can for example be done like this:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$spreadsheet->getActiveSheet()->getProtection()->setSheet(true);
|
||||
```
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ topic lists some of the options to access a cell.
|
|||
Setting a cell value by coordinate can be done using the worksheet's
|
||||
`setCellValue()` method.
|
||||
|
||||
``` php
|
||||
```php
|
||||
// Set cell A1 with a string value
|
||||
$spreadsheet->getActiveSheet()->setCellValue('A1', 'PhpSpreadsheet');
|
||||
|
||||
|
@ -28,7 +28,7 @@ $spreadsheet->getActiveSheet()->setCellValue(
|
|||
Alternatively, you can retrieve the cell object, and then call the
|
||||
cell’s `setValue()` method:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$spreadsheet->getActiveSheet()
|
||||
->getCell('B8')
|
||||
->setValue('Some value');
|
||||
|
@ -56,7 +56,7 @@ the cell object will still retain its data values.
|
|||
|
||||
What does this mean? Consider the following code:
|
||||
|
||||
```
|
||||
```php
|
||||
$spreadSheet = new Spreadsheet();
|
||||
$workSheet = $spreadSheet->getActiveSheet();
|
||||
|
||||
|
@ -74,7 +74,7 @@ $cellA1 = $workSheet->getCell('A1');
|
|||
echo 'Value: ', $cellA1->getValue(), '; Address: ', $cellA1->getCoordinate(), PHP_EOL;
|
||||
|
||||
echo 'Value: ', $cellC1->getValue(), '; Address: ', $cellC1->getCoordinate(), PHP_EOL;
|
||||
```
|
||||
```
|
||||
|
||||
The call to `getCell('C1')` returns the cell at `C1` containing its value (`3`),
|
||||
together with its link to the collection (used to identify its
|
||||
|
@ -153,7 +153,7 @@ was a formula.
|
|||
|
||||
To do this, you need to "escape" the value by setting it as "quoted text".
|
||||
|
||||
```
|
||||
```php
|
||||
// Set cell A4 with a formula
|
||||
$spreadsheet->getActiveSheet()->setCellValue(
|
||||
'A4',
|
||||
|
@ -175,7 +175,7 @@ point value), and a number format mask is used to show how that value
|
|||
should be formatted; so if we want to store a date in a cell, we need to
|
||||
calculate the correct Excel timestamp, and set a number format mask.
|
||||
|
||||
``` php
|
||||
```php
|
||||
// Get the current date/time and convert to an Excel date/time
|
||||
$dateTimeNow = time();
|
||||
$excelDateValue = \PhpOffice\PhpSpreadsheet\Shared\Date::PHPToExcel( $dateTimeNow );
|
||||
|
@ -210,7 +210,7 @@ behaviour.
|
|||
Firstly, you can set the datatype explicitly as a string so that it is
|
||||
not converted to a number.
|
||||
|
||||
``` php
|
||||
```php
|
||||
// Set cell A8 with a numeric value, but tell PhpSpreadsheet it should be treated as a string
|
||||
$spreadsheet->getActiveSheet()->setCellValueExplicit(
|
||||
'A8',
|
||||
|
@ -222,7 +222,7 @@ $spreadsheet->getActiveSheet()->setCellValueExplicit(
|
|||
Alternatively, you can use a number format mask to display the value
|
||||
with leading zeroes.
|
||||
|
||||
``` php
|
||||
```php
|
||||
// Set cell A9 with a numeric value
|
||||
$spreadsheet->getActiveSheet()->setCellValue('A9', 1513789642);
|
||||
// Set a number format mask to display the value as 11 digits with leading zeroes
|
||||
|
@ -236,7 +236,7 @@ $spreadsheet->getActiveSheet()->getStyle('A9')
|
|||
With number format masking, you can even break up the digits into groups
|
||||
to make the value more easily readable.
|
||||
|
||||
``` php
|
||||
```php
|
||||
// Set cell A10 with a numeric value
|
||||
$spreadsheet->getActiveSheet()->setCellValue('A10', 1513789642);
|
||||
// Set a number format mask to display the value as 11 digits with leading zeroes
|
||||
|
@ -259,7 +259,7 @@ writers (Xlsx and Xls).
|
|||
It is also possible to set a range of cell values in a single call by
|
||||
passing an array of values to the `fromArray()` method.
|
||||
|
||||
``` php
|
||||
```php
|
||||
$arrayData = [
|
||||
[NULL, 2010, 2011, 2012],
|
||||
['Q1', 12, 15, 21],
|
||||
|
@ -282,7 +282,7 @@ If you pass a 2-d array, then this will be treated as a series of rows
|
|||
and columns. A 1-d array will be treated as a single row, which is
|
||||
particularly useful if you're fetching an array of data from a database.
|
||||
|
||||
``` php
|
||||
```php
|
||||
$rowArray = ['Value1', 'Value2', 'Value3', 'Value4'];
|
||||
$spreadsheet->getActiveSheet()
|
||||
->fromArray(
|
||||
|
@ -299,7 +299,7 @@ If you have a simple 1-d array, and want to write it as a column, then
|
|||
the following will convert it into an appropriately structured 2-d array
|
||||
that can be fed to the `fromArray()` method:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$rowArray = ['Value1', 'Value2', 'Value3', 'Value4'];
|
||||
$columnArray = array_chunk($rowArray, 1);
|
||||
$spreadsheet->getActiveSheet()
|
||||
|
@ -319,7 +319,7 @@ To retrieve the value of a cell, the cell should first be retrieved from
|
|||
the worksheet using the `getCell()` method. A cell's value can be read
|
||||
using the `getValue()` method.
|
||||
|
||||
``` php
|
||||
```php
|
||||
// Get the value from cell A1
|
||||
$cellValue = $spreadsheet->getActiveSheet()->getCell('A1')->getValue();
|
||||
```
|
||||
|
@ -331,7 +331,7 @@ value rather than the formula itself, then use the cell's
|
|||
`getCalculatedValue()` method. This is further explained in
|
||||
[the calculation engine](./calculation-engine.md).
|
||||
|
||||
``` php
|
||||
```php
|
||||
// Get the value from cell A4
|
||||
$cellValue = $spreadsheet->getActiveSheet()->getCell('A4')->getCalculatedValue();
|
||||
```
|
||||
|
@ -340,7 +340,7 @@ Alternatively, if you want to see the value with any cell formatting
|
|||
applied (e.g. for a human-readable date or time value), then you can use
|
||||
the cell's `getFormattedValue()` method.
|
||||
|
||||
``` php
|
||||
```php
|
||||
// Get the value from cell A6
|
||||
$cellValue = $spreadsheet->getActiveSheet()->getCell('A6')->getFormattedValue();
|
||||
```
|
||||
|
@ -350,7 +350,7 @@ $cellValue = $spreadsheet->getActiveSheet()->getCell('A6')->getFormattedValue();
|
|||
Setting a cell value by coordinate can be done using the worksheet's
|
||||
`setCellValueByColumnAndRow()` method.
|
||||
|
||||
``` php
|
||||
```php
|
||||
// Set cell A5 with a string value
|
||||
$spreadsheet->getActiveSheet()->setCellValueByColumnAndRow(1, 5, 'PhpSpreadsheet');
|
||||
```
|
||||
|
@ -363,7 +363,7 @@ To retrieve the value of a cell, the cell should first be retrieved from
|
|||
the worksheet using the `getCellByColumnAndRow()` method. A cell’s value can
|
||||
be read again using the following line of code:
|
||||
|
||||
``` php
|
||||
```php
|
||||
// Get the value from cell B5
|
||||
$cellValue = $spreadsheet->getActiveSheet()->getCellByColumnAndRow(2, 5)->getValue();
|
||||
```
|
||||
|
@ -371,7 +371,7 @@ $cellValue = $spreadsheet->getActiveSheet()->getCellByColumnAndRow(2, 5)->getVal
|
|||
If you need the calculated value of a cell, use the following code. This
|
||||
is further explained in [the calculation engine](./calculation-engine.md).
|
||||
|
||||
``` php
|
||||
```php
|
||||
// Get the value from cell A4
|
||||
$cellValue = $spreadsheet->getActiveSheet()->getCellByColumnAndRow(1, 4)->getCalculatedValue();
|
||||
```
|
||||
|
@ -382,7 +382,7 @@ It is also possible to retrieve a range of cell values to an array in a
|
|||
single call using the `toArray()`, `rangeToArray()` or
|
||||
`namedRangeToArray()` methods.
|
||||
|
||||
``` php
|
||||
```php
|
||||
$dataArray = $spreadsheet->getActiveSheet()
|
||||
->rangeToArray(
|
||||
'C3:E5', // The worksheet range that we want to retrieve
|
||||
|
@ -409,7 +409,7 @@ cells within a row.
|
|||
Below is an example where we read all the values in a worksheet and
|
||||
display them in a table.
|
||||
|
||||
``` php
|
||||
```php
|
||||
$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader('Xlsx');
|
||||
$reader->setReadDataOnly(TRUE);
|
||||
$spreadsheet = $reader->load("test.xlsx");
|
||||
|
@ -456,7 +456,7 @@ loops.
|
|||
Below is an example where we read all the values in a worksheet and
|
||||
display them in a table.
|
||||
|
||||
``` php
|
||||
```php
|
||||
$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader('Xlsx');
|
||||
$reader->setReadDataOnly(TRUE);
|
||||
$spreadsheet = $reader->load("test.xlsx");
|
||||
|
@ -482,7 +482,7 @@ echo '</table>' . PHP_EOL;
|
|||
Alternatively, you can take advantage of PHP's "Perl-style" character
|
||||
incrementors to loop through the cells by coordinate:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader('Xlsx');
|
||||
$reader->setReadDataOnly(TRUE);
|
||||
$spreadsheet = $reader->load("test.xlsx");
|
||||
|
@ -528,7 +528,7 @@ dates entered as strings to the correct format, also setting the cell's
|
|||
style information. The following example demonstrates how to set the
|
||||
value binder in PhpSpreadsheet:
|
||||
|
||||
``` php
|
||||
```php
|
||||
/** PhpSpreadsheet */
|
||||
require_once 'src/Boostrap.php';
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ PhpSpreadsheet supports fluent interfaces in most locations. This means
|
|||
that you can easily "chain" calls to specific methods without requiring
|
||||
a new PHP statement. For example, take the following code:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$spreadsheet->getProperties()->setCreator("Maarten Balliauw");
|
||||
$spreadsheet->getProperties()->setLastModifiedBy("Maarten Balliauw");
|
||||
$spreadsheet->getProperties()->setTitle("Office 2007 XLSX Test Document");
|
||||
|
@ -55,7 +55,7 @@ $spreadsheet->getProperties()->setCategory("Test result file");
|
|||
|
||||
This can be rewritten as:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$spreadsheet->getProperties()
|
||||
->setCreator("Maarten Balliauw")
|
||||
->setLastModifiedBy("Maarten Balliauw")
|
||||
|
|
|
@ -42,7 +42,7 @@ column, such as "Equals a red cell color" or "Larger than 150".
|
|||
|
||||
To set an autoFilter on a range of cells.
|
||||
|
||||
``` php
|
||||
```php
|
||||
$spreadsheet->getActiveSheet()->setAutoFilter('A1:E20');
|
||||
```
|
||||
|
||||
|
@ -56,7 +56,7 @@ developer to avoid such errors.
|
|||
|
||||
If you want to set the whole worksheet as an autofilter region
|
||||
|
||||
``` php
|
||||
```php
|
||||
$spreadsheet->getActiveSheet()->setAutoFilter(
|
||||
$spreadsheet->getActiveSheet()
|
||||
->calculateWorksheetDimension()
|
||||
|
@ -74,7 +74,7 @@ will extend this to other formats.
|
|||
To apply a filter expression to an autoFilter range, you first need to
|
||||
identify which column you're going to be applying this filter to.
|
||||
|
||||
``` php
|
||||
```php
|
||||
$autoFilter = $spreadsheet->getActiveSheet()->getAutoFilter();
|
||||
$columnFilter = $autoFilter->getColumn('C');
|
||||
```
|
||||
|
@ -114,7 +114,7 @@ To create a filter expression, we need to start by identifying the
|
|||
filter type. In this case, we're just going to specify that this filter
|
||||
is a standard filter.
|
||||
|
||||
``` php
|
||||
```php
|
||||
$columnFilter->setFilterType(
|
||||
\PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column::AUTOFILTER_FILTERTYPE_FILTER
|
||||
);
|
||||
|
@ -127,7 +127,7 @@ When creating a simple filter in PhpSpreadsheet, you only need to
|
|||
specify the values for "checked" columns: you do this by creating a
|
||||
filter rule for each value.
|
||||
|
||||
``` php
|
||||
```php
|
||||
$columnFilter->createRule()
|
||||
->setRule(
|
||||
\PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column\Rule::AUTOFILTER_COLUMN_RULE_EQUAL,
|
||||
|
@ -152,7 +152,7 @@ standard filters are always treated as being joined by an OR condition.
|
|||
|
||||
If you want to create a filter to select blank cells, you would use:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$columnFilter->createRule()
|
||||
->setRule(
|
||||
\PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column\Rule::AUTOFILTER_COLUMN_RULE_EQUAL,
|
||||
|
@ -170,7 +170,7 @@ within a year, or individual days within each month.
|
|||
|
||||
DateGroup filters are still applied as a Standard Filter type.
|
||||
|
||||
``` php
|
||||
```php
|
||||
$columnFilter->setFilterType(
|
||||
\PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column::AUTOFILTER_FILTERTYPE_FILTER
|
||||
);
|
||||
|
@ -181,7 +181,7 @@ for "checked" columns as an associative array of year. month, day, hour
|
|||
minute and second. To select a year and month, you need to create a
|
||||
DateGroup rule identifying the selected year and month:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$columnFilter->createRule()
|
||||
->setRule(
|
||||
\PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column\Rule::AUTOFILTER_COLUMN_RULE_EQUAL,
|
||||
|
@ -229,7 +229,7 @@ either an AND or an OR.
|
|||
|
||||
We start by specifying a Filter type, this time a CUSTOMFILTER.
|
||||
|
||||
``` php
|
||||
```php
|
||||
$columnFilter->setFilterType(
|
||||
\PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column::AUTOFILTER_FILTERTYPE_CUSTOMFILTER
|
||||
);
|
||||
|
@ -240,7 +240,7 @@ And then define our rules.
|
|||
The following shows a simple wildcard filter to show all column entries
|
||||
beginning with the letter `U`.
|
||||
|
||||
``` php
|
||||
```php
|
||||
$columnFilter->createRule()
|
||||
->setRule(
|
||||
\PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column\Rule::AUTOFILTER_COLUMN_RULE_EQUAL,
|
||||
|
@ -264,7 +264,7 @@ is the \~ itself.
|
|||
|
||||
To create a "between" condition, we need to define two rules:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$columnFilter->createRule()
|
||||
->setRule(
|
||||
\PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column\Rule::AUTOFILTER_COLUMN_RULE_GREATERTHANOREQUAL,
|
||||
|
@ -289,7 +289,7 @@ This defined two rules, filtering numbers that are `>= -20` OR `<=
|
|||
20`, so we also need to modify the join condition to reflect AND rather
|
||||
than OR.
|
||||
|
||||
``` php
|
||||
```php
|
||||
$columnFilter->setAndOr(
|
||||
\PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column::AUTOFILTER_COLUMN_ANDOR_AND
|
||||
);
|
||||
|
@ -320,7 +320,7 @@ column at a time.
|
|||
|
||||
Again, we start by specifying a Filter type, this time a DYNAMICFILTER.
|
||||
|
||||
``` php
|
||||
```php
|
||||
$columnFilter->setFilterType(
|
||||
\PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column::AUTOFILTER_FILTERTYPE_DYNAMICFILTER
|
||||
);
|
||||
|
@ -330,7 +330,7 @@ When defining the rule for a dynamic filter, we don't define a value (we
|
|||
can simply set that to NULL) but we do specify the dynamic filter
|
||||
category.
|
||||
|
||||
``` php
|
||||
```php
|
||||
$columnFilter->createRule()
|
||||
->setRule(
|
||||
\PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column\Rule::AUTOFILTER_COLUMN_RULE_EQUAL,
|
||||
|
@ -420,7 +420,7 @@ column at a time.
|
|||
|
||||
We start by specifying a Filter type, this time a DYNAMICFILTER.
|
||||
|
||||
``` php
|
||||
```php
|
||||
$columnFilter->setFilterType(
|
||||
\PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column::AUTOFILTER_FILTERTYPE_TOPTENFILTER
|
||||
);
|
||||
|
@ -428,7 +428,7 @@ $columnFilter->setFilterType(
|
|||
|
||||
Then we create the rule:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$columnFilter->createRule()
|
||||
->setRule(
|
||||
\PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column\Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT,
|
||||
|
@ -444,7 +444,7 @@ This will filter the Top 5 percent of values in the column.
|
|||
|
||||
To specify the lowest (bottom 2 values), we would specify a rule of:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$columnFilter->createRule()
|
||||
->setRule(
|
||||
\PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column\Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_BY_VALUE,
|
||||
|
@ -490,7 +490,7 @@ If you wish to execute your filter from within a script, you need to do
|
|||
this manually. You can do this using the autofilters `showHideRows()`
|
||||
method.
|
||||
|
||||
``` php
|
||||
```php
|
||||
$autoFilter = $spreadsheet->getActiveSheet()->getAutoFilter();
|
||||
$autoFilter->showHideRows();
|
||||
```
|
||||
|
@ -505,7 +505,7 @@ ever row, whether it matches the filter criteria or not. To selectively
|
|||
access only the filtered rows, you need to test each row’s visibility
|
||||
settings.
|
||||
|
||||
``` php
|
||||
```php
|
||||
foreach ($spreadsheet->getActiveSheet()->getRowIterator() as $row) {
|
||||
if ($spreadsheet->getActiveSheet()
|
||||
->getRowDimension($row->getRowIndex())->getVisible()) {
|
||||
|
|
|
@ -13,7 +13,7 @@ evaluates to the sum of values in A1, A2, ..., A10.
|
|||
To calculate a formula, you can call the cell containing the formula’s
|
||||
method `getCalculatedValue()`, for example:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$spreadsheet->getActiveSheet()->getCell('E11')->getCalculatedValue();
|
||||
```
|
||||
|
||||
|
@ -32,7 +32,7 @@ You see that the formula contained in cell E11 is "SUM(E4:E9)". Now,
|
|||
when I write the following line of code, two new product lines are
|
||||
added:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$spreadsheet->getActiveSheet()->insertNewRowBefore(7, 2);
|
||||
```
|
||||
|
||||
|
@ -55,7 +55,7 @@ However, there may be times when you don't want this, perhaps you've changed
|
|||
the underlying data and need to re-evaluate the same formula with that new
|
||||
data.
|
||||
|
||||
```
|
||||
```php
|
||||
Calculation::getInstance($spreadsheet)->disableCalculationCache();
|
||||
```
|
||||
|
||||
|
@ -63,7 +63,7 @@ Will disable calculation caching, and flush the current calculation cache.
|
|||
|
||||
If you want only to flush the cache, then you can call
|
||||
|
||||
```
|
||||
```php
|
||||
Calculation::getInstance($spreadsheet)->clearCalculationCache();
|
||||
```
|
||||
|
||||
|
@ -118,7 +118,7 @@ date values by calling the
|
|||
`\PhpOffice\PhpSpreadsheet\Calculation\Functions::setReturnDateType()`
|
||||
method:
|
||||
|
||||
``` php
|
||||
```php
|
||||
\PhpOffice\PhpSpreadsheet\Calculation\Functions::setReturnDateType($returnDateType);
|
||||
```
|
||||
|
||||
|
@ -134,7 +134,7 @@ if an invalid value is passed in for the return date type).
|
|||
The `\PhpOffice\PhpSpreadsheet\Calculation\Functions::getReturnDateType()`
|
||||
method can be used to determine the current value of this setting:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$returnDateType = \PhpOffice\PhpSpreadsheet\Calculation\Functions::getReturnDateType();
|
||||
```
|
||||
|
||||
|
@ -172,7 +172,7 @@ It is possible for scripts to change the calendar used for calculating
|
|||
Excel date values by calling the
|
||||
`\PhpOffice\PhpSpreadsheet\Shared\Date::setExcelCalendar()` method:
|
||||
|
||||
``` php
|
||||
```php
|
||||
\PhpOffice\PhpSpreadsheet\Shared\Date::setExcelCalendar($baseDate);
|
||||
```
|
||||
|
||||
|
@ -187,7 +187,7 @@ if an invalid value is passed in).
|
|||
The `\PhpOffice\PhpSpreadsheet\Shared\Date::getExcelCalendar()` method can
|
||||
be used to determine the current value of this setting:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$baseDate = \PhpOffice\PhpSpreadsheet\Shared\Date::getExcelCalendar();
|
||||
```
|
||||
|
||||
|
@ -353,7 +353,7 @@ This is the statistical mean.
|
|||
|
||||
##### Examples
|
||||
|
||||
``` php
|
||||
```php
|
||||
$database = [
|
||||
[ 'Tree', 'Height', 'Age', 'Yield', 'Profit' ],
|
||||
[ 'Apple', 18, 20, 14, 105.00 ],
|
||||
|
@ -421,7 +421,7 @@ in which you specify a condition for the column.
|
|||
|
||||
##### Examples
|
||||
|
||||
``` php
|
||||
```php
|
||||
$database = [
|
||||
[ 'Tree', 'Height', 'Age', 'Yield', 'Profit' ],
|
||||
[ 'Apple', 18, 20, 14, 105.00 ],
|
||||
|
@ -492,7 +492,7 @@ in which you specify a condition for the column.
|
|||
|
||||
##### Examples
|
||||
|
||||
``` php
|
||||
```php
|
||||
$database = [
|
||||
[ 'Tree', 'Height', 'Age', 'Yield', 'Profit' ],
|
||||
[ 'Apple', 18, 20, 14, 105.00 ],
|
||||
|
@ -563,7 +563,7 @@ in which you specify a condition for the column.
|
|||
|
||||
#### Examples
|
||||
|
||||
``` php
|
||||
```php
|
||||
$database = [
|
||||
[ 'Tree', 'Height', 'Age', 'Yield', 'Profit' ],
|
||||
[ 'Apple', 18, 20, 14, 105.00 ],
|
||||
|
@ -631,7 +631,7 @@ in which you specify a condition for the column.
|
|||
|
||||
##### Examples
|
||||
|
||||
``` php
|
||||
```php
|
||||
$database = [
|
||||
[ 'Tree', 'Height', 'Age', 'Yield', 'Profit' ],
|
||||
[ 'Apple', 18, 20, 14, 105.00 ],
|
||||
|
@ -699,7 +699,7 @@ in which you specify a condition for the column.
|
|||
|
||||
##### Examples
|
||||
|
||||
``` php
|
||||
```php
|
||||
$database = [
|
||||
[ 'Tree', 'Height', 'Age', 'Yield', 'Profit' ],
|
||||
[ 'Apple', 18, 20, 14, 105.00 ],
|
||||
|
@ -767,7 +767,7 @@ in which you specify a condition for the column.
|
|||
|
||||
##### Examples
|
||||
|
||||
``` php
|
||||
```php
|
||||
$database = [
|
||||
[ 'Tree', 'Height', 'Age', 'Yield', 'Profit' ],
|
||||
[ 'Apple', 18, 20, 14, 105.00 ],
|
||||
|
@ -836,7 +836,7 @@ in which you specify a condition for the column.
|
|||
|
||||
##### Examples
|
||||
|
||||
``` php
|
||||
```php
|
||||
$database = [
|
||||
[ 'Tree', 'Height', 'Age', 'Yield', 'Profit' ],
|
||||
[ 'Apple', 18, 20, 14, 105.00 ],
|
||||
|
@ -905,7 +905,7 @@ in which you specify a condition for the column.
|
|||
|
||||
##### Examples
|
||||
|
||||
``` php
|
||||
```php
|
||||
$database = [
|
||||
[ 'Tree', 'Height', 'Age', 'Yield', 'Profit' ],
|
||||
[ 'Apple', 18, 20, 14, 105.00 ],
|
||||
|
@ -973,7 +973,7 @@ in which you specify a condition for the column.
|
|||
|
||||
##### Examples
|
||||
|
||||
``` php
|
||||
```php
|
||||
$database = [
|
||||
[ 'Tree', 'Height', 'Age', 'Yield', 'Profit' ],
|
||||
[ 'Apple', 18, 20, 14, 105.00 ],
|
||||
|
@ -1074,7 +1074,7 @@ or an Excel timestamp value (real), depending on the value of
|
|||
|
||||
##### Examples
|
||||
|
||||
``` php
|
||||
```php
|
||||
$worksheet->setCellValue('A1', 'Year')
|
||||
->setCellValue('A2', 'Month')
|
||||
->setCellValue('A3', 'Day');
|
||||
|
@ -1089,7 +1089,7 @@ $retVal = $worksheet->getCell('D1')->getCalculatedValue();
|
|||
// $retVal = 1230681600
|
||||
```
|
||||
|
||||
``` php
|
||||
```php
|
||||
// We're going to be calling the same cell calculation multiple times,
|
||||
// and expecting different return values, so disable calculation cacheing
|
||||
\PhpOffice\PhpSpreadsheet\Calculation\Calculation::getInstance()->setCalculationCacheEnabled(FALSE);
|
||||
|
@ -1170,7 +1170,7 @@ the third parameter.
|
|||
|
||||
##### Examples
|
||||
|
||||
``` php
|
||||
```php
|
||||
$worksheet->setCellValue('A1', 'Year')
|
||||
->setCellValue('A2', 'Month')
|
||||
->setCellValue('A3', 'Day');
|
||||
|
@ -1208,7 +1208,7 @@ $retVal = $worksheet->getCell('D6')->getCalculatedValue();
|
|||
// $retVal = 30
|
||||
```
|
||||
|
||||
``` php
|
||||
```php
|
||||
$date1 = 1193317015; // PHP timestamp for 25-Oct-2007
|
||||
$date2 = 1449579415; // PHP timestamp for 8-Dec-2015
|
||||
|
||||
|
@ -1279,7 +1279,7 @@ or an Excel timestamp value (real), depending on the value of
|
|||
|
||||
##### Examples
|
||||
|
||||
``` php
|
||||
```php
|
||||
$worksheet->setCellValue('A1', 'Date String');
|
||||
->setCellValue('A2', '31-Dec-2008')
|
||||
->setCellValue('A3', '31/12/2008')
|
||||
|
@ -1301,7 +1301,7 @@ $retVal = $worksheet->getCell('B4')->getCalculatedValue();
|
|||
// $retVal = 39813.0 for all cases
|
||||
```
|
||||
|
||||
``` php
|
||||
```php
|
||||
// We're going to be calling the same cell calculation multiple times,
|
||||
// and expecting different return values, so disable calculation cacheing
|
||||
\PhpOffice\PhpSpreadsheet\Calculation\Calculation::getInstance()->setCalculationCacheEnabled(FALSE);
|
||||
|
@ -1371,7 +1371,7 @@ This is an integer ranging from 1 to 31.
|
|||
|
||||
##### Examples
|
||||
|
||||
``` php
|
||||
```php
|
||||
$worksheet->setCellValue('A1', 'Date String')
|
||||
->setCellValue('A2', '31-Dec-2008')
|
||||
->setCellValue('A3', '14-Feb-2008');
|
||||
|
@ -1386,7 +1386,7 @@ $retVal = $worksheet->getCell('B3')->getCalculatedValue();
|
|||
// $retVal = 14
|
||||
```
|
||||
|
||||
``` php
|
||||
```php
|
||||
$retVal = call_user_func_array(
|
||||
['\PhpOffice\PhpSpreadsheet\Calculation\Functions', 'DAYOFMONTH'],
|
||||
['25-Dec-2008']
|
||||
|
@ -1444,7 +1444,7 @@ day year.
|
|||
|
||||
##### Examples
|
||||
|
||||
``` php
|
||||
```php
|
||||
$worksheet->setCellValue('B1', 'Start Date')
|
||||
->setCellValue('C1', 'End Date')
|
||||
->setCellValue('A2', 'Year')
|
||||
|
@ -1469,7 +1469,7 @@ $retVal = $worksheet->getCell('E4')->getCalculatedValue();
|
|||
// $retVal = 1557
|
||||
```
|
||||
|
||||
``` php
|
||||
```php
|
||||
$date1 = 37655.0; // Excel timestamp for 25-Oct-2007
|
||||
$date2 = 39233.0; // Excel timestamp for 8-Dec-2015
|
||||
|
||||
|
@ -1529,7 +1529,7 @@ or an Excel timestamp value (real), depending on the value of
|
|||
|
||||
##### Examples
|
||||
|
||||
``` php
|
||||
```php
|
||||
$worksheet->setCellValue('A1', 'Date String')
|
||||
->setCellValue('A2', '1-Jan-2008')
|
||||
->setCellValue('A3', '29-Feb-2008');
|
||||
|
@ -1548,7 +1548,7 @@ $retVal = $worksheet->getCell('B3')->getCalculatedValue();
|
|||
// $retVal = 39141.0 (28-Feb-2007)
|
||||
```
|
||||
|
||||
``` php
|
||||
```php
|
||||
\PhpOffice\PhpSpreadsheet\Calculation\Functions::setReturnDateType(
|
||||
\PhpOffice\PhpSpreadsheet\Calculation\Functions::RETURNDATE_EXCEL
|
||||
);
|
||||
|
@ -1602,7 +1602,7 @@ or an Excel timestamp value (real), depending on the value of
|
|||
|
||||
##### Examples
|
||||
|
||||
``` php
|
||||
```php
|
||||
$worksheet->setCellValue('A1', 'Date String')
|
||||
->setCellValue('A2', '1-Jan-2000')
|
||||
->setCellValue('A3', '14-Feb-2009');
|
||||
|
@ -1619,7 +1619,7 @@ $retVal = $worksheet->getCell('B3')->getCalculatedValue();
|
|||
// $retVal = 39507.0 (29-Feb-2008)
|
||||
```
|
||||
|
||||
``` php
|
||||
```php
|
||||
\PhpOffice\PhpSpreadsheet\Calculation\Functions::setReturnDateType(
|
||||
\PhpOffice\PhpSpreadsheet\Calculation\Functions::RETURNDATE_EXCEL
|
||||
);
|
||||
|
@ -1661,7 +1661,7 @@ This is an integer ranging from 0 to 23.
|
|||
|
||||
##### Examples
|
||||
|
||||
``` php
|
||||
```php
|
||||
$worksheet->setCellValue('A1', 'Time String')
|
||||
->setCellValue('A2', '31-Dec-2008 17:30')
|
||||
->setCellValue('A3', '14-Feb-2008 4:20 AM')
|
||||
|
@ -1681,7 +1681,7 @@ $retVal = $worksheet->getCell('B4')->getCalculatedValue();
|
|||
// $retVal = 16
|
||||
```
|
||||
|
||||
``` php
|
||||
```php
|
||||
$retVal = call_user_func_array(
|
||||
['\PhpOffice\PhpSpreadsheet\Calculation\Functions', 'HOUROFDAY'],
|
||||
['09:30']
|
||||
|
@ -1719,7 +1719,7 @@ This is an integer ranging from 0 to 59.
|
|||
|
||||
##### Examples
|
||||
|
||||
``` php
|
||||
```php
|
||||
$worksheet->setCellValue('A1', 'Time String')
|
||||
->setCellValue('A2', '31-Dec-2008 17:30')
|
||||
->setCellValue('A3', '14-Feb-2008 4:20 AM')
|
||||
|
@ -1739,7 +1739,7 @@ $retVal = $worksheet->getCell('B4')->getCalculatedValue();
|
|||
// $retVal = 45
|
||||
```
|
||||
|
||||
``` php
|
||||
```php
|
||||
$retVal = call_user_func_array(
|
||||
['\PhpOffice\PhpSpreadsheet\Calculation\Functions', 'MINUTE'],
|
||||
['09:30']
|
||||
|
@ -1777,7 +1777,7 @@ This is an integer ranging from 1 to 12.
|
|||
|
||||
##### Examples
|
||||
|
||||
``` php
|
||||
```php
|
||||
$worksheet->setCellValue('A1', 'Date String');
|
||||
$worksheet->setCellValue('A2', '31-Dec-2008');
|
||||
$worksheet->setCellValue('A3', '14-Feb-2008');
|
||||
|
@ -1792,7 +1792,7 @@ $retVal = $worksheet->getCell('B3')->getCalculatedValue();
|
|||
// $retVal = 2
|
||||
```
|
||||
|
||||
``` php
|
||||
```php
|
||||
$retVal = call_user_func_array(
|
||||
['\PhpOffice\PhpSpreadsheet\Calculation\Functions', 'MONTHOFYEAR'],
|
||||
['14-July-2008']
|
||||
|
@ -1847,10 +1847,10 @@ The number of working days between startDate and endDate.
|
|||
|
||||
##### Examples
|
||||
|
||||
``` php
|
||||
```php
|
||||
```
|
||||
|
||||
``` php
|
||||
```php
|
||||
```
|
||||
|
||||
##### Notes
|
||||
|
@ -1880,10 +1880,10 @@ or an Excel timestamp value (real), depending on the value of
|
|||
|
||||
##### Examples
|
||||
|
||||
``` php
|
||||
```php
|
||||
```
|
||||
|
||||
``` php
|
||||
```php
|
||||
```
|
||||
|
||||
##### Notes
|
||||
|
@ -1917,7 +1917,7 @@ This is an integer ranging from 0 to 59.
|
|||
|
||||
##### Examples
|
||||
|
||||
``` php
|
||||
```php
|
||||
$worksheet->setCellValue('A1', 'Time String')
|
||||
->setCellValue('A2', '31-Dec-2008 17:30:20')
|
||||
->setCellValue('A3', '14-Feb-2008 4:20 AM')
|
||||
|
@ -1937,7 +1937,7 @@ $retVal = $worksheet->getCell('B4')->getCalculatedValue();
|
|||
// $retVal = 59
|
||||
```
|
||||
|
||||
``` php
|
||||
```php
|
||||
$retVal = call_user_func_array(
|
||||
['\PhpOffice\PhpSpreadsheet\Calculation\Functions', 'SECOND'],
|
||||
['09:30:17']
|
||||
|
@ -2002,7 +2002,7 @@ value of method.
|
|||
|
||||
##### Examples
|
||||
|
||||
``` php
|
||||
```php
|
||||
$worksheet->setCellValue('A1', 'Date String')
|
||||
->setCellValue('A2', '31-Dec-2008')
|
||||
->setCellValue('A3', '14-Feb-2008');
|
||||
|
@ -2021,7 +2021,7 @@ $retVal = $worksheet->getCell('B4')->getCalculatedValue();
|
|||
// $retVal = 2
|
||||
```
|
||||
|
||||
``` php
|
||||
```php
|
||||
$retVal = call_user_func_array(
|
||||
['\PhpOffice\PhpSpreadsheet\Calculation\Functions', 'WEEKDAY'],
|
||||
['14-July-2008']
|
||||
|
@ -2066,7 +2066,7 @@ This is an integer year value.
|
|||
|
||||
##### Examples
|
||||
|
||||
``` php
|
||||
```php
|
||||
$worksheet->setCellValue('A1', 'Date String')
|
||||
->setCellValue('A2', '17-Jul-1982')
|
||||
->setCellValue('A3', '16-Apr-2009');
|
||||
|
@ -2081,7 +2081,7 @@ $retVal = $worksheet->getCell('B3')->getCalculatedValue();
|
|||
// $retVal = 2009
|
||||
```
|
||||
|
||||
``` php
|
||||
```php
|
||||
$retVal = call_user_func_array(
|
||||
['\PhpOffice\PhpSpreadsheet\Calculation\Functions', 'YEAR'],
|
||||
['14-July-2001']
|
||||
|
|
|
@ -20,7 +20,7 @@ Details of the different spreadsheet formats supported, and the options
|
|||
available to read them into a Spreadsheet object are described fully in
|
||||
the [Reading Files](./reading-files.md) document.
|
||||
|
||||
``` php
|
||||
```php
|
||||
$inputFileName = './sampleData/example1.xls';
|
||||
|
||||
/** Load $inputFileName to a Spreadsheet object **/
|
||||
|
@ -32,7 +32,7 @@ $spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($inputFileName);
|
|||
If you want to create a new workbook, rather than load one from file,
|
||||
then you simply need to instantiate it as a new Spreadsheet object.
|
||||
|
||||
``` php
|
||||
```php
|
||||
/** Create a new Spreadsheet Object **/
|
||||
$spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
|
||||
```
|
||||
|
@ -53,7 +53,7 @@ then you also need to "break" these cyclic references before doing so.
|
|||
PhpSpreadsheet provides the `disconnectWorksheets()` method for this
|
||||
purpose.
|
||||
|
||||
``` php
|
||||
```php
|
||||
$spreadsheet->disconnectWorksheets();
|
||||
unset($spreadsheet);
|
||||
```
|
||||
|
|
|
@ -16,7 +16,7 @@ cache usages.
|
|||
|
||||
To enable cell caching, you must provide your own implementation of cache like so:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$cache = new MyCustomPsr16Implementation();
|
||||
|
||||
\PhpOffice\PhpSpreadsheet\Settings::setCache($cache);
|
||||
|
|
|
@ -12,7 +12,7 @@ need to be done.
|
|||
automatically your codebase. Assuming your files to be migrated lives
|
||||
in `src/`, you can run the migration like so:
|
||||
|
||||
``` sh
|
||||
```sh
|
||||
composer require rector/rector --dev
|
||||
vendor/bin/rector process src --set phpexcel-to-phpspreadsheet
|
||||
composer remove rector/rector
|
||||
|
|
|
@ -33,7 +33,7 @@ You can create a `\PhpOffice\PhpSpreadsheet\Reader\IReader` instance using
|
|||
`\PhpOffice\PhpSpreadsheet\IOFactory` in automatic file type resolving
|
||||
mode using the following code sample:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load("05featuredemo.xlsx");
|
||||
```
|
||||
|
||||
|
@ -45,7 +45,7 @@ If you need to set some properties on the reader, (e.g. to only read
|
|||
data, see more about this later), then you may instead want to use this
|
||||
variant:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReaderForFile("05featuredemo.xlsx");
|
||||
$reader->setReadDataOnly(true);
|
||||
$reader->load("05featuredemo.xlsx");
|
||||
|
@ -55,7 +55,7 @@ You can create a `\PhpOffice\PhpSpreadsheet\Reader\IReader` instance using
|
|||
`\PhpOffice\PhpSpreadsheet\IOFactory` in explicit mode using the following
|
||||
code sample:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader("Xlsx");
|
||||
$spreadsheet = $reader->load("05featuredemo.xlsx");
|
||||
```
|
||||
|
@ -68,7 +68,7 @@ mode.
|
|||
You can create a `\PhpOffice\PhpSpreadsheet\Writer\IWriter` instance using
|
||||
`\PhpOffice\PhpSpreadsheet\IOFactory`:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, "Xlsx");
|
||||
$writer->save("05featuredemo.xlsx");
|
||||
```
|
||||
|
@ -84,7 +84,7 @@ outputting the in-memory spreadsheet to a .xlsx file.
|
|||
|
||||
You can read an .xlsx file using the following code:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xlsx();
|
||||
$spreadsheet = $reader->load("05featuredemo.xlsx");
|
||||
```
|
||||
|
@ -94,7 +94,7 @@ $spreadsheet = $reader->load("05featuredemo.xlsx");
|
|||
You can set the option setReadDataOnly on the reader, to instruct the
|
||||
reader to ignore styling, data validation, … and just read cell data:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xlsx();
|
||||
$reader->setReadDataOnly(true);
|
||||
$spreadsheet = $reader->load("05featuredemo.xlsx");
|
||||
|
@ -105,7 +105,7 @@ $spreadsheet = $reader->load("05featuredemo.xlsx");
|
|||
You can set the option setLoadSheetsOnly on the reader, to instruct the
|
||||
reader to only load the sheets with a given name:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xlsx();
|
||||
$reader->setLoadSheetsOnly(["Sheet 1", "My special sheet"]);
|
||||
$spreadsheet = $reader->load("05featuredemo.xlsx");
|
||||
|
@ -122,7 +122,7 @@ read using the `\PhpOffice\PhpSpreadsheet\Reader\DefaultReadFilter`.
|
|||
The following code will only read row 1 and rows 20 – 30 of any sheet in
|
||||
the Excel file:
|
||||
|
||||
``` php
|
||||
```php
|
||||
class MyReadFilter implements \PhpOffice\PhpSpreadsheet\Reader\IReadFilter {
|
||||
|
||||
public function readCell($column, $row, $worksheetName = '') {
|
||||
|
@ -145,7 +145,7 @@ $spreadsheet = $reader->load("06largescale.xlsx");
|
|||
|
||||
You can write an .xlsx file using the following code:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet);
|
||||
$writer->save("05featuredemo.xlsx");
|
||||
```
|
||||
|
@ -156,7 +156,7 @@ By default, this writer pre-calculates all formulas in the spreadsheet.
|
|||
This can be slow on large spreadsheets, and maybe even unwanted. You can
|
||||
however disable formula pre-calculation:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet);
|
||||
$writer->setPreCalculateFormulas(false);
|
||||
$writer->save("05featuredemo.xlsx");
|
||||
|
@ -201,7 +201,7 @@ PHP.
|
|||
|
||||
You can read an .xls file using the following code:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xls();
|
||||
$spreadsheet = $reader->load("05featuredemo.xls");
|
||||
```
|
||||
|
@ -211,7 +211,7 @@ $spreadsheet = $reader->load("05featuredemo.xls");
|
|||
You can set the option setReadDataOnly on the reader, to instruct the
|
||||
reader to ignore styling, data validation, … and just read cell data:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xls();
|
||||
$reader->setReadDataOnly(true);
|
||||
$spreadsheet = $reader->load("05featuredemo.xls");
|
||||
|
@ -222,7 +222,7 @@ $spreadsheet = $reader->load("05featuredemo.xls");
|
|||
You can set the option setLoadSheetsOnly on the reader, to instruct the
|
||||
reader to only load the sheets with a given name:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xls();
|
||||
$reader->setLoadSheetsOnly(["Sheet 1", "My special sheet"]);
|
||||
$spreadsheet = $reader->load("05featuredemo.xls");
|
||||
|
@ -239,7 +239,7 @@ read using the `\PhpOffice\PhpSpreadsheet\Reader\DefaultReadFilter`.
|
|||
The following code will only read row 1 and rows 20 to 30 of any sheet
|
||||
in the Excel file:
|
||||
|
||||
``` php
|
||||
```php
|
||||
class MyReadFilter implements \PhpOffice\PhpSpreadsheet\Reader\IReadFilter {
|
||||
|
||||
public function readCell($column, $row, $worksheetName = '') {
|
||||
|
@ -262,7 +262,7 @@ $spreadsheet = $reader->load("06largescale.xls");
|
|||
|
||||
You can write an .xls file using the following code:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Xls($spreadsheet);
|
||||
$writer->save("05featuredemo.xls");
|
||||
```
|
||||
|
@ -282,7 +282,7 @@ spreadsheets via PHP.
|
|||
|
||||
You can read an Excel 2003 .xml file using the following code:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xml();
|
||||
$spreadsheet = $reader->load("05featuredemo.xml");
|
||||
```
|
||||
|
@ -298,7 +298,7 @@ read using the `\PhpOffice\PhpSpreadsheet\Reader\DefaultReadFilter`.
|
|||
The following code will only read row 1 and rows 20 to 30 of any sheet
|
||||
in the Excel file:
|
||||
|
||||
``` php
|
||||
```php
|
||||
class MyReadFilter implements \PhpOffice\PhpSpreadsheet\Reader\IReadFilter {
|
||||
|
||||
public function readCell($column, $row, $worksheetName = '') {
|
||||
|
@ -333,7 +333,7 @@ regarding to styling cells and handling large spreadsheets via PHP.
|
|||
|
||||
You can read an .slk file using the following code:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Slk();
|
||||
$spreadsheet = $reader->load("05featuredemo.slk");
|
||||
```
|
||||
|
@ -349,7 +349,7 @@ read using the `\PhpOffice\PhpSpreadsheet\Reader\DefaultReadFilter`.
|
|||
The following code will only read row 1 and rows 20 to 30 of any sheet
|
||||
in the SYLK file:
|
||||
|
||||
``` php
|
||||
```php
|
||||
class MyReadFilter implements \PhpOffice\PhpSpreadsheet\Reader\IReadFilter {
|
||||
|
||||
public function readCell($column, $row, $worksheetName = '') {
|
||||
|
@ -378,7 +378,7 @@ Open Office or Libre Office Calc files.
|
|||
|
||||
You can read an .ods file using the following code:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Ods();
|
||||
$spreadsheet = $reader->load("05featuredemo.ods");
|
||||
```
|
||||
|
@ -394,7 +394,7 @@ read using the `\PhpOffice\PhpSpreadsheet\Reader\DefaultReadFilter`.
|
|||
The following code will only read row 1 and rows 20 to 30 of any sheet
|
||||
in the Calc file:
|
||||
|
||||
``` php
|
||||
```php
|
||||
class MyReadFilter implements \PhpOffice\PhpSpreadsheet\Reader\IReadFilter {
|
||||
|
||||
public function readCell($column, $row, $worksheetName = '') {
|
||||
|
@ -427,7 +427,7 @@ regarding to styling cells, number formatting, ...
|
|||
|
||||
You can read a .csv file using the following code:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Csv();
|
||||
$spreadsheet = $reader->load("sample.csv");
|
||||
```
|
||||
|
@ -449,7 +449,7 @@ were created in Microsoft Office Excel the correct input encoding may
|
|||
rather be Windows-1252 (CP1252). Always make sure that the input
|
||||
encoding is set appropriately.
|
||||
|
||||
``` php
|
||||
```php
|
||||
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Csv();
|
||||
$reader->setInputEncoding('CP1252');
|
||||
$reader->setDelimiter(';');
|
||||
|
@ -464,7 +464,7 @@ $spreadsheet = $reader->load("sample.csv");
|
|||
CSV files can only contain one worksheet. Therefore, you can specify
|
||||
which sheet to read from CSV:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$reader->setSheetIndex(0);
|
||||
```
|
||||
|
||||
|
@ -475,7 +475,7 @@ data into an existing `Spreadsheet` object. The following code loads a
|
|||
CSV file into an existing `$spreadsheet` containing some sheets, and
|
||||
imports onto the 6th sheet:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Csv();
|
||||
$reader->setDelimiter(';');
|
||||
$reader->setEnclosure('');
|
||||
|
@ -490,7 +490,7 @@ $reader->loadIntoExisting("05featuredemo.csv", $spreadsheet);
|
|||
|
||||
You can write a .csv file using the following code:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Csv($spreadsheet);
|
||||
$writer->save("05featuredemo.csv");
|
||||
```
|
||||
|
@ -502,7 +502,7 @@ as a separator. You can instruct
|
|||
`\PhpOffice\PhpSpreadsheet\Writer\Csv` some options before writing a CSV
|
||||
file:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Csv($spreadsheet);
|
||||
$writer->setDelimiter(';');
|
||||
$writer->setEnclosure('');
|
||||
|
@ -517,7 +517,7 @@ $writer->save("05featuredemo.csv");
|
|||
CSV files can only contain one worksheet. Therefore, you can specify
|
||||
which sheet to write to CSV:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$writer->setSheetIndex(0);
|
||||
```
|
||||
|
||||
|
@ -527,7 +527,7 @@ By default, this writer pre-calculates all formulas in the spreadsheet.
|
|||
This can be slow on large spreadsheets, and maybe even unwanted. You can
|
||||
however disable formula pre-calculation:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Csv($spreadsheet);
|
||||
$writer->setPreCalculateFormulas(false);
|
||||
$writer->save("05featuredemo.csv");
|
||||
|
@ -542,7 +542,7 @@ it should explicitly include a BOM file header;
|
|||
if it doesn't, Excel will not interpret those characters correctly.
|
||||
This can be enabled by using the following code:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Csv($spreadsheet);
|
||||
$writer->setUseBOM(true);
|
||||
$writer->save("05featuredemo.csv");
|
||||
|
@ -560,14 +560,14 @@ to set the characters explicitly as shown below.
|
|||
|
||||
English users will want to use this before doing the export:
|
||||
|
||||
``` php
|
||||
```php
|
||||
\PhpOffice\PhpSpreadsheet\Shared\StringHelper::setDecimalSeparator('.');
|
||||
\PhpOffice\PhpSpreadsheet\Shared\StringHelper::setThousandsSeparator(',');
|
||||
```
|
||||
|
||||
German users will want to use the opposite values.
|
||||
|
||||
``` php
|
||||
```php
|
||||
\PhpOffice\PhpSpreadsheet\Shared\StringHelper::setDecimalSeparator(',');
|
||||
\PhpOffice\PhpSpreadsheet\Shared\StringHelper::setThousandsSeparator('.');
|
||||
```
|
||||
|
@ -592,7 +592,7 @@ regarding to styling cells, number formatting, ...
|
|||
|
||||
You can read an .html or .htm file using the following code:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Html();
|
||||
|
||||
$spreadsheet = $reader->load("05featuredemo.html");
|
||||
|
@ -610,7 +610,7 @@ first worksheet by default.
|
|||
|
||||
You can write a .htm file using the following code:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Html($spreadsheet);
|
||||
|
||||
$writer->save("05featuredemo.htm");
|
||||
|
@ -621,7 +621,7 @@ $writer->save("05featuredemo.htm");
|
|||
HTML files can contain one or more worksheets. If you want to write all
|
||||
sheets into a single HTML file, use the following code:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$writer->writeAllSheets();
|
||||
```
|
||||
|
||||
|
@ -630,7 +630,7 @@ $writer->writeAllSheets();
|
|||
HTML files can contain one or more worksheets. Therefore, you can
|
||||
specify which sheet to write to HTML:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$writer->setSheetIndex(0);
|
||||
```
|
||||
|
||||
|
@ -639,19 +639,19 @@ $writer->setSheetIndex(0);
|
|||
There might be situations where you want to explicitly set the included
|
||||
images root. For example, instead of:
|
||||
|
||||
``` html
|
||||
```html
|
||||
<img src="./images/logo.jpg">
|
||||
```
|
||||
|
||||
You might want to see:
|
||||
|
||||
``` html
|
||||
```html
|
||||
<img src="http://www.domain.com/images/logo.jpg">
|
||||
```
|
||||
|
||||
You can use the following code to achieve this result:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$writer->setImagesRoot('http://www.example.com');
|
||||
```
|
||||
|
||||
|
@ -661,7 +661,7 @@ By default, this writer pre-calculates all formulas in the spreadsheet.
|
|||
This can be slow on large spreadsheets, and maybe even unwanted. You can
|
||||
however disable formula pre-calculation:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Html($spreadsheet);
|
||||
$writer->setPreCalculateFormulas(false);
|
||||
|
||||
|
@ -686,7 +686,7 @@ Supported methods:
|
|||
Here's an example which retrieves all parts independently and merges
|
||||
them into a resulting HTML page:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Html($spreadsheet);
|
||||
$hdr = $writer->generateHTMLHeader();
|
||||
$sty = $writer->generateStyles(false); // do not write <style> and </style>
|
||||
|
@ -757,7 +757,7 @@ own circumstances.
|
|||
|
||||
You can instantiate a writer with its specific name, like so:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, 'Mpdf');
|
||||
```
|
||||
|
||||
|
@ -765,7 +765,7 @@ Or you can register which writer you are using with a more generic name,
|
|||
so you don't need to remember which library you chose, only that you want
|
||||
to write PDF files:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$class = \PhpOffice\PhpSpreadsheet\Writer\Pdf\Mpdf::class;
|
||||
\PhpOffice\PhpSpreadsheet\IOFactory::registerWriter('Pdf', $class);
|
||||
$writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, 'Pdf');
|
||||
|
@ -773,7 +773,7 @@ $writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, 'Pdf')
|
|||
|
||||
Or you can instantiate directly the writer of your choice like so:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$writer = \PhpOffice\PhpSpreadsheet\Writer\Pdf\Mpdf($spreadsheet);
|
||||
```
|
||||
|
||||
|
@ -782,7 +782,7 @@ $writer = \PhpOffice\PhpSpreadsheet\Writer\Pdf\Mpdf($spreadsheet);
|
|||
If you need a custom implementation, or custom configuration, of a supported
|
||||
PDF library. You can extends the PDF library, and the PDF writer like so:
|
||||
|
||||
``` php
|
||||
```php
|
||||
class My_Custom_TCPDF extends TCPDF
|
||||
{
|
||||
// ...
|
||||
|
@ -808,7 +808,7 @@ class My_Custom_TCPDF_Writer extends \PhpOffice\PhpSpreadsheet\Writer\Pdf\Tcpdf
|
|||
Once you have identified the Renderer that you wish to use for PDF
|
||||
generation, you can write a .pdf file using the following code:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Pdf\Mpdf($spreadsheet);
|
||||
$writer->save("05featuredemo.pdf");
|
||||
```
|
||||
|
@ -821,7 +821,7 @@ first worksheet by default.
|
|||
PDF files can contain one or more worksheets. If you want to write all
|
||||
sheets into a single PDF file, use the following code:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$writer->writeAllSheets();
|
||||
```
|
||||
|
||||
|
@ -830,7 +830,7 @@ $writer->writeAllSheets();
|
|||
PDF files can contain one or more worksheets. Therefore, you can specify
|
||||
which sheet to write to PDF:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$writer->setSheetIndex(0);
|
||||
```
|
||||
|
||||
|
@ -840,7 +840,7 @@ By default, this writer pre-calculates all formulas in the spreadsheet.
|
|||
This can be slow on large spreadsheets, and maybe even unwanted. You can
|
||||
however disable formula pre-calculation:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Pdf\Mpdf($spreadsheet);
|
||||
$writer->setPreCalculateFormulas(false);
|
||||
|
||||
|
@ -868,7 +868,7 @@ page setup properties, headers etc.
|
|||
Here is an example how to open a template file, fill in a couple of
|
||||
fields and save it again:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load('template.xlsx');
|
||||
|
||||
$worksheet = $spreadsheet->getActiveSheet();
|
||||
|
|
|
@ -22,7 +22,7 @@ The simplest way to load a workbook file is to let PhpSpreadsheet's IO
|
|||
Factory identify the file type and load it, calling the static `load()`
|
||||
method of the `\PhpOffice\PhpSpreadsheet\IOFactory` class.
|
||||
|
||||
``` php
|
||||
```php
|
||||
$inputFileName = './sampleData/example1.xls';
|
||||
|
||||
/** Load $inputFileName to a Spreadsheet Object **/
|
||||
|
@ -59,7 +59,7 @@ supported filetype by name. However, you may get unpredictable results
|
|||
if the file isn't of the right type (e.g. it is a CSV with an extension
|
||||
of .xls), although this type of exception should normally be trapped.
|
||||
|
||||
``` php
|
||||
```php
|
||||
$inputFileName = './sampleData/example1.xls';
|
||||
|
||||
/** Create a new Xls Reader **/
|
||||
|
@ -81,7 +81,7 @@ Alternatively, you can use the IO Factory's `createReader()` method to
|
|||
instantiate the reader object for you, simply telling it the file type
|
||||
of the reader that you want instantiating.
|
||||
|
||||
``` php
|
||||
```php
|
||||
$inputFileType = 'Xls';
|
||||
// $inputFileType = 'Xlsx';
|
||||
// $inputFileType = 'Xml';
|
||||
|
@ -104,7 +104,7 @@ If you're uncertain of the filetype, you can use the `IOFactory::identify()`
|
|||
method to identify the reader that you need, before using the
|
||||
`createReader()` method to instantiate the reader object.
|
||||
|
||||
``` php
|
||||
```php
|
||||
$inputFileName = './sampleData/example1.xls';
|
||||
|
||||
/** Identify the type of $inputFileName **/
|
||||
|
@ -131,7 +131,7 @@ need any of the cell formatting information, then you can set the reader
|
|||
to read only the data values and any formulae from each cell using the
|
||||
`setReadDataOnly()` method.
|
||||
|
||||
``` php
|
||||
```php
|
||||
$inputFileType = 'Xls';
|
||||
$inputFileName = './sampleData/example1.xls';
|
||||
|
||||
|
@ -176,7 +176,7 @@ in reading.
|
|||
To read a single sheet, you can pass that sheet name as a parameter to
|
||||
the `setLoadSheetsOnly()` method.
|
||||
|
||||
``` php
|
||||
```php
|
||||
$inputFileType = 'Xls';
|
||||
$inputFileName = './sampleData/example1.xls';
|
||||
$sheetname = 'Data Sheet #2';
|
||||
|
@ -195,7 +195,7 @@ for a working example of this code.
|
|||
If you want to read more than just a single sheet, you can pass a list
|
||||
of sheet names as an array parameter to the `setLoadSheetsOnly()` method.
|
||||
|
||||
``` php
|
||||
```php
|
||||
$inputFileType = 'Xls';
|
||||
$inputFileName = './sampleData/example1.xls';
|
||||
$sheetnames = ['Data Sheet #1','Data Sheet #3'];
|
||||
|
@ -214,7 +214,7 @@ for a working example of this code.
|
|||
To reset this option to the default, you can call the `setLoadAllSheets()`
|
||||
method.
|
||||
|
||||
``` php
|
||||
```php
|
||||
$inputFileType = 'Xls';
|
||||
$inputFileName = './sampleData/example1.xls';
|
||||
|
||||
|
@ -248,7 +248,7 @@ should be read by the loader. A read filter must implement the
|
|||
whether a workbook cell identified by those arguments should be read or
|
||||
not.
|
||||
|
||||
``` php
|
||||
```php
|
||||
$inputFileType = 'Xls';
|
||||
$inputFileName = './sampleData/example1.xls';
|
||||
$sheetname = 'Data Sheet #3';
|
||||
|
@ -286,7 +286,7 @@ a very specific circumstance (when you only want cells in the range
|
|||
A1:E7 from your worksheet. A generic Read Filter would probably be more
|
||||
useful:
|
||||
|
||||
``` php
|
||||
```php
|
||||
/** Define a Read Filter class implementing \PhpOffice\PhpSpreadsheet\Reader\IReadFilter */
|
||||
class MyReadFilter implements \PhpOffice\PhpSpreadsheet\Reader\IReadFilter
|
||||
{
|
||||
|
@ -324,7 +324,7 @@ to read and process a large workbook in "chunks": an example of this
|
|||
usage might be when transferring data from an Excel worksheet to a
|
||||
database.
|
||||
|
||||
``` php
|
||||
```php
|
||||
$inputFileType = 'Xls';
|
||||
$inputFileName = './sampleData/example2.xls';
|
||||
|
||||
|
@ -393,7 +393,7 @@ the `setSheetIndex()` method of the `$reader`, then use the
|
|||
`loadIntoExisting()` method rather than the `load()` method to actually read
|
||||
the file into that worksheet.
|
||||
|
||||
``` php
|
||||
```php
|
||||
$inputFileType = 'Csv';
|
||||
$inputFileNames = [
|
||||
'./sampleData/example1.csv',
|
||||
|
@ -452,7 +452,7 @@ Class that we defined in [the above section](#reading-only-specific-columns-and-
|
|||
and the `setSheetIndex()` method of the `$reader`, we can split the CSV
|
||||
file across several individual worksheets.
|
||||
|
||||
``` php
|
||||
```php
|
||||
$inputFileType = 'Csv';
|
||||
$inputFileName = './sampleData/example2.csv';
|
||||
|
||||
|
@ -523,7 +523,7 @@ cannot auto-detect, it will default to the comma. If this does not fit your
|
|||
use-case, you can manually specify a separator by using the `setDelimiter()`
|
||||
method.
|
||||
|
||||
``` php
|
||||
```php
|
||||
$inputFileType = 'Csv';
|
||||
$inputFileName = './sampleData/example1.tsv';
|
||||
|
||||
|
@ -585,7 +585,7 @@ it encountered a hyperlink, or HTML markup within a CSV file.
|
|||
So using a Value Binder allows a great deal more flexibility in the
|
||||
loader logic when reading unformatted text files.
|
||||
|
||||
``` php
|
||||
```php
|
||||
/** Tell PhpSpreadsheet that we want to use the Advanced Value Binder **/
|
||||
\PhpOffice\PhpSpreadsheet\Cell\Cell::setValueBinder( new \PhpOffice\PhpSpreadsheet\Cell\AdvancedValueBinder() );
|
||||
|
||||
|
@ -619,7 +619,7 @@ manner.
|
|||
The PhpSpreadsheet Readers throw a
|
||||
`\PhpOffice\PhpSpreadsheet\Reader\Exception`.
|
||||
|
||||
``` php
|
||||
```php
|
||||
$inputFileName = './sampleData/example-1.xls';
|
||||
|
||||
try {
|
||||
|
@ -646,7 +646,7 @@ whole file.
|
|||
The `listWorksheetNames()` method returns a simple array listing each
|
||||
worksheet name within the workbook:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader($inputFileType);
|
||||
|
||||
$worksheetNames = $reader->listWorksheetNames($inputFileName);
|
||||
|
@ -667,7 +667,7 @@ for a working example of this code.
|
|||
The `listWorksheetInfo()` method returns a nested array, with each entry
|
||||
listing the name and dimensions for a worksheet:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader($inputFileType);
|
||||
|
||||
$worksheetData = $reader->listWorksheetInfo($inputFileName);
|
||||
|
|
|
@ -20,7 +20,7 @@ metadata to search for a specific document in its document lists.
|
|||
|
||||
Setting spreadsheet metadata is done as follows:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$spreadsheet->getProperties()
|
||||
->setCreator("Maarten Balliauw")
|
||||
->setLastModifiedBy("Maarten Balliauw")
|
||||
|
@ -38,13 +38,13 @@ $spreadsheet->getProperties()
|
|||
The following line of code sets the active sheet index to the first
|
||||
sheet:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$spreadsheet->setActiveSheetIndex(0);
|
||||
```
|
||||
|
||||
You can also set the active sheet by its name/title
|
||||
|
||||
``` php
|
||||
```php
|
||||
$spreadsheet->setActiveSheetIndexByName('DataSheet')
|
||||
```
|
||||
|
||||
|
@ -68,7 +68,7 @@ UST.
|
|||
Writing a date value in a cell consists of 2 lines of code. Select the
|
||||
method that suits you the best. Here are some examples:
|
||||
|
||||
``` php
|
||||
```php
|
||||
|
||||
// MySQL-like timestamp '2008-12-31' or date string
|
||||
\PhpOffice\PhpSpreadsheet\Cell\Cell::setValueBinder( new \PhpOffice\PhpSpreadsheet\Cell\AdvancedValueBinder() );
|
||||
|
@ -136,14 +136,14 @@ The following line of code writes the formula
|
|||
formula must start with `=` to make PhpSpreadsheet recognise this as a
|
||||
formula.
|
||||
|
||||
``` php
|
||||
```php
|
||||
$spreadsheet->getActiveSheet()->setCellValue('B8','=IF(C4>500,"profit","loss")');
|
||||
```
|
||||
|
||||
If you want to write a string beginning with an `=` character to a
|
||||
cell, then you should use the `setCellValueExplicit()` method.
|
||||
|
||||
``` php
|
||||
```php
|
||||
$spreadsheet->getActiveSheet()
|
||||
->setCellValueExplicit(
|
||||
'B8',
|
||||
|
@ -154,14 +154,14 @@ $spreadsheet->getActiveSheet()
|
|||
|
||||
A cell's formula can be read again using the following line of code:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$formula = $spreadsheet->getActiveSheet()->getCell('B8')->getValue();
|
||||
```
|
||||
|
||||
If you need the calculated value of a cell, use the following code. This
|
||||
is further explained in [the calculation engine](./calculation-engine.md).
|
||||
|
||||
``` php
|
||||
```php
|
||||
$value = $spreadsheet->getActiveSheet()->getCell('B8')->getCalculatedValue();
|
||||
```
|
||||
|
||||
|
@ -171,7 +171,7 @@ Some localisation elements have been included in PhpSpreadsheet. You can
|
|||
set a locale by changing the settings. To set the locale to Russian you
|
||||
would use:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$locale = 'ru';
|
||||
$validLocale = \PhpOffice\PhpSpreadsheet\Settings::setLocale($locale);
|
||||
if (!$validLocale) {
|
||||
|
@ -185,7 +185,7 @@ will return an error, and English settings will be used throughout.
|
|||
Once you have set a locale, you can translate a formula from its
|
||||
internal English coding.
|
||||
|
||||
``` php
|
||||
```php
|
||||
$formula = $spreadsheet->getActiveSheet()->getCell('B8')->getValue();
|
||||
$translatedFormula = \PhpOffice\PhpSpreadsheet\Calculation\Calculation::getInstance()->_translateFormulaToLocale($formula);
|
||||
```
|
||||
|
@ -194,7 +194,7 @@ You can also create a formula using the function names and argument
|
|||
separators appropriate to the defined locale; then translate it to
|
||||
English before setting the cell value:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$formula = '=ДНЕЙ360(ДАТА(2010;2;5);ДАТА(2010;12;31);ИСТИНА)';
|
||||
$internalFormula = \PhpOffice\PhpSpreadsheet\Calculation\Calculation::getInstance()->translateFormulaToEnglish($formula);
|
||||
$spreadsheet->getActiveSheet()->setCellValue('B8',$internalFormula);
|
||||
|
@ -232,7 +232,7 @@ the cell.
|
|||
|
||||
Here is how to achieve this in PhpSpreadsheet:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$spreadsheet->getActiveSheet()->getCell('A1')->setValue("hello\nworld");
|
||||
$spreadsheet->getActiveSheet()->getStyle('A1')->getAlignment()->setWrapText(true);
|
||||
```
|
||||
|
@ -247,7 +247,7 @@ AdvancedValuebinder.php automatically turns on "wrap text" for the cell
|
|||
when it sees a newline character in a string that you are inserting in a
|
||||
cell. Just like Microsoft Office Excel. Try this:
|
||||
|
||||
``` php
|
||||
```php
|
||||
\PhpOffice\PhpSpreadsheet\Cell\Cell::setValueBinder( new \PhpOffice\PhpSpreadsheet\Cell\AdvancedValueBinder() );
|
||||
|
||||
$spreadsheet->getActiveSheet()->getCell('A1')->setValue("hello\nworld");
|
||||
|
@ -261,7 +261,7 @@ You can set a cell's datatype explicitly by using the cell's
|
|||
setValueExplicit method, or the setCellValueExplicit method of a
|
||||
worksheet. Here's an example:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$spreadsheet->getActiveSheet()->getCell('A1')
|
||||
->setValueExplicit(
|
||||
'25',
|
||||
|
@ -273,7 +273,7 @@ $spreadsheet->getActiveSheet()->getCell('A1')
|
|||
|
||||
You can make a cell a clickable URL by setting its hyperlink property:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$spreadsheet->getActiveSheet()->setCellValue('E26', 'www.phpexcel.net');
|
||||
$spreadsheet->getActiveSheet()->getCell('E26')->getHyperlink()->setUrl('https://www.example.com');
|
||||
```
|
||||
|
@ -281,7 +281,7 @@ $spreadsheet->getActiveSheet()->getCell('E26')->getHyperlink()->setUrl('https://
|
|||
If you want to make a hyperlink to another worksheet/cell, use the
|
||||
following code:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$spreadsheet->getActiveSheet()->setCellValue('E26', 'www.phpexcel.net');
|
||||
$spreadsheet->getActiveSheet()->getCell('E26')->getHyperlink()->setUrl("sheet://'Sheetname'!A1");
|
||||
```
|
||||
|
@ -293,7 +293,7 @@ $spreadsheet->getActiveSheet()->getCell('E26')->getHyperlink()->setUrl("sheet://
|
|||
Setting a worksheet's page orientation and size can be done using the
|
||||
following lines of code:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$spreadsheet->getActiveSheet()->getPageSetup()
|
||||
->setOrientation(\PhpOffice\PhpSpreadsheet\Worksheet\PageSetup::ORIENTATION_LANDSCAPE);
|
||||
$spreadsheet->getActiveSheet()->getPageSetup()
|
||||
|
@ -324,7 +324,7 @@ setFitToHeight(...) | 1 | setFitToPage(TRUE) | value 0 mean
|
|||
|
||||
Here is how to fit to 1 page wide by infinite pages tall:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$spreadsheet->getActiveSheet()->getPageSetup()->setFitToWidth(1);
|
||||
$spreadsheet->getActiveSheet()->getPageSetup()->setFitToHeight(0);
|
||||
```
|
||||
|
@ -340,7 +340,7 @@ the initial values.
|
|||
|
||||
To set page margins for a worksheet, use this code:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$spreadsheet->getActiveSheet()->getPageMargins()->setTop(1);
|
||||
$spreadsheet->getActiveSheet()->getPageMargins()->setRight(0.75);
|
||||
$spreadsheet->getActiveSheet()->getPageMargins()->setLeft(0.75);
|
||||
|
@ -356,7 +356,7 @@ Note that the margin values are specified in inches.
|
|||
To center a page horizontally/vertically, you can use the following
|
||||
code:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$spreadsheet->getActiveSheet()->getPageSetup()->setHorizontalCentered(true);
|
||||
$spreadsheet->getActiveSheet()->getPageSetup()->setVerticalCentered(false);
|
||||
```
|
||||
|
@ -366,7 +366,7 @@ $spreadsheet->getActiveSheet()->getPageSetup()->setVerticalCentered(false);
|
|||
Setting a worksheet's print header and footer can be done using the
|
||||
following lines of code:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$spreadsheet->getActiveSheet()->getHeaderFooter()
|
||||
->setOddHeader('&C&HPlease treat this document as confidential!');
|
||||
$spreadsheet->getActiveSheet()->getHeaderFooter()
|
||||
|
@ -460,13 +460,13 @@ $spreadsheet->getActiveSheet()->getHeaderFooter()->addImage($drawing, \PhpOffice
|
|||
To set a print break, use the following code, which sets a row break on
|
||||
row 10.
|
||||
|
||||
``` php
|
||||
```php
|
||||
$spreadsheet->getActiveSheet()->setBreak('A10', \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet::BREAK_ROW);
|
||||
```
|
||||
|
||||
The following line of code sets a print break on column D:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$spreadsheet->getActiveSheet()->setBreak('D10', \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet::BREAK_COLUMN);
|
||||
```
|
||||
|
||||
|
@ -484,7 +484,7 @@ PhpSpreadsheet can repeat specific rows/cells at top/left of a page. The
|
|||
following code is an example of how to repeat row 1 to 5 on each printed
|
||||
page of a specific worksheet:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$spreadsheet->getActiveSheet()->getPageSetup()->setRowsToRepeatAtTopByStartAndEnd(1, 5);
|
||||
```
|
||||
|
||||
|
@ -492,13 +492,13 @@ $spreadsheet->getActiveSheet()->getPageSetup()->setRowsToRepeatAtTopByStartAndEn
|
|||
|
||||
To specify a worksheet's printing area, use the following code:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$spreadsheet->getActiveSheet()->getPageSetup()->setPrintArea('A1:E5');
|
||||
```
|
||||
|
||||
There can also be multiple printing areas in a single worksheet:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$spreadsheet->getActiveSheet()->getPageSetup()->setPrintArea('A1:E5,G4:M20');
|
||||
```
|
||||
|
||||
|
@ -511,7 +511,7 @@ For example, one can set the foreground colour of a cell to red, aligned
|
|||
to the right, and the border to black and thick border style. Let's do
|
||||
that on cell B2:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$spreadsheet->getActiveSheet()->getStyle('B2')
|
||||
->getFont()->getColor()->setARGB(\PhpOffice\PhpSpreadsheet\Style\Color::COLOR_RED);
|
||||
$spreadsheet->getActiveSheet()->getStyle('B2')
|
||||
|
@ -533,7 +533,7 @@ $spreadsheet->getActiveSheet()->getStyle('B2')
|
|||
`getStyle()` also accepts a cell range as a parameter. For example, you
|
||||
can set a red background color on a range of cells:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$spreadsheet->getActiveSheet()->getStyle('B3:B7')->getFill()
|
||||
->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID)
|
||||
->getStartColor()->setARGB('FFFF0000');
|
||||
|
@ -548,7 +548,7 @@ There is also an alternative manner to set styles. The following code
|
|||
sets a cell's style to font bold, alignment right, top border thin and a
|
||||
gradient fill:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$styleArray = [
|
||||
'font' => [
|
||||
'bold' => true,
|
||||
|
@ -578,7 +578,7 @@ $spreadsheet->getActiveSheet()->getStyle('A3')->applyFromArray($styleArray);
|
|||
|
||||
Or with a range of cells:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$spreadsheet->getActiveSheet()->getStyle('B3:B7')->applyFromArray($styleArray);
|
||||
```
|
||||
|
||||
|
@ -602,7 +602,7 @@ number format code unless you need a custom number format.
|
|||
In PhpSpreadsheet, you can also apply various predefined number formats.
|
||||
Example:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$spreadsheet->getActiveSheet()->getStyle('A1')->getNumberFormat()
|
||||
->setFormatCode(\PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_NUMBER_COMMA_SEPARATED1);
|
||||
```
|
||||
|
@ -614,7 +614,7 @@ up as 1.587,20)
|
|||
|
||||
You can achieve exactly the same as the above by using this:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$spreadsheet->getActiveSheet()->getStyle('A1')->getNumberFormat()
|
||||
->setFormatCode('#,##0.00');
|
||||
```
|
||||
|
@ -623,7 +623,7 @@ In Microsoft Office Excel, as well as in PhpSpreadsheet, you will have
|
|||
to interact with raw number format codes whenever you need some special
|
||||
custom number format. Example:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$spreadsheet->getActiveSheet()->getStyle('A1')->getNumberFormat()
|
||||
->setFormatCode('[Blue][>=3000]$#,##0;[Red][<0]$#,##0;$#,##0');
|
||||
```
|
||||
|
@ -631,7 +631,7 @@ $spreadsheet->getActiveSheet()->getStyle('A1')->getNumberFormat()
|
|||
Another example is when you want numbers zero-padded with leading zeros
|
||||
to a fixed length:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$spreadsheet->getActiveSheet()->getCell('A1')->setValue(19);
|
||||
$spreadsheet->getActiveSheet()->getStyle('A1')->getNumberFormat()
|
||||
->setFormatCode('0000'); // will show as 0019 in Excel
|
||||
|
@ -646,7 +646,7 @@ The readers shipped with PhpSpreadsheet come to the rescue. Load your
|
|||
template workbook using e.g. Xlsx reader to reveal the number format
|
||||
code. Example how read a number format code for cell A1:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader('Xlsx');
|
||||
$spreadsheet = $reader->load('template.xlsx');
|
||||
var_dump($spreadsheet->getActiveSheet()->getStyle('A1')->getNumberFormat()->getFormatCode());
|
||||
|
@ -661,14 +661,14 @@ code in *xl/styles.xml*.
|
|||
|
||||
Let's set vertical alignment to the top for cells A1:D4
|
||||
|
||||
``` php
|
||||
```php
|
||||
$spreadsheet->getActiveSheet()->getStyle('A1:D4')
|
||||
->getAlignment()->setVertical(\PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_TOP);
|
||||
```
|
||||
|
||||
Here is how to achieve wrap text:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$spreadsheet->getActiveSheet()->getStyle('A1:D4')
|
||||
->getAlignment()->setWrapText(true);
|
||||
```
|
||||
|
@ -678,7 +678,7 @@ $spreadsheet->getActiveSheet()->getStyle('A1:D4')
|
|||
It is possible to set the default style of a workbook. Let's set the
|
||||
default font to Arial size 8:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$spreadsheet->getDefaultStyle()->getFont()->setName('Arial');
|
||||
$spreadsheet->getDefaultStyle()->getFont()->setSize(8);
|
||||
```
|
||||
|
@ -689,7 +689,7 @@ In PhpSpreadsheet it is easy to apply various borders on a rectangular
|
|||
selection. Here is how to apply a thick red border outline around cells
|
||||
B2:G8.
|
||||
|
||||
``` php
|
||||
```php
|
||||
$styleArray = [
|
||||
'borders' => [
|
||||
'outline' => [
|
||||
|
@ -839,7 +839,7 @@ is below zero, and to green if its value is zero or more.
|
|||
One can set a conditional style ruleset to a cell using the following
|
||||
code:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$conditional1 = new \PhpOffice\PhpSpreadsheet\Style\Conditional();
|
||||
$conditional1->setConditionType(\PhpOffice\PhpSpreadsheet\Style\Conditional::CONDITION_CELLIS);
|
||||
$conditional1->setOperatorType(\PhpOffice\PhpSpreadsheet\Style\Conditional::OPERATOR_LESSTHAN);
|
||||
|
@ -864,7 +864,7 @@ $spreadsheet->getActiveSheet()->getStyle('B2')->setConditionalStyles($conditiona
|
|||
If you want to copy the ruleset to other cells, you can duplicate the
|
||||
style object:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$spreadsheet->getActiveSheet()
|
||||
->duplicateStyle(
|
||||
$spreadsheet->getActiveSheet()->getStyle('B2'),
|
||||
|
@ -877,7 +877,7 @@ $spreadsheet->getActiveSheet()
|
|||
To add a comment to a cell, use the following code. The example below
|
||||
adds a comment to cell E11:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$spreadsheet->getActiveSheet()
|
||||
->getComment('E11')
|
||||
->setAuthor('Mark Baker');
|
||||
|
@ -899,7 +899,7 @@ $spreadsheet->getActiveSheet()
|
|||
|
||||
To apply an autofilter to a range of cells, use the following code:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$spreadsheet->getActiveSheet()->setAutoFilter('A1:C9');
|
||||
```
|
||||
|
||||
|
@ -919,45 +919,85 @@ disallow inserting rows on a specific sheet, disallow sorting, ...
|
|||
- Cell: offers the option to lock/unlock a cell as well as show/hide
|
||||
the internal formula.
|
||||
|
||||
**Make sure you enable worksheet protection if you need any of the
|
||||
worksheet or cell protection features!** This can be done using the following
|
||||
code:
|
||||
|
||||
```php
|
||||
$spreadsheet->getActiveSheet()->getProtection()->setSheet(true);
|
||||
```
|
||||
|
||||
### Document
|
||||
|
||||
An example on setting document security:
|
||||
|
||||
``` php
|
||||
$spreadsheet->getSecurity()->setLockWindows(true);
|
||||
$spreadsheet->getSecurity()->setLockStructure(true);
|
||||
$spreadsheet->getSecurity()->setWorkbookPassword("PhpSpreadsheet");
|
||||
```php
|
||||
$security = $spreadsheet->getSecurity();
|
||||
$security->setLockWindows(true);
|
||||
$security->setLockStructure(true);
|
||||
$security->setWorkbookPassword("PhpSpreadsheet");
|
||||
```
|
||||
|
||||
### Worksheet
|
||||
|
||||
An example on setting worksheet security:
|
||||
|
||||
``` php
|
||||
$spreadsheet->getActiveSheet()
|
||||
->getProtection()->setPassword('PhpSpreadsheet');
|
||||
$spreadsheet->getActiveSheet()
|
||||
->getProtection()->setSheet(true);
|
||||
$spreadsheet->getActiveSheet()
|
||||
->getProtection()->setSort(true);
|
||||
$spreadsheet->getActiveSheet()
|
||||
->getProtection()->setInsertRows(true);
|
||||
$spreadsheet->getActiveSheet()
|
||||
->getProtection()->setFormatCells(true);
|
||||
```php
|
||||
$protection = $spreadsheet->getActiveSheet()->getProtection();
|
||||
$protection->setPassword('PhpSpreadsheet');
|
||||
$protection->setSheet(true);
|
||||
$protection->setSort(true);
|
||||
$protection->setInsertRows(true);
|
||||
$protection->setFormatCells(true);
|
||||
```
|
||||
|
||||
If writing Xlsx files you can specify the algorithm used to hash the password
|
||||
before calling `setPassword()` like so:
|
||||
|
||||
```php
|
||||
$protection = $spreadsheet->getActiveSheet()->getProtection();
|
||||
$protection->setAlgorithm(Protection::ALGORITHM_SHA_512);
|
||||
$protection->setSpinCount(20000);
|
||||
$protection->setPassword('PhpSpreadsheet');
|
||||
```
|
||||
|
||||
The salt should **not** be set manually and will be automatically generated
|
||||
when setting a new password.
|
||||
|
||||
### Cell
|
||||
|
||||
An example on setting cell security:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$spreadsheet->getActiveSheet()->getStyle('B1')
|
||||
->getProtection()
|
||||
->setLocked(\PhpOffice\PhpSpreadsheet\Style\Protection::PROTECTION_UNPROTECTED);
|
||||
```
|
||||
|
||||
**Make sure you enable worksheet protection if you need any of the
|
||||
worksheet protection features!** This can be done using the following
|
||||
code:
|
||||
## Reading protected spreadsheet
|
||||
|
||||
``` php
|
||||
$spreadsheet->getActiveSheet()->getProtection()->setSheet(true);
|
||||
Spreadsheets that are protected as described above can always be read by
|
||||
PhpSpreadsheet. There is no need to know the password or do anything special in
|
||||
order to read a protected file.
|
||||
|
||||
However if you need to implement a password verification mechanism, you can use the
|
||||
following helper method:
|
||||
|
||||
|
||||
```php
|
||||
$protection = $spreadsheet->getActiveSheet()->getProtection();
|
||||
$allowed = $protection->verify('my password');
|
||||
|
||||
if ($allowed) {
|
||||
doSomething();
|
||||
} else {
|
||||
throw new Exception('Incorrect password');
|
||||
}
|
||||
```
|
||||
|
||||
If you need to completely prevent reading a file by any tool, including PhpSpreadsheet,
|
||||
then you are looking for "encryption", not "protection".
|
||||
|
||||
## Setting data validation on a cell
|
||||
|
||||
Data validation is a powerful feature of Xlsx. It allows to specify an
|
||||
|
@ -968,7 +1008,7 @@ filter can be a range (i.e. value must be between 0 and 10), a list
|
|||
The following piece of code only allows numbers between 10 and 20 to be
|
||||
entered in cell B3:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$validation = $spreadsheet->getActiveSheet()->getCell('B3')
|
||||
->getDataValidation();
|
||||
$validation->setType( \PhpOffice\PhpSpreadsheet\Cell\DataValidation::TYPE_WHOLE );
|
||||
|
@ -987,7 +1027,7 @@ $validation->setFormula2(20);
|
|||
The following piece of code only allows an item picked from a list of
|
||||
data to be entered in cell B5:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$validation = $spreadsheet->getActiveSheet()->getCell('B5')
|
||||
->getDataValidation();
|
||||
$validation->setType( \PhpOffice\PhpSpreadsheet\Cell\DataValidation::TYPE_LIST );
|
||||
|
@ -1017,7 +1057,7 @@ the item values themselves can contain the comma `,` character itself.
|
|||
If you need data validation on multiple cells, one can clone the
|
||||
ruleset:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$spreadsheet->getActiveSheet()->getCell('B8')->setDataValidation(clone $validation);
|
||||
```
|
||||
|
||||
|
@ -1025,7 +1065,7 @@ $spreadsheet->getActiveSheet()->getCell('B8')->setDataValidation(clone $validati
|
|||
|
||||
A column's width can be set using the following code:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$spreadsheet->getActiveSheet()->getColumnDimension('D')->setWidth(12);
|
||||
```
|
||||
|
||||
|
@ -1033,7 +1073,7 @@ If you want PhpSpreadsheet to perform an automatic width calculation,
|
|||
use the following code. PhpSpreadsheet will approximate the column with
|
||||
to the width of the widest column value.
|
||||
|
||||
``` php
|
||||
```php
|
||||
$spreadsheet->getActiveSheet()->getColumnDimension('B')->setAutoSize(true);
|
||||
```
|
||||
|
||||
|
@ -1070,7 +1110,7 @@ To set a worksheet's column visibility, you can use the following code.
|
|||
The first line explicitly shows the column C, the second line hides
|
||||
column D.
|
||||
|
||||
``` php
|
||||
```php
|
||||
$spreadsheet->getActiveSheet()->getColumnDimension('C')->setVisible(true);
|
||||
$spreadsheet->getActiveSheet()->getColumnDimension('D')->setVisible(false);
|
||||
```
|
||||
|
@ -1079,7 +1119,7 @@ $spreadsheet->getActiveSheet()->getColumnDimension('D')->setVisible(false);
|
|||
|
||||
To group/outline a column, you can use the following code:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$spreadsheet->getActiveSheet()->getColumnDimension('E')->setOutlineLevel(1);
|
||||
```
|
||||
|
||||
|
@ -1087,7 +1127,7 @@ You can also collapse the column. Note that you should also set the
|
|||
column invisible, otherwise the collapse will not be visible in Excel
|
||||
2007.
|
||||
|
||||
``` php
|
||||
```php
|
||||
$spreadsheet->getActiveSheet()->getColumnDimension('E')->setCollapsed(true);
|
||||
$spreadsheet->getActiveSheet()->getColumnDimension('E')->setVisible(false);
|
||||
```
|
||||
|
@ -1098,7 +1138,7 @@ on collapsing.
|
|||
You can instruct PhpSpreadsheet to add a summary to the right (default),
|
||||
or to the left. The following code adds the summary to the left:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$spreadsheet->getActiveSheet()->setShowSummaryRight(false);
|
||||
```
|
||||
|
||||
|
@ -1106,7 +1146,7 @@ $spreadsheet->getActiveSheet()->setShowSummaryRight(false);
|
|||
|
||||
A row's height can be set using the following code:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$spreadsheet->getActiveSheet()->getRowDimension('10')->setRowHeight(100);
|
||||
```
|
||||
|
||||
|
@ -1119,7 +1159,7 @@ of values is between 0 and 409 pts, where 0 pts is a hidden row.
|
|||
To set a worksheet''s row visibility, you can use the following code.
|
||||
The following example hides row number 10.
|
||||
|
||||
``` php
|
||||
```php
|
||||
$spreadsheet->getActiveSheet()->getRowDimension('10')->setVisible(false);
|
||||
```
|
||||
|
||||
|
@ -1131,21 +1171,21 @@ AutoFilter range if you save the file.
|
|||
|
||||
To group/outline a row, you can use the following code:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$spreadsheet->getActiveSheet()->getRowDimension('5')->setOutlineLevel(1);
|
||||
```
|
||||
|
||||
You can also collapse the row. Note that you should also set the row
|
||||
invisible, otherwise the collapse will not be visible in Excel 2007.
|
||||
|
||||
``` php
|
||||
```php
|
||||
$spreadsheet->getActiveSheet()->getRowDimension('5')->setCollapsed(true);
|
||||
$spreadsheet->getActiveSheet()->getRowDimension('5')->setVisible(false);
|
||||
```
|
||||
|
||||
Here's an example which collapses rows 50 to 80:
|
||||
|
||||
``` php
|
||||
```php
|
||||
for ($i = 51; $i <= 80; $i++) {
|
||||
$spreadsheet->getActiveSheet()->setCellValue('A' . $i, "FName $i");
|
||||
$spreadsheet->getActiveSheet()->setCellValue('B' . $i, "LName $i");
|
||||
|
@ -1162,7 +1202,7 @@ $spreadsheet->getActiveSheet()->getRowDimension(81)->setCollapsed(true);
|
|||
You can instruct PhpSpreadsheet to add a summary below the collapsible
|
||||
rows (default), or above. The following code adds the summary above:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$spreadsheet->getActiveSheet()->setShowSummaryBelow(false);
|
||||
```
|
||||
|
||||
|
@ -1172,13 +1212,13 @@ If you have a big piece of data you want to display in a worksheet, you
|
|||
can merge two or more cells together, to become one cell. This can be
|
||||
done using the following code:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$spreadsheet->getActiveSheet()->mergeCells('A18:E22');
|
||||
```
|
||||
|
||||
Removing a merge can be done using the unmergeCells method:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$spreadsheet->getActiveSheet()->unmergeCells('A18:E22');
|
||||
```
|
||||
|
||||
|
@ -1187,7 +1227,7 @@ $spreadsheet->getActiveSheet()->unmergeCells('A18:E22');
|
|||
You can insert/remove rows/columns at a specific position. The following
|
||||
code inserts 2 new rows, right before row 7:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$spreadsheet->getActiveSheet()->insertNewRowBefore(7, 2);
|
||||
```
|
||||
|
||||
|
@ -1198,7 +1238,7 @@ to a worksheet. Therefore, you must first instantiate a new
|
|||
`\PhpOffice\PhpSpreadsheet\Worksheet\Drawing`, and assign its properties a
|
||||
meaningful value:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$drawing = new \PhpOffice\PhpSpreadsheet\Worksheet\Drawing();
|
||||
$drawing->setName('Logo');
|
||||
$drawing->setDescription('Logo');
|
||||
|
@ -1210,13 +1250,13 @@ To add the above drawing to the worksheet, use the following snippet of
|
|||
code. PhpSpreadsheet creates the link between the drawing and the
|
||||
worksheet:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$drawing->setWorksheet($spreadsheet->getActiveSheet());
|
||||
```
|
||||
|
||||
You can set numerous properties on a drawing, here are some examples:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$drawing->setName('Paid');
|
||||
$drawing->setDescription('Paid');
|
||||
$drawing->setPath('./images/paid.png');
|
||||
|
@ -1230,7 +1270,7 @@ $drawing->getShadow()->setDirection(45);
|
|||
You can also add images created using GD functions without needing to
|
||||
save them to disk first as In-Memory drawings.
|
||||
|
||||
``` php
|
||||
```php
|
||||
// Use GD to create an in-memory image
|
||||
$gdImage = @imagecreatetruecolor(120, 20) or die('Cannot Initialize new GD image stream');
|
||||
$textColor = imagecolorallocate($gdImage, 255, 255, 255);
|
||||
|
@ -1258,7 +1298,7 @@ that has been loaded, and save them as individual image files to disk.
|
|||
The following code extracts images from the current active worksheet,
|
||||
and writes each as a separate file.
|
||||
|
||||
``` php
|
||||
```php
|
||||
$i = 0;
|
||||
foreach ($spreadsheet->getActiveSheet()->getDrawingCollection() as $drawing) {
|
||||
if ($drawing instanceof \PhpOffice\PhpSpreadsheet\Worksheet\MemoryDrawing) {
|
||||
|
@ -1303,7 +1343,7 @@ creates the following rich text string:
|
|||
> This invoice is ***payable within thirty days after the end of the
|
||||
> month*** unless specified otherwise on the invoice.
|
||||
|
||||
``` php
|
||||
```php
|
||||
$richText = new \PhpOffice\PhpSpreadsheet\RichText\RichText();
|
||||
$richText->createText('This invoice is ');
|
||||
$payable = $richText->createTextRun('payable within thirty days after the end of the month');
|
||||
|
@ -1319,7 +1359,7 @@ $spreadsheet->getActiveSheet()->getCell('A18')->setValue($richText);
|
|||
PhpSpreadsheet supports the definition of named ranges. These can be
|
||||
defined using the following code:
|
||||
|
||||
``` php
|
||||
```php
|
||||
// Add some data
|
||||
$spreadsheet->setActiveSheetIndex(0);
|
||||
$spreadsheet->getActiveSheet()->setCellValue('A1', 'Firstname:');
|
||||
|
@ -1362,7 +1402,7 @@ your document is needed, it is recommended not to use `php://output`.
|
|||
Example of a script redirecting an Excel 2007 file to the client's
|
||||
browser:
|
||||
|
||||
``` php
|
||||
```php
|
||||
/* Here there will be some code where you create $spreadsheet */
|
||||
|
||||
// redirect output to client browser
|
||||
|
@ -1376,7 +1416,7 @@ $writer->save('php://output');
|
|||
|
||||
Example of a script redirecting an Xls file to the client's browser:
|
||||
|
||||
``` php
|
||||
```php
|
||||
/* Here there will be some code where you create $spreadsheet */
|
||||
|
||||
// redirect output to client browser
|
||||
|
@ -1404,7 +1444,7 @@ at the client browser, and/or that headers cannot be set by PHP
|
|||
|
||||
Default column width can be set using the following code:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$spreadsheet->getActiveSheet()->getDefaultColumnDimension()->setWidth(12);
|
||||
```
|
||||
|
||||
|
@ -1412,7 +1452,7 @@ $spreadsheet->getActiveSheet()->getDefaultColumnDimension()->setWidth(12);
|
|||
|
||||
Default row height can be set using the following code:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$spreadsheet->getActiveSheet()->getDefaultRowDimension()->setRowHeight(15);
|
||||
```
|
||||
|
||||
|
@ -1425,7 +1465,7 @@ file to a temporary location.
|
|||
Here''s an example which generates an image in memory and adds it to the
|
||||
active worksheet:
|
||||
|
||||
``` php
|
||||
```php
|
||||
// Generate an image
|
||||
$gdImage = @imagecreatetruecolor(120, 20) or die('Cannot Initialize new GD image stream');
|
||||
$textColor = imagecolorallocate($gdImage, 255, 255, 255);
|
||||
|
@ -1446,7 +1486,7 @@ $drawing->setWorksheet($spreadsheet->getActiveSheet());
|
|||
|
||||
To set a worksheet's zoom level, the following code can be used:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$spreadsheet->getActiveSheet()->getSheetView()->setZoomScale(75);
|
||||
```
|
||||
|
||||
|
@ -1457,7 +1497,7 @@ Note that zoom level should be in range 10 - 400.
|
|||
Sometimes you want to set a color for sheet tab. For example you can
|
||||
have a red sheet tab:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$worksheet->getTabColor()->setRGB('FF0000');
|
||||
```
|
||||
|
||||
|
@ -1465,7 +1505,7 @@ $worksheet->getTabColor()->setRGB('FF0000');
|
|||
|
||||
If you need to create more worksheets in the workbook, here is how:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$worksheet1 = $spreadsheet->createSheet();
|
||||
$worksheet1->setTitle('Another sheet');
|
||||
```
|
||||
|
@ -1478,7 +1518,7 @@ worksheets in the workbook.
|
|||
|
||||
Set a worksheet to be **hidden** using this code:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$spreadsheet->getActiveSheet()
|
||||
->setSheetState(\PhpOffice\PhpSpreadsheet\Worksheet\Worksheet::SHEETSTATE_HIDDEN);
|
||||
```
|
||||
|
@ -1500,7 +1540,7 @@ Worksheets can be set individually whether column `A` should start at
|
|||
left or right side. Default is left. Here is how to set columns from
|
||||
right-to-left.
|
||||
|
||||
``` php
|
||||
```php
|
||||
// right-to-left worksheet
|
||||
$spreadsheet->getActiveSheet()->setRightToLeft(true);
|
||||
```
|
||||
|
|
|
@ -13,7 +13,7 @@ Read more about [memory saving](./memory_saving.md).
|
|||
|
||||
To enable cell caching, you must provide your own implementation of cache like so:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$cache = new MyCustomPsr16Implementation();
|
||||
|
||||
\PhpOffice\PhpSpreadsheet\Settings::setCache($cache);
|
||||
|
@ -25,7 +25,7 @@ Some localisation elements have been included in PhpSpreadsheet. You can
|
|||
set a locale by changing the settings. To set the locale to Brazilian
|
||||
Portuguese you would use:
|
||||
|
||||
``` php
|
||||
```php
|
||||
$locale = 'pt_br';
|
||||
$validLocale = \PhpOffice\PhpSpreadsheet\Settings::setLocale($locale);
|
||||
if (!$validLocale) {
|
||||
|
|
|
@ -25,7 +25,7 @@ each worksheet "tab" is shown when the workbook is opened in MS Excel
|
|||
(or other appropriate Spreadsheet program). To access a sheet by its
|
||||
index, use the `getSheet()` method.
|
||||
|
||||
``` php
|
||||
```php
|
||||
// Get the second sheet in the workbook
|
||||
// Note that sheets are indexed from 0
|
||||
$spreadsheet->getSheet(1);
|
||||
|
@ -38,7 +38,7 @@ workbook.
|
|||
To access a sheet by name, use the `getSheetByName()` method, specifying
|
||||
the name of the worksheet that you want to access.
|
||||
|
||||
``` php
|
||||
```php
|
||||
// Retrieve the worksheet called 'Worksheet 1'
|
||||
$spreadsheet->getSheetByName('Worksheet 1');
|
||||
```
|
||||
|
@ -48,7 +48,7 @@ and you can access that directly. The currently active worksheet is the
|
|||
one that will be active when the workbook is opened in MS Excel (or
|
||||
other appropriate Spreadsheet program).
|
||||
|
||||
``` php
|
||||
```php
|
||||
// Retrieve the current active worksheet
|
||||
$spreadsheet->getActiveSheet();
|
||||
```
|
||||
|
@ -64,7 +64,7 @@ a new "last" sheet; but you can also specify an index position as an
|
|||
argument, and the worksheet will be inserted at that position, shuffling
|
||||
all subsequent worksheets in the collection down a place.
|
||||
|
||||
``` php
|
||||
```php
|
||||
$spreadsheet->createSheet();
|
||||
```
|
||||
|
||||
|
@ -76,7 +76,7 @@ Alternatively, you can instantiate a new worksheet (setting the title to
|
|||
whatever you choose) and then insert it into your workbook using the
|
||||
`addSheet()` method.
|
||||
|
||||
``` php
|
||||
```php
|
||||
// Create a new worksheet called "My Data"
|
||||
$myWorkSheet = new \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet($spreadsheet, 'My Data');
|
||||
|
||||
|
@ -93,7 +93,7 @@ Sheets within the same workbook can be copied by creating a clone of the
|
|||
worksheet you wish to copy, and then using the `addSheet()` method to
|
||||
insert the clone into the workbook.
|
||||
|
||||
``` php
|
||||
```php
|
||||
$clonedWorksheet = clone $spreadsheet->getSheetByName('Worksheet 1');
|
||||
$clonedWorksheet->setTitle('Copy of Worksheet 1');
|
||||
$spreadsheet->addSheet($clonedWorksheet);
|
||||
|
@ -117,7 +117,7 @@ duplicate name.
|
|||
You can delete a worksheet from a workbook, identified by its index
|
||||
position, using the `removeSheetByIndex()` method
|
||||
|
||||
``` php
|
||||
```php
|
||||
$sheetIndex = $spreadsheet->getIndex(
|
||||
$spreadsheet->getSheetByName('Worksheet 1')
|
||||
);
|
||||
|
|
|
@ -3456,10 +3456,8 @@ class Calculation
|
|||
if ((isset(self::$comparisonOperators[$opCharacter])) && (strlen($formula) > $index) && (isset(self::$comparisonOperators[$formula[$index + 1]]))) {
|
||||
$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);
|
||||
|
||||
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);
|
||||
|
@ -3627,7 +3625,6 @@ class Calculation
|
|||
$expectingOperand = false;
|
||||
$val = $match[1];
|
||||
$length = strlen($val);
|
||||
|
||||
if (preg_match('/^' . self::CALCULATION_REGEXP_FUNCTION . '$/i', $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
|
||||
|
@ -3662,7 +3659,6 @@ class Calculation
|
|||
} elseif (preg_match('/^' . self::CALCULATION_REGEXP_CELLREF . '$/i', $val, $matches)) {
|
||||
// Watch for this case-change when modifying to allow cell references in different worksheets...
|
||||
// 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'] == ':') {
|
||||
|
@ -3719,6 +3715,8 @@ class Calculation
|
|||
}
|
||||
|
||||
$localeConstant = false;
|
||||
$stackItemType = 'Value';
|
||||
$stackItemReference = null;
|
||||
if ($opCharacter == self::FORMULA_STRING_QUOTE) {
|
||||
// UnEscape any quotes within the string
|
||||
$val = self::wrapResult(str_replace('""', self::FORMULA_STRING_QUOTE, self::unwrapResult($val)));
|
||||
|
@ -3729,12 +3727,17 @@ class Calculation
|
|||
$val = (int) $val;
|
||||
}
|
||||
} elseif (isset(self::$excelConstants[trim(strtoupper($val))])) {
|
||||
$stackItemType = 'Constant';
|
||||
$excelConstant = trim(strtoupper($val));
|
||||
$val = self::$excelConstants[$excelConstant];
|
||||
} elseif (($localeConstant = array_search(trim(strtoupper($val)), self::$localeBoolean)) !== false) {
|
||||
$stackItemType = 'Constant';
|
||||
$val = self::$excelConstants[$localeConstant];
|
||||
} elseif (preg_match('/^' . self::CALCULATION_REGEXP_NAMEDRANGE . '.*/Ui', $val, $match)) {
|
||||
$stackItemType = 'Named Range';
|
||||
$stackItemReference = $val;
|
||||
}
|
||||
$details = $stack->getStackItem('Value', $val, null, $currentCondition, $currentOnlyIf, $currentOnlyIfNot);
|
||||
$details = $stack->getStackItem($stackItemType, $val, $stackItemReference, $currentCondition, $currentOnlyIf, $currentOnlyIfNot);
|
||||
if ($localeConstant) {
|
||||
$details['localeValue'] = $localeConstant;
|
||||
}
|
||||
|
@ -3776,8 +3779,12 @@ class Calculation
|
|||
}
|
||||
// If we're expecting an operator, but only have a space between the previous and next operands (and both are
|
||||
// Cell References) then we have an INTERSECTION operator
|
||||
if (($expectingOperator) && (preg_match('/^' . self::CALCULATION_REGEXP_CELLREF . '.*/Ui', substr($formula, $index), $match)) &&
|
||||
($output[count($output) - 1]['type'] == 'Cell Reference')) {
|
||||
if (($expectingOperator) &&
|
||||
((preg_match('/^' . self::CALCULATION_REGEXP_CELLREF . '.*/Ui', substr($formula, $index), $match)) &&
|
||||
($output[count($output) - 1]['type'] == 'Cell Reference') ||
|
||||
(preg_match('/^' . self::CALCULATION_REGEXP_NAMEDRANGE . '.*/Ui', substr($formula, $index), $match)) &&
|
||||
($output[count($output) - 1]['type'] == 'Named Range' || $output[count($output) - 1]['type'] == 'Value')
|
||||
)) {
|
||||
while ($stack->count() > 0 &&
|
||||
($o2 = $stack->last()) &&
|
||||
isset(self::$operators[$o2['value']]) &&
|
||||
|
@ -3840,7 +3847,6 @@ class Calculation
|
|||
$fakedForBranchPruning = [];
|
||||
// help us to know when pruning ['branchTestId' => true/false]
|
||||
$branchStore = [];
|
||||
|
||||
// Loop through each token in turn
|
||||
foreach ($tokens as $tokenData) {
|
||||
$token = $tokenData['value'];
|
||||
|
|
|
@ -668,30 +668,19 @@ class DateTime
|
|||
$endMonths = $PHPEndDateObject->format('n');
|
||||
$endYears = $PHPEndDateObject->format('Y');
|
||||
|
||||
$PHPDiffDateObject = $PHPEndDateObject->diff($PHPStartDateObject);
|
||||
|
||||
switch ($unit) {
|
||||
case 'D':
|
||||
$retVal = (int) $difference;
|
||||
|
||||
break;
|
||||
case 'M':
|
||||
$retVal = (int) ($endMonths - $startMonths) + ((int) ($endYears - $startYears) * 12);
|
||||
// We're only interested in full months
|
||||
if ($endDays < $startDays) {
|
||||
--$retVal;
|
||||
}
|
||||
$retVal = (int) 12 * $PHPDiffDateObject->format('%y') + $PHPDiffDateObject->format('%m');
|
||||
|
||||
break;
|
||||
case 'Y':
|
||||
$retVal = (int) ($endYears - $startYears);
|
||||
// We're only interested in full months
|
||||
if ($endMonths < $startMonths) {
|
||||
--$retVal;
|
||||
} elseif (($endMonths == $startMonths) && ($endDays < $startDays)) {
|
||||
// Remove start month
|
||||
--$retVal;
|
||||
// Remove end month
|
||||
--$retVal;
|
||||
}
|
||||
$retVal = (int) $PHPDiffDateObject->format('%y');
|
||||
|
||||
break;
|
||||
case 'MD':
|
||||
|
@ -701,19 +690,12 @@ class DateTime
|
|||
$adjustDays = $PHPEndDateObject->format('j');
|
||||
$retVal += ($adjustDays - $startDays);
|
||||
} else {
|
||||
$retVal = $endDays - $startDays;
|
||||
$retVal = (int) $PHPDiffDateObject->format('%d');
|
||||
}
|
||||
|
||||
break;
|
||||
case 'YM':
|
||||
$retVal = (int) ($endMonths - $startMonths);
|
||||
if ($retVal < 0) {
|
||||
$retVal += 12;
|
||||
}
|
||||
// We're only interested in full months
|
||||
if ($endDays < $startDays) {
|
||||
--$retVal;
|
||||
}
|
||||
$retVal = (int) $PHPDiffDateObject->format('%m');
|
||||
|
||||
break;
|
||||
case 'YD':
|
||||
|
|
|
@ -312,32 +312,59 @@ abstract class Coordinate
|
|||
/**
|
||||
* Extract all cell references in range, which may be comprised of multiple cell ranges.
|
||||
*
|
||||
* @param string $pRange Range (e.g. A1 or A1:C10 or A1:E10 A20:E25)
|
||||
* @param string $cellRange Range: e.g. 'A1' or 'A1:C10' or 'A1:E10,A20:E25' or 'A1:E5 C3:G7' or 'A1:C1,A3:C3 B1:C3'
|
||||
*
|
||||
* @return array Array containing single cell references
|
||||
*/
|
||||
public static function extractAllCellReferencesInRange($pRange)
|
||||
public static function extractAllCellReferencesInRange($cellRange): array
|
||||
{
|
||||
$returnValue = [];
|
||||
[$ranges, $operators] = self::getCellBlocksFromRangeString($cellRange);
|
||||
|
||||
// Explode spaces
|
||||
$cellBlocks = self::getCellBlocksFromRangeString($pRange);
|
||||
foreach ($cellBlocks as $cellBlock) {
|
||||
$returnValue = array_merge($returnValue, self::getReferencesForCellBlock($cellBlock));
|
||||
$cells = [];
|
||||
foreach ($ranges as $range) {
|
||||
$cells[] = self::getReferencesForCellBlock($range);
|
||||
}
|
||||
|
||||
$cells = self::processRangeSetOperators($operators, $cells);
|
||||
|
||||
if (empty($cells)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$cellList = array_merge(...$cells);
|
||||
$cellList = self::sortCellReferenceArray($cellList);
|
||||
|
||||
return $cellList;
|
||||
}
|
||||
|
||||
private static function processRangeSetOperators(array $operators, array $cells): array
|
||||
{
|
||||
for ($offset = 0; $offset < count($operators); ++$offset) {
|
||||
$operator = $operators[$offset];
|
||||
if ($operator !== ' ') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$cells[$offset] = array_intersect($cells[$offset], $cells[$offset + 1]);
|
||||
unset($operators[$offset], $cells[$offset + 1]);
|
||||
$operators = array_values($operators);
|
||||
$cells = array_values($cells);
|
||||
--$offset;
|
||||
}
|
||||
|
||||
return $cells;
|
||||
}
|
||||
|
||||
private static function sortCellReferenceArray(array $cellList): array
|
||||
{
|
||||
// Sort the result by column and row
|
||||
$sortKeys = [];
|
||||
foreach (array_unique($returnValue) as $coord) {
|
||||
$column = '';
|
||||
$row = 0;
|
||||
|
||||
sscanf($coord, '%[A-Z]%d', $column, $row);
|
||||
foreach ($cellList as $coord) {
|
||||
[$column, $row] = sscanf($coord, '%[A-Z]%d');
|
||||
$sortKeys[sprintf('%3s%09d', $column, $row)] = $coord;
|
||||
}
|
||||
ksort($sortKeys);
|
||||
|
||||
// Return value
|
||||
return array_values($sortKeys);
|
||||
}
|
||||
|
||||
|
@ -482,15 +509,25 @@ abstract class Coordinate
|
|||
}
|
||||
|
||||
/**
|
||||
* Get the individual cell blocks from a range string, splitting by space and removing any $ characters.
|
||||
* Get the individual cell blocks from a range string, removing any $ characters.
|
||||
* then splitting by operators and returning an array with ranges and operators.
|
||||
*
|
||||
* @param string $pRange
|
||||
* @param string $rangeString
|
||||
*
|
||||
* @return string[]
|
||||
* @return array[]
|
||||
*/
|
||||
private static function getCellBlocksFromRangeString($pRange)
|
||||
private static function getCellBlocksFromRangeString($rangeString)
|
||||
{
|
||||
return explode(' ', str_replace('$', '', strtoupper($pRange)));
|
||||
$rangeString = str_replace('$', '', strtoupper($rangeString));
|
||||
|
||||
// split range sets on intersection (space) or union (,) operators
|
||||
$tokens = preg_split('/([ ,])/', $rangeString, -1, PREG_SPLIT_DELIM_CAPTURE);
|
||||
// separate the range sets and the operators into arrays
|
||||
$split = array_chunk($tokens, 2);
|
||||
$ranges = array_column($split, 0);
|
||||
$operators = array_column($split, 1);
|
||||
|
||||
return [$ranges, $operators];
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -763,13 +763,8 @@ class Xlsx extends BaseReader
|
|||
}
|
||||
}
|
||||
|
||||
if (!$this->readDataOnly && $xmlSheet && $xmlSheet->sheetProtection) {
|
||||
$docSheet->getProtection()->setPassword((string) $xmlSheet->sheetProtection['password'], true);
|
||||
if ($xmlSheet->protectedRanges->protectedRange) {
|
||||
foreach ($xmlSheet->protectedRanges->protectedRange as $protectedRange) {
|
||||
$docSheet->protectCells((string) $protectedRange['sqref'], (string) $protectedRange['password'], true);
|
||||
}
|
||||
}
|
||||
if ($xmlSheet) {
|
||||
$this->readSheetProtection($docSheet, $xmlSheet);
|
||||
}
|
||||
|
||||
if ($xmlSheet && $xmlSheet->autoFilter && !$this->readDataOnly) {
|
||||
|
@ -2031,4 +2026,29 @@ class Xlsx extends BaseReader
|
|||
|
||||
return $workbookBasename;
|
||||
}
|
||||
|
||||
private function readSheetProtection(Worksheet $docSheet, SimpleXMLElement $xmlSheet): void
|
||||
{
|
||||
if ($this->readDataOnly || !$xmlSheet->sheetProtection) {
|
||||
return;
|
||||
}
|
||||
|
||||
$algorithmName = (string) $xmlSheet->sheetProtection['algorithmName'];
|
||||
$protection = $docSheet->getProtection();
|
||||
$protection->setAlgorithm($algorithmName);
|
||||
|
||||
if ($algorithmName) {
|
||||
$protection->setPassword((string) $xmlSheet->sheetProtection['hashValue'], true);
|
||||
$protection->setSalt((string) $xmlSheet->sheetProtection['saltValue']);
|
||||
$protection->setSpinCount((int) $xmlSheet->sheetProtection['spinCount']);
|
||||
} else {
|
||||
$protection->setPassword((string) $xmlSheet->sheetProtection['password'], true);
|
||||
}
|
||||
|
||||
if ($xmlSheet->protectedRanges->protectedRange) {
|
||||
foreach ($xmlSheet->protectedRanges->protectedRange as $protectedRange) {
|
||||
$docSheet->protectCells((string) $protectedRange['sqref'], (string) $protectedRange['password'], true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,8 +2,41 @@
|
|||
|
||||
namespace PhpOffice\PhpSpreadsheet\Shared;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\Protection;
|
||||
|
||||
class PasswordHasher
|
||||
{
|
||||
/**
|
||||
* Get algorithm name for PHP.
|
||||
*/
|
||||
private static function getAlgorithm(string $algorithmName): string
|
||||
{
|
||||
if (!$algorithmName) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Mapping between algorithm name in Excel and algorithm name in PHP
|
||||
$mapping = [
|
||||
Protection::ALGORITHM_MD2 => 'md2',
|
||||
Protection::ALGORITHM_MD4 => 'md4',
|
||||
Protection::ALGORITHM_MD5 => 'md5',
|
||||
Protection::ALGORITHM_SHA_1 => 'sha1',
|
||||
Protection::ALGORITHM_SHA_256 => 'sha256',
|
||||
Protection::ALGORITHM_SHA_384 => 'sha384',
|
||||
Protection::ALGORITHM_SHA_512 => 'sha512',
|
||||
Protection::ALGORITHM_RIPEMD_128 => 'ripemd128',
|
||||
Protection::ALGORITHM_RIPEMD_160 => 'ripemd160',
|
||||
Protection::ALGORITHM_WHIRLPOOL => 'whirlpool',
|
||||
];
|
||||
|
||||
if (array_key_exists($algorithmName, $mapping)) {
|
||||
return $mapping[$algorithmName];
|
||||
}
|
||||
|
||||
throw new Exception('Unsupported password algorithm: ' . $algorithmName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a password hash from a given string.
|
||||
*
|
||||
|
@ -12,10 +45,8 @@ class PasswordHasher
|
|||
* Spreadsheet_Excel_Writer by Xavier Noguer <xnoguer@rezebra.com>.
|
||||
*
|
||||
* @param string $pPassword Password to hash
|
||||
*
|
||||
* @return string Hashed password
|
||||
*/
|
||||
public static function hashPassword($pPassword)
|
||||
private static function defaultHashPassword(string $pPassword): string
|
||||
{
|
||||
$password = 0x0000;
|
||||
$charPos = 1; // char position
|
||||
|
@ -34,4 +65,36 @@ class PasswordHasher
|
|||
|
||||
return strtoupper(dechex($password));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a password hash from a given string by a specific algorithm.
|
||||
*
|
||||
* 2.4.2.4 ISO Write Protection Method
|
||||
*
|
||||
* @see https://docs.microsoft.com/en-us/openspecs/office_file_formats/ms-offcrypto/1357ea58-646e-4483-92ef-95d718079d6f
|
||||
*
|
||||
* @param string $password Password to hash
|
||||
* @param string $algorithm Hash algorithm used to compute the password hash value
|
||||
* @param string $salt Pseudorandom string
|
||||
* @param int $spinCount Number of times to iterate on a hash of a password
|
||||
*
|
||||
* @return string Hashed password
|
||||
*/
|
||||
public static function hashPassword(string $password, string $algorithm = '', string $salt = '', int $spinCount = 10000): string
|
||||
{
|
||||
$phpAlgorithm = self::getAlgorithm($algorithm);
|
||||
if (!$phpAlgorithm) {
|
||||
return self::defaultHashPassword($password);
|
||||
}
|
||||
|
||||
$saltValue = base64_decode($salt);
|
||||
$encodedPassword = mb_convert_encoding($password, 'UCS-2LE', 'UTF-8');
|
||||
|
||||
$hashValue = hash($phpAlgorithm, $saltValue . $encodedPassword, true);
|
||||
for ($i = 0; $i < $spinCount; ++$i) {
|
||||
$hashValue = hash($phpAlgorithm, $hashValue . pack('L', $i), true);
|
||||
}
|
||||
|
||||
return base64_encode($hashValue);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,17 @@ use PhpOffice\PhpSpreadsheet\Shared\PasswordHasher;
|
|||
|
||||
class Protection
|
||||
{
|
||||
const ALGORITHM_MD2 = 'MD2';
|
||||
const ALGORITHM_MD4 = 'MD4';
|
||||
const ALGORITHM_MD5 = 'MD5';
|
||||
const ALGORITHM_SHA_1 = 'SHA-1';
|
||||
const ALGORITHM_SHA_256 = 'SHA-256';
|
||||
const ALGORITHM_SHA_384 = 'SHA-384';
|
||||
const ALGORITHM_SHA_512 = 'SHA-512';
|
||||
const ALGORITHM_RIPEMD_128 = 'RIPEMD-128';
|
||||
const ALGORITHM_RIPEMD_160 = 'RIPEMD-160';
|
||||
const ALGORITHM_WHIRLPOOL = 'WHIRLPOOL';
|
||||
|
||||
/**
|
||||
* Sheet.
|
||||
*
|
||||
|
@ -119,12 +130,40 @@ class Protection
|
|||
private $selectUnlockedCells = false;
|
||||
|
||||
/**
|
||||
* Password.
|
||||
* Hashed password.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $password = '';
|
||||
|
||||
/**
|
||||
* Algorithm name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $algorithm = '';
|
||||
|
||||
/**
|
||||
* Hash value.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $hash = '';
|
||||
|
||||
/**
|
||||
* Salt value.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $salt = '';
|
||||
|
||||
/**
|
||||
* Spin count.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $spinCount = 10000;
|
||||
|
||||
/**
|
||||
* Create a new Protection.
|
||||
*/
|
||||
|
@ -542,7 +581,7 @@ class Protection
|
|||
}
|
||||
|
||||
/**
|
||||
* Get Password (hashed).
|
||||
* Get hashed password.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
|
@ -562,13 +601,86 @@ class Protection
|
|||
public function setPassword($pValue, $pAlreadyHashed = false)
|
||||
{
|
||||
if (!$pAlreadyHashed) {
|
||||
$pValue = PasswordHasher::hashPassword($pValue);
|
||||
$salt = $this->generateSalt();
|
||||
$this->setSalt($salt);
|
||||
$pValue = PasswordHasher::hashPassword($pValue, $this->getAlgorithm(), $this->getSalt(), $this->getSpinCount());
|
||||
}
|
||||
|
||||
$this->password = $pValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a pseudorandom string.
|
||||
*/
|
||||
private function generateSalt(): string
|
||||
{
|
||||
return base64_encode(random_bytes(16));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get algorithm name.
|
||||
*/
|
||||
public function getAlgorithm(): string
|
||||
{
|
||||
return $this->algorithm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set algorithm name.
|
||||
*/
|
||||
public function setAlgorithm(string $algorithm): void
|
||||
{
|
||||
$this->algorithm = $algorithm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get salt value.
|
||||
*/
|
||||
public function getSalt(): string
|
||||
{
|
||||
return $this->salt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set salt value.
|
||||
*/
|
||||
public function setSalt(string $salt): void
|
||||
{
|
||||
$this->salt = $salt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get spin count.
|
||||
*/
|
||||
public function getSpinCount(): int
|
||||
{
|
||||
return $this->spinCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set spin count.
|
||||
*/
|
||||
public function setSpinCount(int $spinCount): void
|
||||
{
|
||||
$this->spinCount = $spinCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that the given non-hashed password can "unlock" the protection.
|
||||
*/
|
||||
public function verify(string $password): bool
|
||||
{
|
||||
if (!$this->isProtectionEnabled()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$hash = PasswordHasher::hashPassword($password, $this->getAlgorithm(), $this->getSalt(), $this->getSpinCount());
|
||||
|
||||
return $this->getPassword() === $hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement PHP __clone to create a deep clone, not just a shallow copy.
|
||||
*/
|
||||
|
|
|
@ -187,7 +187,7 @@ class Worksheet implements IComparable
|
|||
/**
|
||||
* Collection of merged cell ranges.
|
||||
*
|
||||
* @var array
|
||||
* @var string[]
|
||||
*/
|
||||
private $mergeCells = [];
|
||||
|
||||
|
@ -1747,7 +1747,7 @@ class Worksheet implements IComparable
|
|||
/**
|
||||
* Get merge cells array.
|
||||
*
|
||||
* @return array[]
|
||||
* @return string[]
|
||||
*/
|
||||
public function getMergeCells()
|
||||
{
|
||||
|
@ -1758,6 +1758,8 @@ class Worksheet implements IComparable
|
|||
* Set merge cells array for the entire sheet. Use instead mergeCells() to merge
|
||||
* a single cell range.
|
||||
*
|
||||
* @param string[] $pValue
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setMergeCells(array $pValue)
|
||||
|
|
|
@ -420,26 +420,33 @@ class Worksheet extends WriterPart
|
|||
// sheetProtection
|
||||
$objWriter->startElement('sheetProtection');
|
||||
|
||||
if ($pSheet->getProtection()->getPassword() !== '') {
|
||||
$objWriter->writeAttribute('password', $pSheet->getProtection()->getPassword());
|
||||
$protection = $pSheet->getProtection();
|
||||
|
||||
if ($protection->getAlgorithm()) {
|
||||
$objWriter->writeAttribute('algorithmName', $protection->getAlgorithm());
|
||||
$objWriter->writeAttribute('hashValue', $protection->getPassword());
|
||||
$objWriter->writeAttribute('saltValue', $protection->getSalt());
|
||||
$objWriter->writeAttribute('spinCount', $protection->getSpinCount());
|
||||
} elseif ($protection->getPassword() !== '') {
|
||||
$objWriter->writeAttribute('password', $protection->getPassword());
|
||||
}
|
||||
|
||||
$objWriter->writeAttribute('sheet', ($pSheet->getProtection()->getSheet() ? 'true' : 'false'));
|
||||
$objWriter->writeAttribute('objects', ($pSheet->getProtection()->getObjects() ? 'true' : 'false'));
|
||||
$objWriter->writeAttribute('scenarios', ($pSheet->getProtection()->getScenarios() ? 'true' : 'false'));
|
||||
$objWriter->writeAttribute('formatCells', ($pSheet->getProtection()->getFormatCells() ? 'true' : 'false'));
|
||||
$objWriter->writeAttribute('formatColumns', ($pSheet->getProtection()->getFormatColumns() ? 'true' : 'false'));
|
||||
$objWriter->writeAttribute('formatRows', ($pSheet->getProtection()->getFormatRows() ? 'true' : 'false'));
|
||||
$objWriter->writeAttribute('insertColumns', ($pSheet->getProtection()->getInsertColumns() ? 'true' : 'false'));
|
||||
$objWriter->writeAttribute('insertRows', ($pSheet->getProtection()->getInsertRows() ? 'true' : 'false'));
|
||||
$objWriter->writeAttribute('insertHyperlinks', ($pSheet->getProtection()->getInsertHyperlinks() ? 'true' : 'false'));
|
||||
$objWriter->writeAttribute('deleteColumns', ($pSheet->getProtection()->getDeleteColumns() ? 'true' : 'false'));
|
||||
$objWriter->writeAttribute('deleteRows', ($pSheet->getProtection()->getDeleteRows() ? 'true' : 'false'));
|
||||
$objWriter->writeAttribute('selectLockedCells', ($pSheet->getProtection()->getSelectLockedCells() ? 'true' : 'false'));
|
||||
$objWriter->writeAttribute('sort', ($pSheet->getProtection()->getSort() ? 'true' : 'false'));
|
||||
$objWriter->writeAttribute('autoFilter', ($pSheet->getProtection()->getAutoFilter() ? 'true' : 'false'));
|
||||
$objWriter->writeAttribute('pivotTables', ($pSheet->getProtection()->getPivotTables() ? 'true' : 'false'));
|
||||
$objWriter->writeAttribute('selectUnlockedCells', ($pSheet->getProtection()->getSelectUnlockedCells() ? 'true' : 'false'));
|
||||
$objWriter->writeAttribute('sheet', ($protection->getSheet() ? 'true' : 'false'));
|
||||
$objWriter->writeAttribute('objects', ($protection->getObjects() ? 'true' : 'false'));
|
||||
$objWriter->writeAttribute('scenarios', ($protection->getScenarios() ? 'true' : 'false'));
|
||||
$objWriter->writeAttribute('formatCells', ($protection->getFormatCells() ? 'true' : 'false'));
|
||||
$objWriter->writeAttribute('formatColumns', ($protection->getFormatColumns() ? 'true' : 'false'));
|
||||
$objWriter->writeAttribute('formatRows', ($protection->getFormatRows() ? 'true' : 'false'));
|
||||
$objWriter->writeAttribute('insertColumns', ($protection->getInsertColumns() ? 'true' : 'false'));
|
||||
$objWriter->writeAttribute('insertRows', ($protection->getInsertRows() ? 'true' : 'false'));
|
||||
$objWriter->writeAttribute('insertHyperlinks', ($protection->getInsertHyperlinks() ? 'true' : 'false'));
|
||||
$objWriter->writeAttribute('deleteColumns', ($protection->getDeleteColumns() ? 'true' : 'false'));
|
||||
$objWriter->writeAttribute('deleteRows', ($protection->getDeleteRows() ? 'true' : 'false'));
|
||||
$objWriter->writeAttribute('selectLockedCells', ($protection->getSelectLockedCells() ? 'true' : 'false'));
|
||||
$objWriter->writeAttribute('sort', ($protection->getSort() ? 'true' : 'false'));
|
||||
$objWriter->writeAttribute('autoFilter', ($protection->getAutoFilter() ? 'true' : 'false'));
|
||||
$objWriter->writeAttribute('pivotTables', ($protection->getPivotTables() ? 'true' : 'false'));
|
||||
$objWriter->writeAttribute('selectUnlockedCells', ($protection->getSelectUnlockedCells() ? 'true' : 'false'));
|
||||
$objWriter->endElement();
|
||||
}
|
||||
|
||||
|
@ -1133,7 +1140,7 @@ class Worksheet extends WriterPart
|
|||
$this->getParentWriter()->getOffice2003Compatibility() === false,
|
||||
'v',
|
||||
($this->getParentWriter()->getPreCalculateFormulas() && !is_array($calculatedValue) && substr($calculatedValue, 0, 1) !== '#')
|
||||
? StringHelper::formatNumber($calculatedValue) : '0'
|
||||
? StringHelper::formatNumber($calculatedValue) : '0'
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Engine;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
use PhpOffice\PhpSpreadsheet\NamedRange;
|
||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
|
@ -28,7 +29,7 @@ class RangeTest extends TestCase
|
|||
/**
|
||||
* @dataProvider providerRangeEvaluation
|
||||
*
|
||||
* @param mixed $formula
|
||||
* @param string $formula
|
||||
* @param int $expectedResult
|
||||
*/
|
||||
public function testRangeEvaluation($formula, $expectedResult): void
|
||||
|
@ -44,11 +45,93 @@ class RangeTest extends TestCase
|
|||
{
|
||||
return[
|
||||
['=SUM(A1:B3,A1:C2)', 48],
|
||||
['=COUNT(A1:B3,A1:C2)', 12],
|
||||
['=SUM(A1:B3 A1:C2)', 12],
|
||||
['=COUNT(A1:B3 A1:C2)', 4],
|
||||
['=SUM(A1:A3,C1:C3)', 30],
|
||||
['=COUNT(A1:A3,C1:C3)', 6],
|
||||
['=SUM(A1:A3 C1:C3)', Functions::null()],
|
||||
['=COUNT(A1:A3 C1:C3)', 0],
|
||||
['=SUM(A1:B2,B2:C3)', 40],
|
||||
['=COUNT(A1:B2,B2:C3)', 8],
|
||||
['=SUM(A1:B2 B2:C3)', 5],
|
||||
['=COUNT(A1:B2 B2:C3)', 1],
|
||||
['=SUM(A1:C1,A3:C3,B1:C3)', 63],
|
||||
['=COUNT(A1:C1,A3:C3,B1:C3)', 12],
|
||||
['=SUM(A1:C1,A3:C3 B1:C3)', 23],
|
||||
['=COUNT(A1:C1,A3:C3 B1:C3)', 5],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerNamedRangeEvaluation
|
||||
*
|
||||
* @param string $group1
|
||||
* @param string $group2
|
||||
* @param string $formula
|
||||
* @param int $expectedResult
|
||||
*/
|
||||
public function testNamedRangeEvaluation($group1, $group2, $formula, $expectedResult): void
|
||||
{
|
||||
$workSheet = $this->spreadSheet->getActiveSheet();
|
||||
$this->spreadSheet->addNamedRange(new NamedRange('GROUP1', $workSheet, $group1));
|
||||
$this->spreadSheet->addNamedRange(new NamedRange('GROUP2', $workSheet, $group2));
|
||||
|
||||
$workSheet->setCellValue('E1', $formula);
|
||||
|
||||
$sumRresult = $workSheet->getCell('E1')->getCalculatedValue();
|
||||
self::assertSame($expectedResult, $sumRresult);
|
||||
}
|
||||
|
||||
public function providerNamedRangeEvaluation()
|
||||
{
|
||||
return[
|
||||
['A1:B3', 'A1:C2', '=SUM(GROUP1,GROUP2)', 48],
|
||||
['A1:B3', 'A1:C2', '=COUNT(GROUP1,GROUP2)', 12],
|
||||
['A1:B3', 'A1:C2', '=SUM(GROUP1 GROUP2)', 12],
|
||||
['A1:B3', 'A1:C2', '=COUNT(GROUP1 GROUP2)', 4],
|
||||
['A1:B2', 'B2:C3', '=SUM(GROUP1,GROUP2)', 40],
|
||||
['A1:B2', 'B2:C3', '=COUNT(GROUP1,GROUP2)', 8],
|
||||
['A1:B2', 'B2:C3', '=SUM(GROUP1 GROUP2)', 5],
|
||||
['A1:B2', 'B2:C3', '=COUNT(GROUP1 GROUP2)', 1],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerCompositeNamedRangeEvaluation
|
||||
*
|
||||
* @param string $composite
|
||||
* @param int $expectedSum
|
||||
* @param int $expectedCount
|
||||
*/
|
||||
public function testCompositeNamedRangeEvaluation($composite, $expectedSum, $expectedCount): void
|
||||
{
|
||||
$workSheet = $this->spreadSheet->getActiveSheet();
|
||||
$this->spreadSheet->addNamedRange(new NamedRange('COMPOSITE', $workSheet, $composite));
|
||||
|
||||
$workSheet->setCellValue('E1', '=SUM(COMPOSITE)');
|
||||
$workSheet->setCellValue('E2', '=COUNT(COMPOSITE)');
|
||||
|
||||
$actualSum = $workSheet->getCell('E1')->getCalculatedValue();
|
||||
self::assertSame($expectedSum, $actualSum);
|
||||
$actualCount = $workSheet->getCell('E2')->getCalculatedValue();
|
||||
self::assertSame($expectedCount, $actualCount);
|
||||
}
|
||||
|
||||
public function providerCompositeNamedRangeEvaluation()
|
||||
{
|
||||
return[
|
||||
// Calculation engine doesn't yet handle union ranges with overlap
|
||||
// 'Union with overlap' => [
|
||||
// 'A1:C1,A3:C3,B1:C3',
|
||||
// 63,
|
||||
// 12,
|
||||
// ],
|
||||
'Intersection' => [
|
||||
'A1:C1,A3:C3 B1:C3',
|
||||
23,
|
||||
5,
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -83,10 +83,11 @@ class CoordinateTest extends TestCase
|
|||
* @dataProvider providerCoordinates
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
* @param string $rangeSet
|
||||
*/
|
||||
public function testCoordinateFromString($expectedResult, ...$args): void
|
||||
public function testCoordinateFromString($expectedResult, $rangeSet): void
|
||||
{
|
||||
$result = Coordinate::coordinateFromString(...$args);
|
||||
$result = Coordinate::coordinateFromString($rangeSet);
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
|
@ -143,11 +144,12 @@ class CoordinateTest extends TestCase
|
|||
/**
|
||||
* @dataProvider providerAbsoluteCoordinates
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
* @param string $expectedResult
|
||||
* @param string $rangeSet
|
||||
*/
|
||||
public function testAbsoluteCoordinateFromString($expectedResult, ...$args): void
|
||||
public function testAbsoluteCoordinateFromString($expectedResult, $rangeSet): void
|
||||
{
|
||||
$result = Coordinate::absoluteCoordinate(...$args);
|
||||
$result = Coordinate::absoluteCoordinate($rangeSet);
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
|
@ -175,10 +177,11 @@ class CoordinateTest extends TestCase
|
|||
* @dataProvider providerAbsoluteReferences
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
* @param string $rangeSet
|
||||
*/
|
||||
public function testAbsoluteReferenceFromString($expectedResult, ...$args): void
|
||||
public function testAbsoluteReferenceFromString($expectedResult, $rangeSet): void
|
||||
{
|
||||
$result = Coordinate::absoluteReference(...$args);
|
||||
$result = Coordinate::absoluteReference($rangeSet);
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
|
@ -206,10 +209,11 @@ class CoordinateTest extends TestCase
|
|||
* @dataProvider providerSplitRange
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
* @param string $rangeSet
|
||||
*/
|
||||
public function testSplitRange($expectedResult, ...$args): void
|
||||
public function testSplitRange($expectedResult, $rangeSet): void
|
||||
{
|
||||
$result = Coordinate::splitRange(...$args);
|
||||
$result = Coordinate::splitRange($rangeSet);
|
||||
foreach ($result as $key => $split) {
|
||||
if (!is_array($expectedResult[$key])) {
|
||||
self::assertEquals($expectedResult[$key], $split[0]);
|
||||
|
@ -252,10 +256,11 @@ class CoordinateTest extends TestCase
|
|||
* @dataProvider providerRangeBoundaries
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
* @param string $rangeSet
|
||||
*/
|
||||
public function testRangeBoundaries($expectedResult, ...$args): void
|
||||
public function testRangeBoundaries($expectedResult, $rangeSet): void
|
||||
{
|
||||
$result = Coordinate::rangeBoundaries(...$args);
|
||||
$result = Coordinate::rangeBoundaries($rangeSet);
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
|
@ -268,10 +273,11 @@ class CoordinateTest extends TestCase
|
|||
* @dataProvider providerRangeDimension
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
* @param string $rangeSet
|
||||
*/
|
||||
public function testRangeDimension($expectedResult, ...$args): void
|
||||
public function testRangeDimension($expectedResult, $rangeSet): void
|
||||
{
|
||||
$result = Coordinate::rangeDimension(...$args);
|
||||
$result = Coordinate::rangeDimension($rangeSet);
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
|
@ -284,10 +290,11 @@ class CoordinateTest extends TestCase
|
|||
* @dataProvider providerGetRangeBoundaries
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
* @param string $rangeSet
|
||||
*/
|
||||
public function testGetRangeBoundaries($expectedResult, ...$args): void
|
||||
public function testGetRangeBoundaries($expectedResult, $rangeSet): void
|
||||
{
|
||||
$result = Coordinate::getRangeBoundaries(...$args);
|
||||
$result = Coordinate::getRangeBoundaries($rangeSet);
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
|
@ -299,11 +306,12 @@ class CoordinateTest extends TestCase
|
|||
/**
|
||||
* @dataProvider providerExtractAllCellReferencesInRange
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
* @param array $expectedResult
|
||||
* @param string $rangeSet
|
||||
*/
|
||||
public function testExtractAllCellReferencesInRange($expectedResult, ...$args): void
|
||||
public function testExtractAllCellReferencesInRange($expectedResult, $rangeSet): void
|
||||
{
|
||||
$result = Coordinate::extractAllCellReferencesInRange(...$args);
|
||||
$result = Coordinate::extractAllCellReferencesInRange($rangeSet);
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
|
@ -350,10 +358,11 @@ class CoordinateTest extends TestCase
|
|||
* @dataProvider providerCoordinateIsRange
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
* @param string $rangeSet
|
||||
*/
|
||||
public function testCoordinateIsRange($expectedResult, ...$args): void
|
||||
public function testCoordinateIsRange($expectedResult, $rangeSet): void
|
||||
{
|
||||
$result = Coordinate::coordinateIsRange(...$args);
|
||||
$result = Coordinate::coordinateIsRange($rangeSet);
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Worksheet;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\Protection;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class ProtectionTest extends TestCase
|
||||
{
|
||||
public function testVerifyPassword(): void
|
||||
{
|
||||
$protection = new Protection();
|
||||
self::assertTrue($protection->verify('foo'), 'non-protected always pass');
|
||||
|
||||
$protection->setSheet(true);
|
||||
self::assertFalse($protection->verify('foo'), 'protected will fail');
|
||||
|
||||
$protection->setPassword('foo', true);
|
||||
self::assertSame('foo', $protection->getPassword(), 'was not stored as-is, without hashing');
|
||||
self::assertFalse($protection->verify('foo'), 'setting already hashed password will not match');
|
||||
|
||||
$protection->setPassword('foo');
|
||||
self::assertSame('CC40', $protection->getPassword(), 'was hashed');
|
||||
self::assertTrue($protection->verify('foo'), 'setting non-hashed password will hash it and not match');
|
||||
|
||||
$protection->setAlgorithm(Protection::ALGORITHM_MD5);
|
||||
self::assertFalse($protection->verify('foo'), 'changing algorithm will not match anymore');
|
||||
|
||||
$protection->setPassword('foo');
|
||||
$hash1 = $protection->getPassword();
|
||||
$protection->setPassword('foo');
|
||||
$hash2 = $protection->getPassword();
|
||||
|
||||
self::assertSame(24, mb_strlen($hash1));
|
||||
self::assertSame(24, mb_strlen($hash2));
|
||||
self::assertNotSame($hash1, $hash2, 'was hashed with automatic salt');
|
||||
self::assertTrue($protection->verify('foo'), 'setting password again, will hash with proper algorithm and will match');
|
||||
}
|
||||
}
|
|
@ -393,6 +393,10 @@ return [
|
|||
1,
|
||||
'19-12-1960', '26-01-2012', 'YM',
|
||||
],
|
||||
[
|
||||
11,
|
||||
'19-12-1960', '26-11-1962', 'YM',
|
||||
],
|
||||
[
|
||||
38,
|
||||
'19-12-1960', '26-01-2012', 'YD',
|
||||
|
@ -402,7 +406,15 @@ return [
|
|||
'19-12-1960', '26-01-2012', 'MD',
|
||||
],
|
||||
[
|
||||
50,
|
||||
0,
|
||||
'19-12-1960', '12-12-1961', 'Y',
|
||||
],
|
||||
[
|
||||
1,
|
||||
'19-12-1960', '12-12-1962', 'Y',
|
||||
],
|
||||
[
|
||||
51,
|
||||
'19-12-1960', '12-12-2012', 'Y',
|
||||
],
|
||||
[
|
||||
|
|
|
@ -22,12 +22,6 @@ return [
|
|||
],
|
||||
[
|
||||
[
|
||||
'B4',
|
||||
'B5',
|
||||
'B6',
|
||||
'D4',
|
||||
'D5',
|
||||
'D6',
|
||||
],
|
||||
'B4:B6 D4:D6',
|
||||
],
|
||||
|
@ -66,20 +60,10 @@ return [
|
|||
],
|
||||
[
|
||||
[
|
||||
'B4',
|
||||
'B5',
|
||||
'B6',
|
||||
'C4',
|
||||
'C5',
|
||||
'C6',
|
||||
'C7',
|
||||
'D4',
|
||||
'D5',
|
||||
'D6',
|
||||
'D7',
|
||||
'E5',
|
||||
'E6',
|
||||
'E7',
|
||||
],
|
||||
'B4:D6 C5:E7',
|
||||
],
|
||||
|
@ -105,7 +89,7 @@ return [
|
|||
'F5',
|
||||
'F6',
|
||||
],
|
||||
'B2:D4 C5:D5 E3:E5 D6:E6 F4:F6',
|
||||
'B2:D4,C5:D5,E3:E5,D6:E6,F4:F6',
|
||||
],
|
||||
[
|
||||
[
|
||||
|
@ -129,16 +113,13 @@ return [
|
|||
'F5',
|
||||
'F6',
|
||||
],
|
||||
'B2:D4 C3:E5 D4:F6',
|
||||
'B2:D4,C3:E5,D4:F6',
|
||||
],
|
||||
[
|
||||
[
|
||||
'B4',
|
||||
'B5',
|
||||
'B6',
|
||||
'B8',
|
||||
],
|
||||
'B4:B6 B8',
|
||||
'B4:B6 B5',
|
||||
],
|
||||
[
|
||||
[
|
||||
|
|
|
@ -25,4 +25,30 @@ return [
|
|||
'CE4B',
|
||||
'',
|
||||
],
|
||||
[
|
||||
'O6EXRLpLEDNJDL/AzYtnnA4O4bY=',
|
||||
'',
|
||||
'SHA-1',
|
||||
],
|
||||
[
|
||||
'GYvlIMljDI1Czc4jfWrGaxU5pxl9n5Og0KUzyAfYxwk=',
|
||||
'PhpSpreadsheet',
|
||||
'SHA-256',
|
||||
'Php_salt',
|
||||
1000,
|
||||
],
|
||||
[
|
||||
'sSHdxQv9qgpkr4LDT0bYQxM9hOQJFRhJ4D752/NHQtDDR1EVy67NCEW9cPd6oWvCoBGd96MqKpuma1A7pN1nEA==',
|
||||
'Mark Baker',
|
||||
'SHA-512',
|
||||
'Mark_salt',
|
||||
10000,
|
||||
],
|
||||
[
|
||||
'r9KVLLCKIYOILvE2rcby+g==',
|
||||
'!+&=()~§±æþ',
|
||||
'MD5',
|
||||
'Symbols_salt',
|
||||
100000,
|
||||
],
|
||||
];
|
||||
|
|
Loading…
Reference in New Issue