updated-packages
This commit is contained in:
871
vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/AutoFilter.php
vendored
Normal file
871
vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/AutoFilter.php
vendored
Normal file
@@ -0,0 +1,871 @@
|
||||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Worksheet;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\DateTime;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
|
||||
use PhpOffice\PhpSpreadsheet\Exception as PhpSpreadsheetException;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\Date;
|
||||
|
||||
class AutoFilter
|
||||
{
|
||||
/**
|
||||
* Autofilter Worksheet.
|
||||
*
|
||||
* @var Worksheet
|
||||
*/
|
||||
private $workSheet;
|
||||
|
||||
/**
|
||||
* Autofilter Range.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $range = '';
|
||||
|
||||
/**
|
||||
* Autofilter Column Ruleset.
|
||||
*
|
||||
* @var AutoFilter\Column[]
|
||||
*/
|
||||
private $columns = [];
|
||||
|
||||
/**
|
||||
* Create a new AutoFilter.
|
||||
*
|
||||
* @param string $pRange Cell range (i.e. A1:E10)
|
||||
* @param Worksheet $pSheet
|
||||
*/
|
||||
public function __construct($pRange = '', ?Worksheet $pSheet = null)
|
||||
{
|
||||
$this->range = $pRange;
|
||||
$this->workSheet = $pSheet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get AutoFilter Parent Worksheet.
|
||||
*
|
||||
* @return Worksheet
|
||||
*/
|
||||
public function getParent()
|
||||
{
|
||||
return $this->workSheet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set AutoFilter Parent Worksheet.
|
||||
*
|
||||
* @param Worksheet $pSheet
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setParent(?Worksheet $pSheet = null)
|
||||
{
|
||||
$this->workSheet = $pSheet;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get AutoFilter Range.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getRange()
|
||||
{
|
||||
return $this->range;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set AutoFilter Range.
|
||||
*
|
||||
* @param string $pRange Cell range (i.e. A1:E10)
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setRange($pRange)
|
||||
{
|
||||
// extract coordinate
|
||||
[$worksheet, $pRange] = Worksheet::extractSheetTitle($pRange, true);
|
||||
|
||||
if (strpos($pRange, ':') !== false) {
|
||||
$this->range = $pRange;
|
||||
} elseif (empty($pRange)) {
|
||||
$this->range = '';
|
||||
} else {
|
||||
throw new PhpSpreadsheetException('Autofilter must be set on a range of cells.');
|
||||
}
|
||||
|
||||
if (empty($pRange)) {
|
||||
// Discard all column rules
|
||||
$this->columns = [];
|
||||
} else {
|
||||
// Discard any column rules that are no longer valid within this range
|
||||
[$rangeStart, $rangeEnd] = Coordinate::rangeBoundaries($this->range);
|
||||
foreach ($this->columns as $key => $value) {
|
||||
$colIndex = Coordinate::columnIndexFromString($key);
|
||||
if (($rangeStart[0] > $colIndex) || ($rangeEnd[0] < $colIndex)) {
|
||||
unset($this->columns[$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all AutoFilter Columns.
|
||||
*
|
||||
* @return AutoFilter\Column[]
|
||||
*/
|
||||
public function getColumns()
|
||||
{
|
||||
return $this->columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate that the specified column is in the AutoFilter range.
|
||||
*
|
||||
* @param string $column Column name (e.g. A)
|
||||
*
|
||||
* @return int The column offset within the autofilter range
|
||||
*/
|
||||
public function testColumnInRange($column)
|
||||
{
|
||||
if (empty($this->range)) {
|
||||
throw new PhpSpreadsheetException('No autofilter range is defined.');
|
||||
}
|
||||
|
||||
$columnIndex = Coordinate::columnIndexFromString($column);
|
||||
[$rangeStart, $rangeEnd] = Coordinate::rangeBoundaries($this->range);
|
||||
if (($rangeStart[0] > $columnIndex) || ($rangeEnd[0] < $columnIndex)) {
|
||||
throw new PhpSpreadsheetException('Column is outside of current autofilter range.');
|
||||
}
|
||||
|
||||
return $columnIndex - $rangeStart[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a specified AutoFilter Column Offset within the defined AutoFilter range.
|
||||
*
|
||||
* @param string $pColumn Column name (e.g. A)
|
||||
*
|
||||
* @return int The offset of the specified column within the autofilter range
|
||||
*/
|
||||
public function getColumnOffset($pColumn)
|
||||
{
|
||||
return $this->testColumnInRange($pColumn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a specified AutoFilter Column.
|
||||
*
|
||||
* @param string $pColumn Column name (e.g. A)
|
||||
*
|
||||
* @return AutoFilter\Column
|
||||
*/
|
||||
public function getColumn($pColumn)
|
||||
{
|
||||
$this->testColumnInRange($pColumn);
|
||||
|
||||
if (!isset($this->columns[$pColumn])) {
|
||||
$this->columns[$pColumn] = new AutoFilter\Column($pColumn, $this);
|
||||
}
|
||||
|
||||
return $this->columns[$pColumn];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a specified AutoFilter Column by it's offset.
|
||||
*
|
||||
* @param int $pColumnOffset Column offset within range (starting from 0)
|
||||
*
|
||||
* @return AutoFilter\Column
|
||||
*/
|
||||
public function getColumnByOffset($pColumnOffset)
|
||||
{
|
||||
[$rangeStart, $rangeEnd] = Coordinate::rangeBoundaries($this->range);
|
||||
$pColumn = Coordinate::stringFromColumnIndex($rangeStart[0] + $pColumnOffset);
|
||||
|
||||
return $this->getColumn($pColumn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set AutoFilter.
|
||||
*
|
||||
* @param AutoFilter\Column|string $pColumn
|
||||
* A simple string containing a Column ID like 'A' is permitted
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setColumn($pColumn)
|
||||
{
|
||||
if ((is_string($pColumn)) && (!empty($pColumn))) {
|
||||
$column = $pColumn;
|
||||
} elseif (is_object($pColumn) && ($pColumn instanceof AutoFilter\Column)) {
|
||||
$column = $pColumn->getColumnIndex();
|
||||
} else {
|
||||
throw new PhpSpreadsheetException('Column is not within the autofilter range.');
|
||||
}
|
||||
$this->testColumnInRange($column);
|
||||
|
||||
if (is_string($pColumn)) {
|
||||
$this->columns[$pColumn] = new AutoFilter\Column($pColumn, $this);
|
||||
} elseif (is_object($pColumn) && ($pColumn instanceof AutoFilter\Column)) {
|
||||
$pColumn->setParent($this);
|
||||
$this->columns[$column] = $pColumn;
|
||||
}
|
||||
ksort($this->columns);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear a specified AutoFilter Column.
|
||||
*
|
||||
* @param string $pColumn Column name (e.g. A)
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function clearColumn($pColumn)
|
||||
{
|
||||
$this->testColumnInRange($pColumn);
|
||||
|
||||
if (isset($this->columns[$pColumn])) {
|
||||
unset($this->columns[$pColumn]);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shift an AutoFilter Column Rule to a different column.
|
||||
*
|
||||
* Note: This method bypasses validation of the destination column to ensure it is within this AutoFilter range.
|
||||
* Nor does it verify whether any column rule already exists at $toColumn, but will simply override any existing value.
|
||||
* Use with caution.
|
||||
*
|
||||
* @param string $fromColumn Column name (e.g. A)
|
||||
* @param string $toColumn Column name (e.g. B)
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function shiftColumn($fromColumn, $toColumn)
|
||||
{
|
||||
$fromColumn = strtoupper($fromColumn);
|
||||
$toColumn = strtoupper($toColumn);
|
||||
|
||||
if (($fromColumn !== null) && (isset($this->columns[$fromColumn])) && ($toColumn !== null)) {
|
||||
$this->columns[$fromColumn]->setParent();
|
||||
$this->columns[$fromColumn]->setColumnIndex($toColumn);
|
||||
$this->columns[$toColumn] = $this->columns[$fromColumn];
|
||||
$this->columns[$toColumn]->setParent($this);
|
||||
unset($this->columns[$fromColumn]);
|
||||
|
||||
ksort($this->columns);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if cell value is in the defined set of values.
|
||||
*
|
||||
* @param mixed $cellValue
|
||||
* @param mixed[] $dataSet
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private static function filterTestInSimpleDataSet($cellValue, $dataSet)
|
||||
{
|
||||
$dataSetValues = $dataSet['filterValues'];
|
||||
$blanks = $dataSet['blanks'];
|
||||
if (($cellValue == '') || ($cellValue === null)) {
|
||||
return $blanks;
|
||||
}
|
||||
|
||||
return in_array($cellValue, $dataSetValues);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if cell value is in the defined set of Excel date values.
|
||||
*
|
||||
* @param mixed $cellValue
|
||||
* @param mixed[] $dataSet
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private static function filterTestInDateGroupSet($cellValue, $dataSet)
|
||||
{
|
||||
$dateSet = $dataSet['filterValues'];
|
||||
$blanks = $dataSet['blanks'];
|
||||
if (($cellValue == '') || ($cellValue === null)) {
|
||||
return $blanks;
|
||||
}
|
||||
|
||||
if (is_numeric($cellValue)) {
|
||||
$dateValue = Date::excelToTimestamp($cellValue);
|
||||
if ($cellValue < 1) {
|
||||
// Just the time part
|
||||
$dtVal = date('His', $dateValue);
|
||||
$dateSet = $dateSet['time'];
|
||||
} elseif ($cellValue == floor($cellValue)) {
|
||||
// Just the date part
|
||||
$dtVal = date('Ymd', $dateValue);
|
||||
$dateSet = $dateSet['date'];
|
||||
} else {
|
||||
// date and time parts
|
||||
$dtVal = date('YmdHis', $dateValue);
|
||||
$dateSet = $dateSet['dateTime'];
|
||||
}
|
||||
foreach ($dateSet as $dateValue) {
|
||||
// Use of substr to extract value at the appropriate group level
|
||||
if (substr($dtVal, 0, strlen($dateValue)) == $dateValue) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if cell value is within a set of values defined by a ruleset.
|
||||
*
|
||||
* @param mixed $cellValue
|
||||
* @param mixed[] $ruleSet
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private static function filterTestInCustomDataSet($cellValue, $ruleSet)
|
||||
{
|
||||
$dataSet = $ruleSet['filterRules'];
|
||||
$join = $ruleSet['join'];
|
||||
$customRuleForBlanks = $ruleSet['customRuleForBlanks'] ?? false;
|
||||
|
||||
if (!$customRuleForBlanks) {
|
||||
// Blank cells are always ignored, so return a FALSE
|
||||
if (($cellValue == '') || ($cellValue === null)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
$returnVal = ($join == AutoFilter\Column::AUTOFILTER_COLUMN_JOIN_AND);
|
||||
foreach ($dataSet as $rule) {
|
||||
$retVal = false;
|
||||
|
||||
if (is_numeric($rule['value'])) {
|
||||
// Numeric values are tested using the appropriate operator
|
||||
switch ($rule['operator']) {
|
||||
case AutoFilter\Column\Rule::AUTOFILTER_COLUMN_RULE_EQUAL:
|
||||
$retVal = ($cellValue == $rule['value']);
|
||||
|
||||
break;
|
||||
case AutoFilter\Column\Rule::AUTOFILTER_COLUMN_RULE_NOTEQUAL:
|
||||
$retVal = ($cellValue != $rule['value']);
|
||||
|
||||
break;
|
||||
case AutoFilter\Column\Rule::AUTOFILTER_COLUMN_RULE_GREATERTHAN:
|
||||
$retVal = ($cellValue > $rule['value']);
|
||||
|
||||
break;
|
||||
case AutoFilter\Column\Rule::AUTOFILTER_COLUMN_RULE_GREATERTHANOREQUAL:
|
||||
$retVal = ($cellValue >= $rule['value']);
|
||||
|
||||
break;
|
||||
case AutoFilter\Column\Rule::AUTOFILTER_COLUMN_RULE_LESSTHAN:
|
||||
$retVal = ($cellValue < $rule['value']);
|
||||
|
||||
break;
|
||||
case AutoFilter\Column\Rule::AUTOFILTER_COLUMN_RULE_LESSTHANOREQUAL:
|
||||
$retVal = ($cellValue <= $rule['value']);
|
||||
|
||||
break;
|
||||
}
|
||||
} elseif ($rule['value'] == '') {
|
||||
switch ($rule['operator']) {
|
||||
case AutoFilter\Column\Rule::AUTOFILTER_COLUMN_RULE_EQUAL:
|
||||
$retVal = (($cellValue == '') || ($cellValue === null));
|
||||
|
||||
break;
|
||||
case AutoFilter\Column\Rule::AUTOFILTER_COLUMN_RULE_NOTEQUAL:
|
||||
$retVal = (($cellValue != '') && ($cellValue !== null));
|
||||
|
||||
break;
|
||||
default:
|
||||
$retVal = true;
|
||||
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// String values are always tested for equality, factoring in for wildcards (hence a regexp test)
|
||||
$retVal = preg_match('/^' . $rule['value'] . '$/i', $cellValue);
|
||||
}
|
||||
// If there are multiple conditions, then we need to test both using the appropriate join operator
|
||||
switch ($join) {
|
||||
case AutoFilter\Column::AUTOFILTER_COLUMN_JOIN_OR:
|
||||
$returnVal = $returnVal || $retVal;
|
||||
// Break as soon as we have a TRUE match for OR joins,
|
||||
// to avoid unnecessary additional code execution
|
||||
if ($returnVal) {
|
||||
return $returnVal;
|
||||
}
|
||||
|
||||
break;
|
||||
case AutoFilter\Column::AUTOFILTER_COLUMN_JOIN_AND:
|
||||
$returnVal = $returnVal && $retVal;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $returnVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if cell date value is matches a set of values defined by a set of months.
|
||||
*
|
||||
* @param mixed $cellValue
|
||||
* @param mixed[] $monthSet
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private static function filterTestInPeriodDateSet($cellValue, $monthSet)
|
||||
{
|
||||
// Blank cells are always ignored, so return a FALSE
|
||||
if (($cellValue == '') || ($cellValue === null)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (is_numeric($cellValue)) {
|
||||
$dateValue = date('m', Date::excelToTimestamp($cellValue));
|
||||
if (in_array($dateValue, $monthSet)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search/Replace arrays to convert Excel wildcard syntax to a regexp syntax for preg_matching.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $fromReplace = ['\*', '\?', '~~', '~.*', '~.?'];
|
||||
|
||||
private static $toReplace = ['.*', '.', '~', '\*', '\?'];
|
||||
|
||||
/**
|
||||
* Convert a dynamic rule daterange to a custom filter range expression for ease of calculation.
|
||||
*
|
||||
* @param string $dynamicRuleType
|
||||
* @param AutoFilter\Column $filterColumn
|
||||
*
|
||||
* @return mixed[]
|
||||
*/
|
||||
private function dynamicFilterDateRange($dynamicRuleType, &$filterColumn)
|
||||
{
|
||||
$rDateType = Functions::getReturnDateType();
|
||||
Functions::setReturnDateType(Functions::RETURNDATE_PHP_NUMERIC);
|
||||
$val = $maxVal = null;
|
||||
|
||||
$ruleValues = [];
|
||||
$baseDate = DateTime::DATENOW();
|
||||
// Calculate start/end dates for the required date range based on current date
|
||||
switch ($dynamicRuleType) {
|
||||
case AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTWEEK:
|
||||
$baseDate = strtotime('-7 days', $baseDate);
|
||||
|
||||
break;
|
||||
case AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTWEEK:
|
||||
$baseDate = strtotime('-7 days', $baseDate);
|
||||
|
||||
break;
|
||||
case AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTMONTH:
|
||||
$baseDate = strtotime('-1 month', gmmktime(0, 0, 0, 1, date('m', $baseDate), date('Y', $baseDate)));
|
||||
|
||||
break;
|
||||
case AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTMONTH:
|
||||
$baseDate = strtotime('+1 month', gmmktime(0, 0, 0, 1, date('m', $baseDate), date('Y', $baseDate)));
|
||||
|
||||
break;
|
||||
case AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTQUARTER:
|
||||
$baseDate = strtotime('-3 month', gmmktime(0, 0, 0, 1, date('m', $baseDate), date('Y', $baseDate)));
|
||||
|
||||
break;
|
||||
case AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTQUARTER:
|
||||
$baseDate = strtotime('+3 month', gmmktime(0, 0, 0, 1, date('m', $baseDate), date('Y', $baseDate)));
|
||||
|
||||
break;
|
||||
case AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTYEAR:
|
||||
$baseDate = strtotime('-1 year', gmmktime(0, 0, 0, 1, date('m', $baseDate), date('Y', $baseDate)));
|
||||
|
||||
break;
|
||||
case AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTYEAR:
|
||||
$baseDate = strtotime('+1 year', gmmktime(0, 0, 0, 1, date('m', $baseDate), date('Y', $baseDate)));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
switch ($dynamicRuleType) {
|
||||
case AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DYNAMIC_TODAY:
|
||||
case AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DYNAMIC_YESTERDAY:
|
||||
case AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DYNAMIC_TOMORROW:
|
||||
$maxVal = (int) Date::PHPtoExcel(strtotime('+1 day', $baseDate));
|
||||
$val = (int) Date::PHPToExcel($baseDate);
|
||||
|
||||
break;
|
||||
case AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DYNAMIC_YEARTODATE:
|
||||
$maxVal = (int) Date::PHPtoExcel(strtotime('+1 day', $baseDate));
|
||||
$val = (int) Date::PHPToExcel(gmmktime(0, 0, 0, 1, 1, date('Y', $baseDate)));
|
||||
|
||||
break;
|
||||
case AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DYNAMIC_THISYEAR:
|
||||
case AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTYEAR:
|
||||
case AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTYEAR:
|
||||
$maxVal = (int) Date::PHPToExcel(gmmktime(0, 0, 0, 31, 12, date('Y', $baseDate)));
|
||||
++$maxVal;
|
||||
$val = (int) Date::PHPToExcel(gmmktime(0, 0, 0, 1, 1, date('Y', $baseDate)));
|
||||
|
||||
break;
|
||||
case AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DYNAMIC_THISQUARTER:
|
||||
case AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTQUARTER:
|
||||
case AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTQUARTER:
|
||||
$thisMonth = date('m', $baseDate);
|
||||
$thisQuarter = floor(--$thisMonth / 3);
|
||||
$maxVal = (int) Date::PHPtoExcel(gmmktime(0, 0, 0, date('t', $baseDate), (1 + $thisQuarter) * 3, date('Y', $baseDate)));
|
||||
++$maxVal;
|
||||
$val = (int) Date::PHPToExcel(gmmktime(0, 0, 0, 1, 1 + $thisQuarter * 3, date('Y', $baseDate)));
|
||||
|
||||
break;
|
||||
case AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DYNAMIC_THISMONTH:
|
||||
case AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTMONTH:
|
||||
case AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTMONTH:
|
||||
$maxVal = (int) Date::PHPtoExcel(gmmktime(0, 0, 0, date('t', $baseDate), date('m', $baseDate), date('Y', $baseDate)));
|
||||
++$maxVal;
|
||||
$val = (int) Date::PHPToExcel(gmmktime(0, 0, 0, 1, date('m', $baseDate), date('Y', $baseDate)));
|
||||
|
||||
break;
|
||||
case AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DYNAMIC_THISWEEK:
|
||||
case AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTWEEK:
|
||||
case AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTWEEK:
|
||||
$dayOfWeek = date('w', $baseDate);
|
||||
$val = (int) Date::PHPToExcel($baseDate) - $dayOfWeek;
|
||||
$maxVal = $val + 7;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
switch ($dynamicRuleType) {
|
||||
// Adjust Today dates for Yesterday and Tomorrow
|
||||
case AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DYNAMIC_YESTERDAY:
|
||||
--$maxVal;
|
||||
--$val;
|
||||
|
||||
break;
|
||||
case AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DYNAMIC_TOMORROW:
|
||||
++$maxVal;
|
||||
++$val;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// Set the filter column rule attributes ready for writing
|
||||
$filterColumn->setAttributes(['val' => $val, 'maxVal' => $maxVal]);
|
||||
|
||||
// Set the rules for identifying rows for hide/show
|
||||
$ruleValues[] = ['operator' => AutoFilter\Column\Rule::AUTOFILTER_COLUMN_RULE_GREATERTHANOREQUAL, 'value' => $val];
|
||||
$ruleValues[] = ['operator' => AutoFilter\Column\Rule::AUTOFILTER_COLUMN_RULE_LESSTHAN, 'value' => $maxVal];
|
||||
Functions::setReturnDateType($rDateType);
|
||||
|
||||
return ['method' => 'filterTestInCustomDataSet', 'arguments' => ['filterRules' => $ruleValues, 'join' => AutoFilter\Column::AUTOFILTER_COLUMN_JOIN_AND]];
|
||||
}
|
||||
|
||||
private function calculateTopTenValue($columnID, $startRow, $endRow, $ruleType, $ruleValue)
|
||||
{
|
||||
$range = $columnID . $startRow . ':' . $columnID . $endRow;
|
||||
$dataValues = Functions::flattenArray($this->workSheet->rangeToArray($range, null, true, false));
|
||||
|
||||
$dataValues = array_filter($dataValues);
|
||||
if ($ruleType == AutoFilter\Column\Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP) {
|
||||
rsort($dataValues);
|
||||
} else {
|
||||
sort($dataValues);
|
||||
}
|
||||
|
||||
return array_pop(array_slice($dataValues, 0, $ruleValue));
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the AutoFilter rules to the AutoFilter Range.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function showHideRows()
|
||||
{
|
||||
[$rangeStart, $rangeEnd] = Coordinate::rangeBoundaries($this->range);
|
||||
|
||||
// The heading row should always be visible
|
||||
$this->workSheet->getRowDimension($rangeStart[1])->setVisible(true);
|
||||
|
||||
$columnFilterTests = [];
|
||||
foreach ($this->columns as $columnID => $filterColumn) {
|
||||
$rules = $filterColumn->getRules();
|
||||
switch ($filterColumn->getFilterType()) {
|
||||
case AutoFilter\Column::AUTOFILTER_FILTERTYPE_FILTER:
|
||||
$ruleType = null;
|
||||
$ruleValues = [];
|
||||
// Build a list of the filter value selections
|
||||
foreach ($rules as $rule) {
|
||||
$ruleType = $rule->getRuleType();
|
||||
$ruleValues[] = $rule->getValue();
|
||||
}
|
||||
// Test if we want to include blanks in our filter criteria
|
||||
$blanks = false;
|
||||
$ruleDataSet = array_filter($ruleValues);
|
||||
if (count($ruleValues) != count($ruleDataSet)) {
|
||||
$blanks = true;
|
||||
}
|
||||
if ($ruleType == AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_FILTER) {
|
||||
// Filter on absolute values
|
||||
$columnFilterTests[$columnID] = [
|
||||
'method' => 'filterTestInSimpleDataSet',
|
||||
'arguments' => ['filterValues' => $ruleDataSet, 'blanks' => $blanks],
|
||||
];
|
||||
} else {
|
||||
// Filter on date group values
|
||||
$arguments = [
|
||||
'date' => [],
|
||||
'time' => [],
|
||||
'dateTime' => [],
|
||||
];
|
||||
foreach ($ruleDataSet as $ruleValue) {
|
||||
$date = $time = '';
|
||||
if (
|
||||
(isset($ruleValue[AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DATEGROUP_YEAR])) &&
|
||||
($ruleValue[AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DATEGROUP_YEAR] !== '')
|
||||
) {
|
||||
$date .= sprintf('%04d', $ruleValue[AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DATEGROUP_YEAR]);
|
||||
}
|
||||
if (
|
||||
(isset($ruleValue[AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DATEGROUP_MONTH])) &&
|
||||
($ruleValue[AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DATEGROUP_MONTH] != '')
|
||||
) {
|
||||
$date .= sprintf('%02d', $ruleValue[AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DATEGROUP_MONTH]);
|
||||
}
|
||||
if (
|
||||
(isset($ruleValue[AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DATEGROUP_DAY])) &&
|
||||
($ruleValue[AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DATEGROUP_DAY] !== '')
|
||||
) {
|
||||
$date .= sprintf('%02d', $ruleValue[AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DATEGROUP_DAY]);
|
||||
}
|
||||
if (
|
||||
(isset($ruleValue[AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DATEGROUP_HOUR])) &&
|
||||
($ruleValue[AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DATEGROUP_HOUR] !== '')
|
||||
) {
|
||||
$time .= sprintf('%02d', $ruleValue[AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DATEGROUP_HOUR]);
|
||||
}
|
||||
if (
|
||||
(isset($ruleValue[AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DATEGROUP_MINUTE])) &&
|
||||
($ruleValue[AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DATEGROUP_MINUTE] !== '')
|
||||
) {
|
||||
$time .= sprintf('%02d', $ruleValue[AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DATEGROUP_MINUTE]);
|
||||
}
|
||||
if (
|
||||
(isset($ruleValue[AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DATEGROUP_SECOND])) &&
|
||||
($ruleValue[AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DATEGROUP_SECOND] !== '')
|
||||
) {
|
||||
$time .= sprintf('%02d', $ruleValue[AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DATEGROUP_SECOND]);
|
||||
}
|
||||
$dateTime = $date . $time;
|
||||
$arguments['date'][] = $date;
|
||||
$arguments['time'][] = $time;
|
||||
$arguments['dateTime'][] = $dateTime;
|
||||
}
|
||||
// Remove empty elements
|
||||
$arguments['date'] = array_filter($arguments['date']);
|
||||
$arguments['time'] = array_filter($arguments['time']);
|
||||
$arguments['dateTime'] = array_filter($arguments['dateTime']);
|
||||
$columnFilterTests[$columnID] = [
|
||||
'method' => 'filterTestInDateGroupSet',
|
||||
'arguments' => ['filterValues' => $arguments, 'blanks' => $blanks],
|
||||
];
|
||||
}
|
||||
|
||||
break;
|
||||
case AutoFilter\Column::AUTOFILTER_FILTERTYPE_CUSTOMFILTER:
|
||||
$customRuleForBlanks = false;
|
||||
$ruleValues = [];
|
||||
// Build a list of the filter value selections
|
||||
foreach ($rules as $rule) {
|
||||
$ruleValue = $rule->getValue();
|
||||
if (!is_numeric($ruleValue)) {
|
||||
// Convert to a regexp allowing for regexp reserved characters, wildcards and escaped wildcards
|
||||
$ruleValue = preg_quote($ruleValue);
|
||||
$ruleValue = str_replace(self::$fromReplace, self::$toReplace, $ruleValue);
|
||||
if (trim($ruleValue) == '') {
|
||||
$customRuleForBlanks = true;
|
||||
$ruleValue = trim($ruleValue);
|
||||
}
|
||||
}
|
||||
$ruleValues[] = ['operator' => $rule->getOperator(), 'value' => $ruleValue];
|
||||
}
|
||||
$join = $filterColumn->getJoin();
|
||||
$columnFilterTests[$columnID] = [
|
||||
'method' => 'filterTestInCustomDataSet',
|
||||
'arguments' => ['filterRules' => $ruleValues, 'join' => $join, 'customRuleForBlanks' => $customRuleForBlanks],
|
||||
];
|
||||
|
||||
break;
|
||||
case AutoFilter\Column::AUTOFILTER_FILTERTYPE_DYNAMICFILTER:
|
||||
$ruleValues = [];
|
||||
foreach ($rules as $rule) {
|
||||
// We should only ever have one Dynamic Filter Rule anyway
|
||||
$dynamicRuleType = $rule->getGrouping();
|
||||
if (
|
||||
($dynamicRuleType == AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DYNAMIC_ABOVEAVERAGE) ||
|
||||
($dynamicRuleType == AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DYNAMIC_BELOWAVERAGE)
|
||||
) {
|
||||
// Number (Average) based
|
||||
// Calculate the average
|
||||
$averageFormula = '=AVERAGE(' . $columnID . ($rangeStart[1] + 1) . ':' . $columnID . $rangeEnd[1] . ')';
|
||||
$average = Calculation::getInstance()->calculateFormula($averageFormula, null, $this->workSheet->getCell('A1'));
|
||||
// Set above/below rule based on greaterThan or LessTan
|
||||
$operator = ($dynamicRuleType === AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DYNAMIC_ABOVEAVERAGE)
|
||||
? AutoFilter\Column\Rule::AUTOFILTER_COLUMN_RULE_GREATERTHAN
|
||||
: AutoFilter\Column\Rule::AUTOFILTER_COLUMN_RULE_LESSTHAN;
|
||||
$ruleValues[] = [
|
||||
'operator' => $operator,
|
||||
'value' => $average,
|
||||
];
|
||||
$columnFilterTests[$columnID] = [
|
||||
'method' => 'filterTestInCustomDataSet',
|
||||
'arguments' => ['filterRules' => $ruleValues, 'join' => AutoFilter\Column::AUTOFILTER_COLUMN_JOIN_OR],
|
||||
];
|
||||
} else {
|
||||
// Date based
|
||||
if ($dynamicRuleType[0] == 'M' || $dynamicRuleType[0] == 'Q') {
|
||||
$periodType = '';
|
||||
$period = 0;
|
||||
// Month or Quarter
|
||||
sscanf($dynamicRuleType, '%[A-Z]%d', $periodType, $period);
|
||||
if ($periodType == 'M') {
|
||||
$ruleValues = [$period];
|
||||
} else {
|
||||
--$period;
|
||||
$periodEnd = (1 + $period) * 3;
|
||||
$periodStart = 1 + $period * 3;
|
||||
$ruleValues = range($periodStart, $periodEnd);
|
||||
}
|
||||
$columnFilterTests[$columnID] = [
|
||||
'method' => 'filterTestInPeriodDateSet',
|
||||
'arguments' => $ruleValues,
|
||||
];
|
||||
$filterColumn->setAttributes([]);
|
||||
} else {
|
||||
// Date Range
|
||||
$columnFilterTests[$columnID] = $this->dynamicFilterDateRange($dynamicRuleType, $filterColumn);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case AutoFilter\Column::AUTOFILTER_FILTERTYPE_TOPTENFILTER:
|
||||
$ruleValues = [];
|
||||
$dataRowCount = $rangeEnd[1] - $rangeStart[1];
|
||||
foreach ($rules as $rule) {
|
||||
// We should only ever have one Dynamic Filter Rule anyway
|
||||
$toptenRuleType = $rule->getGrouping();
|
||||
$ruleValue = $rule->getValue();
|
||||
$ruleOperator = $rule->getOperator();
|
||||
}
|
||||
if ($ruleOperator === AutoFilter\Column\Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT) {
|
||||
$ruleValue = floor($ruleValue * ($dataRowCount / 100));
|
||||
}
|
||||
if ($ruleValue < 1) {
|
||||
$ruleValue = 1;
|
||||
}
|
||||
if ($ruleValue > 500) {
|
||||
$ruleValue = 500;
|
||||
}
|
||||
|
||||
$maxVal = $this->calculateTopTenValue($columnID, $rangeStart[1] + 1, $rangeEnd[1], $toptenRuleType, $ruleValue);
|
||||
|
||||
$operator = ($toptenRuleType == AutoFilter\Column\Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP)
|
||||
? AutoFilter\Column\Rule::AUTOFILTER_COLUMN_RULE_GREATERTHANOREQUAL
|
||||
: AutoFilter\Column\Rule::AUTOFILTER_COLUMN_RULE_LESSTHANOREQUAL;
|
||||
$ruleValues[] = ['operator' => $operator, 'value' => $maxVal];
|
||||
$columnFilterTests[$columnID] = [
|
||||
'method' => 'filterTestInCustomDataSet',
|
||||
'arguments' => ['filterRules' => $ruleValues, 'join' => AutoFilter\Column::AUTOFILTER_COLUMN_JOIN_OR],
|
||||
];
|
||||
$filterColumn->setAttributes(['maxVal' => $maxVal]);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Execute the column tests for each row in the autoFilter range to determine show/hide,
|
||||
for ($row = $rangeStart[1] + 1; $row <= $rangeEnd[1]; ++$row) {
|
||||
$result = true;
|
||||
foreach ($columnFilterTests as $columnID => $columnFilterTest) {
|
||||
$cellValue = $this->workSheet->getCell($columnID . $row)->getCalculatedValue();
|
||||
// Execute the filter test
|
||||
$result = $result &&
|
||||
call_user_func_array(
|
||||
[self::class, $columnFilterTest['method']],
|
||||
[$cellValue, $columnFilterTest['arguments']]
|
||||
);
|
||||
// If filter test has resulted in FALSE, exit the loop straightaway rather than running any more tests
|
||||
if (!$result) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Set show/hide for the row based on the result of the autoFilter result
|
||||
$this->workSheet->getRowDimension($row)->setVisible($result);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement PHP __clone to create a deep clone, not just a shallow copy.
|
||||
*/
|
||||
public function __clone()
|
||||
{
|
||||
$vars = get_object_vars($this);
|
||||
foreach ($vars as $key => $value) {
|
||||
if (is_object($value)) {
|
||||
if ($key === 'workSheet') {
|
||||
// Detach from worksheet
|
||||
$this->{$key} = null;
|
||||
} else {
|
||||
$this->{$key} = clone $value;
|
||||
}
|
||||
} elseif ((is_array($value)) && ($key == 'columns')) {
|
||||
// The columns array of \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet\AutoFilter objects
|
||||
$this->{$key} = [];
|
||||
foreach ($value as $k => $v) {
|
||||
$this->{$key}[$k] = clone $v;
|
||||
// attach the new cloned Column to this new cloned Autofilter object
|
||||
$this->{$key}[$k]->setParent($this);
|
||||
}
|
||||
} else {
|
||||
$this->{$key} = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* toString method replicates previous behavior by returning the range if object is
|
||||
* referenced as a property of its parent.
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return (string) $this->range;
|
||||
}
|
||||
}
|
380
vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/AutoFilter/Column.php
vendored
Normal file
380
vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/AutoFilter/Column.php
vendored
Normal file
@@ -0,0 +1,380 @@
|
||||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Exception as PhpSpreadsheetException;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter;
|
||||
|
||||
class Column
|
||||
{
|
||||
const AUTOFILTER_FILTERTYPE_FILTER = 'filters';
|
||||
const AUTOFILTER_FILTERTYPE_CUSTOMFILTER = 'customFilters';
|
||||
// Supports no more than 2 rules, with an And/Or join criteria
|
||||
// if more than 1 rule is defined
|
||||
const AUTOFILTER_FILTERTYPE_DYNAMICFILTER = 'dynamicFilter';
|
||||
// Even though the filter rule is constant, the filtered data can vary
|
||||
// e.g. filtered by date = TODAY
|
||||
const AUTOFILTER_FILTERTYPE_TOPTENFILTER = 'top10';
|
||||
|
||||
/**
|
||||
* Types of autofilter rules.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
private static $filterTypes = [
|
||||
// Currently we're not handling
|
||||
// colorFilter
|
||||
// extLst
|
||||
// iconFilter
|
||||
self::AUTOFILTER_FILTERTYPE_FILTER,
|
||||
self::AUTOFILTER_FILTERTYPE_CUSTOMFILTER,
|
||||
self::AUTOFILTER_FILTERTYPE_DYNAMICFILTER,
|
||||
self::AUTOFILTER_FILTERTYPE_TOPTENFILTER,
|
||||
];
|
||||
|
||||
// Multiple Rule Connections
|
||||
const AUTOFILTER_COLUMN_JOIN_AND = 'and';
|
||||
const AUTOFILTER_COLUMN_JOIN_OR = 'or';
|
||||
|
||||
/**
|
||||
* Join options for autofilter rules.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
private static $ruleJoins = [
|
||||
self::AUTOFILTER_COLUMN_JOIN_AND,
|
||||
self::AUTOFILTER_COLUMN_JOIN_OR,
|
||||
];
|
||||
|
||||
/**
|
||||
* Autofilter.
|
||||
*
|
||||
* @var AutoFilter
|
||||
*/
|
||||
private $parent;
|
||||
|
||||
/**
|
||||
* Autofilter Column Index.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $columnIndex = '';
|
||||
|
||||
/**
|
||||
* Autofilter Column Filter Type.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $filterType = self::AUTOFILTER_FILTERTYPE_FILTER;
|
||||
|
||||
/**
|
||||
* Autofilter Multiple Rules And/Or.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $join = self::AUTOFILTER_COLUMN_JOIN_OR;
|
||||
|
||||
/**
|
||||
* Autofilter Column Rules.
|
||||
*
|
||||
* @var array of Column\Rule
|
||||
*/
|
||||
private $ruleset = [];
|
||||
|
||||
/**
|
||||
* Autofilter Column Dynamic Attributes.
|
||||
*
|
||||
* @var array of mixed
|
||||
*/
|
||||
private $attributes = [];
|
||||
|
||||
/**
|
||||
* Create a new Column.
|
||||
*
|
||||
* @param string $pColumn Column (e.g. A)
|
||||
* @param AutoFilter $pParent Autofilter for this column
|
||||
*/
|
||||
public function __construct($pColumn, ?AutoFilter $pParent = null)
|
||||
{
|
||||
$this->columnIndex = $pColumn;
|
||||
$this->parent = $pParent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get AutoFilter column index as string eg: 'A'.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getColumnIndex()
|
||||
{
|
||||
return $this->columnIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set AutoFilter column index as string eg: 'A'.
|
||||
*
|
||||
* @param string $pColumn Column (e.g. A)
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setColumnIndex($pColumn)
|
||||
{
|
||||
// Uppercase coordinate
|
||||
$pColumn = strtoupper($pColumn);
|
||||
if ($this->parent !== null) {
|
||||
$this->parent->testColumnInRange($pColumn);
|
||||
}
|
||||
|
||||
$this->columnIndex = $pColumn;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get this Column's AutoFilter Parent.
|
||||
*
|
||||
* @return AutoFilter
|
||||
*/
|
||||
public function getParent()
|
||||
{
|
||||
return $this->parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set this Column's AutoFilter Parent.
|
||||
*
|
||||
* @param AutoFilter $pParent
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setParent(?AutoFilter $pParent = null)
|
||||
{
|
||||
$this->parent = $pParent;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get AutoFilter Type.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getFilterType()
|
||||
{
|
||||
return $this->filterType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set AutoFilter Type.
|
||||
*
|
||||
* @param string $pFilterType
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setFilterType($pFilterType)
|
||||
{
|
||||
if (!in_array($pFilterType, self::$filterTypes)) {
|
||||
throw new PhpSpreadsheetException('Invalid filter type for column AutoFilter.');
|
||||
}
|
||||
|
||||
$this->filterType = $pFilterType;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get AutoFilter Multiple Rules And/Or Join.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getJoin()
|
||||
{
|
||||
return $this->join;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set AutoFilter Multiple Rules And/Or.
|
||||
*
|
||||
* @param string $pJoin And/Or
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setJoin($pJoin)
|
||||
{
|
||||
// Lowercase And/Or
|
||||
$pJoin = strtolower($pJoin);
|
||||
if (!in_array($pJoin, self::$ruleJoins)) {
|
||||
throw new PhpSpreadsheetException('Invalid rule connection for column AutoFilter.');
|
||||
}
|
||||
|
||||
$this->join = $pJoin;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set AutoFilter Attributes.
|
||||
*
|
||||
* @param string[] $attributes
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setAttributes(array $attributes)
|
||||
{
|
||||
$this->attributes = $attributes;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set An AutoFilter Attribute.
|
||||
*
|
||||
* @param string $pName Attribute Name
|
||||
* @param string $pValue Attribute Value
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setAttribute($pName, $pValue)
|
||||
{
|
||||
$this->attributes[$pName] = $pValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get AutoFilter Column Attributes.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function getAttributes()
|
||||
{
|
||||
return $this->attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get specific AutoFilter Column Attribute.
|
||||
*
|
||||
* @param string $pName Attribute Name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getAttribute($pName)
|
||||
{
|
||||
if (isset($this->attributes[$pName])) {
|
||||
return $this->attributes[$pName];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all AutoFilter Column Rules.
|
||||
*
|
||||
* @return Column\Rule[]
|
||||
*/
|
||||
public function getRules()
|
||||
{
|
||||
return $this->ruleset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a specified AutoFilter Column Rule.
|
||||
*
|
||||
* @param int $pIndex Rule index in the ruleset array
|
||||
*
|
||||
* @return Column\Rule
|
||||
*/
|
||||
public function getRule($pIndex)
|
||||
{
|
||||
if (!isset($this->ruleset[$pIndex])) {
|
||||
$this->ruleset[$pIndex] = new Column\Rule($this);
|
||||
}
|
||||
|
||||
return $this->ruleset[$pIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new AutoFilter Column Rule in the ruleset.
|
||||
*
|
||||
* @return Column\Rule
|
||||
*/
|
||||
public function createRule()
|
||||
{
|
||||
$this->ruleset[] = new Column\Rule($this);
|
||||
|
||||
return end($this->ruleset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new AutoFilter Column Rule to the ruleset.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addRule(Column\Rule $pRule)
|
||||
{
|
||||
$pRule->setParent($this);
|
||||
$this->ruleset[] = $pRule;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a specified AutoFilter Column Rule
|
||||
* If the number of rules is reduced to 1, then we reset And/Or logic to Or.
|
||||
*
|
||||
* @param int $pIndex Rule index in the ruleset array
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function deleteRule($pIndex)
|
||||
{
|
||||
if (isset($this->ruleset[$pIndex])) {
|
||||
unset($this->ruleset[$pIndex]);
|
||||
// If we've just deleted down to a single rule, then reset And/Or joining to Or
|
||||
if (count($this->ruleset) <= 1) {
|
||||
$this->setJoin(self::AUTOFILTER_COLUMN_JOIN_OR);
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all AutoFilter Column Rules.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function clearRules()
|
||||
{
|
||||
$this->ruleset = [];
|
||||
$this->setJoin(self::AUTOFILTER_COLUMN_JOIN_OR);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement PHP __clone to create a deep clone, not just a shallow copy.
|
||||
*/
|
||||
public function __clone()
|
||||
{
|
||||
$vars = get_object_vars($this);
|
||||
foreach ($vars as $key => $value) {
|
||||
if ($key === 'parent') {
|
||||
// Detach from autofilter parent
|
||||
$this->parent = null;
|
||||
} elseif ($key === 'ruleset') {
|
||||
// The columns array of \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet\AutoFilter objects
|
||||
$this->ruleset = [];
|
||||
foreach ($value as $k => $v) {
|
||||
$cloned = clone $v;
|
||||
$cloned->setParent($this); // attach the new cloned Rule to this new cloned Autofilter Cloned object
|
||||
$this->ruleset[$k] = $cloned;
|
||||
}
|
||||
} elseif (is_object($value)) {
|
||||
$this->$key = clone $value;
|
||||
} else {
|
||||
$this->$key = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
449
vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/AutoFilter/Column/Rule.php
vendored
Normal file
449
vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/AutoFilter/Column/Rule.php
vendored
Normal file
@@ -0,0 +1,449 @@
|
||||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Exception as PhpSpreadsheetException;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column;
|
||||
|
||||
class Rule
|
||||
{
|
||||
const AUTOFILTER_RULETYPE_FILTER = 'filter';
|
||||
const AUTOFILTER_RULETYPE_DATEGROUP = 'dateGroupItem';
|
||||
const AUTOFILTER_RULETYPE_CUSTOMFILTER = 'customFilter';
|
||||
const AUTOFILTER_RULETYPE_DYNAMICFILTER = 'dynamicFilter';
|
||||
const AUTOFILTER_RULETYPE_TOPTENFILTER = 'top10Filter';
|
||||
|
||||
private static $ruleTypes = [
|
||||
// Currently we're not handling
|
||||
// colorFilter
|
||||
// extLst
|
||||
// iconFilter
|
||||
self::AUTOFILTER_RULETYPE_FILTER,
|
||||
self::AUTOFILTER_RULETYPE_DATEGROUP,
|
||||
self::AUTOFILTER_RULETYPE_CUSTOMFILTER,
|
||||
self::AUTOFILTER_RULETYPE_DYNAMICFILTER,
|
||||
self::AUTOFILTER_RULETYPE_TOPTENFILTER,
|
||||
];
|
||||
|
||||
const AUTOFILTER_RULETYPE_DATEGROUP_YEAR = 'year';
|
||||
const AUTOFILTER_RULETYPE_DATEGROUP_MONTH = 'month';
|
||||
const AUTOFILTER_RULETYPE_DATEGROUP_DAY = 'day';
|
||||
const AUTOFILTER_RULETYPE_DATEGROUP_HOUR = 'hour';
|
||||
const AUTOFILTER_RULETYPE_DATEGROUP_MINUTE = 'minute';
|
||||
const AUTOFILTER_RULETYPE_DATEGROUP_SECOND = 'second';
|
||||
|
||||
private static $dateTimeGroups = [
|
||||
self::AUTOFILTER_RULETYPE_DATEGROUP_YEAR,
|
||||
self::AUTOFILTER_RULETYPE_DATEGROUP_MONTH,
|
||||
self::AUTOFILTER_RULETYPE_DATEGROUP_DAY,
|
||||
self::AUTOFILTER_RULETYPE_DATEGROUP_HOUR,
|
||||
self::AUTOFILTER_RULETYPE_DATEGROUP_MINUTE,
|
||||
self::AUTOFILTER_RULETYPE_DATEGROUP_SECOND,
|
||||
];
|
||||
|
||||
const AUTOFILTER_RULETYPE_DYNAMIC_YESTERDAY = 'yesterday';
|
||||
const AUTOFILTER_RULETYPE_DYNAMIC_TODAY = 'today';
|
||||
const AUTOFILTER_RULETYPE_DYNAMIC_TOMORROW = 'tomorrow';
|
||||
const AUTOFILTER_RULETYPE_DYNAMIC_YEARTODATE = 'yearToDate';
|
||||
const AUTOFILTER_RULETYPE_DYNAMIC_THISYEAR = 'thisYear';
|
||||
const AUTOFILTER_RULETYPE_DYNAMIC_THISQUARTER = 'thisQuarter';
|
||||
const AUTOFILTER_RULETYPE_DYNAMIC_THISMONTH = 'thisMonth';
|
||||
const AUTOFILTER_RULETYPE_DYNAMIC_THISWEEK = 'thisWeek';
|
||||
const AUTOFILTER_RULETYPE_DYNAMIC_LASTYEAR = 'lastYear';
|
||||
const AUTOFILTER_RULETYPE_DYNAMIC_LASTQUARTER = 'lastQuarter';
|
||||
const AUTOFILTER_RULETYPE_DYNAMIC_LASTMONTH = 'lastMonth';
|
||||
const AUTOFILTER_RULETYPE_DYNAMIC_LASTWEEK = 'lastWeek';
|
||||
const AUTOFILTER_RULETYPE_DYNAMIC_NEXTYEAR = 'nextYear';
|
||||
const AUTOFILTER_RULETYPE_DYNAMIC_NEXTQUARTER = 'nextQuarter';
|
||||
const AUTOFILTER_RULETYPE_DYNAMIC_NEXTMONTH = 'nextMonth';
|
||||
const AUTOFILTER_RULETYPE_DYNAMIC_NEXTWEEK = 'nextWeek';
|
||||
const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_1 = 'M1';
|
||||
const AUTOFILTER_RULETYPE_DYNAMIC_JANUARY = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_1;
|
||||
const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_2 = 'M2';
|
||||
const AUTOFILTER_RULETYPE_DYNAMIC_FEBRUARY = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_2;
|
||||
const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_3 = 'M3';
|
||||
const AUTOFILTER_RULETYPE_DYNAMIC_MARCH = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_3;
|
||||
const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_4 = 'M4';
|
||||
const AUTOFILTER_RULETYPE_DYNAMIC_APRIL = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_4;
|
||||
const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_5 = 'M5';
|
||||
const AUTOFILTER_RULETYPE_DYNAMIC_MAY = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_5;
|
||||
const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_6 = 'M6';
|
||||
const AUTOFILTER_RULETYPE_DYNAMIC_JUNE = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_6;
|
||||
const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_7 = 'M7';
|
||||
const AUTOFILTER_RULETYPE_DYNAMIC_JULY = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_7;
|
||||
const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_8 = 'M8';
|
||||
const AUTOFILTER_RULETYPE_DYNAMIC_AUGUST = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_8;
|
||||
const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_9 = 'M9';
|
||||
const AUTOFILTER_RULETYPE_DYNAMIC_SEPTEMBER = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_9;
|
||||
const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_10 = 'M10';
|
||||
const AUTOFILTER_RULETYPE_DYNAMIC_OCTOBER = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_10;
|
||||
const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_11 = 'M11';
|
||||
const AUTOFILTER_RULETYPE_DYNAMIC_NOVEMBER = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_11;
|
||||
const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_12 = 'M12';
|
||||
const AUTOFILTER_RULETYPE_DYNAMIC_DECEMBER = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_12;
|
||||
const AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_1 = 'Q1';
|
||||
const AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_2 = 'Q2';
|
||||
const AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_3 = 'Q3';
|
||||
const AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_4 = 'Q4';
|
||||
const AUTOFILTER_RULETYPE_DYNAMIC_ABOVEAVERAGE = 'aboveAverage';
|
||||
const AUTOFILTER_RULETYPE_DYNAMIC_BELOWAVERAGE = 'belowAverage';
|
||||
|
||||
private static $dynamicTypes = [
|
||||
self::AUTOFILTER_RULETYPE_DYNAMIC_YESTERDAY,
|
||||
self::AUTOFILTER_RULETYPE_DYNAMIC_TODAY,
|
||||
self::AUTOFILTER_RULETYPE_DYNAMIC_TOMORROW,
|
||||
self::AUTOFILTER_RULETYPE_DYNAMIC_YEARTODATE,
|
||||
self::AUTOFILTER_RULETYPE_DYNAMIC_THISYEAR,
|
||||
self::AUTOFILTER_RULETYPE_DYNAMIC_THISQUARTER,
|
||||
self::AUTOFILTER_RULETYPE_DYNAMIC_THISMONTH,
|
||||
self::AUTOFILTER_RULETYPE_DYNAMIC_THISWEEK,
|
||||
self::AUTOFILTER_RULETYPE_DYNAMIC_LASTYEAR,
|
||||
self::AUTOFILTER_RULETYPE_DYNAMIC_LASTQUARTER,
|
||||
self::AUTOFILTER_RULETYPE_DYNAMIC_LASTMONTH,
|
||||
self::AUTOFILTER_RULETYPE_DYNAMIC_LASTWEEK,
|
||||
self::AUTOFILTER_RULETYPE_DYNAMIC_NEXTYEAR,
|
||||
self::AUTOFILTER_RULETYPE_DYNAMIC_NEXTQUARTER,
|
||||
self::AUTOFILTER_RULETYPE_DYNAMIC_NEXTMONTH,
|
||||
self::AUTOFILTER_RULETYPE_DYNAMIC_NEXTWEEK,
|
||||
self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_1,
|
||||
self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_2,
|
||||
self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_3,
|
||||
self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_4,
|
||||
self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_5,
|
||||
self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_6,
|
||||
self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_7,
|
||||
self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_8,
|
||||
self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_9,
|
||||
self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_10,
|
||||
self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_11,
|
||||
self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_12,
|
||||
self::AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_1,
|
||||
self::AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_2,
|
||||
self::AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_3,
|
||||
self::AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_4,
|
||||
self::AUTOFILTER_RULETYPE_DYNAMIC_ABOVEAVERAGE,
|
||||
self::AUTOFILTER_RULETYPE_DYNAMIC_BELOWAVERAGE,
|
||||
];
|
||||
|
||||
/*
|
||||
* The only valid filter rule operators for filter and customFilter types are:
|
||||
* <xsd:enumeration value="equal"/>
|
||||
* <xsd:enumeration value="lessThan"/>
|
||||
* <xsd:enumeration value="lessThanOrEqual"/>
|
||||
* <xsd:enumeration value="notEqual"/>
|
||||
* <xsd:enumeration value="greaterThanOrEqual"/>
|
||||
* <xsd:enumeration value="greaterThan"/>
|
||||
*/
|
||||
const AUTOFILTER_COLUMN_RULE_EQUAL = 'equal';
|
||||
const AUTOFILTER_COLUMN_RULE_NOTEQUAL = 'notEqual';
|
||||
const AUTOFILTER_COLUMN_RULE_GREATERTHAN = 'greaterThan';
|
||||
const AUTOFILTER_COLUMN_RULE_GREATERTHANOREQUAL = 'greaterThanOrEqual';
|
||||
const AUTOFILTER_COLUMN_RULE_LESSTHAN = 'lessThan';
|
||||
const AUTOFILTER_COLUMN_RULE_LESSTHANOREQUAL = 'lessThanOrEqual';
|
||||
|
||||
private static $operators = [
|
||||
self::AUTOFILTER_COLUMN_RULE_EQUAL,
|
||||
self::AUTOFILTER_COLUMN_RULE_NOTEQUAL,
|
||||
self::AUTOFILTER_COLUMN_RULE_GREATERTHAN,
|
||||
self::AUTOFILTER_COLUMN_RULE_GREATERTHANOREQUAL,
|
||||
self::AUTOFILTER_COLUMN_RULE_LESSTHAN,
|
||||
self::AUTOFILTER_COLUMN_RULE_LESSTHANOREQUAL,
|
||||
];
|
||||
|
||||
const AUTOFILTER_COLUMN_RULE_TOPTEN_BY_VALUE = 'byValue';
|
||||
const AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT = 'byPercent';
|
||||
|
||||
private static $topTenValue = [
|
||||
self::AUTOFILTER_COLUMN_RULE_TOPTEN_BY_VALUE,
|
||||
self::AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT,
|
||||
];
|
||||
|
||||
const AUTOFILTER_COLUMN_RULE_TOPTEN_TOP = 'top';
|
||||
const AUTOFILTER_COLUMN_RULE_TOPTEN_BOTTOM = 'bottom';
|
||||
|
||||
private static $topTenType = [
|
||||
self::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP,
|
||||
self::AUTOFILTER_COLUMN_RULE_TOPTEN_BOTTOM,
|
||||
];
|
||||
|
||||
// Rule Operators (Numeric, Boolean etc)
|
||||
// const AUTOFILTER_COLUMN_RULE_BETWEEN = 'between'; // greaterThanOrEqual 1 && lessThanOrEqual 2
|
||||
// Rule Operators (Numeric Special) which are translated to standard numeric operators with calculated values
|
||||
// const AUTOFILTER_COLUMN_RULE_TOPTEN = 'topTen'; // greaterThan calculated value
|
||||
// const AUTOFILTER_COLUMN_RULE_TOPTENPERCENT = 'topTenPercent'; // greaterThan calculated value
|
||||
// const AUTOFILTER_COLUMN_RULE_ABOVEAVERAGE = 'aboveAverage'; // Value is calculated as the average
|
||||
// const AUTOFILTER_COLUMN_RULE_BELOWAVERAGE = 'belowAverage'; // Value is calculated as the average
|
||||
// Rule Operators (String) which are set as wild-carded values
|
||||
// const AUTOFILTER_COLUMN_RULE_BEGINSWITH = 'beginsWith'; // A*
|
||||
// const AUTOFILTER_COLUMN_RULE_ENDSWITH = 'endsWith'; // *Z
|
||||
// const AUTOFILTER_COLUMN_RULE_CONTAINS = 'contains'; // *B*
|
||||
// const AUTOFILTER_COLUMN_RULE_DOESNTCONTAIN = 'notEqual'; // notEqual *B*
|
||||
// Rule Operators (Date Special) which are translated to standard numeric operators with calculated values
|
||||
// const AUTOFILTER_COLUMN_RULE_BEFORE = 'lessThan';
|
||||
// const AUTOFILTER_COLUMN_RULE_AFTER = 'greaterThan';
|
||||
// const AUTOFILTER_COLUMN_RULE_YESTERDAY = 'yesterday';
|
||||
// const AUTOFILTER_COLUMN_RULE_TODAY = 'today';
|
||||
// const AUTOFILTER_COLUMN_RULE_TOMORROW = 'tomorrow';
|
||||
// const AUTOFILTER_COLUMN_RULE_LASTWEEK = 'lastWeek';
|
||||
// const AUTOFILTER_COLUMN_RULE_THISWEEK = 'thisWeek';
|
||||
// const AUTOFILTER_COLUMN_RULE_NEXTWEEK = 'nextWeek';
|
||||
// const AUTOFILTER_COLUMN_RULE_LASTMONTH = 'lastMonth';
|
||||
// const AUTOFILTER_COLUMN_RULE_THISMONTH = 'thisMonth';
|
||||
// const AUTOFILTER_COLUMN_RULE_NEXTMONTH = 'nextMonth';
|
||||
// const AUTOFILTER_COLUMN_RULE_LASTQUARTER = 'lastQuarter';
|
||||
// const AUTOFILTER_COLUMN_RULE_THISQUARTER = 'thisQuarter';
|
||||
// const AUTOFILTER_COLUMN_RULE_NEXTQUARTER = 'nextQuarter';
|
||||
// const AUTOFILTER_COLUMN_RULE_LASTYEAR = 'lastYear';
|
||||
// const AUTOFILTER_COLUMN_RULE_THISYEAR = 'thisYear';
|
||||
// const AUTOFILTER_COLUMN_RULE_NEXTYEAR = 'nextYear';
|
||||
// const AUTOFILTER_COLUMN_RULE_YEARTODATE = 'yearToDate'; // <dynamicFilter val="40909" type="yearToDate" maxVal="41113"/>
|
||||
// const AUTOFILTER_COLUMN_RULE_ALLDATESINMONTH = 'allDatesInMonth'; // <dynamicFilter type="M2"/> for Month/February
|
||||
// const AUTOFILTER_COLUMN_RULE_ALLDATESINQUARTER = 'allDatesInQuarter'; // <dynamicFilter type="Q2"/> for Quarter 2
|
||||
|
||||
/**
|
||||
* Autofilter Column.
|
||||
*
|
||||
* @var Column
|
||||
*/
|
||||
private $parent;
|
||||
|
||||
/**
|
||||
* Autofilter Rule Type.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $ruleType = self::AUTOFILTER_RULETYPE_FILTER;
|
||||
|
||||
/**
|
||||
* Autofilter Rule Value.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $value = '';
|
||||
|
||||
/**
|
||||
* Autofilter Rule Operator.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $operator = self::AUTOFILTER_COLUMN_RULE_EQUAL;
|
||||
|
||||
/**
|
||||
* DateTimeGrouping Group Value.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $grouping = '';
|
||||
|
||||
/**
|
||||
* Create a new Rule.
|
||||
*
|
||||
* @param Column $pParent
|
||||
*/
|
||||
public function __construct(?Column $pParent = null)
|
||||
{
|
||||
$this->parent = $pParent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get AutoFilter Rule Type.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getRuleType()
|
||||
{
|
||||
return $this->ruleType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set AutoFilter Rule Type.
|
||||
*
|
||||
* @param string $pRuleType see self::AUTOFILTER_RULETYPE_*
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setRuleType($pRuleType)
|
||||
{
|
||||
if (!in_array($pRuleType, self::$ruleTypes)) {
|
||||
throw new PhpSpreadsheetException('Invalid rule type for column AutoFilter Rule.');
|
||||
}
|
||||
|
||||
$this->ruleType = $pRuleType;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get AutoFilter Rule Value.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getValue()
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set AutoFilter Rule Value.
|
||||
*
|
||||
* @param string|string[] $pValue
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setValue($pValue)
|
||||
{
|
||||
if (is_array($pValue)) {
|
||||
$grouping = -1;
|
||||
foreach ($pValue as $key => $value) {
|
||||
// Validate array entries
|
||||
if (!in_array($key, self::$dateTimeGroups)) {
|
||||
// Remove any invalid entries from the value array
|
||||
unset($pValue[$key]);
|
||||
} else {
|
||||
// Work out what the dateTime grouping will be
|
||||
$grouping = max($grouping, array_search($key, self::$dateTimeGroups));
|
||||
}
|
||||
}
|
||||
if (count($pValue) == 0) {
|
||||
throw new PhpSpreadsheetException('Invalid rule value for column AutoFilter Rule.');
|
||||
}
|
||||
// Set the dateTime grouping that we've anticipated
|
||||
$this->setGrouping(self::$dateTimeGroups[$grouping]);
|
||||
}
|
||||
$this->value = $pValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get AutoFilter Rule Operator.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getOperator()
|
||||
{
|
||||
return $this->operator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set AutoFilter Rule Operator.
|
||||
*
|
||||
* @param string $pOperator see self::AUTOFILTER_COLUMN_RULE_*
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setOperator($pOperator)
|
||||
{
|
||||
if (empty($pOperator)) {
|
||||
$pOperator = self::AUTOFILTER_COLUMN_RULE_EQUAL;
|
||||
}
|
||||
if (
|
||||
(!in_array($pOperator, self::$operators)) &&
|
||||
(!in_array($pOperator, self::$topTenValue))
|
||||
) {
|
||||
throw new PhpSpreadsheetException('Invalid operator for column AutoFilter Rule.');
|
||||
}
|
||||
$this->operator = $pOperator;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get AutoFilter Rule Grouping.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getGrouping()
|
||||
{
|
||||
return $this->grouping;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set AutoFilter Rule Grouping.
|
||||
*
|
||||
* @param string $pGrouping
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setGrouping($pGrouping)
|
||||
{
|
||||
if (
|
||||
($pGrouping !== null) &&
|
||||
(!in_array($pGrouping, self::$dateTimeGroups)) &&
|
||||
(!in_array($pGrouping, self::$dynamicTypes)) &&
|
||||
(!in_array($pGrouping, self::$topTenType))
|
||||
) {
|
||||
throw new PhpSpreadsheetException('Invalid rule type for column AutoFilter Rule.');
|
||||
}
|
||||
$this->grouping = $pGrouping;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set AutoFilter Rule.
|
||||
*
|
||||
* @param string $pOperator see self::AUTOFILTER_COLUMN_RULE_*
|
||||
* @param string|string[] $pValue
|
||||
* @param string $pGrouping
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setRule($pOperator, $pValue, $pGrouping = null)
|
||||
{
|
||||
$this->setOperator($pOperator);
|
||||
$this->setValue($pValue);
|
||||
// Only set grouping if it's been passed in as a user-supplied argument,
|
||||
// otherwise we're calculating it when we setValue() and don't want to overwrite that
|
||||
// If the user supplies an argumnet for grouping, then on their own head be it
|
||||
if ($pGrouping !== null) {
|
||||
$this->setGrouping($pGrouping);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get this Rule's AutoFilter Column Parent.
|
||||
*
|
||||
* @return Column
|
||||
*/
|
||||
public function getParent()
|
||||
{
|
||||
return $this->parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set this Rule's AutoFilter Column Parent.
|
||||
*
|
||||
* @param Column $pParent
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setParent(?Column $pParent = null)
|
||||
{
|
||||
$this->parent = $pParent;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement PHP __clone to create a deep clone, not just a shallow copy.
|
||||
*/
|
||||
public function __clone()
|
||||
{
|
||||
$vars = get_object_vars($this);
|
||||
foreach ($vars as $key => $value) {
|
||||
if (is_object($value)) {
|
||||
if ($key == 'parent') {
|
||||
// Detach from autofilter column parent
|
||||
$this->$key = null;
|
||||
} else {
|
||||
$this->$key = clone $value;
|
||||
}
|
||||
} else {
|
||||
$this->$key = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
532
vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/BaseDrawing.php
vendored
Normal file
532
vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/BaseDrawing.php
vendored
Normal file
@@ -0,0 +1,532 @@
|
||||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Worksheet;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Cell\Hyperlink;
|
||||
use PhpOffice\PhpSpreadsheet\Exception as PhpSpreadsheetException;
|
||||
use PhpOffice\PhpSpreadsheet\IComparable;
|
||||
|
||||
class BaseDrawing implements IComparable
|
||||
{
|
||||
/**
|
||||
* Image counter.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private static $imageCounter = 0;
|
||||
|
||||
/**
|
||||
* Image index.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $imageIndex = 0;
|
||||
|
||||
/**
|
||||
* Name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $name;
|
||||
|
||||
/**
|
||||
* Description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description;
|
||||
|
||||
/**
|
||||
* Worksheet.
|
||||
*
|
||||
* @var Worksheet
|
||||
*/
|
||||
protected $worksheet;
|
||||
|
||||
/**
|
||||
* Coordinates.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $coordinates;
|
||||
|
||||
/**
|
||||
* Offset X.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $offsetX;
|
||||
|
||||
/**
|
||||
* Offset Y.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $offsetY;
|
||||
|
||||
/**
|
||||
* Width.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $width;
|
||||
|
||||
/**
|
||||
* Height.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $height;
|
||||
|
||||
/**
|
||||
* Proportional resize.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $resizeProportional;
|
||||
|
||||
/**
|
||||
* Rotation.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $rotation;
|
||||
|
||||
/**
|
||||
* Shadow.
|
||||
*
|
||||
* @var Drawing\Shadow
|
||||
*/
|
||||
protected $shadow;
|
||||
|
||||
/**
|
||||
* Image hyperlink.
|
||||
*
|
||||
* @var null|Hyperlink
|
||||
*/
|
||||
private $hyperlink;
|
||||
|
||||
/**
|
||||
* Create a new BaseDrawing.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
// Initialise values
|
||||
$this->name = '';
|
||||
$this->description = '';
|
||||
$this->worksheet = null;
|
||||
$this->coordinates = 'A1';
|
||||
$this->offsetX = 0;
|
||||
$this->offsetY = 0;
|
||||
$this->width = 0;
|
||||
$this->height = 0;
|
||||
$this->resizeProportional = true;
|
||||
$this->rotation = 0;
|
||||
$this->shadow = new Drawing\Shadow();
|
||||
|
||||
// Set image index
|
||||
++self::$imageCounter;
|
||||
$this->imageIndex = self::$imageCounter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get image index.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getImageIndex()
|
||||
{
|
||||
return $this->imageIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Name.
|
||||
*
|
||||
* @param string $pValue
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setName($pValue)
|
||||
{
|
||||
$this->name = $pValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Description.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Description.
|
||||
*
|
||||
* @param string $description
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setDescription($description)
|
||||
{
|
||||
$this->description = $description;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Worksheet.
|
||||
*
|
||||
* @return Worksheet
|
||||
*/
|
||||
public function getWorksheet()
|
||||
{
|
||||
return $this->worksheet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Worksheet.
|
||||
*
|
||||
* @param Worksheet $pValue
|
||||
* @param bool $pOverrideOld If a Worksheet has already been assigned, overwrite it and remove image from old Worksheet?
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setWorksheet(?Worksheet $pValue = null, $pOverrideOld = false)
|
||||
{
|
||||
if ($this->worksheet === null) {
|
||||
// Add drawing to \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet
|
||||
$this->worksheet = $pValue;
|
||||
$this->worksheet->getCell($this->coordinates);
|
||||
$this->worksheet->getDrawingCollection()->append($this);
|
||||
} else {
|
||||
if ($pOverrideOld) {
|
||||
// Remove drawing from old \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet
|
||||
$iterator = $this->worksheet->getDrawingCollection()->getIterator();
|
||||
|
||||
while ($iterator->valid()) {
|
||||
if ($iterator->current()->getHashCode() === $this->getHashCode()) {
|
||||
$this->worksheet->getDrawingCollection()->offsetUnset($iterator->key());
|
||||
$this->worksheet = null;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Set new \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet
|
||||
$this->setWorksheet($pValue);
|
||||
} else {
|
||||
throw new PhpSpreadsheetException('A Worksheet has already been assigned. Drawings can only exist on one \\PhpOffice\\PhpSpreadsheet\\Worksheet.');
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Coordinates.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getCoordinates()
|
||||
{
|
||||
return $this->coordinates;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Coordinates.
|
||||
*
|
||||
* @param string $pValue eg: 'A1'
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setCoordinates($pValue)
|
||||
{
|
||||
$this->coordinates = $pValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get OffsetX.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getOffsetX()
|
||||
{
|
||||
return $this->offsetX;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set OffsetX.
|
||||
*
|
||||
* @param int $pValue
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setOffsetX($pValue)
|
||||
{
|
||||
$this->offsetX = $pValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get OffsetY.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getOffsetY()
|
||||
{
|
||||
return $this->offsetY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set OffsetY.
|
||||
*
|
||||
* @param int $pValue
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setOffsetY($pValue)
|
||||
{
|
||||
$this->offsetY = $pValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Width.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getWidth()
|
||||
{
|
||||
return $this->width;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Width.
|
||||
*
|
||||
* @param int $pValue
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setWidth($pValue)
|
||||
{
|
||||
// Resize proportional?
|
||||
if ($this->resizeProportional && $pValue != 0) {
|
||||
$ratio = $this->height / ($this->width != 0 ? $this->width : 1);
|
||||
$this->height = round($ratio * $pValue);
|
||||
}
|
||||
|
||||
// Set width
|
||||
$this->width = $pValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Height.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getHeight()
|
||||
{
|
||||
return $this->height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Height.
|
||||
*
|
||||
* @param int $pValue
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setHeight($pValue)
|
||||
{
|
||||
// Resize proportional?
|
||||
if ($this->resizeProportional && $pValue != 0) {
|
||||
$ratio = $this->width / ($this->height != 0 ? $this->height : 1);
|
||||
$this->width = round($ratio * $pValue);
|
||||
}
|
||||
|
||||
// Set height
|
||||
$this->height = $pValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set width and height with proportional resize.
|
||||
*
|
||||
* Example:
|
||||
* <code>
|
||||
* $objDrawing->setResizeProportional(true);
|
||||
* $objDrawing->setWidthAndHeight(160,120);
|
||||
* </code>
|
||||
*
|
||||
* @author Vincent@luo MSN:kele_100@hotmail.com
|
||||
*
|
||||
* @param int $width
|
||||
* @param int $height
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setWidthAndHeight($width, $height)
|
||||
{
|
||||
$xratio = $width / ($this->width != 0 ? $this->width : 1);
|
||||
$yratio = $height / ($this->height != 0 ? $this->height : 1);
|
||||
if ($this->resizeProportional && !($width == 0 || $height == 0)) {
|
||||
if (($xratio * $this->height) < $height) {
|
||||
$this->height = ceil($xratio * $this->height);
|
||||
$this->width = $width;
|
||||
} else {
|
||||
$this->width = ceil($yratio * $this->width);
|
||||
$this->height = $height;
|
||||
}
|
||||
} else {
|
||||
$this->width = $width;
|
||||
$this->height = $height;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get ResizeProportional.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getResizeProportional()
|
||||
{
|
||||
return $this->resizeProportional;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set ResizeProportional.
|
||||
*
|
||||
* @param bool $pValue
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setResizeProportional($pValue)
|
||||
{
|
||||
$this->resizeProportional = $pValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Rotation.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getRotation()
|
||||
{
|
||||
return $this->rotation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Rotation.
|
||||
*
|
||||
* @param int $pValue
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setRotation($pValue)
|
||||
{
|
||||
$this->rotation = $pValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Shadow.
|
||||
*
|
||||
* @return Drawing\Shadow
|
||||
*/
|
||||
public function getShadow()
|
||||
{
|
||||
return $this->shadow;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Shadow.
|
||||
*
|
||||
* @param Drawing\Shadow $pValue
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setShadow(?Drawing\Shadow $pValue = null)
|
||||
{
|
||||
$this->shadow = $pValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get hash code.
|
||||
*
|
||||
* @return string Hash code
|
||||
*/
|
||||
public function getHashCode()
|
||||
{
|
||||
return md5(
|
||||
$this->name .
|
||||
$this->description .
|
||||
$this->worksheet->getHashCode() .
|
||||
$this->coordinates .
|
||||
$this->offsetX .
|
||||
$this->offsetY .
|
||||
$this->width .
|
||||
$this->height .
|
||||
$this->rotation .
|
||||
$this->shadow->getHashCode() .
|
||||
__CLASS__
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement PHP __clone to create a deep clone, not just a shallow copy.
|
||||
*/
|
||||
public function __clone()
|
||||
{
|
||||
$vars = get_object_vars($this);
|
||||
foreach ($vars as $key => $value) {
|
||||
if ($key == 'worksheet') {
|
||||
$this->worksheet = null;
|
||||
} elseif (is_object($value)) {
|
||||
$this->$key = clone $value;
|
||||
} else {
|
||||
$this->$key = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function setHyperlink(?Hyperlink $pHyperlink = null): void
|
||||
{
|
||||
$this->hyperlink = $pHyperlink;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|Hyperlink
|
||||
*/
|
||||
public function getHyperlink()
|
||||
{
|
||||
return $this->hyperlink;
|
||||
}
|
||||
}
|
57
vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/CellIterator.php
vendored
Normal file
57
vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/CellIterator.php
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Worksheet;
|
||||
|
||||
use Iterator;
|
||||
|
||||
abstract class CellIterator implements Iterator
|
||||
{
|
||||
/**
|
||||
* Worksheet to iterate.
|
||||
*
|
||||
* @var Worksheet
|
||||
*/
|
||||
protected $worksheet;
|
||||
|
||||
/**
|
||||
* Iterate only existing cells.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $onlyExistingCells = false;
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
$this->worksheet = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get loop only existing cells.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getIterateOnlyExistingCells()
|
||||
{
|
||||
return $this->onlyExistingCells;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate start/end values for "IterateOnlyExistingCells" mode, and adjust if necessary.
|
||||
*/
|
||||
abstract protected function adjustForExistingOnlyRange();
|
||||
|
||||
/**
|
||||
* Set the iterator to loop only existing cells.
|
||||
*
|
||||
* @param bool $value
|
||||
*/
|
||||
public function setIterateOnlyExistingCells($value): void
|
||||
{
|
||||
$this->onlyExistingCells = (bool) $value;
|
||||
|
||||
$this->adjustForExistingOnlyRange();
|
||||
}
|
||||
}
|
64
vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/Column.php
vendored
Normal file
64
vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/Column.php
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Worksheet;
|
||||
|
||||
class Column
|
||||
{
|
||||
/**
|
||||
* \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet.
|
||||
*
|
||||
* @var Worksheet
|
||||
*/
|
||||
private $parent;
|
||||
|
||||
/**
|
||||
* Column index.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $columnIndex;
|
||||
|
||||
/**
|
||||
* Create a new column.
|
||||
*
|
||||
* @param Worksheet $parent
|
||||
* @param string $columnIndex
|
||||
*/
|
||||
public function __construct(?Worksheet $parent = null, $columnIndex = 'A')
|
||||
{
|
||||
// Set parent and column index
|
||||
$this->parent = $parent;
|
||||
$this->columnIndex = $columnIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
$this->parent = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get column index as string eg: 'A'.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getColumnIndex()
|
||||
{
|
||||
return $this->columnIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cell iterator.
|
||||
*
|
||||
* @param int $startRow The row number at which to start iterating
|
||||
* @param int $endRow Optionally, the row number at which to stop iterating
|
||||
*
|
||||
* @return ColumnCellIterator
|
||||
*/
|
||||
public function getCellIterator($startRow = 1, $endRow = null)
|
||||
{
|
||||
return new ColumnCellIterator($this->parent, $this->columnIndex, $startRow, $endRow);
|
||||
}
|
||||
}
|
192
vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/ColumnCellIterator.php
vendored
Normal file
192
vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/ColumnCellIterator.php
vendored
Normal file
@@ -0,0 +1,192 @@
|
||||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Worksheet;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
|
||||
use PhpOffice\PhpSpreadsheet\Exception as PhpSpreadsheetException;
|
||||
|
||||
class ColumnCellIterator extends CellIterator
|
||||
{
|
||||
/**
|
||||
* Current iterator position.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $currentRow;
|
||||
|
||||
/**
|
||||
* Column index.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $columnIndex;
|
||||
|
||||
/**
|
||||
* Start position.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $startRow = 1;
|
||||
|
||||
/**
|
||||
* End position.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $endRow = 1;
|
||||
|
||||
/**
|
||||
* Create a new row iterator.
|
||||
*
|
||||
* @param Worksheet $subject The worksheet to iterate over
|
||||
* @param string $columnIndex The column that we want to iterate
|
||||
* @param int $startRow The row number at which to start iterating
|
||||
* @param int $endRow Optionally, the row number at which to stop iterating
|
||||
*/
|
||||
public function __construct(?Worksheet $subject = null, $columnIndex = 'A', $startRow = 1, $endRow = null)
|
||||
{
|
||||
// Set subject
|
||||
$this->worksheet = $subject;
|
||||
$this->columnIndex = Coordinate::columnIndexFromString($columnIndex);
|
||||
$this->resetEnd($endRow);
|
||||
$this->resetStart($startRow);
|
||||
}
|
||||
|
||||
/**
|
||||
* (Re)Set the start row and the current row pointer.
|
||||
*
|
||||
* @param int $startRow The row number at which to start iterating
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function resetStart($startRow = 1)
|
||||
{
|
||||
$this->startRow = $startRow;
|
||||
$this->adjustForExistingOnlyRange();
|
||||
$this->seek($startRow);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* (Re)Set the end row.
|
||||
*
|
||||
* @param int $endRow The row number at which to stop iterating
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function resetEnd($endRow = null)
|
||||
{
|
||||
$this->endRow = ($endRow) ? $endRow : $this->worksheet->getHighestRow();
|
||||
$this->adjustForExistingOnlyRange();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the row pointer to the selected row.
|
||||
*
|
||||
* @param int $row The row number to set the current pointer at
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function seek($row = 1)
|
||||
{
|
||||
if ($this->onlyExistingCells && !($this->worksheet->cellExistsByColumnAndRow($this->columnIndex, $row))) {
|
||||
throw new PhpSpreadsheetException('In "IterateOnlyExistingCells" mode and Cell does not exist');
|
||||
}
|
||||
if (($row < $this->startRow) || ($row > $this->endRow)) {
|
||||
throw new PhpSpreadsheetException("Row $row is out of range ({$this->startRow} - {$this->endRow})");
|
||||
}
|
||||
$this->currentRow = $row;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rewind the iterator to the starting row.
|
||||
*/
|
||||
public function rewind(): void
|
||||
{
|
||||
$this->currentRow = $this->startRow;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current cell in this worksheet column.
|
||||
*
|
||||
* @return \PhpOffice\PhpSpreadsheet\Cell\Cell
|
||||
*/
|
||||
public function current()
|
||||
{
|
||||
return $this->worksheet->getCellByColumnAndRow($this->columnIndex, $this->currentRow);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current iterator key.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function key()
|
||||
{
|
||||
return $this->currentRow;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the iterator to its next value.
|
||||
*/
|
||||
public function next(): void
|
||||
{
|
||||
do {
|
||||
++$this->currentRow;
|
||||
} while (
|
||||
($this->onlyExistingCells) &&
|
||||
(!$this->worksheet->cellExistsByColumnAndRow($this->columnIndex, $this->currentRow)) &&
|
||||
($this->currentRow <= $this->endRow)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the iterator to its previous value.
|
||||
*/
|
||||
public function prev(): void
|
||||
{
|
||||
do {
|
||||
--$this->currentRow;
|
||||
} while (
|
||||
($this->onlyExistingCells) &&
|
||||
(!$this->worksheet->cellExistsByColumnAndRow($this->columnIndex, $this->currentRow)) &&
|
||||
($this->currentRow >= $this->startRow)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate if more rows exist in the worksheet range of rows that we're iterating.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function valid()
|
||||
{
|
||||
return $this->currentRow <= $this->endRow && $this->currentRow >= $this->startRow;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate start/end values for "IterateOnlyExistingCells" mode, and adjust if necessary.
|
||||
*/
|
||||
protected function adjustForExistingOnlyRange(): void
|
||||
{
|
||||
if ($this->onlyExistingCells) {
|
||||
while (
|
||||
(!$this->worksheet->cellExistsByColumnAndRow($this->columnIndex, $this->startRow)) &&
|
||||
($this->startRow <= $this->endRow)
|
||||
) {
|
||||
++$this->startRow;
|
||||
}
|
||||
while (
|
||||
(!$this->worksheet->cellExistsByColumnAndRow($this->columnIndex, $this->endRow)) &&
|
||||
($this->endRow >= $this->startRow)
|
||||
) {
|
||||
--$this->endRow;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
115
vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/ColumnDimension.php
vendored
Normal file
115
vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/ColumnDimension.php
vendored
Normal file
@@ -0,0 +1,115 @@
|
||||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Worksheet;
|
||||
|
||||
class ColumnDimension extends Dimension
|
||||
{
|
||||
/**
|
||||
* Column index.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $columnIndex;
|
||||
|
||||
/**
|
||||
* Column width.
|
||||
*
|
||||
* When this is set to a negative value, the column width should be ignored by IWriter
|
||||
*
|
||||
* @var float
|
||||
*/
|
||||
private $width = -1;
|
||||
|
||||
/**
|
||||
* Auto size?
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $autoSize = false;
|
||||
|
||||
/**
|
||||
* Create a new ColumnDimension.
|
||||
*
|
||||
* @param string $pIndex Character column index
|
||||
*/
|
||||
public function __construct($pIndex = 'A')
|
||||
{
|
||||
// Initialise values
|
||||
$this->columnIndex = $pIndex;
|
||||
|
||||
// set dimension as unformatted by default
|
||||
parent::__construct(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get column index as string eg: 'A'.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getColumnIndex()
|
||||
{
|
||||
return $this->columnIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set column index as string eg: 'A'.
|
||||
*
|
||||
* @param string $pValue
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setColumnIndex($pValue)
|
||||
{
|
||||
$this->columnIndex = $pValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Width.
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function getWidth()
|
||||
{
|
||||
return $this->width;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Width.
|
||||
*
|
||||
* @param float $pValue
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setWidth($pValue)
|
||||
{
|
||||
$this->width = $pValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Auto Size.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getAutoSize()
|
||||
{
|
||||
return $this->autoSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Auto Size.
|
||||
*
|
||||
* @param bool $pValue
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setAutoSize($pValue)
|
||||
{
|
||||
$this->autoSize = $pValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
172
vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/ColumnIterator.php
vendored
Normal file
172
vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/ColumnIterator.php
vendored
Normal file
@@ -0,0 +1,172 @@
|
||||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Worksheet;
|
||||
|
||||
use Iterator;
|
||||
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
|
||||
use PhpOffice\PhpSpreadsheet\Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Exception as PhpSpreadsheetException;
|
||||
|
||||
class ColumnIterator implements Iterator
|
||||
{
|
||||
/**
|
||||
* Worksheet to iterate.
|
||||
*
|
||||
* @var Worksheet
|
||||
*/
|
||||
private $worksheet;
|
||||
|
||||
/**
|
||||
* Current iterator position.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $currentColumnIndex = 1;
|
||||
|
||||
/**
|
||||
* Start position.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $startColumnIndex = 1;
|
||||
|
||||
/**
|
||||
* End position.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $endColumnIndex = 1;
|
||||
|
||||
/**
|
||||
* Create a new column iterator.
|
||||
*
|
||||
* @param Worksheet $worksheet The worksheet to iterate over
|
||||
* @param string $startColumn The column address at which to start iterating
|
||||
* @param string $endColumn Optionally, the column address at which to stop iterating
|
||||
*/
|
||||
public function __construct(Worksheet $worksheet, $startColumn = 'A', $endColumn = null)
|
||||
{
|
||||
// Set subject
|
||||
$this->worksheet = $worksheet;
|
||||
$this->resetEnd($endColumn);
|
||||
$this->resetStart($startColumn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
$this->worksheet = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* (Re)Set the start column and the current column pointer.
|
||||
*
|
||||
* @param string $startColumn The column address at which to start iterating
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function resetStart($startColumn = 'A')
|
||||
{
|
||||
$startColumnIndex = Coordinate::columnIndexFromString($startColumn);
|
||||
if ($startColumnIndex > Coordinate::columnIndexFromString($this->worksheet->getHighestColumn())) {
|
||||
throw new Exception("Start column ({$startColumn}) is beyond highest column ({$this->worksheet->getHighestColumn()})");
|
||||
}
|
||||
|
||||
$this->startColumnIndex = $startColumnIndex;
|
||||
if ($this->endColumnIndex < $this->startColumnIndex) {
|
||||
$this->endColumnIndex = $this->startColumnIndex;
|
||||
}
|
||||
$this->seek($startColumn);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* (Re)Set the end column.
|
||||
*
|
||||
* @param string $endColumn The column address at which to stop iterating
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function resetEnd($endColumn = null)
|
||||
{
|
||||
$endColumn = $endColumn ? $endColumn : $this->worksheet->getHighestColumn();
|
||||
$this->endColumnIndex = Coordinate::columnIndexFromString($endColumn);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the column pointer to the selected column.
|
||||
*
|
||||
* @param string $column The column address to set the current pointer at
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function seek($column = 'A')
|
||||
{
|
||||
$column = Coordinate::columnIndexFromString($column);
|
||||
if (($column < $this->startColumnIndex) || ($column > $this->endColumnIndex)) {
|
||||
throw new PhpSpreadsheetException("Column $column is out of range ({$this->startColumnIndex} - {$this->endColumnIndex})");
|
||||
}
|
||||
$this->currentColumnIndex = $column;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rewind the iterator to the starting column.
|
||||
*/
|
||||
public function rewind(): void
|
||||
{
|
||||
$this->currentColumnIndex = $this->startColumnIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current column in this worksheet.
|
||||
*
|
||||
* @return Column
|
||||
*/
|
||||
public function current()
|
||||
{
|
||||
return new Column($this->worksheet, Coordinate::stringFromColumnIndex($this->currentColumnIndex));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current iterator key.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function key()
|
||||
{
|
||||
return Coordinate::stringFromColumnIndex($this->currentColumnIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the iterator to its next value.
|
||||
*/
|
||||
public function next(): void
|
||||
{
|
||||
++$this->currentColumnIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the iterator to its previous value.
|
||||
*/
|
||||
public function prev(): void
|
||||
{
|
||||
--$this->currentColumnIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate if more columns exist in the worksheet range of columns that we're iterating.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function valid()
|
||||
{
|
||||
return $this->currentColumnIndex <= $this->endColumnIndex && $this->currentColumnIndex >= $this->startColumnIndex;
|
||||
}
|
||||
}
|
163
vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/Dimension.php
vendored
Normal file
163
vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/Dimension.php
vendored
Normal file
@@ -0,0 +1,163 @@
|
||||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Worksheet;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Exception as PhpSpreadsheetException;
|
||||
|
||||
abstract class Dimension
|
||||
{
|
||||
/**
|
||||
* Visible?
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $visible = true;
|
||||
|
||||
/**
|
||||
* Outline level.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $outlineLevel = 0;
|
||||
|
||||
/**
|
||||
* Collapsed.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $collapsed = false;
|
||||
|
||||
/**
|
||||
* Index to cellXf. Null value means row has no explicit cellXf format.
|
||||
*
|
||||
* @var null|int
|
||||
*/
|
||||
private $xfIndex;
|
||||
|
||||
/**
|
||||
* Create a new Dimension.
|
||||
*
|
||||
* @param int $initialValue Numeric row index
|
||||
*/
|
||||
public function __construct($initialValue = null)
|
||||
{
|
||||
// set dimension as unformatted by default
|
||||
$this->xfIndex = $initialValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Visible.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getVisible()
|
||||
{
|
||||
return $this->visible;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Visible.
|
||||
*
|
||||
* @param bool $pValue
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setVisible($pValue)
|
||||
{
|
||||
$this->visible = (bool) $pValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Outline Level.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getOutlineLevel()
|
||||
{
|
||||
return $this->outlineLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Outline Level.
|
||||
* Value must be between 0 and 7.
|
||||
*
|
||||
* @param int $pValue
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setOutlineLevel($pValue)
|
||||
{
|
||||
if ($pValue < 0 || $pValue > 7) {
|
||||
throw new PhpSpreadsheetException('Outline level must range between 0 and 7.');
|
||||
}
|
||||
|
||||
$this->outlineLevel = $pValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Collapsed.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getCollapsed()
|
||||
{
|
||||
return $this->collapsed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Collapsed.
|
||||
*
|
||||
* @param bool $pValue
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setCollapsed($pValue)
|
||||
{
|
||||
$this->collapsed = (bool) $pValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get index to cellXf.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getXfIndex()
|
||||
{
|
||||
return $this->xfIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set index to cellXf.
|
||||
*
|
||||
* @param int $pValue
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setXfIndex($pValue)
|
||||
{
|
||||
$this->xfIndex = $pValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement PHP __clone to create a deep clone, not just a shallow copy.
|
||||
*/
|
||||
public function __clone()
|
||||
{
|
||||
$vars = get_object_vars($this);
|
||||
foreach ($vars as $key => $value) {
|
||||
if (is_object($value)) {
|
||||
$this->$key = clone $value;
|
||||
} else {
|
||||
$this->$key = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
114
vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/Drawing.php
vendored
Normal file
114
vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/Drawing.php
vendored
Normal file
@@ -0,0 +1,114 @@
|
||||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Worksheet;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Exception as PhpSpreadsheetException;
|
||||
|
||||
class Drawing extends BaseDrawing
|
||||
{
|
||||
/**
|
||||
* Path.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $path;
|
||||
|
||||
/**
|
||||
* Create a new Drawing.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
// Initialise values
|
||||
$this->path = '';
|
||||
|
||||
// Initialize parent
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Filename.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getFilename()
|
||||
{
|
||||
return basename($this->path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get indexed filename (using image index).
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getIndexedFilename()
|
||||
{
|
||||
$fileName = $this->getFilename();
|
||||
$fileName = str_replace(' ', '_', $fileName);
|
||||
|
||||
return str_replace('.' . $this->getExtension(), '', $fileName) . $this->getImageIndex() . '.' . $this->getExtension();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Extension.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getExtension()
|
||||
{
|
||||
$exploded = explode('.', basename($this->path));
|
||||
|
||||
return $exploded[count($exploded) - 1];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Path.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPath()
|
||||
{
|
||||
return $this->path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Path.
|
||||
*
|
||||
* @param string $pValue File path
|
||||
* @param bool $pVerifyFile Verify file
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setPath($pValue, $pVerifyFile = true)
|
||||
{
|
||||
if ($pVerifyFile) {
|
||||
if (file_exists($pValue)) {
|
||||
$this->path = $pValue;
|
||||
|
||||
if ($this->width == 0 && $this->height == 0) {
|
||||
// Get width/height
|
||||
[$this->width, $this->height] = getimagesize($pValue);
|
||||
}
|
||||
} else {
|
||||
throw new PhpSpreadsheetException("File $pValue not found!");
|
||||
}
|
||||
} else {
|
||||
$this->path = $pValue;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get hash code.
|
||||
*
|
||||
* @return string Hash code
|
||||
*/
|
||||
public function getHashCode()
|
||||
{
|
||||
return md5(
|
||||
$this->path .
|
||||
parent::getHashCode() .
|
||||
__CLASS__
|
||||
);
|
||||
}
|
||||
}
|
289
vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/Drawing/Shadow.php
vendored
Normal file
289
vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/Drawing/Shadow.php
vendored
Normal file
@@ -0,0 +1,289 @@
|
||||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Worksheet\Drawing;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\IComparable;
|
||||
use PhpOffice\PhpSpreadsheet\Style\Color;
|
||||
|
||||
class Shadow implements IComparable
|
||||
{
|
||||
// Shadow alignment
|
||||
const SHADOW_BOTTOM = 'b';
|
||||
const SHADOW_BOTTOM_LEFT = 'bl';
|
||||
const SHADOW_BOTTOM_RIGHT = 'br';
|
||||
const SHADOW_CENTER = 'ctr';
|
||||
const SHADOW_LEFT = 'l';
|
||||
const SHADOW_TOP = 't';
|
||||
const SHADOW_TOP_LEFT = 'tl';
|
||||
const SHADOW_TOP_RIGHT = 'tr';
|
||||
|
||||
/**
|
||||
* Visible.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $visible;
|
||||
|
||||
/**
|
||||
* Blur radius.
|
||||
*
|
||||
* Defaults to 6
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $blurRadius;
|
||||
|
||||
/**
|
||||
* Shadow distance.
|
||||
*
|
||||
* Defaults to 2
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $distance;
|
||||
|
||||
/**
|
||||
* Shadow direction (in degrees).
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $direction;
|
||||
|
||||
/**
|
||||
* Shadow alignment.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $alignment;
|
||||
|
||||
/**
|
||||
* Color.
|
||||
*
|
||||
* @var Color
|
||||
*/
|
||||
private $color;
|
||||
|
||||
/**
|
||||
* Alpha.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $alpha;
|
||||
|
||||
/**
|
||||
* Create a new Shadow.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
// Initialise values
|
||||
$this->visible = false;
|
||||
$this->blurRadius = 6;
|
||||
$this->distance = 2;
|
||||
$this->direction = 0;
|
||||
$this->alignment = self::SHADOW_BOTTOM_RIGHT;
|
||||
$this->color = new Color(Color::COLOR_BLACK);
|
||||
$this->alpha = 50;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Visible.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getVisible()
|
||||
{
|
||||
return $this->visible;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Visible.
|
||||
*
|
||||
* @param bool $pValue
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setVisible($pValue)
|
||||
{
|
||||
$this->visible = $pValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Blur radius.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getBlurRadius()
|
||||
{
|
||||
return $this->blurRadius;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Blur radius.
|
||||
*
|
||||
* @param int $pValue
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setBlurRadius($pValue)
|
||||
{
|
||||
$this->blurRadius = $pValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Shadow distance.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getDistance()
|
||||
{
|
||||
return $this->distance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Shadow distance.
|
||||
*
|
||||
* @param int $pValue
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setDistance($pValue)
|
||||
{
|
||||
$this->distance = $pValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Shadow direction (in degrees).
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getDirection()
|
||||
{
|
||||
return $this->direction;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Shadow direction (in degrees).
|
||||
*
|
||||
* @param int $pValue
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setDirection($pValue)
|
||||
{
|
||||
$this->direction = $pValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Shadow alignment.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getAlignment()
|
||||
{
|
||||
return $this->alignment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Shadow alignment.
|
||||
*
|
||||
* @param int $pValue
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setAlignment($pValue)
|
||||
{
|
||||
$this->alignment = $pValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Color.
|
||||
*
|
||||
* @return Color
|
||||
*/
|
||||
public function getColor()
|
||||
{
|
||||
return $this->color;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Color.
|
||||
*
|
||||
* @param Color $pValue
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setColor(?Color $pValue = null)
|
||||
{
|
||||
$this->color = $pValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Alpha.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getAlpha()
|
||||
{
|
||||
return $this->alpha;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Alpha.
|
||||
*
|
||||
* @param int $pValue
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setAlpha($pValue)
|
||||
{
|
||||
$this->alpha = $pValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get hash code.
|
||||
*
|
||||
* @return string Hash code
|
||||
*/
|
||||
public function getHashCode()
|
||||
{
|
||||
return md5(
|
||||
($this->visible ? 't' : 'f') .
|
||||
$this->blurRadius .
|
||||
$this->distance .
|
||||
$this->direction .
|
||||
$this->alignment .
|
||||
$this->color->getHashCode() .
|
||||
$this->alpha .
|
||||
__CLASS__
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement PHP __clone to create a deep clone, not just a shallow copy.
|
||||
*/
|
||||
public function __clone()
|
||||
{
|
||||
$vars = get_object_vars($this);
|
||||
foreach ($vars as $key => $value) {
|
||||
if (is_object($value)) {
|
||||
$this->$key = clone $value;
|
||||
} else {
|
||||
$this->$key = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
490
vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/HeaderFooter.php
vendored
Normal file
490
vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/HeaderFooter.php
vendored
Normal file
@@ -0,0 +1,490 @@
|
||||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Worksheet;
|
||||
|
||||
/**
|
||||
* <code>
|
||||
* Header/Footer Formatting Syntax taken from Office Open XML Part 4 - Markup Language Reference, page 1970:.
|
||||
*
|
||||
* There are a number of formatting codes that can be written inline with the actual header / footer text, which
|
||||
* affect the formatting in the header or footer.
|
||||
*
|
||||
* Example: This example shows the text "Center Bold Header" on the first line (center section), and the date on
|
||||
* the second line (center section).
|
||||
* &CCenter &"-,Bold"Bold&"-,Regular"Header_x000A_&D
|
||||
*
|
||||
* General Rules:
|
||||
* There is no required order in which these codes must appear.
|
||||
*
|
||||
* The first occurrence of the following codes turns the formatting ON, the second occurrence turns it OFF again:
|
||||
* - strikethrough
|
||||
* - superscript
|
||||
* - subscript
|
||||
* Superscript and subscript cannot both be ON at same time. Whichever comes first wins and the other is ignored,
|
||||
* while the first is ON.
|
||||
* &L - code for "left section" (there are three header / footer locations, "left", "center", and "right"). When
|
||||
* two or more occurrences of this section marker exist, the contents from all markers are concatenated, in the
|
||||
* order of appearance, and placed into the left section.
|
||||
* &P - code for "current page #"
|
||||
* &N - code for "total pages"
|
||||
* &font size - code for "text font size", where font size is a font size in points.
|
||||
* &K - code for "text font color"
|
||||
* RGB Color is specified as RRGGBB
|
||||
* Theme Color is specifed as TTSNN where TT is the theme color Id, S is either "+" or "-" of the tint/shade
|
||||
* value, NN is the tint/shade value.
|
||||
* &S - code for "text strikethrough" on / off
|
||||
* &X - code for "text super script" on / off
|
||||
* &Y - code for "text subscript" on / off
|
||||
* &C - code for "center section". When two or more occurrences of this section marker exist, the contents
|
||||
* from all markers are concatenated, in the order of appearance, and placed into the center section.
|
||||
*
|
||||
* &D - code for "date"
|
||||
* &T - code for "time"
|
||||
* &G - code for "picture as background"
|
||||
* &U - code for "text single underline"
|
||||
* &E - code for "double underline"
|
||||
* &R - code for "right section". When two or more occurrences of this section marker exist, the contents
|
||||
* from all markers are concatenated, in the order of appearance, and placed into the right section.
|
||||
* &Z - code for "this workbook's file path"
|
||||
* &F - code for "this workbook's file name"
|
||||
* &A - code for "sheet tab name"
|
||||
* &+ - code for add to page #.
|
||||
* &- - code for subtract from page #.
|
||||
* &"font name,font type" - code for "text font name" and "text font type", where font name and font type
|
||||
* are strings specifying the name and type of the font, separated by a comma. When a hyphen appears in font
|
||||
* name, it means "none specified". Both of font name and font type can be localized values.
|
||||
* &"-,Bold" - code for "bold font style"
|
||||
* &B - also means "bold font style".
|
||||
* &"-,Regular" - code for "regular font style"
|
||||
* &"-,Italic" - code for "italic font style"
|
||||
* &I - also means "italic font style"
|
||||
* &"-,Bold Italic" code for "bold italic font style"
|
||||
* &O - code for "outline style"
|
||||
* &H - code for "shadow style"
|
||||
* </code>
|
||||
*/
|
||||
class HeaderFooter
|
||||
{
|
||||
// Header/footer image location
|
||||
const IMAGE_HEADER_LEFT = 'LH';
|
||||
const IMAGE_HEADER_CENTER = 'CH';
|
||||
const IMAGE_HEADER_RIGHT = 'RH';
|
||||
const IMAGE_FOOTER_LEFT = 'LF';
|
||||
const IMAGE_FOOTER_CENTER = 'CF';
|
||||
const IMAGE_FOOTER_RIGHT = 'RF';
|
||||
|
||||
/**
|
||||
* OddHeader.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $oddHeader = '';
|
||||
|
||||
/**
|
||||
* OddFooter.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $oddFooter = '';
|
||||
|
||||
/**
|
||||
* EvenHeader.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $evenHeader = '';
|
||||
|
||||
/**
|
||||
* EvenFooter.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $evenFooter = '';
|
||||
|
||||
/**
|
||||
* FirstHeader.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $firstHeader = '';
|
||||
|
||||
/**
|
||||
* FirstFooter.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $firstFooter = '';
|
||||
|
||||
/**
|
||||
* Different header for Odd/Even, defaults to false.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $differentOddEven = false;
|
||||
|
||||
/**
|
||||
* Different header for first page, defaults to false.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $differentFirst = false;
|
||||
|
||||
/**
|
||||
* Scale with document, defaults to true.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $scaleWithDocument = true;
|
||||
|
||||
/**
|
||||
* Align with margins, defaults to true.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $alignWithMargins = true;
|
||||
|
||||
/**
|
||||
* Header/footer images.
|
||||
*
|
||||
* @var HeaderFooterDrawing[]
|
||||
*/
|
||||
private $headerFooterImages = [];
|
||||
|
||||
/**
|
||||
* Create a new HeaderFooter.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Get OddHeader.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getOddHeader()
|
||||
{
|
||||
return $this->oddHeader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set OddHeader.
|
||||
*
|
||||
* @param string $pValue
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setOddHeader($pValue)
|
||||
{
|
||||
$this->oddHeader = $pValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get OddFooter.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getOddFooter()
|
||||
{
|
||||
return $this->oddFooter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set OddFooter.
|
||||
*
|
||||
* @param string $pValue
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setOddFooter($pValue)
|
||||
{
|
||||
$this->oddFooter = $pValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get EvenHeader.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getEvenHeader()
|
||||
{
|
||||
return $this->evenHeader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set EvenHeader.
|
||||
*
|
||||
* @param string $pValue
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setEvenHeader($pValue)
|
||||
{
|
||||
$this->evenHeader = $pValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get EvenFooter.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getEvenFooter()
|
||||
{
|
||||
return $this->evenFooter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set EvenFooter.
|
||||
*
|
||||
* @param string $pValue
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setEvenFooter($pValue)
|
||||
{
|
||||
$this->evenFooter = $pValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get FirstHeader.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getFirstHeader()
|
||||
{
|
||||
return $this->firstHeader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set FirstHeader.
|
||||
*
|
||||
* @param string $pValue
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setFirstHeader($pValue)
|
||||
{
|
||||
$this->firstHeader = $pValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get FirstFooter.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getFirstFooter()
|
||||
{
|
||||
return $this->firstFooter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set FirstFooter.
|
||||
*
|
||||
* @param string $pValue
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setFirstFooter($pValue)
|
||||
{
|
||||
$this->firstFooter = $pValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get DifferentOddEven.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getDifferentOddEven()
|
||||
{
|
||||
return $this->differentOddEven;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set DifferentOddEven.
|
||||
*
|
||||
* @param bool $pValue
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setDifferentOddEven($pValue)
|
||||
{
|
||||
$this->differentOddEven = $pValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get DifferentFirst.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getDifferentFirst()
|
||||
{
|
||||
return $this->differentFirst;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set DifferentFirst.
|
||||
*
|
||||
* @param bool $pValue
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setDifferentFirst($pValue)
|
||||
{
|
||||
$this->differentFirst = $pValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get ScaleWithDocument.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getScaleWithDocument()
|
||||
{
|
||||
return $this->scaleWithDocument;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set ScaleWithDocument.
|
||||
*
|
||||
* @param bool $pValue
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setScaleWithDocument($pValue)
|
||||
{
|
||||
$this->scaleWithDocument = $pValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get AlignWithMargins.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getAlignWithMargins()
|
||||
{
|
||||
return $this->alignWithMargins;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set AlignWithMargins.
|
||||
*
|
||||
* @param bool $pValue
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setAlignWithMargins($pValue)
|
||||
{
|
||||
$this->alignWithMargins = $pValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add header/footer image.
|
||||
*
|
||||
* @param string $location
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addImage(HeaderFooterDrawing $image, $location = self::IMAGE_HEADER_LEFT)
|
||||
{
|
||||
$this->headerFooterImages[$location] = $image;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove header/footer image.
|
||||
*
|
||||
* @param string $location
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function removeImage($location = self::IMAGE_HEADER_LEFT)
|
||||
{
|
||||
if (isset($this->headerFooterImages[$location])) {
|
||||
unset($this->headerFooterImages[$location]);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set header/footer images.
|
||||
*
|
||||
* @param HeaderFooterDrawing[] $images
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setImages(array $images)
|
||||
{
|
||||
$this->headerFooterImages = $images;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get header/footer images.
|
||||
*
|
||||
* @return HeaderFooterDrawing[]
|
||||
*/
|
||||
public function getImages()
|
||||
{
|
||||
// Sort array
|
||||
$images = [];
|
||||
if (isset($this->headerFooterImages[self::IMAGE_HEADER_LEFT])) {
|
||||
$images[self::IMAGE_HEADER_LEFT] = $this->headerFooterImages[self::IMAGE_HEADER_LEFT];
|
||||
}
|
||||
if (isset($this->headerFooterImages[self::IMAGE_HEADER_CENTER])) {
|
||||
$images[self::IMAGE_HEADER_CENTER] = $this->headerFooterImages[self::IMAGE_HEADER_CENTER];
|
||||
}
|
||||
if (isset($this->headerFooterImages[self::IMAGE_HEADER_RIGHT])) {
|
||||
$images[self::IMAGE_HEADER_RIGHT] = $this->headerFooterImages[self::IMAGE_HEADER_RIGHT];
|
||||
}
|
||||
if (isset($this->headerFooterImages[self::IMAGE_FOOTER_LEFT])) {
|
||||
$images[self::IMAGE_FOOTER_LEFT] = $this->headerFooterImages[self::IMAGE_FOOTER_LEFT];
|
||||
}
|
||||
if (isset($this->headerFooterImages[self::IMAGE_FOOTER_CENTER])) {
|
||||
$images[self::IMAGE_FOOTER_CENTER] = $this->headerFooterImages[self::IMAGE_FOOTER_CENTER];
|
||||
}
|
||||
if (isset($this->headerFooterImages[self::IMAGE_FOOTER_RIGHT])) {
|
||||
$images[self::IMAGE_FOOTER_RIGHT] = $this->headerFooterImages[self::IMAGE_FOOTER_RIGHT];
|
||||
}
|
||||
$this->headerFooterImages = $images;
|
||||
|
||||
return $this->headerFooterImages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement PHP __clone to create a deep clone, not just a shallow copy.
|
||||
*/
|
||||
public function __clone()
|
||||
{
|
||||
$vars = get_object_vars($this);
|
||||
foreach ($vars as $key => $value) {
|
||||
if (is_object($value)) {
|
||||
$this->$key = clone $value;
|
||||
} else {
|
||||
$this->$key = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
24
vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/HeaderFooterDrawing.php
vendored
Normal file
24
vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/HeaderFooterDrawing.php
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Worksheet;
|
||||
|
||||
class HeaderFooterDrawing extends Drawing
|
||||
{
|
||||
/**
|
||||
* Get hash code.
|
||||
*
|
||||
* @return string Hash code
|
||||
*/
|
||||
public function getHashCode()
|
||||
{
|
||||
return md5(
|
||||
$this->getPath() .
|
||||
$this->name .
|
||||
$this->offsetX .
|
||||
$this->offsetY .
|
||||
$this->width .
|
||||
$this->height .
|
||||
__CLASS__
|
||||
);
|
||||
}
|
||||
}
|
85
vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/Iterator.php
vendored
Normal file
85
vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/Iterator.php
vendored
Normal file
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Worksheet;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
|
||||
class Iterator implements \Iterator
|
||||
{
|
||||
/**
|
||||
* Spreadsheet to iterate.
|
||||
*
|
||||
* @var Spreadsheet
|
||||
*/
|
||||
private $subject;
|
||||
|
||||
/**
|
||||
* Current iterator position.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $position = 0;
|
||||
|
||||
/**
|
||||
* Create a new worksheet iterator.
|
||||
*/
|
||||
public function __construct(Spreadsheet $subject)
|
||||
{
|
||||
// Set subject
|
||||
$this->subject = $subject;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
$this->subject = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rewind iterator.
|
||||
*/
|
||||
public function rewind(): void
|
||||
{
|
||||
$this->position = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Current Worksheet.
|
||||
*
|
||||
* @return Worksheet
|
||||
*/
|
||||
public function current()
|
||||
{
|
||||
return $this->subject->getSheet($this->position);
|
||||
}
|
||||
|
||||
/**
|
||||
* Current key.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function key()
|
||||
{
|
||||
return $this->position;
|
||||
}
|
||||
|
||||
/**
|
||||
* Next value.
|
||||
*/
|
||||
public function next(): void
|
||||
{
|
||||
++$this->position;
|
||||
}
|
||||
|
||||
/**
|
||||
* Are there more Worksheet instances available?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function valid()
|
||||
{
|
||||
return $this->position < $this->subject->getSheetCount() && $this->position >= 0;
|
||||
}
|
||||
}
|
171
vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/MemoryDrawing.php
vendored
Normal file
171
vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/MemoryDrawing.php
vendored
Normal file
@@ -0,0 +1,171 @@
|
||||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Worksheet;
|
||||
|
||||
use GdImage;
|
||||
|
||||
class MemoryDrawing extends BaseDrawing
|
||||
{
|
||||
// Rendering functions
|
||||
const RENDERING_DEFAULT = 'imagepng';
|
||||
const RENDERING_PNG = 'imagepng';
|
||||
const RENDERING_GIF = 'imagegif';
|
||||
const RENDERING_JPEG = 'imagejpeg';
|
||||
|
||||
// MIME types
|
||||
const MIMETYPE_DEFAULT = 'image/png';
|
||||
const MIMETYPE_PNG = 'image/png';
|
||||
const MIMETYPE_GIF = 'image/gif';
|
||||
const MIMETYPE_JPEG = 'image/jpeg';
|
||||
|
||||
/**
|
||||
* Image resource.
|
||||
*
|
||||
* @var GdImage|resource
|
||||
*/
|
||||
private $imageResource;
|
||||
|
||||
/**
|
||||
* Rendering function.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $renderingFunction;
|
||||
|
||||
/**
|
||||
* Mime type.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $mimeType;
|
||||
|
||||
/**
|
||||
* Unique name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $uniqueName;
|
||||
|
||||
/**
|
||||
* Create a new MemoryDrawing.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
// Initialise values
|
||||
$this->imageResource = null;
|
||||
$this->renderingFunction = self::RENDERING_DEFAULT;
|
||||
$this->mimeType = self::MIMETYPE_DEFAULT;
|
||||
$this->uniqueName = md5(mt_rand(0, 9999) . time() . mt_rand(0, 9999));
|
||||
|
||||
// Initialize parent
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get image resource.
|
||||
*
|
||||
* @return GdImage|resource
|
||||
*/
|
||||
public function getImageResource()
|
||||
{
|
||||
return $this->imageResource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set image resource.
|
||||
*
|
||||
* @param GdImage|resource $value
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setImageResource($value)
|
||||
{
|
||||
$this->imageResource = $value;
|
||||
|
||||
if ($this->imageResource !== null) {
|
||||
// Get width/height
|
||||
$this->width = imagesx($this->imageResource);
|
||||
$this->height = imagesy($this->imageResource);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get rendering function.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getRenderingFunction()
|
||||
{
|
||||
return $this->renderingFunction;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set rendering function.
|
||||
*
|
||||
* @param string $value see self::RENDERING_*
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setRenderingFunction($value)
|
||||
{
|
||||
$this->renderingFunction = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get mime type.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getMimeType()
|
||||
{
|
||||
return $this->mimeType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set mime type.
|
||||
*
|
||||
* @param string $value see self::MIMETYPE_*
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setMimeType($value)
|
||||
{
|
||||
$this->mimeType = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get indexed filename (using image index).
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getIndexedFilename()
|
||||
{
|
||||
$extension = strtolower($this->getMimeType());
|
||||
$extension = explode('/', $extension);
|
||||
$extension = $extension[1];
|
||||
|
||||
return $this->uniqueName . $this->getImageIndex() . '.' . $extension;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get hash code.
|
||||
*
|
||||
* @return string Hash code
|
||||
*/
|
||||
public function getHashCode()
|
||||
{
|
||||
return md5(
|
||||
$this->renderingFunction .
|
||||
$this->mimeType .
|
||||
$this->uniqueName .
|
||||
parent::getHashCode() .
|
||||
__CLASS__
|
||||
);
|
||||
}
|
||||
}
|
244
vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/PageMargins.php
vendored
Normal file
244
vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/PageMargins.php
vendored
Normal file
@@ -0,0 +1,244 @@
|
||||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Worksheet;
|
||||
|
||||
class PageMargins
|
||||
{
|
||||
/**
|
||||
* Left.
|
||||
*
|
||||
* @var float
|
||||
*/
|
||||
private $left = 0.7;
|
||||
|
||||
/**
|
||||
* Right.
|
||||
*
|
||||
* @var float
|
||||
*/
|
||||
private $right = 0.7;
|
||||
|
||||
/**
|
||||
* Top.
|
||||
*
|
||||
* @var float
|
||||
*/
|
||||
private $top = 0.75;
|
||||
|
||||
/**
|
||||
* Bottom.
|
||||
*
|
||||
* @var float
|
||||
*/
|
||||
private $bottom = 0.75;
|
||||
|
||||
/**
|
||||
* Header.
|
||||
*
|
||||
* @var float
|
||||
*/
|
||||
private $header = 0.3;
|
||||
|
||||
/**
|
||||
* Footer.
|
||||
*
|
||||
* @var float
|
||||
*/
|
||||
private $footer = 0.3;
|
||||
|
||||
/**
|
||||
* Create a new PageMargins.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Left.
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function getLeft()
|
||||
{
|
||||
return $this->left;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Left.
|
||||
*
|
||||
* @param float $pValue
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setLeft($pValue)
|
||||
{
|
||||
$this->left = $pValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Right.
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function getRight()
|
||||
{
|
||||
return $this->right;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Right.
|
||||
*
|
||||
* @param float $pValue
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setRight($pValue)
|
||||
{
|
||||
$this->right = $pValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Top.
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function getTop()
|
||||
{
|
||||
return $this->top;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Top.
|
||||
*
|
||||
* @param float $pValue
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setTop($pValue)
|
||||
{
|
||||
$this->top = $pValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Bottom.
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function getBottom()
|
||||
{
|
||||
return $this->bottom;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Bottom.
|
||||
*
|
||||
* @param float $pValue
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setBottom($pValue)
|
||||
{
|
||||
$this->bottom = $pValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Header.
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function getHeader()
|
||||
{
|
||||
return $this->header;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Header.
|
||||
*
|
||||
* @param float $pValue
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setHeader($pValue)
|
||||
{
|
||||
$this->header = $pValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Footer.
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function getFooter()
|
||||
{
|
||||
return $this->footer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Footer.
|
||||
*
|
||||
* @param float $pValue
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setFooter($pValue)
|
||||
{
|
||||
$this->footer = $pValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement PHP __clone to create a deep clone, not just a shallow copy.
|
||||
*/
|
||||
public function __clone()
|
||||
{
|
||||
$vars = get_object_vars($this);
|
||||
foreach ($vars as $key => $value) {
|
||||
if (is_object($value)) {
|
||||
$this->$key = clone $value;
|
||||
} else {
|
||||
$this->$key = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function fromCentimeters(float $value): float
|
||||
{
|
||||
return $value / 2.54;
|
||||
}
|
||||
|
||||
public static function toCentimeters(float $value): float
|
||||
{
|
||||
return $value * 2.54;
|
||||
}
|
||||
|
||||
public static function fromMillimeters(float $value): float
|
||||
{
|
||||
return $value / 25.4;
|
||||
}
|
||||
|
||||
public static function toMillimeters(float $value): float
|
||||
{
|
||||
return $value * 25.4;
|
||||
}
|
||||
|
||||
public static function fromPoints(float $value): float
|
||||
{
|
||||
return $value / 72;
|
||||
}
|
||||
|
||||
public static function toPoints(float $value): float
|
||||
{
|
||||
return $value * 72;
|
||||
}
|
||||
}
|
857
vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/PageSetup.php
vendored
Normal file
857
vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/PageSetup.php
vendored
Normal file
@@ -0,0 +1,857 @@
|
||||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Worksheet;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
|
||||
use PhpOffice\PhpSpreadsheet\Exception as PhpSpreadsheetException;
|
||||
|
||||
/**
|
||||
* <code>
|
||||
* Paper size taken from Office Open XML Part 4 - Markup Language Reference, page 1988:.
|
||||
*
|
||||
* 1 = Letter paper (8.5 in. by 11 in.)
|
||||
* 2 = Letter small paper (8.5 in. by 11 in.)
|
||||
* 3 = Tabloid paper (11 in. by 17 in.)
|
||||
* 4 = Ledger paper (17 in. by 11 in.)
|
||||
* 5 = Legal paper (8.5 in. by 14 in.)
|
||||
* 6 = Statement paper (5.5 in. by 8.5 in.)
|
||||
* 7 = Executive paper (7.25 in. by 10.5 in.)
|
||||
* 8 = A3 paper (297 mm by 420 mm)
|
||||
* 9 = A4 paper (210 mm by 297 mm)
|
||||
* 10 = A4 small paper (210 mm by 297 mm)
|
||||
* 11 = A5 paper (148 mm by 210 mm)
|
||||
* 12 = B4 paper (250 mm by 353 mm)
|
||||
* 13 = B5 paper (176 mm by 250 mm)
|
||||
* 14 = Folio paper (8.5 in. by 13 in.)
|
||||
* 15 = Quarto paper (215 mm by 275 mm)
|
||||
* 16 = Standard paper (10 in. by 14 in.)
|
||||
* 17 = Standard paper (11 in. by 17 in.)
|
||||
* 18 = Note paper (8.5 in. by 11 in.)
|
||||
* 19 = #9 envelope (3.875 in. by 8.875 in.)
|
||||
* 20 = #10 envelope (4.125 in. by 9.5 in.)
|
||||
* 21 = #11 envelope (4.5 in. by 10.375 in.)
|
||||
* 22 = #12 envelope (4.75 in. by 11 in.)
|
||||
* 23 = #14 envelope (5 in. by 11.5 in.)
|
||||
* 24 = C paper (17 in. by 22 in.)
|
||||
* 25 = D paper (22 in. by 34 in.)
|
||||
* 26 = E paper (34 in. by 44 in.)
|
||||
* 27 = DL envelope (110 mm by 220 mm)
|
||||
* 28 = C5 envelope (162 mm by 229 mm)
|
||||
* 29 = C3 envelope (324 mm by 458 mm)
|
||||
* 30 = C4 envelope (229 mm by 324 mm)
|
||||
* 31 = C6 envelope (114 mm by 162 mm)
|
||||
* 32 = C65 envelope (114 mm by 229 mm)
|
||||
* 33 = B4 envelope (250 mm by 353 mm)
|
||||
* 34 = B5 envelope (176 mm by 250 mm)
|
||||
* 35 = B6 envelope (176 mm by 125 mm)
|
||||
* 36 = Italy envelope (110 mm by 230 mm)
|
||||
* 37 = Monarch envelope (3.875 in. by 7.5 in.).
|
||||
* 38 = 6 3/4 envelope (3.625 in. by 6.5 in.)
|
||||
* 39 = US standard fanfold (14.875 in. by 11 in.)
|
||||
* 40 = German standard fanfold (8.5 in. by 12 in.)
|
||||
* 41 = German legal fanfold (8.5 in. by 13 in.)
|
||||
* 42 = ISO B4 (250 mm by 353 mm)
|
||||
* 43 = Japanese double postcard (200 mm by 148 mm)
|
||||
* 44 = Standard paper (9 in. by 11 in.)
|
||||
* 45 = Standard paper (10 in. by 11 in.)
|
||||
* 46 = Standard paper (15 in. by 11 in.)
|
||||
* 47 = Invite envelope (220 mm by 220 mm)
|
||||
* 50 = Letter extra paper (9.275 in. by 12 in.)
|
||||
* 51 = Legal extra paper (9.275 in. by 15 in.)
|
||||
* 52 = Tabloid extra paper (11.69 in. by 18 in.)
|
||||
* 53 = A4 extra paper (236 mm by 322 mm)
|
||||
* 54 = Letter transverse paper (8.275 in. by 11 in.)
|
||||
* 55 = A4 transverse paper (210 mm by 297 mm)
|
||||
* 56 = Letter extra transverse paper (9.275 in. by 12 in.)
|
||||
* 57 = SuperA/SuperA/A4 paper (227 mm by 356 mm)
|
||||
* 58 = SuperB/SuperB/A3 paper (305 mm by 487 mm)
|
||||
* 59 = Letter plus paper (8.5 in. by 12.69 in.)
|
||||
* 60 = A4 plus paper (210 mm by 330 mm)
|
||||
* 61 = A5 transverse paper (148 mm by 210 mm)
|
||||
* 62 = JIS B5 transverse paper (182 mm by 257 mm)
|
||||
* 63 = A3 extra paper (322 mm by 445 mm)
|
||||
* 64 = A5 extra paper (174 mm by 235 mm)
|
||||
* 65 = ISO B5 extra paper (201 mm by 276 mm)
|
||||
* 66 = A2 paper (420 mm by 594 mm)
|
||||
* 67 = A3 transverse paper (297 mm by 420 mm)
|
||||
* 68 = A3 extra transverse paper (322 mm by 445 mm)
|
||||
* </code>
|
||||
*/
|
||||
class PageSetup
|
||||
{
|
||||
// Paper size
|
||||
const PAPERSIZE_LETTER = 1;
|
||||
const PAPERSIZE_LETTER_SMALL = 2;
|
||||
const PAPERSIZE_TABLOID = 3;
|
||||
const PAPERSIZE_LEDGER = 4;
|
||||
const PAPERSIZE_LEGAL = 5;
|
||||
const PAPERSIZE_STATEMENT = 6;
|
||||
const PAPERSIZE_EXECUTIVE = 7;
|
||||
const PAPERSIZE_A3 = 8;
|
||||
const PAPERSIZE_A4 = 9;
|
||||
const PAPERSIZE_A4_SMALL = 10;
|
||||
const PAPERSIZE_A5 = 11;
|
||||
const PAPERSIZE_B4 = 12;
|
||||
const PAPERSIZE_B5 = 13;
|
||||
const PAPERSIZE_FOLIO = 14;
|
||||
const PAPERSIZE_QUARTO = 15;
|
||||
const PAPERSIZE_STANDARD_1 = 16;
|
||||
const PAPERSIZE_STANDARD_2 = 17;
|
||||
const PAPERSIZE_NOTE = 18;
|
||||
const PAPERSIZE_NO9_ENVELOPE = 19;
|
||||
const PAPERSIZE_NO10_ENVELOPE = 20;
|
||||
const PAPERSIZE_NO11_ENVELOPE = 21;
|
||||
const PAPERSIZE_NO12_ENVELOPE = 22;
|
||||
const PAPERSIZE_NO14_ENVELOPE = 23;
|
||||
const PAPERSIZE_C = 24;
|
||||
const PAPERSIZE_D = 25;
|
||||
const PAPERSIZE_E = 26;
|
||||
const PAPERSIZE_DL_ENVELOPE = 27;
|
||||
const PAPERSIZE_C5_ENVELOPE = 28;
|
||||
const PAPERSIZE_C3_ENVELOPE = 29;
|
||||
const PAPERSIZE_C4_ENVELOPE = 30;
|
||||
const PAPERSIZE_C6_ENVELOPE = 31;
|
||||
const PAPERSIZE_C65_ENVELOPE = 32;
|
||||
const PAPERSIZE_B4_ENVELOPE = 33;
|
||||
const PAPERSIZE_B5_ENVELOPE = 34;
|
||||
const PAPERSIZE_B6_ENVELOPE = 35;
|
||||
const PAPERSIZE_ITALY_ENVELOPE = 36;
|
||||
const PAPERSIZE_MONARCH_ENVELOPE = 37;
|
||||
const PAPERSIZE_6_3_4_ENVELOPE = 38;
|
||||
const PAPERSIZE_US_STANDARD_FANFOLD = 39;
|
||||
const PAPERSIZE_GERMAN_STANDARD_FANFOLD = 40;
|
||||
const PAPERSIZE_GERMAN_LEGAL_FANFOLD = 41;
|
||||
const PAPERSIZE_ISO_B4 = 42;
|
||||
const PAPERSIZE_JAPANESE_DOUBLE_POSTCARD = 43;
|
||||
const PAPERSIZE_STANDARD_PAPER_1 = 44;
|
||||
const PAPERSIZE_STANDARD_PAPER_2 = 45;
|
||||
const PAPERSIZE_STANDARD_PAPER_3 = 46;
|
||||
const PAPERSIZE_INVITE_ENVELOPE = 47;
|
||||
const PAPERSIZE_LETTER_EXTRA_PAPER = 48;
|
||||
const PAPERSIZE_LEGAL_EXTRA_PAPER = 49;
|
||||
const PAPERSIZE_TABLOID_EXTRA_PAPER = 50;
|
||||
const PAPERSIZE_A4_EXTRA_PAPER = 51;
|
||||
const PAPERSIZE_LETTER_TRANSVERSE_PAPER = 52;
|
||||
const PAPERSIZE_A4_TRANSVERSE_PAPER = 53;
|
||||
const PAPERSIZE_LETTER_EXTRA_TRANSVERSE_PAPER = 54;
|
||||
const PAPERSIZE_SUPERA_SUPERA_A4_PAPER = 55;
|
||||
const PAPERSIZE_SUPERB_SUPERB_A3_PAPER = 56;
|
||||
const PAPERSIZE_LETTER_PLUS_PAPER = 57;
|
||||
const PAPERSIZE_A4_PLUS_PAPER = 58;
|
||||
const PAPERSIZE_A5_TRANSVERSE_PAPER = 59;
|
||||
const PAPERSIZE_JIS_B5_TRANSVERSE_PAPER = 60;
|
||||
const PAPERSIZE_A3_EXTRA_PAPER = 61;
|
||||
const PAPERSIZE_A5_EXTRA_PAPER = 62;
|
||||
const PAPERSIZE_ISO_B5_EXTRA_PAPER = 63;
|
||||
const PAPERSIZE_A2_PAPER = 64;
|
||||
const PAPERSIZE_A3_TRANSVERSE_PAPER = 65;
|
||||
const PAPERSIZE_A3_EXTRA_TRANSVERSE_PAPER = 66;
|
||||
|
||||
// Page orientation
|
||||
const ORIENTATION_DEFAULT = 'default';
|
||||
const ORIENTATION_LANDSCAPE = 'landscape';
|
||||
const ORIENTATION_PORTRAIT = 'portrait';
|
||||
|
||||
// Print Range Set Method
|
||||
const SETPRINTRANGE_OVERWRITE = 'O';
|
||||
const SETPRINTRANGE_INSERT = 'I';
|
||||
|
||||
const PAGEORDER_OVER_THEN_DOWN = 'overThenDown';
|
||||
const PAGEORDER_DOWN_THEN_OVER = 'downThenOver';
|
||||
|
||||
/**
|
||||
* Paper size.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $paperSize = self::PAPERSIZE_LETTER;
|
||||
|
||||
/**
|
||||
* Orientation.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $orientation = self::ORIENTATION_DEFAULT;
|
||||
|
||||
/**
|
||||
* Scale (Print Scale).
|
||||
*
|
||||
* Print scaling. Valid values range from 10 to 400
|
||||
* This setting is overridden when fitToWidth and/or fitToHeight are in use
|
||||
*
|
||||
* @var null|int
|
||||
*/
|
||||
private $scale = 100;
|
||||
|
||||
/**
|
||||
* Fit To Page
|
||||
* Whether scale or fitToWith / fitToHeight applies.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $fitToPage = false;
|
||||
|
||||
/**
|
||||
* Fit To Height
|
||||
* Number of vertical pages to fit on.
|
||||
*
|
||||
* @var null|int
|
||||
*/
|
||||
private $fitToHeight = 1;
|
||||
|
||||
/**
|
||||
* Fit To Width
|
||||
* Number of horizontal pages to fit on.
|
||||
*
|
||||
* @var null|int
|
||||
*/
|
||||
private $fitToWidth = 1;
|
||||
|
||||
/**
|
||||
* Columns to repeat at left.
|
||||
*
|
||||
* @var array Containing start column and end column, empty array if option unset
|
||||
*/
|
||||
private $columnsToRepeatAtLeft = ['', ''];
|
||||
|
||||
/**
|
||||
* Rows to repeat at top.
|
||||
*
|
||||
* @var array Containing start row number and end row number, empty array if option unset
|
||||
*/
|
||||
private $rowsToRepeatAtTop = [0, 0];
|
||||
|
||||
/**
|
||||
* Center page horizontally.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $horizontalCentered = false;
|
||||
|
||||
/**
|
||||
* Center page vertically.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $verticalCentered = false;
|
||||
|
||||
/**
|
||||
* Print area.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $printArea;
|
||||
|
||||
/**
|
||||
* First page number.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $firstPageNumber;
|
||||
|
||||
private $pageOrder = self::PAGEORDER_DOWN_THEN_OVER;
|
||||
|
||||
/**
|
||||
* Create a new PageSetup.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Paper Size.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getPaperSize()
|
||||
{
|
||||
return $this->paperSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Paper Size.
|
||||
*
|
||||
* @param int $pValue see self::PAPERSIZE_*
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setPaperSize($pValue)
|
||||
{
|
||||
$this->paperSize = $pValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Orientation.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getOrientation()
|
||||
{
|
||||
return $this->orientation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Orientation.
|
||||
*
|
||||
* @param string $pValue see self::ORIENTATION_*
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setOrientation($pValue)
|
||||
{
|
||||
$this->orientation = $pValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Scale.
|
||||
*
|
||||
* @return null|int
|
||||
*/
|
||||
public function getScale()
|
||||
{
|
||||
return $this->scale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Scale.
|
||||
* Print scaling. Valid values range from 10 to 400
|
||||
* This setting is overridden when fitToWidth and/or fitToHeight are in use.
|
||||
*
|
||||
* @param null|int $pValue
|
||||
* @param bool $pUpdate Update fitToPage so scaling applies rather than fitToHeight / fitToWidth
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setScale($pValue, $pUpdate = true)
|
||||
{
|
||||
// Microsoft Office Excel 2007 only allows setting a scale between 10 and 400 via the user interface,
|
||||
// but it is apparently still able to handle any scale >= 0, where 0 results in 100
|
||||
if (($pValue >= 0) || $pValue === null) {
|
||||
$this->scale = $pValue;
|
||||
if ($pUpdate) {
|
||||
$this->fitToPage = false;
|
||||
}
|
||||
} else {
|
||||
throw new PhpSpreadsheetException('Scale must not be negative');
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Fit To Page.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getFitToPage()
|
||||
{
|
||||
return $this->fitToPage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Fit To Page.
|
||||
*
|
||||
* @param bool $pValue
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setFitToPage($pValue)
|
||||
{
|
||||
$this->fitToPage = $pValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Fit To Height.
|
||||
*
|
||||
* @return null|int
|
||||
*/
|
||||
public function getFitToHeight()
|
||||
{
|
||||
return $this->fitToHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Fit To Height.
|
||||
*
|
||||
* @param null|int $pValue
|
||||
* @param bool $pUpdate Update fitToPage so it applies rather than scaling
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setFitToHeight($pValue, $pUpdate = true)
|
||||
{
|
||||
$this->fitToHeight = $pValue;
|
||||
if ($pUpdate) {
|
||||
$this->fitToPage = true;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Fit To Width.
|
||||
*
|
||||
* @return null|int
|
||||
*/
|
||||
public function getFitToWidth()
|
||||
{
|
||||
return $this->fitToWidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Fit To Width.
|
||||
*
|
||||
* @param null|int $pValue
|
||||
* @param bool $pUpdate Update fitToPage so it applies rather than scaling
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setFitToWidth($pValue, $pUpdate = true)
|
||||
{
|
||||
$this->fitToWidth = $pValue;
|
||||
if ($pUpdate) {
|
||||
$this->fitToPage = true;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is Columns to repeat at left set?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isColumnsToRepeatAtLeftSet()
|
||||
{
|
||||
if (is_array($this->columnsToRepeatAtLeft)) {
|
||||
if ($this->columnsToRepeatAtLeft[0] != '' && $this->columnsToRepeatAtLeft[1] != '') {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Columns to repeat at left.
|
||||
*
|
||||
* @return array Containing start column and end column, empty array if option unset
|
||||
*/
|
||||
public function getColumnsToRepeatAtLeft()
|
||||
{
|
||||
return $this->columnsToRepeatAtLeft;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Columns to repeat at left.
|
||||
*
|
||||
* @param array $pValue Containing start column and end column, empty array if option unset
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setColumnsToRepeatAtLeft(array $pValue)
|
||||
{
|
||||
$this->columnsToRepeatAtLeft = $pValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Columns to repeat at left by start and end.
|
||||
*
|
||||
* @param string $pStart eg: 'A'
|
||||
* @param string $pEnd eg: 'B'
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setColumnsToRepeatAtLeftByStartAndEnd($pStart, $pEnd)
|
||||
{
|
||||
$this->columnsToRepeatAtLeft = [$pStart, $pEnd];
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is Rows to repeat at top set?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isRowsToRepeatAtTopSet()
|
||||
{
|
||||
if (is_array($this->rowsToRepeatAtTop)) {
|
||||
if ($this->rowsToRepeatAtTop[0] != 0 && $this->rowsToRepeatAtTop[1] != 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Rows to repeat at top.
|
||||
*
|
||||
* @return array Containing start column and end column, empty array if option unset
|
||||
*/
|
||||
public function getRowsToRepeatAtTop()
|
||||
{
|
||||
return $this->rowsToRepeatAtTop;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Rows to repeat at top.
|
||||
*
|
||||
* @param array $pValue Containing start column and end column, empty array if option unset
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setRowsToRepeatAtTop(array $pValue)
|
||||
{
|
||||
$this->rowsToRepeatAtTop = $pValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Rows to repeat at top by start and end.
|
||||
*
|
||||
* @param int $pStart eg: 1
|
||||
* @param int $pEnd eg: 1
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setRowsToRepeatAtTopByStartAndEnd($pStart, $pEnd)
|
||||
{
|
||||
$this->rowsToRepeatAtTop = [$pStart, $pEnd];
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get center page horizontally.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getHorizontalCentered()
|
||||
{
|
||||
return $this->horizontalCentered;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set center page horizontally.
|
||||
*
|
||||
* @param bool $value
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setHorizontalCentered($value)
|
||||
{
|
||||
$this->horizontalCentered = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get center page vertically.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getVerticalCentered()
|
||||
{
|
||||
return $this->verticalCentered;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set center page vertically.
|
||||
*
|
||||
* @param bool $value
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setVerticalCentered($value)
|
||||
{
|
||||
$this->verticalCentered = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get print area.
|
||||
*
|
||||
* @param int $index Identifier for a specific print area range if several ranges have been set
|
||||
* Default behaviour, or a index value of 0, will return all ranges as a comma-separated string
|
||||
* Otherwise, the specific range identified by the value of $index will be returned
|
||||
* Print areas are numbered from 1
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPrintArea($index = 0)
|
||||
{
|
||||
if ($index == 0) {
|
||||
return $this->printArea;
|
||||
}
|
||||
$printAreas = explode(',', $this->printArea);
|
||||
if (isset($printAreas[$index - 1])) {
|
||||
return $printAreas[$index - 1];
|
||||
}
|
||||
|
||||
throw new PhpSpreadsheetException('Requested Print Area does not exist');
|
||||
}
|
||||
|
||||
/**
|
||||
* Is print area set?
|
||||
*
|
||||
* @param int $index Identifier for a specific print area range if several ranges have been set
|
||||
* Default behaviour, or an index value of 0, will identify whether any print range is set
|
||||
* Otherwise, existence of the range identified by the value of $index will be returned
|
||||
* Print areas are numbered from 1
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isPrintAreaSet($index = 0)
|
||||
{
|
||||
if ($index == 0) {
|
||||
return $this->printArea !== null;
|
||||
}
|
||||
$printAreas = explode(',', $this->printArea);
|
||||
|
||||
return isset($printAreas[$index - 1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear a print area.
|
||||
*
|
||||
* @param int $index Identifier for a specific print area range if several ranges have been set
|
||||
* Default behaviour, or an index value of 0, will clear all print ranges that are set
|
||||
* Otherwise, the range identified by the value of $index will be removed from the series
|
||||
* Print areas are numbered from 1
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function clearPrintArea($index = 0)
|
||||
{
|
||||
if ($index == 0) {
|
||||
$this->printArea = null;
|
||||
} else {
|
||||
$printAreas = explode(',', $this->printArea);
|
||||
if (isset($printAreas[$index - 1])) {
|
||||
unset($printAreas[$index - 1]);
|
||||
$this->printArea = implode(',', $printAreas);
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set print area. e.g. 'A1:D10' or 'A1:D10,G5:M20'.
|
||||
*
|
||||
* @param string $value
|
||||
* @param int $index Identifier for a specific print area range allowing several ranges to be set
|
||||
* When the method is "O"verwrite, then a positive integer index will overwrite that indexed
|
||||
* entry in the print areas list; a negative index value will identify which entry to
|
||||
* overwrite working bacward through the print area to the list, with the last entry as -1.
|
||||
* Specifying an index value of 0, will overwrite <b>all</b> existing print ranges.
|
||||
* When the method is "I"nsert, then a positive index will insert after that indexed entry in
|
||||
* the print areas list, while a negative index will insert before the indexed entry.
|
||||
* Specifying an index value of 0, will always append the new print range at the end of the
|
||||
* list.
|
||||
* Print areas are numbered from 1
|
||||
* @param string $method Determines the method used when setting multiple print areas
|
||||
* Default behaviour, or the "O" method, overwrites existing print area
|
||||
* The "I" method, inserts the new print area before any specified index, or at the end of the list
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setPrintArea($value, $index = 0, $method = self::SETPRINTRANGE_OVERWRITE)
|
||||
{
|
||||
if (strpos($value, '!') !== false) {
|
||||
throw new PhpSpreadsheetException('Cell coordinate must not specify a worksheet.');
|
||||
} elseif (strpos($value, ':') === false) {
|
||||
throw new PhpSpreadsheetException('Cell coordinate must be a range of cells.');
|
||||
} elseif (strpos($value, '$') !== false) {
|
||||
throw new PhpSpreadsheetException('Cell coordinate must not be absolute.');
|
||||
}
|
||||
$value = strtoupper($value);
|
||||
if (!$this->printArea) {
|
||||
$index = 0;
|
||||
}
|
||||
|
||||
if ($method == self::SETPRINTRANGE_OVERWRITE) {
|
||||
if ($index == 0) {
|
||||
$this->printArea = $value;
|
||||
} else {
|
||||
$printAreas = explode(',', $this->printArea);
|
||||
if ($index < 0) {
|
||||
$index = count($printAreas) - abs($index) + 1;
|
||||
}
|
||||
if (($index <= 0) || ($index > count($printAreas))) {
|
||||
throw new PhpSpreadsheetException('Invalid index for setting print range.');
|
||||
}
|
||||
$printAreas[$index - 1] = $value;
|
||||
$this->printArea = implode(',', $printAreas);
|
||||
}
|
||||
} elseif ($method == self::SETPRINTRANGE_INSERT) {
|
||||
if ($index == 0) {
|
||||
$this->printArea = $this->printArea ? ($this->printArea . ',' . $value) : $value;
|
||||
} else {
|
||||
$printAreas = explode(',', $this->printArea);
|
||||
if ($index < 0) {
|
||||
$index = abs($index) - 1;
|
||||
}
|
||||
if ($index > count($printAreas)) {
|
||||
throw new PhpSpreadsheetException('Invalid index for setting print range.');
|
||||
}
|
||||
$printAreas = array_merge(array_slice($printAreas, 0, $index), [$value], array_slice($printAreas, $index));
|
||||
$this->printArea = implode(',', $printAreas);
|
||||
}
|
||||
} else {
|
||||
throw new PhpSpreadsheetException('Invalid method for setting print range.');
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new print area (e.g. 'A1:D10' or 'A1:D10,G5:M20') to the list of print areas.
|
||||
*
|
||||
* @param string $value
|
||||
* @param int $index Identifier for a specific print area range allowing several ranges to be set
|
||||
* A positive index will insert after that indexed entry in the print areas list, while a
|
||||
* negative index will insert before the indexed entry.
|
||||
* Specifying an index value of 0, will always append the new print range at the end of the
|
||||
* list.
|
||||
* Print areas are numbered from 1
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addPrintArea($value, $index = -1)
|
||||
{
|
||||
return $this->setPrintArea($value, $index, self::SETPRINTRANGE_INSERT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set print area.
|
||||
*
|
||||
* @param int $column1 Column 1
|
||||
* @param int $row1 Row 1
|
||||
* @param int $column2 Column 2
|
||||
* @param int $row2 Row 2
|
||||
* @param int $index Identifier for a specific print area range allowing several ranges to be set
|
||||
* When the method is "O"verwrite, then a positive integer index will overwrite that indexed
|
||||
* entry in the print areas list; a negative index value will identify which entry to
|
||||
* overwrite working backward through the print area to the list, with the last entry as -1.
|
||||
* Specifying an index value of 0, will overwrite <b>all</b> existing print ranges.
|
||||
* When the method is "I"nsert, then a positive index will insert after that indexed entry in
|
||||
* the print areas list, while a negative index will insert before the indexed entry.
|
||||
* Specifying an index value of 0, will always append the new print range at the end of the
|
||||
* list.
|
||||
* Print areas are numbered from 1
|
||||
* @param string $method Determines the method used when setting multiple print areas
|
||||
* Default behaviour, or the "O" method, overwrites existing print area
|
||||
* The "I" method, inserts the new print area before any specified index, or at the end of the list
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setPrintAreaByColumnAndRow($column1, $row1, $column2, $row2, $index = 0, $method = self::SETPRINTRANGE_OVERWRITE)
|
||||
{
|
||||
return $this->setPrintArea(
|
||||
Coordinate::stringFromColumnIndex($column1) . $row1 . ':' . Coordinate::stringFromColumnIndex($column2) . $row2,
|
||||
$index,
|
||||
$method
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new print area to the list of print areas.
|
||||
*
|
||||
* @param int $column1 Start Column for the print area
|
||||
* @param int $row1 Start Row for the print area
|
||||
* @param int $column2 End Column for the print area
|
||||
* @param int $row2 End Row for the print area
|
||||
* @param int $index Identifier for a specific print area range allowing several ranges to be set
|
||||
* A positive index will insert after that indexed entry in the print areas list, while a
|
||||
* negative index will insert before the indexed entry.
|
||||
* Specifying an index value of 0, will always append the new print range at the end of the
|
||||
* list.
|
||||
* Print areas are numbered from 1
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addPrintAreaByColumnAndRow($column1, $row1, $column2, $row2, $index = -1)
|
||||
{
|
||||
return $this->setPrintArea(
|
||||
Coordinate::stringFromColumnIndex($column1) . $row1 . ':' . Coordinate::stringFromColumnIndex($column2) . $row2,
|
||||
$index,
|
||||
self::SETPRINTRANGE_INSERT
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get first page number.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getFirstPageNumber()
|
||||
{
|
||||
return $this->firstPageNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set first page number.
|
||||
*
|
||||
* @param int $value
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setFirstPageNumber($value)
|
||||
{
|
||||
$this->firstPageNumber = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset first page number.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function resetFirstPageNumber()
|
||||
{
|
||||
return $this->setFirstPageNumber(null);
|
||||
}
|
||||
|
||||
public function getPageOrder(): string
|
||||
{
|
||||
return $this->pageOrder;
|
||||
}
|
||||
|
||||
public function setPageOrder(?string $pageOrder): self
|
||||
{
|
||||
if ($pageOrder === null || $pageOrder === self::PAGEORDER_DOWN_THEN_OVER || $pageOrder === self::PAGEORDER_OVER_THEN_DOWN) {
|
||||
$this->pageOrder = $pageOrder ?? self::PAGEORDER_DOWN_THEN_OVER;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement PHP __clone to create a deep clone, not just a shallow copy.
|
||||
*/
|
||||
public function __clone()
|
||||
{
|
||||
$vars = get_object_vars($this);
|
||||
foreach ($vars as $key => $value) {
|
||||
if (is_object($value)) {
|
||||
$this->$key = clone $value;
|
||||
} else {
|
||||
$this->$key = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
691
vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/Protection.php
vendored
Normal file
691
vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/Protection.php
vendored
Normal file
@@ -0,0 +1,691 @@
|
||||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Worksheet;
|
||||
|
||||
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.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $sheet = false;
|
||||
|
||||
/**
|
||||
* Objects.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $objects = false;
|
||||
|
||||
/**
|
||||
* Scenarios.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $scenarios = false;
|
||||
|
||||
/**
|
||||
* Format cells.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $formatCells = false;
|
||||
|
||||
/**
|
||||
* Format columns.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $formatColumns = false;
|
||||
|
||||
/**
|
||||
* Format rows.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $formatRows = false;
|
||||
|
||||
/**
|
||||
* Insert columns.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $insertColumns = false;
|
||||
|
||||
/**
|
||||
* Insert rows.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $insertRows = false;
|
||||
|
||||
/**
|
||||
* Insert hyperlinks.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $insertHyperlinks = false;
|
||||
|
||||
/**
|
||||
* Delete columns.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $deleteColumns = false;
|
||||
|
||||
/**
|
||||
* Delete rows.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $deleteRows = false;
|
||||
|
||||
/**
|
||||
* Select locked cells.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $selectLockedCells = false;
|
||||
|
||||
/**
|
||||
* Sort.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $sort = false;
|
||||
|
||||
/**
|
||||
* AutoFilter.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $autoFilter = false;
|
||||
|
||||
/**
|
||||
* Pivot tables.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $pivotTables = false;
|
||||
|
||||
/**
|
||||
* Select unlocked cells.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $selectUnlockedCells = false;
|
||||
|
||||
/**
|
||||
* Hashed password.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $password = '';
|
||||
|
||||
/**
|
||||
* Algorithm name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $algorithm = '';
|
||||
|
||||
/**
|
||||
* Salt value.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $salt = '';
|
||||
|
||||
/**
|
||||
* Spin count.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $spinCount = 10000;
|
||||
|
||||
/**
|
||||
* Create a new Protection.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Is some sort of protection enabled?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isProtectionEnabled()
|
||||
{
|
||||
return $this->sheet ||
|
||||
$this->objects ||
|
||||
$this->scenarios ||
|
||||
$this->formatCells ||
|
||||
$this->formatColumns ||
|
||||
$this->formatRows ||
|
||||
$this->insertColumns ||
|
||||
$this->insertRows ||
|
||||
$this->insertHyperlinks ||
|
||||
$this->deleteColumns ||
|
||||
$this->deleteRows ||
|
||||
$this->selectLockedCells ||
|
||||
$this->sort ||
|
||||
$this->autoFilter ||
|
||||
$this->pivotTables ||
|
||||
$this->selectUnlockedCells;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Sheet.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getSheet()
|
||||
{
|
||||
return $this->sheet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Sheet.
|
||||
*
|
||||
* @param bool $pValue
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setSheet($pValue)
|
||||
{
|
||||
$this->sheet = $pValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Objects.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getObjects()
|
||||
{
|
||||
return $this->objects;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Objects.
|
||||
*
|
||||
* @param bool $pValue
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setObjects($pValue)
|
||||
{
|
||||
$this->objects = $pValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Scenarios.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getScenarios()
|
||||
{
|
||||
return $this->scenarios;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Scenarios.
|
||||
*
|
||||
* @param bool $pValue
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setScenarios($pValue)
|
||||
{
|
||||
$this->scenarios = $pValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get FormatCells.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getFormatCells()
|
||||
{
|
||||
return $this->formatCells;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set FormatCells.
|
||||
*
|
||||
* @param bool $pValue
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setFormatCells($pValue)
|
||||
{
|
||||
$this->formatCells = $pValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get FormatColumns.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getFormatColumns()
|
||||
{
|
||||
return $this->formatColumns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set FormatColumns.
|
||||
*
|
||||
* @param bool $pValue
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setFormatColumns($pValue)
|
||||
{
|
||||
$this->formatColumns = $pValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get FormatRows.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getFormatRows()
|
||||
{
|
||||
return $this->formatRows;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set FormatRows.
|
||||
*
|
||||
* @param bool $pValue
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setFormatRows($pValue)
|
||||
{
|
||||
$this->formatRows = $pValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get InsertColumns.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getInsertColumns()
|
||||
{
|
||||
return $this->insertColumns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set InsertColumns.
|
||||
*
|
||||
* @param bool $pValue
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setInsertColumns($pValue)
|
||||
{
|
||||
$this->insertColumns = $pValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get InsertRows.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getInsertRows()
|
||||
{
|
||||
return $this->insertRows;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set InsertRows.
|
||||
*
|
||||
* @param bool $pValue
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setInsertRows($pValue)
|
||||
{
|
||||
$this->insertRows = $pValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get InsertHyperlinks.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getInsertHyperlinks()
|
||||
{
|
||||
return $this->insertHyperlinks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set InsertHyperlinks.
|
||||
*
|
||||
* @param bool $pValue
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setInsertHyperlinks($pValue)
|
||||
{
|
||||
$this->insertHyperlinks = $pValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get DeleteColumns.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getDeleteColumns()
|
||||
{
|
||||
return $this->deleteColumns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set DeleteColumns.
|
||||
*
|
||||
* @param bool $pValue
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setDeleteColumns($pValue)
|
||||
{
|
||||
$this->deleteColumns = $pValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get DeleteRows.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getDeleteRows()
|
||||
{
|
||||
return $this->deleteRows;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set DeleteRows.
|
||||
*
|
||||
* @param bool $pValue
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setDeleteRows($pValue)
|
||||
{
|
||||
$this->deleteRows = $pValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get SelectLockedCells.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getSelectLockedCells()
|
||||
{
|
||||
return $this->selectLockedCells;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set SelectLockedCells.
|
||||
*
|
||||
* @param bool $pValue
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setSelectLockedCells($pValue)
|
||||
{
|
||||
$this->selectLockedCells = $pValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Sort.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getSort()
|
||||
{
|
||||
return $this->sort;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Sort.
|
||||
*
|
||||
* @param bool $pValue
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setSort($pValue)
|
||||
{
|
||||
$this->sort = $pValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get AutoFilter.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getAutoFilter()
|
||||
{
|
||||
return $this->autoFilter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set AutoFilter.
|
||||
*
|
||||
* @param bool $pValue
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setAutoFilter($pValue)
|
||||
{
|
||||
$this->autoFilter = $pValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get PivotTables.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getPivotTables()
|
||||
{
|
||||
return $this->pivotTables;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set PivotTables.
|
||||
*
|
||||
* @param bool $pValue
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setPivotTables($pValue)
|
||||
{
|
||||
$this->pivotTables = $pValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get SelectUnlockedCells.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getSelectUnlockedCells()
|
||||
{
|
||||
return $this->selectUnlockedCells;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set SelectUnlockedCells.
|
||||
*
|
||||
* @param bool $pValue
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setSelectUnlockedCells($pValue)
|
||||
{
|
||||
$this->selectUnlockedCells = $pValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get hashed password.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPassword()
|
||||
{
|
||||
return $this->password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Password.
|
||||
*
|
||||
* @param string $pValue
|
||||
* @param bool $pAlreadyHashed If the password has already been hashed, set this to true
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setPassword($pValue, $pAlreadyHashed = false)
|
||||
{
|
||||
if (!$pAlreadyHashed) {
|
||||
$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.
|
||||
*/
|
||||
public function __clone()
|
||||
{
|
||||
$vars = get_object_vars($this);
|
||||
foreach ($vars as $key => $value) {
|
||||
if (is_object($value)) {
|
||||
$this->$key = clone $value;
|
||||
} else {
|
||||
$this->$key = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
74
vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/Row.php
vendored
Normal file
74
vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/Row.php
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Worksheet;
|
||||
|
||||
class Row
|
||||
{
|
||||
/**
|
||||
* \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet.
|
||||
*
|
||||
* @var Worksheet
|
||||
*/
|
||||
private $worksheet;
|
||||
|
||||
/**
|
||||
* Row index.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $rowIndex = 0;
|
||||
|
||||
/**
|
||||
* Create a new row.
|
||||
*
|
||||
* @param Worksheet $worksheet
|
||||
* @param int $rowIndex
|
||||
*/
|
||||
public function __construct(?Worksheet $worksheet = null, $rowIndex = 1)
|
||||
{
|
||||
// Set parent and row index
|
||||
$this->worksheet = $worksheet;
|
||||
$this->rowIndex = $rowIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
$this->worksheet = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get row index.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getRowIndex()
|
||||
{
|
||||
return $this->rowIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cell iterator.
|
||||
*
|
||||
* @param string $startColumn The column address at which to start iterating
|
||||
* @param string $endColumn Optionally, the column address at which to stop iterating
|
||||
*
|
||||
* @return RowCellIterator
|
||||
*/
|
||||
public function getCellIterator($startColumn = 'A', $endColumn = null)
|
||||
{
|
||||
return new RowCellIterator($this->worksheet, $this->rowIndex, $startColumn, $endColumn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns bound worksheet.
|
||||
*
|
||||
* @return Worksheet
|
||||
*/
|
||||
public function getWorksheet()
|
||||
{
|
||||
return $this->worksheet;
|
||||
}
|
||||
}
|
191
vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/RowCellIterator.php
vendored
Normal file
191
vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/RowCellIterator.php
vendored
Normal file
@@ -0,0 +1,191 @@
|
||||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Worksheet;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
|
||||
use PhpOffice\PhpSpreadsheet\Exception as PhpSpreadsheetException;
|
||||
|
||||
class RowCellIterator extends CellIterator
|
||||
{
|
||||
/**
|
||||
* Current iterator position.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $currentColumnIndex;
|
||||
|
||||
/**
|
||||
* Row index.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $rowIndex = 1;
|
||||
|
||||
/**
|
||||
* Start position.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $startColumnIndex = 1;
|
||||
|
||||
/**
|
||||
* End position.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $endColumnIndex = 1;
|
||||
|
||||
/**
|
||||
* Create a new column iterator.
|
||||
*
|
||||
* @param Worksheet $worksheet The worksheet to iterate over
|
||||
* @param int $rowIndex The row that we want to iterate
|
||||
* @param string $startColumn The column address at which to start iterating
|
||||
* @param string $endColumn Optionally, the column address at which to stop iterating
|
||||
*/
|
||||
public function __construct(?Worksheet $worksheet = null, $rowIndex = 1, $startColumn = 'A', $endColumn = null)
|
||||
{
|
||||
// Set subject and row index
|
||||
$this->worksheet = $worksheet;
|
||||
$this->rowIndex = $rowIndex;
|
||||
$this->resetEnd($endColumn);
|
||||
$this->resetStart($startColumn);
|
||||
}
|
||||
|
||||
/**
|
||||
* (Re)Set the start column and the current column pointer.
|
||||
*
|
||||
* @param string $startColumn The column address at which to start iterating
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function resetStart($startColumn = 'A')
|
||||
{
|
||||
$this->startColumnIndex = Coordinate::columnIndexFromString($startColumn);
|
||||
$this->adjustForExistingOnlyRange();
|
||||
$this->seek(Coordinate::stringFromColumnIndex($this->startColumnIndex));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* (Re)Set the end column.
|
||||
*
|
||||
* @param string $endColumn The column address at which to stop iterating
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function resetEnd($endColumn = null)
|
||||
{
|
||||
$endColumn = $endColumn ? $endColumn : $this->worksheet->getHighestColumn();
|
||||
$this->endColumnIndex = Coordinate::columnIndexFromString($endColumn);
|
||||
$this->adjustForExistingOnlyRange();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the column pointer to the selected column.
|
||||
*
|
||||
* @param string $column The column address to set the current pointer at
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function seek($column = 'A')
|
||||
{
|
||||
$columnx = $column;
|
||||
$column = Coordinate::columnIndexFromString($column);
|
||||
if ($this->onlyExistingCells && !($this->worksheet->cellExistsByColumnAndRow($column, $this->rowIndex))) {
|
||||
throw new PhpSpreadsheetException('In "IterateOnlyExistingCells" mode and Cell does not exist');
|
||||
}
|
||||
if (($column < $this->startColumnIndex) || ($column > $this->endColumnIndex)) {
|
||||
throw new PhpSpreadsheetException("Column $columnx is out of range ({$this->startColumnIndex} - {$this->endColumnIndex})");
|
||||
}
|
||||
$this->currentColumnIndex = $column;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rewind the iterator to the starting column.
|
||||
*/
|
||||
public function rewind(): void
|
||||
{
|
||||
$this->currentColumnIndex = $this->startColumnIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current cell in this worksheet row.
|
||||
*
|
||||
* @return \PhpOffice\PhpSpreadsheet\Cell\Cell
|
||||
*/
|
||||
public function current()
|
||||
{
|
||||
return $this->worksheet->getCellByColumnAndRow($this->currentColumnIndex, $this->rowIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current iterator key.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function key()
|
||||
{
|
||||
return Coordinate::stringFromColumnIndex($this->currentColumnIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the iterator to its next value.
|
||||
*/
|
||||
public function next(): void
|
||||
{
|
||||
do {
|
||||
++$this->currentColumnIndex;
|
||||
} while (($this->onlyExistingCells) && (!$this->worksheet->cellExistsByColumnAndRow($this->currentColumnIndex, $this->rowIndex)) && ($this->currentColumnIndex <= $this->endColumnIndex));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the iterator to its previous value.
|
||||
*/
|
||||
public function prev(): void
|
||||
{
|
||||
do {
|
||||
--$this->currentColumnIndex;
|
||||
} while (($this->onlyExistingCells) && (!$this->worksheet->cellExistsByColumnAndRow($this->currentColumnIndex, $this->rowIndex)) && ($this->currentColumnIndex >= $this->startColumnIndex));
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate if more columns exist in the worksheet range of columns that we're iterating.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function valid()
|
||||
{
|
||||
return $this->currentColumnIndex <= $this->endColumnIndex && $this->currentColumnIndex >= $this->startColumnIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current iterator position.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getCurrentColumnIndex()
|
||||
{
|
||||
return $this->currentColumnIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate start/end values for "IterateOnlyExistingCells" mode, and adjust if necessary.
|
||||
*/
|
||||
protected function adjustForExistingOnlyRange(): void
|
||||
{
|
||||
if ($this->onlyExistingCells) {
|
||||
while ((!$this->worksheet->cellExistsByColumnAndRow($this->startColumnIndex, $this->rowIndex)) && ($this->startColumnIndex <= $this->endColumnIndex)) {
|
||||
++$this->startColumnIndex;
|
||||
}
|
||||
while ((!$this->worksheet->cellExistsByColumnAndRow($this->endColumnIndex, $this->rowIndex)) && ($this->endColumnIndex >= $this->startColumnIndex)) {
|
||||
--$this->endColumnIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
115
vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/RowDimension.php
vendored
Normal file
115
vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/RowDimension.php
vendored
Normal file
@@ -0,0 +1,115 @@
|
||||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Worksheet;
|
||||
|
||||
class RowDimension extends Dimension
|
||||
{
|
||||
/**
|
||||
* Row index.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $rowIndex;
|
||||
|
||||
/**
|
||||
* Row height (in pt).
|
||||
*
|
||||
* When this is set to a negative value, the row height should be ignored by IWriter
|
||||
*
|
||||
* @var float
|
||||
*/
|
||||
private $height = -1;
|
||||
|
||||
/**
|
||||
* ZeroHeight for Row?
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $zeroHeight = false;
|
||||
|
||||
/**
|
||||
* Create a new RowDimension.
|
||||
*
|
||||
* @param int $pIndex Numeric row index
|
||||
*/
|
||||
public function __construct($pIndex = 0)
|
||||
{
|
||||
// Initialise values
|
||||
$this->rowIndex = $pIndex;
|
||||
|
||||
// set dimension as unformatted by default
|
||||
parent::__construct(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Row Index.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getRowIndex()
|
||||
{
|
||||
return $this->rowIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Row Index.
|
||||
*
|
||||
* @param int $pValue
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setRowIndex($pValue)
|
||||
{
|
||||
$this->rowIndex = $pValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Row Height.
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function getRowHeight()
|
||||
{
|
||||
return $this->height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Row Height.
|
||||
*
|
||||
* @param float $pValue
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setRowHeight($pValue)
|
||||
{
|
||||
$this->height = $pValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get ZeroHeight.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getZeroHeight()
|
||||
{
|
||||
return $this->zeroHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set ZeroHeight.
|
||||
*
|
||||
* @param bool $pValue
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setZeroHeight($pValue)
|
||||
{
|
||||
$this->zeroHeight = $pValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
167
vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/RowIterator.php
vendored
Normal file
167
vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/RowIterator.php
vendored
Normal file
@@ -0,0 +1,167 @@
|
||||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Worksheet;
|
||||
|
||||
use Iterator;
|
||||
use PhpOffice\PhpSpreadsheet\Exception as PhpSpreadsheetException;
|
||||
|
||||
class RowIterator implements Iterator
|
||||
{
|
||||
/**
|
||||
* Worksheet to iterate.
|
||||
*
|
||||
* @var Worksheet
|
||||
*/
|
||||
private $subject;
|
||||
|
||||
/**
|
||||
* Current iterator position.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $position = 1;
|
||||
|
||||
/**
|
||||
* Start position.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $startRow = 1;
|
||||
|
||||
/**
|
||||
* End position.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $endRow = 1;
|
||||
|
||||
/**
|
||||
* Create a new row iterator.
|
||||
*
|
||||
* @param Worksheet $subject The worksheet to iterate over
|
||||
* @param int $startRow The row number at which to start iterating
|
||||
* @param int $endRow Optionally, the row number at which to stop iterating
|
||||
*/
|
||||
public function __construct(Worksheet $subject, $startRow = 1, $endRow = null)
|
||||
{
|
||||
// Set subject
|
||||
$this->subject = $subject;
|
||||
$this->resetEnd($endRow);
|
||||
$this->resetStart($startRow);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
$this->subject = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* (Re)Set the start row and the current row pointer.
|
||||
*
|
||||
* @param int $startRow The row number at which to start iterating
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function resetStart($startRow = 1)
|
||||
{
|
||||
if ($startRow > $this->subject->getHighestRow()) {
|
||||
throw new PhpSpreadsheetException("Start row ({$startRow}) is beyond highest row ({$this->subject->getHighestRow()})");
|
||||
}
|
||||
|
||||
$this->startRow = $startRow;
|
||||
if ($this->endRow < $this->startRow) {
|
||||
$this->endRow = $this->startRow;
|
||||
}
|
||||
$this->seek($startRow);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* (Re)Set the end row.
|
||||
*
|
||||
* @param int $endRow The row number at which to stop iterating
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function resetEnd($endRow = null)
|
||||
{
|
||||
$this->endRow = ($endRow) ? $endRow : $this->subject->getHighestRow();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the row pointer to the selected row.
|
||||
*
|
||||
* @param int $row The row number to set the current pointer at
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function seek($row = 1)
|
||||
{
|
||||
if (($row < $this->startRow) || ($row > $this->endRow)) {
|
||||
throw new PhpSpreadsheetException("Row $row is out of range ({$this->startRow} - {$this->endRow})");
|
||||
}
|
||||
$this->position = $row;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rewind the iterator to the starting row.
|
||||
*/
|
||||
public function rewind(): void
|
||||
{
|
||||
$this->position = $this->startRow;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current row in this worksheet.
|
||||
*
|
||||
* @return Row
|
||||
*/
|
||||
public function current()
|
||||
{
|
||||
return new Row($this->subject, $this->position);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current iterator key.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function key()
|
||||
{
|
||||
return $this->position;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the iterator to its next value.
|
||||
*/
|
||||
public function next(): void
|
||||
{
|
||||
++$this->position;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the iterator to its previous value.
|
||||
*/
|
||||
public function prev(): void
|
||||
{
|
||||
--$this->position;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate if more rows exist in the worksheet range of rows that we're iterating.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function valid()
|
||||
{
|
||||
return $this->position <= $this->endRow && $this->position >= $this->startRow;
|
||||
}
|
||||
}
|
193
vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/SheetView.php
vendored
Normal file
193
vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/SheetView.php
vendored
Normal file
@@ -0,0 +1,193 @@
|
||||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Worksheet;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Exception as PhpSpreadsheetException;
|
||||
|
||||
class SheetView
|
||||
{
|
||||
// Sheet View types
|
||||
const SHEETVIEW_NORMAL = 'normal';
|
||||
const SHEETVIEW_PAGE_LAYOUT = 'pageLayout';
|
||||
const SHEETVIEW_PAGE_BREAK_PREVIEW = 'pageBreakPreview';
|
||||
|
||||
private static $sheetViewTypes = [
|
||||
self::SHEETVIEW_NORMAL,
|
||||
self::SHEETVIEW_PAGE_LAYOUT,
|
||||
self::SHEETVIEW_PAGE_BREAK_PREVIEW,
|
||||
];
|
||||
|
||||
/**
|
||||
* ZoomScale.
|
||||
*
|
||||
* Valid values range from 10 to 400.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $zoomScale = 100;
|
||||
|
||||
/**
|
||||
* ZoomScaleNormal.
|
||||
*
|
||||
* Valid values range from 10 to 400.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $zoomScaleNormal = 100;
|
||||
|
||||
/**
|
||||
* ShowZeros.
|
||||
*
|
||||
* If true, "null" values from a calculation will be shown as "0". This is the default Excel behaviour and can be changed
|
||||
* with the advanced worksheet option "Show a zero in cells that have zero value"
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $showZeros = true;
|
||||
|
||||
/**
|
||||
* View.
|
||||
*
|
||||
* Valid values range from 10 to 400.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $sheetviewType = self::SHEETVIEW_NORMAL;
|
||||
|
||||
/**
|
||||
* Create a new SheetView.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Get ZoomScale.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getZoomScale()
|
||||
{
|
||||
return $this->zoomScale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set ZoomScale.
|
||||
* Valid values range from 10 to 400.
|
||||
*
|
||||
* @param int $pValue
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setZoomScale($pValue)
|
||||
{
|
||||
// Microsoft Office Excel 2007 only allows setting a scale between 10 and 400 via the user interface,
|
||||
// but it is apparently still able to handle any scale >= 1
|
||||
if (($pValue >= 1) || $pValue === null) {
|
||||
$this->zoomScale = $pValue;
|
||||
} else {
|
||||
throw new PhpSpreadsheetException('Scale must be greater than or equal to 1.');
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get ZoomScaleNormal.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getZoomScaleNormal()
|
||||
{
|
||||
return $this->zoomScaleNormal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set ZoomScale.
|
||||
* Valid values range from 10 to 400.
|
||||
*
|
||||
* @param int $pValue
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setZoomScaleNormal($pValue)
|
||||
{
|
||||
if (($pValue >= 1) || $pValue === null) {
|
||||
$this->zoomScaleNormal = $pValue;
|
||||
} else {
|
||||
throw new PhpSpreadsheetException('Scale must be greater than or equal to 1.');
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set ShowZeroes setting.
|
||||
*
|
||||
* @param bool $pValue
|
||||
*/
|
||||
public function setShowZeros($pValue): void
|
||||
{
|
||||
$this->showZeros = $pValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function getShowZeros()
|
||||
{
|
||||
return $this->showZeros;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get View.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getView()
|
||||
{
|
||||
return $this->sheetviewType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set View.
|
||||
*
|
||||
* Valid values are
|
||||
* 'normal' self::SHEETVIEW_NORMAL
|
||||
* 'pageLayout' self::SHEETVIEW_PAGE_LAYOUT
|
||||
* 'pageBreakPreview' self::SHEETVIEW_PAGE_BREAK_PREVIEW
|
||||
*
|
||||
* @param string $pValue
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setView($pValue)
|
||||
{
|
||||
// MS Excel 2007 allows setting the view to 'normal', 'pageLayout' or 'pageBreakPreview' via the user interface
|
||||
if ($pValue === null) {
|
||||
$pValue = self::SHEETVIEW_NORMAL;
|
||||
}
|
||||
if (in_array($pValue, self::$sheetViewTypes)) {
|
||||
$this->sheetviewType = $pValue;
|
||||
} else {
|
||||
throw new PhpSpreadsheetException('Invalid sheetview layout type.');
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement PHP __clone to create a deep clone, not just a shallow copy.
|
||||
*/
|
||||
public function __clone()
|
||||
{
|
||||
$vars = get_object_vars($this);
|
||||
foreach ($vars as $key => $value) {
|
||||
if (is_object($value)) {
|
||||
$this->$key = clone $value;
|
||||
} else {
|
||||
$this->$key = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
3019
vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/Worksheet.php
vendored
Normal file
3019
vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/Worksheet.php
vendored
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user