Файловый менеджер - Редактировать - /home/easybachat/hisabat365.com/4a7891/phpoffice.tar
Ðазад
phpspreadsheet/phpstan.neon.dist 0000644 00000002536 15060132323 0013064 0 ustar 00 includes: - phpstan-baseline.neon - phpstan-conditional.php - vendor/phpstan/phpstan-phpunit/extension.neon - vendor/phpstan/phpstan-phpunit/rules.neon parameters: level: 8 paths: - src/ - tests/ excludePaths: - src/PhpSpreadsheet/Chart/Renderer/JpGraph.php - src/PhpSpreadsheet/Chart/Renderer/JpGraphRendererBase.php - src/PhpSpreadsheet/Collection/Memory/SimpleCache1.php - src/PhpSpreadsheet/Collection/Memory/SimpleCache3.php - src/PhpSpreadsheet/Writer/ZipStream2.php - src/PhpSpreadsheet/Writer/ZipStream3.php parallel: processTimeout: 300.0 checkMissingIterableValueType: false ignoreErrors: - '~^Parameter \#1 \$im(age)? of function (imagedestroy|imageistruecolor|imagealphablending|imagesavealpha|imagecolortransparent|imagecolorsforindex|imagesavealpha|imagesx|imagesy|imagepng) expects (GdImage|resource), GdImage\|resource given\.$~' - '~^Parameter \#2 \$src_im(age)? of function imagecopy expects (GdImage|resource), GdImage\|resource given\.$~' # Accept a bit anything for assert methods - '~^Parameter \#2 .* of static method PHPUnit\\Framework\\Assert\:\:assert\w+\(\) expects .*, .* given\.$~' - '~^Method PhpOffice\\PhpSpreadsheetTests\\.*\:\:test.*\(\) has parameter \$args with no type specified\.$~' phpspreadsheet/src/PhpSpreadsheet/IOFactory.php 0000644 00000021474 15060132323 0015644 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet; use PhpOffice\PhpSpreadsheet\Reader\IReader; use PhpOffice\PhpSpreadsheet\Shared\File; use PhpOffice\PhpSpreadsheet\Writer\IWriter; /** * Factory to create readers and writers easily. * * It is not required to use this class, but it should make it easier to read and write files. * Especially for reading files with an unknown format. */ abstract class IOFactory { public const READER_XLSX = 'Xlsx'; public const READER_XLS = 'Xls'; public const READER_XML = 'Xml'; public const READER_ODS = 'Ods'; public const READER_SYLK = 'Slk'; public const READER_SLK = 'Slk'; public const READER_GNUMERIC = 'Gnumeric'; public const READER_HTML = 'Html'; public const READER_CSV = 'Csv'; public const WRITER_XLSX = 'Xlsx'; public const WRITER_XLS = 'Xls'; public const WRITER_ODS = 'Ods'; public const WRITER_CSV = 'Csv'; public const WRITER_HTML = 'Html'; /** @var string[] */ private static $readers = [ self::READER_XLSX => Reader\Xlsx::class, self::READER_XLS => Reader\Xls::class, self::READER_XML => Reader\Xml::class, self::READER_ODS => Reader\Ods::class, self::READER_SLK => Reader\Slk::class, self::READER_GNUMERIC => Reader\Gnumeric::class, self::READER_HTML => Reader\Html::class, self::READER_CSV => Reader\Csv::class, ]; /** @var string[] */ private static $writers = [ self::WRITER_XLS => Writer\Xls::class, self::WRITER_XLSX => Writer\Xlsx::class, self::WRITER_ODS => Writer\Ods::class, self::WRITER_CSV => Writer\Csv::class, self::WRITER_HTML => Writer\Html::class, 'Tcpdf' => Writer\Pdf\Tcpdf::class, 'Dompdf' => Writer\Pdf\Dompdf::class, 'Mpdf' => Writer\Pdf\Mpdf::class, ]; /** * Create Writer\IWriter. */ public static function createWriter(Spreadsheet $spreadsheet, string $writerType): IWriter { if (!isset(self::$writers[$writerType])) { throw new Writer\Exception("No writer found for type $writerType"); } // Instantiate writer /** @var IWriter */ $className = self::$writers[$writerType]; return new $className($spreadsheet); } /** * Create IReader. */ public static function createReader(string $readerType): IReader { if (!isset(self::$readers[$readerType])) { throw new Reader\Exception("No reader found for type $readerType"); } // Instantiate reader /** @var IReader */ $className = self::$readers[$readerType]; return new $className(); } /** * Loads Spreadsheet from file using automatic Reader\IReader resolution. * * @param string $filename The name of the spreadsheet file * @param int $flags the optional second parameter flags may be used to identify specific elements * that should be loaded, but which won't be loaded by default, using these values: * IReader::LOAD_WITH_CHARTS - Include any charts that are defined in the loaded file. * IReader::READ_DATA_ONLY - Read cell values only, not formatting or merge structure. * IReader::IGNORE_EMPTY_CELLS - Don't load empty cells into the model. * @param string[] $readers An array of Readers to use to identify the file type. By default, load() will try * all possible Readers until it finds a match; but this allows you to pass in a * list of Readers so it will only try the subset that you specify here. * Values in this list can be any of the constant values defined in the set * IOFactory::READER_*. */ public static function load(string $filename, int $flags = 0, ?array $readers = null): Spreadsheet { $reader = self::createReaderForFile($filename, $readers); return $reader->load($filename, $flags); } /** * Identify file type using automatic IReader resolution. */ public static function identify(string $filename, ?array $readers = null): string { $reader = self::createReaderForFile($filename, $readers); $className = get_class($reader); $classType = explode('\\', $className); unset($reader); return array_pop($classType); } /** * Create Reader\IReader for file using automatic IReader resolution. * * @param string[] $readers An array of Readers to use to identify the file type. By default, load() will try * all possible Readers until it finds a match; but this allows you to pass in a * list of Readers so it will only try the subset that you specify here. * Values in this list can be any of the constant values defined in the set * IOFactory::READER_*. */ public static function createReaderForFile(string $filename, ?array $readers = null): IReader { File::assertFile($filename); $testReaders = self::$readers; if ($readers !== null) { $readers = array_map('strtoupper', $readers); $testReaders = array_filter( self::$readers, function (string $readerType) use ($readers) { return in_array(strtoupper($readerType), $readers, true); }, ARRAY_FILTER_USE_KEY ); } // First, lucky guess by inspecting file extension $guessedReader = self::getReaderTypeFromExtension($filename); if (($guessedReader !== null) && array_key_exists($guessedReader, $testReaders)) { $reader = self::createReader($guessedReader); // Let's see if we are lucky if ($reader->canRead($filename)) { return $reader; } } // If we reach here then "lucky guess" didn't give any result // Try walking through all the options in self::$readers (or the selected subset) foreach ($testReaders as $readerType => $class) { // Ignore our original guess, we know that won't work if ($readerType !== $guessedReader) { $reader = self::createReader($readerType); if ($reader->canRead($filename)) { return $reader; } } } throw new Reader\Exception('Unable to identify a reader for this file'); } /** * Guess a reader type from the file extension, if any. */ private static function getReaderTypeFromExtension(string $filename): ?string { $pathinfo = pathinfo($filename); if (!isset($pathinfo['extension'])) { return null; } switch (strtolower($pathinfo['extension'])) { case 'xlsx': // Excel (OfficeOpenXML) Spreadsheet case 'xlsm': // Excel (OfficeOpenXML) Macro Spreadsheet (macros will be discarded) case 'xltx': // Excel (OfficeOpenXML) Template case 'xltm': // Excel (OfficeOpenXML) Macro Template (macros will be discarded) return 'Xlsx'; case 'xls': // Excel (BIFF) Spreadsheet case 'xlt': // Excel (BIFF) Template return 'Xls'; case 'ods': // Open/Libre Offic Calc case 'ots': // Open/Libre Offic Calc Template return 'Ods'; case 'slk': return 'Slk'; case 'xml': // Excel 2003 SpreadSheetML return 'Xml'; case 'gnumeric': return 'Gnumeric'; case 'htm': case 'html': return 'Html'; case 'csv': // Do nothing // We must not try to use CSV reader since it loads // all files including Excel files etc. return null; default: return null; } } /** * Register a writer with its type and class name. */ public static function registerWriter(string $writerType, string $writerClass): void { if (!is_a($writerClass, IWriter::class, true)) { throw new Writer\Exception('Registered writers must implement ' . IWriter::class); } self::$writers[$writerType] = $writerClass; } /** * Register a reader with its type and class name. */ public static function registerReader(string $readerType, string $readerClass): void { if (!is_a($readerClass, IReader::class, true)) { throw new Reader\Exception('Registered readers must implement ' . IReader::class); } self::$readers[$readerType] = $readerClass; } } phpspreadsheet/src/PhpSpreadsheet/Cell/DataValidator.php 0000644 00000011002 15060132323 0017365 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Cell; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; use PhpOffice\PhpSpreadsheet\Exception; /** * Validate a cell value according to its validation rules. */ class DataValidator { /** * Does this cell contain valid value? * * @param Cell $cell Cell to check the value * * @return bool */ public function isValid(Cell $cell) { if (!$cell->hasDataValidation() || $cell->getDataValidation()->getType() === DataValidation::TYPE_NONE) { return true; } $cellValue = $cell->getValue(); $dataValidation = $cell->getDataValidation(); if (!$dataValidation->getAllowBlank() && ($cellValue === null || $cellValue === '')) { return false; } $returnValue = false; $type = $dataValidation->getType(); if ($type === DataValidation::TYPE_LIST) { $returnValue = $this->isValueInList($cell); } elseif ($type === DataValidation::TYPE_WHOLE) { if (!is_numeric($cellValue) || fmod((float) $cellValue, 1) != 0) { $returnValue = false; } else { $returnValue = $this->numericOperator($dataValidation, (int) $cellValue); } } elseif ($type === DataValidation::TYPE_DECIMAL || $type === DataValidation::TYPE_DATE || $type === DataValidation::TYPE_TIME) { if (!is_numeric($cellValue)) { $returnValue = false; } else { $returnValue = $this->numericOperator($dataValidation, (float) $cellValue); } } elseif ($type === DataValidation::TYPE_TEXTLENGTH) { $returnValue = $this->numericOperator($dataValidation, mb_strlen((string) $cellValue)); } return $returnValue; } /** @param float|int $cellValue */ private function numericOperator(DataValidation $dataValidation, $cellValue): bool { $operator = $dataValidation->getOperator(); $formula1 = $dataValidation->getFormula1(); $formula2 = $dataValidation->getFormula2(); $returnValue = false; if ($operator === DataValidation::OPERATOR_BETWEEN) { $returnValue = $cellValue >= $formula1 && $cellValue <= $formula2; } elseif ($operator === DataValidation::OPERATOR_NOTBETWEEN) { $returnValue = $cellValue < $formula1 || $cellValue > $formula2; } elseif ($operator === DataValidation::OPERATOR_EQUAL) { $returnValue = $cellValue == $formula1; } elseif ($operator === DataValidation::OPERATOR_NOTEQUAL) { $returnValue = $cellValue != $formula1; } elseif ($operator === DataValidation::OPERATOR_LESSTHAN) { $returnValue = $cellValue < $formula1; } elseif ($operator === DataValidation::OPERATOR_LESSTHANOREQUAL) { $returnValue = $cellValue <= $formula1; } elseif ($operator === DataValidation::OPERATOR_GREATERTHAN) { $returnValue = $cellValue > $formula1; } elseif ($operator === DataValidation::OPERATOR_GREATERTHANOREQUAL) { $returnValue = $cellValue >= $formula1; } return $returnValue; } /** * Does this cell contain valid value, based on list? * * @param Cell $cell Cell to check the value * * @return bool */ private function isValueInList(Cell $cell) { $cellValue = $cell->getValue(); $dataValidation = $cell->getDataValidation(); $formula1 = $dataValidation->getFormula1(); if (!empty($formula1)) { // inline values list if ($formula1[0] === '"') { return in_array(strtolower($cellValue), explode(',', strtolower(trim($formula1, '"'))), true); } elseif (strpos($formula1, ':') > 0) { // values list cells $matchFormula = '=MATCH(' . $cell->getCoordinate() . ', ' . $formula1 . ', 0)'; $calculation = Calculation::getInstance($cell->getWorksheet()->getParent()); try { $result = $calculation->calculateFormula($matchFormula, $cell->getCoordinate(), $cell); while (is_array($result)) { $result = array_pop($result); } return $result !== ExcelError::NA(); } catch (Exception $ex) { return false; } } } return true; } } phpspreadsheet/src/PhpSpreadsheet/Cell/CellRange.php 0000644 00000011366 15060132323 0016517 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Cell; use PhpOffice\PhpSpreadsheet\Exception; use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; class CellRange implements AddressRange { /** * @var CellAddress */ protected $from; /** * @var CellAddress */ protected $to; public function __construct(CellAddress $from, CellAddress $to) { $this->validateFromTo($from, $to); } private function validateFromTo(CellAddress $from, CellAddress $to): void { // Identify actual top-left and bottom-right values (in case we've been given top-right and bottom-left) $firstColumn = min($from->columnId(), $to->columnId()); $firstRow = min($from->rowId(), $to->rowId()); $lastColumn = max($from->columnId(), $to->columnId()); $lastRow = max($from->rowId(), $to->rowId()); $fromWorksheet = $from->worksheet(); $toWorksheet = $to->worksheet(); $this->validateWorksheets($fromWorksheet, $toWorksheet); $this->from = $this->cellAddressWrapper($firstColumn, $firstRow, $fromWorksheet); $this->to = $this->cellAddressWrapper($lastColumn, $lastRow, $toWorksheet); } private function validateWorksheets(?Worksheet $fromWorksheet, ?Worksheet $toWorksheet): void { if ($fromWorksheet !== null && $toWorksheet !== null) { // We could simply compare worksheets rather than worksheet titles; but at some point we may introduce // support for 3d ranges; and at that point we drop this check and let the validation fall through // to the check for same workbook; but unless we check on titles, this test will also detect if the // worksheets are in different spreadsheets, and the next check will never execute or throw its // own exception. if ($fromWorksheet->getTitle() !== $toWorksheet->getTitle()) { throw new Exception('3d Cell Ranges are not supported'); } elseif ($fromWorksheet->getParent() !== $toWorksheet->getParent()) { throw new Exception('Worksheets must be in the same spreadsheet'); } } } private function cellAddressWrapper(int $column, int $row, ?Worksheet $worksheet = null): CellAddress { $cellAddress = Coordinate::stringFromColumnIndex($column) . (string) $row; return new class ($cellAddress, $worksheet) extends CellAddress { public function nextRow(int $offset = 1): CellAddress { /** @var CellAddress $result */ $result = parent::nextRow($offset); $this->rowId = $result->rowId; $this->cellAddress = $result->cellAddress; return $this; } public function previousRow(int $offset = 1): CellAddress { /** @var CellAddress $result */ $result = parent::previousRow($offset); $this->rowId = $result->rowId; $this->cellAddress = $result->cellAddress; return $this; } public function nextColumn(int $offset = 1): CellAddress { /** @var CellAddress $result */ $result = parent::nextColumn($offset); $this->columnId = $result->columnId; $this->columnName = $result->columnName; $this->cellAddress = $result->cellAddress; return $this; } public function previousColumn(int $offset = 1): CellAddress { /** @var CellAddress $result */ $result = parent::previousColumn($offset); $this->columnId = $result->columnId; $this->columnName = $result->columnName; $this->cellAddress = $result->cellAddress; return $this; } }; } public function from(): CellAddress { // Re-order from/to in case the cell addresses have been modified $this->validateFromTo($this->from, $this->to); return $this->from; } public function to(): CellAddress { // Re-order from/to in case the cell addresses have been modified $this->validateFromTo($this->from, $this->to); return $this->to; } public function __toString(): string { // Re-order from/to in case the cell addresses have been modified $this->validateFromTo($this->from, $this->to); if ($this->from->cellAddress() === $this->to->cellAddress()) { return "{$this->from->fullCellAddress()}"; } $fromAddress = $this->from->fullCellAddress(); $toAddress = $this->to->cellAddress(); return "{$fromAddress}:{$toAddress}"; } } phpspreadsheet/src/PhpSpreadsheet/Cell/DataType.php 0000644 00000004240 15060132323 0016367 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Cell; use PhpOffice\PhpSpreadsheet\RichText\RichText; use PhpOffice\PhpSpreadsheet\Shared\StringHelper; class DataType { // Data types const TYPE_STRING2 = 'str'; const TYPE_STRING = 's'; const TYPE_FORMULA = 'f'; const TYPE_NUMERIC = 'n'; const TYPE_BOOL = 'b'; const TYPE_NULL = 'null'; const TYPE_INLINE = 'inlineStr'; const TYPE_ERROR = 'e'; const TYPE_ISO_DATE = 'd'; /** * List of error codes. * * @var array<string, int> */ private static $errorCodes = [ '#NULL!' => 0, '#DIV/0!' => 1, '#VALUE!' => 2, '#REF!' => 3, '#NAME?' => 4, '#NUM!' => 5, '#N/A' => 6, '#CALC!' => 7, ]; public const MAX_STRING_LENGTH = 32767; /** * Get list of error codes. * * @return array<string, int> */ public static function getErrorCodes() { return self::$errorCodes; } /** * Check a string that it satisfies Excel requirements. * * @param null|RichText|string $textValue Value to sanitize to an Excel string * * @return RichText|string Sanitized value */ public static function checkString($textValue) { if ($textValue instanceof RichText) { // TODO: Sanitize Rich-Text string (max. character count is 32,767) return $textValue; } // string must never be longer than 32,767 characters, truncate if necessary $textValue = StringHelper::substring((string) $textValue, 0, self::MAX_STRING_LENGTH); // we require that newline is represented as "\n" in core, not as "\r\n" or "\r" $textValue = str_replace(["\r\n", "\r"], "\n", $textValue); return $textValue; } /** * Check a value that it is a valid error code. * * @param mixed $value Value to sanitize to an Excel error code * * @return string Sanitized value */ public static function checkErrorCode($value) { $value = (string) $value; if (!isset(self::$errorCodes[$value])) { $value = '#NULL!'; } return $value; } } phpspreadsheet/src/PhpSpreadsheet/Cell/AddressHelper.php 0000644 00000015122 15060132323 0017402 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Cell; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Exception; class AddressHelper { public const R1C1_COORDINATE_REGEX = '/(R((?:\[-?\d*\])|(?:\d*))?)(C((?:\[-?\d*\])|(?:\d*))?)/i'; /** @return string[] */ public static function getRowAndColumnChars() { $rowChar = 'R'; $colChar = 'C'; if (Functions::getCompatibilityMode() === Functions::COMPATIBILITY_EXCEL) { $rowColChars = Calculation::localeFunc('*RC'); if (mb_strlen($rowColChars) === 2) { $rowChar = mb_substr($rowColChars, 0, 1); $colChar = mb_substr($rowColChars, 1, 1); } } return [$rowChar, $colChar]; } /** * Converts an R1C1 format cell address to an A1 format cell address. */ public static function convertToA1( string $address, int $currentRowNumber = 1, int $currentColumnNumber = 1, bool $useLocale = true ): string { [$rowChar, $colChar] = $useLocale ? self::getRowAndColumnChars() : ['R', 'C']; $regex = '/^(' . $rowChar . '(\[?[-+]?\d*\]?))(' . $colChar . '(\[?[-+]?\d*\]?))$/i'; $validityCheck = preg_match($regex, $address, $cellReference); if (empty($validityCheck)) { throw new Exception('Invalid R1C1-format Cell Reference'); } $rowReference = $cellReference[2]; // Empty R reference is the current row if ($rowReference === '') { $rowReference = (string) $currentRowNumber; } // Bracketed R references are relative to the current row if ($rowReference[0] === '[') { $rowReference = $currentRowNumber + (int) trim($rowReference, '[]'); } $columnReference = $cellReference[4]; // Empty C reference is the current column if ($columnReference === '') { $columnReference = (string) $currentColumnNumber; } // Bracketed C references are relative to the current column if (is_string($columnReference) && $columnReference[0] === '[') { $columnReference = $currentColumnNumber + (int) trim($columnReference, '[]'); } $columnReference = (int) $columnReference; if ($columnReference <= 0 || $rowReference <= 0) { throw new Exception('Invalid R1C1-format Cell Reference, Value out of range'); } $A1CellReference = Coordinate::stringFromColumnIndex($columnReference) . $rowReference; return $A1CellReference; } protected static function convertSpreadsheetMLFormula(string $formula): string { $formula = substr($formula, 3); $temp = explode('"', $formula); $key = false; foreach ($temp as &$value) { // Only replace in alternate array entries (i.e. non-quoted blocks) $key = $key === false; if ($key) { $value = str_replace(['[.', ':.', ']'], ['', ':', ''], $value); } } unset($value); return implode('"', $temp); } /** * Converts a formula that uses R1C1/SpreadsheetXML format cell address to an A1 format cell address. */ public static function convertFormulaToA1( string $formula, int $currentRowNumber = 1, int $currentColumnNumber = 1 ): string { if (substr($formula, 0, 3) == 'of:') { // We have an old-style SpreadsheetML Formula return self::convertSpreadsheetMLFormula($formula); } // Convert R1C1 style references to A1 style references (but only when not quoted) $temp = explode('"', $formula); $key = false; foreach ($temp as &$value) { // Only replace in alternate array entries (i.e. non-quoted blocks) $key = $key === false; if ($key) { preg_match_all(self::R1C1_COORDINATE_REGEX, $value, $cellReferences, PREG_SET_ORDER + PREG_OFFSET_CAPTURE); // Reverse the matches array, otherwise all our offsets will become incorrect if we modify our way // through the formula from left to right. Reversing means that we work right to left.through // the formula $cellReferences = array_reverse($cellReferences); // Loop through each R1C1 style reference in turn, converting it to its A1 style equivalent, // then modify the formula to use that new reference foreach ($cellReferences as $cellReference) { $A1CellReference = self::convertToA1($cellReference[0][0], $currentRowNumber, $currentColumnNumber, false); $value = substr_replace($value, $A1CellReference, $cellReference[0][1], strlen($cellReference[0][0])); } } } unset($value); // Then rebuild the formula string return implode('"', $temp); } /** * Converts an A1 format cell address to an R1C1 format cell address. * If $currentRowNumber or $currentColumnNumber are provided, then the R1C1 address will be formatted as a relative address. */ public static function convertToR1C1( string $address, ?int $currentRowNumber = null, ?int $currentColumnNumber = null ): string { $validityCheck = preg_match(Coordinate::A1_COORDINATE_REGEX, $address, $cellReference); if ($validityCheck === 0) { throw new Exception('Invalid A1-format Cell Reference'); } if ($cellReference['col'][0] === '$') { // Column must be absolute address $currentColumnNumber = null; } $columnId = Coordinate::columnIndexFromString(ltrim($cellReference['col'], '$')); if ($cellReference['row'][0] === '$') { // Row must be absolute address $currentRowNumber = null; } $rowId = (int) ltrim($cellReference['row'], '$'); if ($currentRowNumber !== null) { if ($rowId === $currentRowNumber) { $rowId = ''; } else { $rowId = '[' . ($rowId - $currentRowNumber) . ']'; } } if ($currentColumnNumber !== null) { if ($columnId === $currentColumnNumber) { $columnId = ''; } else { $columnId = '[' . ($columnId - $currentColumnNumber) . ']'; } } $R1C1Address = "R{$rowId}C{$columnId}"; return $R1C1Address; } } phpspreadsheet/src/PhpSpreadsheet/Cell/Hyperlink.php 0000644 00000003512 15060132323 0016622 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Cell; class Hyperlink { /** * URL to link the cell to. * * @var string */ private $url; /** * Tooltip to display on the hyperlink. * * @var string */ private $tooltip; /** * Create a new Hyperlink. * * @param string $url Url to link the cell to * @param string $tooltip Tooltip to display on the hyperlink */ public function __construct($url = '', $tooltip = '') { // Initialise member variables $this->url = $url; $this->tooltip = $tooltip; } /** * Get URL. * * @return string */ public function getUrl() { return $this->url; } /** * Set URL. * * @param string $url * * @return $this */ public function setUrl($url) { $this->url = $url; return $this; } /** * Get tooltip. * * @return string */ public function getTooltip() { return $this->tooltip; } /** * Set tooltip. * * @param string $tooltip * * @return $this */ public function setTooltip($tooltip) { $this->tooltip = $tooltip; return $this; } /** * Is this hyperlink internal? (to another worksheet). * * @return bool */ public function isInternal() { return strpos($this->url, 'sheet://') !== false; } /** * @return string */ public function getTypeHyperlink() { return $this->isInternal() ? '' : 'External'; } /** * Get hash code. * * @return string Hash code */ public function getHashCode() { return md5( $this->url . $this->tooltip . __CLASS__ ); } } phpspreadsheet/src/PhpSpreadsheet/Cell/CellAddress.php 0000644 00000010021 15060132323 0017033 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Cell; use PhpOffice\PhpSpreadsheet\Exception; use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; class CellAddress { /** * @var ?Worksheet */ protected $worksheet; /** * @var string */ protected $cellAddress; /** * @var string */ protected $columnName; /** * @var int */ protected $columnId; /** * @var int */ protected $rowId; public function __construct(string $cellAddress, ?Worksheet $worksheet = null) { $this->cellAddress = str_replace('$', '', $cellAddress); [$this->columnId, $this->rowId, $this->columnName] = Coordinate::indexesFromString($this->cellAddress); $this->worksheet = $worksheet; } /** * @param mixed $columnId * @param mixed $rowId */ private static function validateColumnAndRow($columnId, $rowId): void { if (!is_numeric($columnId) || $columnId <= 0 || !is_numeric($rowId) || $rowId <= 0) { throw new Exception('Row and Column Ids must be positive integer values'); } } /** * @param mixed $columnId * @param mixed $rowId */ public static function fromColumnAndRow($columnId, $rowId, ?Worksheet $worksheet = null): self { self::validateColumnAndRow($columnId, $rowId); /** @phpstan-ignore-next-line */ return new static(Coordinate::stringFromColumnIndex($columnId) . ((string) $rowId), $worksheet); } public static function fromColumnRowArray(array $array, ?Worksheet $worksheet = null): self { [$columnId, $rowId] = $array; return static::fromColumnAndRow($columnId, $rowId, $worksheet); } /** * @param mixed $cellAddress */ public static function fromCellAddress($cellAddress, ?Worksheet $worksheet = null): self { /** @phpstan-ignore-next-line */ return new static($cellAddress, $worksheet); } /** * The returned address string will contain the worksheet name as well, if available, * (ie. if a Worksheet was provided to the constructor). * e.g. "'Mark''s Worksheet'!C5". */ public function fullCellAddress(): string { if ($this->worksheet !== null) { $title = str_replace("'", "''", $this->worksheet->getTitle()); return "'{$title}'!{$this->cellAddress}"; } return $this->cellAddress; } public function worksheet(): ?Worksheet { return $this->worksheet; } /** * The returned address string will contain just the column/row address, * (even if a Worksheet was provided to the constructor). * e.g. "C5". */ public function cellAddress(): string { return $this->cellAddress; } public function rowId(): int { return $this->rowId; } public function columnId(): int { return $this->columnId; } public function columnName(): string { return $this->columnName; } public function nextRow(int $offset = 1): self { $newRowId = $this->rowId + $offset; if ($newRowId < 1) { $newRowId = 1; } return static::fromColumnAndRow($this->columnId, $newRowId); } public function previousRow(int $offset = 1): self { return $this->nextRow(0 - $offset); } public function nextColumn(int $offset = 1): self { $newColumnId = $this->columnId + $offset; if ($newColumnId < 1) { $newColumnId = 1; } return static::fromColumnAndRow($newColumnId, $this->rowId); } public function previousColumn(int $offset = 1): self { return $this->nextColumn(0 - $offset); } /** * The returned address string will contain the worksheet name as well, if available, * (ie. if a Worksheet was provided to the constructor). * e.g. "'Mark''s Worksheet'!C5". */ public function __toString() { return $this->fullCellAddress(); } } phpspreadsheet/src/PhpSpreadsheet/Cell/IgnoredErrors.php 0000644 00000002256 15060132323 0017445 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Cell; class IgnoredErrors { /** @var bool */ private $numberStoredAsText = false; /** @var bool */ private $formula = false; /** @var bool */ private $twoDigitTextYear = false; /** @var bool */ private $evalError = false; public function setNumberStoredAsText(bool $value): self { $this->numberStoredAsText = $value; return $this; } public function getNumberStoredAsText(): bool { return $this->numberStoredAsText; } public function setFormula(bool $value): self { $this->formula = $value; return $this; } public function getFormula(): bool { return $this->formula; } public function setTwoDigitTextYear(bool $value): self { $this->twoDigitTextYear = $value; return $this; } public function getTwoDigitTextYear(): bool { return $this->twoDigitTextYear; } public function setEvalError(bool $value): self { $this->evalError = $value; return $this; } public function getEvalError(): bool { return $this->evalError; } } phpspreadsheet/src/PhpSpreadsheet/Cell/Coordinate.php 0000644 00000051112 15060132323 0016743 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Cell; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Exception; use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; /** * Helper class to manipulate cell coordinates. * * Columns indexes and rows are always based on 1, **not** on 0. This match the behavior * that Excel users are used to, and also match the Excel functions `COLUMN()` and `ROW()`. */ abstract class Coordinate { public const A1_COORDINATE_REGEX = '/^(?<col>\$?[A-Z]{1,3})(?<row>\$?\d{1,7})$/i'; /** * Default range variable constant. * * @var string */ const DEFAULT_RANGE = 'A1:A1'; /** * Convert string coordinate to [0 => int column index, 1 => int row index]. * * @param string $cellAddress eg: 'A1' * * @return array{0: string, 1: string} Array containing column and row (indexes 0 and 1) */ public static function coordinateFromString($cellAddress): array { if (preg_match(self::A1_COORDINATE_REGEX, $cellAddress, $matches)) { return [$matches['col'], $matches['row']]; } elseif (self::coordinateIsRange($cellAddress)) { throw new Exception('Cell coordinate string can not be a range of cells'); } elseif ($cellAddress == '') { throw new Exception('Cell coordinate can not be zero-length string'); } throw new Exception('Invalid cell coordinate ' . $cellAddress); } /** * Convert string coordinate to [0 => int column index, 1 => int row index, 2 => string column string]. * * @param string $coordinates eg: 'A1', '$B$12' * * @return array{0: int, 1: int, 2: string} Array containing column and row index, and column string */ public static function indexesFromString(string $coordinates): array { [$column, $row] = self::coordinateFromString($coordinates); $column = ltrim($column, '$'); return [ self::columnIndexFromString($column), (int) ltrim($row, '$'), $column, ]; } /** * Checks if a Cell Address represents a range of cells. * * @param string $cellAddress eg: 'A1' or 'A1:A2' or 'A1:A2,C1:C2' * * @return bool Whether the coordinate represents a range of cells */ public static function coordinateIsRange($cellAddress) { return (strpos($cellAddress, ':') !== false) || (strpos($cellAddress, ',') !== false); } /** * Make string row, column or cell coordinate absolute. * * @param string $cellAddress e.g. 'A' or '1' or 'A1' * Note that this value can be a row or column reference as well as a cell reference * * @return string Absolute coordinate e.g. '$A' or '$1' or '$A$1' */ public static function absoluteReference($cellAddress) { if (self::coordinateIsRange($cellAddress)) { throw new Exception('Cell coordinate string can not be a range of cells'); } // Split out any worksheet name from the reference [$worksheet, $cellAddress] = Worksheet::extractSheetTitle($cellAddress, true); if ($worksheet > '') { $worksheet .= '!'; } // Create absolute coordinate $cellAddress = "$cellAddress"; if (ctype_digit($cellAddress)) { return $worksheet . '$' . $cellAddress; } elseif (ctype_alpha($cellAddress)) { return $worksheet . '$' . strtoupper($cellAddress); } return $worksheet . self::absoluteCoordinate($cellAddress); } /** * Make string coordinate absolute. * * @param string $cellAddress e.g. 'A1' * * @return string Absolute coordinate e.g. '$A$1' */ public static function absoluteCoordinate($cellAddress) { if (self::coordinateIsRange($cellAddress)) { throw new Exception('Cell coordinate string can not be a range of cells'); } // Split out any worksheet name from the coordinate [$worksheet, $cellAddress] = Worksheet::extractSheetTitle($cellAddress, true); if ($worksheet > '') { $worksheet .= '!'; } // Create absolute coordinate [$column, $row] = self::coordinateFromString($cellAddress); $column = ltrim($column, '$'); $row = ltrim($row, '$'); return $worksheet . '$' . $column . '$' . $row; } /** * Split range into coordinate strings. * * @param string $range e.g. 'B4:D9' or 'B4:D9,H2:O11' or 'B4' * * @return array Array containing one or more arrays containing one or two coordinate strings * e.g. ['B4','D9'] or [['B4','D9'], ['H2','O11']] * or ['B4'] */ public static function splitRange($range) { // Ensure $pRange is a valid range if (empty($range)) { $range = self::DEFAULT_RANGE; } $exploded = explode(',', $range); $counter = count($exploded); for ($i = 0; $i < $counter; ++$i) { // @phpstan-ignore-next-line $exploded[$i] = explode(':', $exploded[$i]); } return $exploded; } /** * Build range from coordinate strings. * * @param array $range Array containing one or more arrays containing one or two coordinate strings * * @return string String representation of $pRange */ public static function buildRange(array $range) { // Verify range if (empty($range) || !is_array($range[0])) { throw new Exception('Range does not contain any information'); } // Build range $counter = count($range); for ($i = 0; $i < $counter; ++$i) { $range[$i] = implode(':', $range[$i]); } return implode(',', $range); } /** * Calculate range boundaries. * * @param string $range Cell range, Single Cell, Row/Column Range (e.g. A1:A1, B2, B:C, 2:3) * * @return array Range coordinates [Start Cell, End Cell] * where Start Cell and End Cell are arrays (Column Number, Row Number) */ public static function rangeBoundaries(string $range): array { // Ensure $pRange is a valid range if (empty($range)) { $range = self::DEFAULT_RANGE; } // Uppercase coordinate $range = strtoupper($range); // Extract range if (strpos($range, ':') === false) { $rangeA = $rangeB = $range; } else { [$rangeA, $rangeB] = explode(':', $range); } if (is_numeric($rangeA) && is_numeric($rangeB)) { $rangeA = 'A' . $rangeA; $rangeB = AddressRange::MAX_COLUMN . $rangeB; } if (ctype_alpha($rangeA) && ctype_alpha($rangeB)) { $rangeA = $rangeA . '1'; $rangeB = $rangeB . AddressRange::MAX_ROW; } // Calculate range outer borders $rangeStart = self::coordinateFromString($rangeA); $rangeEnd = self::coordinateFromString($rangeB); // Translate column into index $rangeStart[0] = self::columnIndexFromString($rangeStart[0]); $rangeEnd[0] = self::columnIndexFromString($rangeEnd[0]); return [$rangeStart, $rangeEnd]; } /** * Calculate range dimension. * * @param string $range Cell range, Single Cell, Row/Column Range (e.g. A1:A1, B2, B:C, 2:3) * * @return array Range dimension (width, height) */ public static function rangeDimension($range) { // Calculate range outer borders [$rangeStart, $rangeEnd] = self::rangeBoundaries($range); return [($rangeEnd[0] - $rangeStart[0] + 1), ($rangeEnd[1] - $rangeStart[1] + 1)]; } /** * Calculate range boundaries. * * @param string $range Cell range, Single Cell, Row/Column Range (e.g. A1:A1, B2, B:C, 2:3) * * @return array Range coordinates [Start Cell, End Cell] * where Start Cell and End Cell are arrays [Column ID, Row Number] */ public static function getRangeBoundaries($range) { [$rangeA, $rangeB] = self::rangeBoundaries($range); return [ [self::stringFromColumnIndex($rangeA[0]), $rangeA[1]], [self::stringFromColumnIndex($rangeB[0]), $rangeB[1]], ]; } /** * Column index from string. * * @param ?string $columnAddress eg 'A' * * @return int Column index (A = 1) */ public static function columnIndexFromString($columnAddress) { // Using a lookup cache adds a slight memory overhead, but boosts speed // caching using a static within the method is faster than a class static, // though it's additional memory overhead static $indexCache = []; $columnAddress = $columnAddress ?? ''; if (isset($indexCache[$columnAddress])) { return $indexCache[$columnAddress]; } // It's surprising how costly the strtoupper() and ord() calls actually are, so we use a lookup array // rather than use ord() and make it case insensitive to get rid of the strtoupper() as well. // Because it's a static, there's no significant memory overhead either. static $columnLookup = [ 'A' => 1, 'B' => 2, 'C' => 3, 'D' => 4, 'E' => 5, 'F' => 6, 'G' => 7, 'H' => 8, 'I' => 9, 'J' => 10, 'K' => 11, 'L' => 12, 'M' => 13, 'N' => 14, 'O' => 15, 'P' => 16, 'Q' => 17, 'R' => 18, 'S' => 19, 'T' => 20, 'U' => 21, 'V' => 22, 'W' => 23, 'X' => 24, 'Y' => 25, 'Z' => 26, 'a' => 1, 'b' => 2, 'c' => 3, 'd' => 4, 'e' => 5, 'f' => 6, 'g' => 7, 'h' => 8, 'i' => 9, 'j' => 10, 'k' => 11, 'l' => 12, 'm' => 13, 'n' => 14, 'o' => 15, 'p' => 16, 'q' => 17, 'r' => 18, 's' => 19, 't' => 20, 'u' => 21, 'v' => 22, 'w' => 23, 'x' => 24, 'y' => 25, 'z' => 26, ]; // We also use the language construct isset() rather than the more costly strlen() function to match the // length of $columnAddress for improved performance if (isset($columnAddress[0])) { if (!isset($columnAddress[1])) { $indexCache[$columnAddress] = $columnLookup[$columnAddress]; return $indexCache[$columnAddress]; } elseif (!isset($columnAddress[2])) { $indexCache[$columnAddress] = $columnLookup[$columnAddress[0]] * 26 + $columnLookup[$columnAddress[1]]; return $indexCache[$columnAddress]; } elseif (!isset($columnAddress[3])) { $indexCache[$columnAddress] = $columnLookup[$columnAddress[0]] * 676 + $columnLookup[$columnAddress[1]] * 26 + $columnLookup[$columnAddress[2]]; return $indexCache[$columnAddress]; } } throw new Exception( 'Column string index can not be ' . ((isset($columnAddress[0])) ? 'longer than 3 characters' : 'empty') ); } /** * String from column index. * * @param int $columnIndex Column index (A = 1) * * @return string */ public static function stringFromColumnIndex($columnIndex) { static $indexCache = []; static $lookupCache = ' ABCDEFGHIJKLMNOPQRSTUVWXYZ'; if (!isset($indexCache[$columnIndex])) { $indexValue = $columnIndex; $base26 = ''; do { $characterValue = ($indexValue % 26) ?: 26; $indexValue = ($indexValue - $characterValue) / 26; $base26 = $lookupCache[$characterValue] . $base26; } while ($indexValue > 0); $indexCache[$columnIndex] = $base26; } return $indexCache[$columnIndex]; } /** * Extract all cell references in range, which may be comprised of multiple cell ranges. * * @param string $cellRange Range: e.g. 'A1' or 'A1:C10' or 'A1:E10,A20:E25' or 'A1:E5 C3:G7' or 'A1:C1,A3:C3 B1:C3' * * @return array Array containing single cell references */ public static function extractAllCellReferencesInRange($cellRange): array { if (substr_count($cellRange, '!') > 1) { throw new Exception('3-D Range References are not supported'); } [$worksheet, $cellRange] = Worksheet::extractSheetTitle($cellRange, true); $quoted = ''; if ($worksheet > '') { $quoted = Worksheet::nameRequiresQuotes($worksheet) ? "'" : ''; if (substr($worksheet, 0, 1) === "'" && substr($worksheet, -1, 1) === "'") { $worksheet = substr($worksheet, 1, -1); } $worksheet = str_replace("'", "''", $worksheet); } [$ranges, $operators] = self::getCellBlocksFromRangeString($cellRange); $cells = []; foreach ($ranges as $range) { $cells[] = self::getReferencesForCellBlock($range); } $cells = self::processRangeSetOperators($operators, $cells); if (empty($cells)) { return []; } $cellList = array_merge(...$cells); return array_map( function ($cellAddress) use ($worksheet, $quoted) { return ($worksheet !== '') ? "{$quoted}{$worksheet}{$quoted}!{$cellAddress}" : $cellAddress; }, self::sortCellReferenceArray($cellList) ); } private static function processRangeSetOperators(array $operators, array $cells): array { $operatorCount = count($operators); for ($offset = 0; $offset < $operatorCount; ++$offset) { $operator = $operators[$offset]; if ($operator !== ' ') { continue; } $cells[$offset] = array_intersect($cells[$offset], $cells[$offset + 1]); unset($operators[$offset], $cells[$offset + 1]); $operators = array_values($operators); $cells = array_values($cells); --$offset; --$operatorCount; } return $cells; } private static function sortCellReferenceArray(array $cellList): array { // Sort the result by column and row $sortKeys = []; foreach ($cellList as $coordinate) { $column = ''; $row = 0; sscanf($coordinate, '%[A-Z]%d', $column, $row); $key = (--$row * 16384) + self::columnIndexFromString((string) $column); $sortKeys[$key] = $coordinate; } ksort($sortKeys); return array_values($sortKeys); } /** * Get all cell references for an individual cell block. * * @param string $cellBlock A cell range e.g. A4:B5 * * @return array All individual cells in that range */ private static function getReferencesForCellBlock($cellBlock) { $returnValue = []; // Single cell? if (!self::coordinateIsRange($cellBlock)) { return (array) $cellBlock; } // Range... $ranges = self::splitRange($cellBlock); foreach ($ranges as $range) { // Single cell? if (!isset($range[1])) { $returnValue[] = $range[0]; continue; } // Range... [$rangeStart, $rangeEnd] = $range; [$startColumn, $startRow] = self::coordinateFromString($rangeStart); [$endColumn, $endRow] = self::coordinateFromString($rangeEnd); $startColumnIndex = self::columnIndexFromString($startColumn); $endColumnIndex = self::columnIndexFromString($endColumn); ++$endColumnIndex; // Current data $currentColumnIndex = $startColumnIndex; $currentRow = $startRow; self::validateRange($cellBlock, $startColumnIndex, $endColumnIndex, (int) $currentRow, (int) $endRow); // Loop cells while ($currentColumnIndex < $endColumnIndex) { while ($currentRow <= $endRow) { $returnValue[] = self::stringFromColumnIndex($currentColumnIndex) . $currentRow; ++$currentRow; } ++$currentColumnIndex; $currentRow = $startRow; } } return $returnValue; } /** * Convert an associative array of single cell coordinates to values to an associative array * of cell ranges to values. Only adjacent cell coordinates with the same * value will be merged. If the value is an object, it must implement the method getHashCode(). * * For example, this function converts: * * [ 'A1' => 'x', 'A2' => 'x', 'A3' => 'x', 'A4' => 'y' ] * * to: * * [ 'A1:A3' => 'x', 'A4' => 'y' ] * * @param array $coordinateCollection associative array mapping coordinates to values * * @return array associative array mapping coordinate ranges to valuea */ public static function mergeRangesInCollection(array $coordinateCollection) { $hashedValues = []; $mergedCoordCollection = []; foreach ($coordinateCollection as $coord => $value) { if (self::coordinateIsRange($coord)) { $mergedCoordCollection[$coord] = $value; continue; } [$column, $row] = self::coordinateFromString($coord); $row = (int) (ltrim($row, '$')); $hashCode = $column . '-' . ((is_object($value) && method_exists($value, 'getHashCode')) ? $value->getHashCode() : $value); if (!isset($hashedValues[$hashCode])) { $hashedValues[$hashCode] = (object) [ 'value' => $value, 'col' => $column, 'rows' => [$row], ]; } else { $hashedValues[$hashCode]->rows[] = $row; } } ksort($hashedValues); foreach ($hashedValues as $hashedValue) { sort($hashedValue->rows); $rowStart = null; $rowEnd = null; $ranges = []; foreach ($hashedValue->rows as $row) { if ($rowStart === null) { $rowStart = $row; $rowEnd = $row; } elseif ($rowEnd === $row - 1) { $rowEnd = $row; } else { if ($rowStart == $rowEnd) { $ranges[] = $hashedValue->col . $rowStart; } else { $ranges[] = $hashedValue->col . $rowStart . ':' . $hashedValue->col . $rowEnd; } $rowStart = $row; $rowEnd = $row; } } if ($rowStart !== null) { if ($rowStart == $rowEnd) { $ranges[] = $hashedValue->col . $rowStart; } else { $ranges[] = $hashedValue->col . $rowStart . ':' . $hashedValue->col . $rowEnd; } } foreach ($ranges as $range) { $mergedCoordCollection[$range] = $hashedValue->value; } } return $mergedCoordCollection; } /** * Get the individual cell blocks from a range string, removing any $ characters. * then splitting by operators and returning an array with ranges and operators. * * @param string $rangeString * * @return array[] */ private static function getCellBlocksFromRangeString($rangeString) { $rangeString = str_replace('$', '', strtoupper($rangeString)); // split range sets on intersection (space) or union (,) operators $tokens = preg_split('/([ ,])/', $rangeString, -1, PREG_SPLIT_DELIM_CAPTURE); /** @phpstan-ignore-next-line */ $split = array_chunk($tokens, 2); $ranges = array_column($split, 0); $operators = array_column($split, 1); return [$ranges, $operators]; } /** * Check that the given range is valid, i.e. that the start column and row are not greater than the end column and * row. * * @param string $cellBlock The original range, for displaying a meaningful error message * @param int $startColumnIndex * @param int $endColumnIndex * @param int $currentRow * @param int $endRow */ private static function validateRange($cellBlock, $startColumnIndex, $endColumnIndex, $currentRow, $endRow): void { if ($startColumnIndex >= $endColumnIndex || $currentRow > $endRow) { throw new Exception('Invalid range: "' . $cellBlock . '"'); } } } phpspreadsheet/src/PhpSpreadsheet/Cell/IValueBinder.php 0000644 00000000456 15060132323 0017172 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Cell; interface IValueBinder { /** * Bind value to a cell. * * @param Cell $cell Cell to bind value to * @param mixed $value Value to bind in cell * * @return bool */ public function bindValue(Cell $cell, $value); } phpspreadsheet/src/PhpSpreadsheet/Cell/DataValidation.php 0000644 00000020450 15060132323 0017541 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Cell; class DataValidation { // Data validation types const TYPE_NONE = 'none'; const TYPE_CUSTOM = 'custom'; const TYPE_DATE = 'date'; const TYPE_DECIMAL = 'decimal'; const TYPE_LIST = 'list'; const TYPE_TEXTLENGTH = 'textLength'; const TYPE_TIME = 'time'; const TYPE_WHOLE = 'whole'; // Data validation error styles const STYLE_STOP = 'stop'; const STYLE_WARNING = 'warning'; const STYLE_INFORMATION = 'information'; // Data validation operators const OPERATOR_BETWEEN = 'between'; const OPERATOR_EQUAL = 'equal'; const OPERATOR_GREATERTHAN = 'greaterThan'; const OPERATOR_GREATERTHANOREQUAL = 'greaterThanOrEqual'; const OPERATOR_LESSTHAN = 'lessThan'; const OPERATOR_LESSTHANOREQUAL = 'lessThanOrEqual'; const OPERATOR_NOTBETWEEN = 'notBetween'; const OPERATOR_NOTEQUAL = 'notEqual'; /** * Formula 1. * * @var string */ private $formula1 = ''; /** * Formula 2. * * @var string */ private $formula2 = ''; /** * Type. * * @var string */ private $type = self::TYPE_NONE; /** * Error style. * * @var string */ private $errorStyle = self::STYLE_STOP; /** * Operator. * * @var string */ private $operator = self::OPERATOR_BETWEEN; /** * Allow Blank. * * @var bool */ private $allowBlank = false; /** * Show DropDown. * * @var bool */ private $showDropDown = false; /** * Show InputMessage. * * @var bool */ private $showInputMessage = false; /** * Show ErrorMessage. * * @var bool */ private $showErrorMessage = false; /** * Error title. * * @var string */ private $errorTitle = ''; /** * Error. * * @var string */ private $error = ''; /** * Prompt title. * * @var string */ private $promptTitle = ''; /** * Prompt. * * @var string */ private $prompt = ''; /** * Create a new DataValidation. */ public function __construct() { } /** * Get Formula 1. * * @return string */ public function getFormula1() { return $this->formula1; } /** * Set Formula 1. * * @param string $formula * * @return $this */ public function setFormula1($formula) { $this->formula1 = $formula; return $this; } /** * Get Formula 2. * * @return string */ public function getFormula2() { return $this->formula2; } /** * Set Formula 2. * * @param string $formula * * @return $this */ public function setFormula2($formula) { $this->formula2 = $formula; return $this; } /** * Get Type. * * @return string */ public function getType() { return $this->type; } /** * Set Type. * * @param string $type * * @return $this */ public function setType($type) { $this->type = $type; return $this; } /** * Get Error style. * * @return string */ public function getErrorStyle() { return $this->errorStyle; } /** * Set Error style. * * @param string $errorStyle see self::STYLE_* * * @return $this */ public function setErrorStyle($errorStyle) { $this->errorStyle = $errorStyle; return $this; } /** * Get Operator. * * @return string */ public function getOperator() { return $this->operator; } /** * Set Operator. * * @param string $operator * * @return $this */ public function setOperator($operator) { $this->operator = $operator; return $this; } /** * Get Allow Blank. * * @return bool */ public function getAllowBlank() { return $this->allowBlank; } /** * Set Allow Blank. * * @param bool $allowBlank * * @return $this */ public function setAllowBlank($allowBlank) { $this->allowBlank = $allowBlank; return $this; } /** * Get Show DropDown. * * @return bool */ public function getShowDropDown() { return $this->showDropDown; } /** * Set Show DropDown. * * @param bool $showDropDown * * @return $this */ public function setShowDropDown($showDropDown) { $this->showDropDown = $showDropDown; return $this; } /** * Get Show InputMessage. * * @return bool */ public function getShowInputMessage() { return $this->showInputMessage; } /** * Set Show InputMessage. * * @param bool $showInputMessage * * @return $this */ public function setShowInputMessage($showInputMessage) { $this->showInputMessage = $showInputMessage; return $this; } /** * Get Show ErrorMessage. * * @return bool */ public function getShowErrorMessage() { return $this->showErrorMessage; } /** * Set Show ErrorMessage. * * @param bool $showErrorMessage * * @return $this */ public function setShowErrorMessage($showErrorMessage) { $this->showErrorMessage = $showErrorMessage; return $this; } /** * Get Error title. * * @return string */ public function getErrorTitle() { return $this->errorTitle; } /** * Set Error title. * * @param string $errorTitle * * @return $this */ public function setErrorTitle($errorTitle) { $this->errorTitle = $errorTitle; return $this; } /** * Get Error. * * @return string */ public function getError() { return $this->error; } /** * Set Error. * * @param string $error * * @return $this */ public function setError($error) { $this->error = $error; return $this; } /** * Get Prompt title. * * @return string */ public function getPromptTitle() { return $this->promptTitle; } /** * Set Prompt title. * * @param string $promptTitle * * @return $this */ public function setPromptTitle($promptTitle) { $this->promptTitle = $promptTitle; return $this; } /** * Get Prompt. * * @return string */ public function getPrompt() { return $this->prompt; } /** * Set Prompt. * * @param string $prompt * * @return $this */ public function setPrompt($prompt) { $this->prompt = $prompt; return $this; } /** * Get hash code. * * @return string Hash code */ public function getHashCode() { return md5( $this->formula1 . $this->formula2 . $this->type . $this->errorStyle . $this->operator . ($this->allowBlank ? 't' : 'f') . ($this->showDropDown ? 't' : 'f') . ($this->showInputMessage ? 't' : 'f') . ($this->showErrorMessage ? 't' : 'f') . $this->errorTitle . $this->error . $this->promptTitle . $this->prompt . $this->sqref . __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; } } } /** @var ?string */ private $sqref; public function getSqref(): ?string { return $this->sqref; } public function setSqref(?string $str): self { $this->sqref = $str; return $this; } } phpspreadsheet/src/PhpSpreadsheet/Cell/ColumnRange.php 0000644 00000006003 15060132323 0017065 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Cell; use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; class ColumnRange implements AddressRange { /** * @var ?Worksheet */ protected $worksheet; /** * @var int */ protected $from; /** * @var int */ protected $to; public function __construct(string $from, ?string $to = null, ?Worksheet $worksheet = null) { $this->validateFromTo( Coordinate::columnIndexFromString($from), Coordinate::columnIndexFromString($to ?? $from) ); $this->worksheet = $worksheet; } public static function fromColumnIndexes(int $from, int $to, ?Worksheet $worksheet = null): self { return new self(Coordinate::stringFromColumnIndex($from), Coordinate::stringFromColumnIndex($to), $worksheet); } /** * @param array<int|string> $array */ public static function fromArray(array $array, ?Worksheet $worksheet = null): self { array_walk( $array, function (&$column): void { $column = is_numeric($column) ? Coordinate::stringFromColumnIndex((int) $column) : $column; } ); /** @var string $from */ /** @var string $to */ [$from, $to] = $array; return new self($from, $to, $worksheet); } private function validateFromTo(int $from, int $to): void { // Identify actual top and bottom values (in case we've been given bottom and top) $this->from = min($from, $to); $this->to = max($from, $to); } public function columnCount(): int { return $this->to - $this->from + 1; } public function shiftDown(int $offset = 1): self { $newFrom = $this->from + $offset; $newFrom = ($newFrom < 1) ? 1 : $newFrom; $newTo = $this->to + $offset; $newTo = ($newTo < 1) ? 1 : $newTo; return self::fromColumnIndexes($newFrom, $newTo, $this->worksheet); } public function shiftUp(int $offset = 1): self { return $this->shiftDown(0 - $offset); } public function from(): string { return Coordinate::stringFromColumnIndex($this->from); } public function to(): string { return Coordinate::stringFromColumnIndex($this->to); } public function fromIndex(): int { return $this->from; } public function toIndex(): int { return $this->to; } public function toCellRange(): CellRange { return new CellRange( CellAddress::fromColumnAndRow($this->from, 1, $this->worksheet), CellAddress::fromColumnAndRow($this->to, AddressRange::MAX_ROW) ); } public function __toString(): string { $from = $this->from(); $to = $this->to(); if ($this->worksheet !== null) { $title = str_replace("'", "''", $this->worksheet->getTitle()); return "'{$title}'!{$from}:{$to}"; } return "{$from}:{$to}"; } } phpspreadsheet/src/PhpSpreadsheet/Cell/AddressRange.php 0000644 00000000555 15060132323 0017223 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Cell; interface AddressRange { public const MAX_ROW = 1048576; public const MAX_COLUMN = 'XFD'; public const MAX_COLUMN_INT = 16384; /** * @return mixed */ public function from(); /** * @return mixed */ public function to(); public function __toString(): string; } phpspreadsheet/src/PhpSpreadsheet/Cell/StringValueBinder.php 0000644 00000006615 15060132323 0020253 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Cell; use DateTimeInterface; use PhpOffice\PhpSpreadsheet\RichText\RichText; use PhpOffice\PhpSpreadsheet\Shared\StringHelper; class StringValueBinder implements IValueBinder { /** * @var bool */ protected $convertNull = true; /** * @var bool */ protected $convertBoolean = true; /** * @var bool */ protected $convertNumeric = true; /** * @var bool */ protected $convertFormula = true; public function setNullConversion(bool $suppressConversion = false): self { $this->convertNull = $suppressConversion; return $this; } public function setBooleanConversion(bool $suppressConversion = false): self { $this->convertBoolean = $suppressConversion; return $this; } public function getBooleanConversion(): bool { return $this->convertBoolean; } public function setNumericConversion(bool $suppressConversion = false): self { $this->convertNumeric = $suppressConversion; return $this; } public function setFormulaConversion(bool $suppressConversion = false): self { $this->convertFormula = $suppressConversion; return $this; } public function setConversionForAllValueTypes(bool $suppressConversion = false): self { $this->convertNull = $suppressConversion; $this->convertBoolean = $suppressConversion; $this->convertNumeric = $suppressConversion; $this->convertFormula = $suppressConversion; return $this; } /** * Bind value to a cell. * * @param Cell $cell Cell to bind value to * @param mixed $value Value to bind in cell */ public function bindValue(Cell $cell, $value) { if (is_object($value)) { return $this->bindObjectValue($cell, $value); } // sanitize UTF-8 strings if (is_string($value)) { $value = StringHelper::sanitizeUTF8($value); } if ($value === null && $this->convertNull === false) { $cell->setValueExplicit($value, DataType::TYPE_NULL); } elseif (is_bool($value) && $this->convertBoolean === false) { $cell->setValueExplicit($value, DataType::TYPE_BOOL); } elseif ((is_int($value) || is_float($value)) && $this->convertNumeric === false) { $cell->setValueExplicit($value, DataType::TYPE_NUMERIC); } elseif (is_string($value) && strlen($value) > 1 && $value[0] === '=' && $this->convertFormula === false) { $cell->setValueExplicit($value, DataType::TYPE_FORMULA); } else { if (is_string($value) && strlen($value) > 1 && $value[0] === '=') { $cell->getStyle()->setQuotePrefix(true); } $cell->setValueExplicit((string) $value, DataType::TYPE_STRING); } return true; } protected function bindObjectValue(Cell $cell, object $value): bool { // Handle any objects that might be injected if ($value instanceof DateTimeInterface) { $value = $value->format('Y-m-d H:i:s'); } elseif ($value instanceof RichText) { $cell->setValueExplicit($value, DataType::TYPE_INLINE); return true; } $cell->setValueExplicit((string) $value, DataType::TYPE_STRING); // @phpstan-ignore-line return true; } } phpspreadsheet/src/PhpSpreadsheet/Cell/RowRange.php 0000644 00000004223 15060132323 0016401 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Cell; use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; class RowRange implements AddressRange { /** * @var ?Worksheet */ protected $worksheet; /** * @var int */ protected $from; /** * @var int */ protected $to; public function __construct(int $from, ?int $to = null, ?Worksheet $worksheet = null) { $this->validateFromTo($from, $to ?? $from); $this->worksheet = $worksheet; } public static function fromArray(array $array, ?Worksheet $worksheet = null): self { [$from, $to] = $array; return new self($from, $to, $worksheet); } private function validateFromTo(int $from, int $to): void { // Identify actual top and bottom values (in case we've been given bottom and top) $this->from = min($from, $to); $this->to = max($from, $to); } public function from(): int { return $this->from; } public function to(): int { return $this->to; } public function rowCount(): int { return $this->to - $this->from + 1; } public function shiftRight(int $offset = 1): self { $newFrom = $this->from + $offset; $newFrom = ($newFrom < 1) ? 1 : $newFrom; $newTo = $this->to + $offset; $newTo = ($newTo < 1) ? 1 : $newTo; return new self($newFrom, $newTo, $this->worksheet); } public function shiftLeft(int $offset = 1): self { return $this->shiftRight(0 - $offset); } public function toCellRange(): CellRange { return new CellRange( CellAddress::fromColumnAndRow(Coordinate::columnIndexFromString('A'), $this->from, $this->worksheet), CellAddress::fromColumnAndRow(Coordinate::columnIndexFromString(AddressRange::MAX_COLUMN), $this->to) ); } public function __toString(): string { if ($this->worksheet !== null) { $title = str_replace("'", "''", $this->worksheet->getTitle()); return "'{$title}'!{$this->from}:{$this->to}"; } return "{$this->from}:{$this->to}"; } } phpspreadsheet/src/PhpSpreadsheet/Cell/DefaultValueBinder.php 0000644 00000005256 15060132323 0020371 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Cell; use DateTimeInterface; use PhpOffice\PhpSpreadsheet\RichText\RichText; use PhpOffice\PhpSpreadsheet\Shared\StringHelper; class DefaultValueBinder implements IValueBinder { /** * Bind value to a cell. * * @param Cell $cell Cell to bind value to * @param mixed $value Value to bind in cell * * @return bool */ public function bindValue(Cell $cell, $value) { // sanitize UTF-8 strings if (is_string($value)) { $value = StringHelper::sanitizeUTF8($value); } elseif (is_object($value)) { // Handle any objects that might be injected if ($value instanceof DateTimeInterface) { $value = $value->format('Y-m-d H:i:s'); } elseif (!($value instanceof RichText)) { // Attempt to cast any unexpected objects to string $value = (string) $value; // @phpstan-ignore-line } } // Set value explicit $cell->setValueExplicit($value, static::dataTypeForValue($value)); // Done! return true; } /** * DataType for value. * * @param mixed $value * * @return string */ public static function dataTypeForValue($value) { // Match the value against a few data types if ($value === null) { return DataType::TYPE_NULL; } elseif (is_float($value) || is_int($value)) { return DataType::TYPE_NUMERIC; } elseif (is_bool($value)) { return DataType::TYPE_BOOL; } elseif ($value === '') { return DataType::TYPE_STRING; } elseif ($value instanceof RichText) { return DataType::TYPE_INLINE; } elseif (is_string($value) && strlen($value) > 1 && $value[0] === '=') { return DataType::TYPE_FORMULA; } elseif (preg_match('/^[\+\-]?(\d+\\.?\d*|\d*\\.?\d+)([Ee][\-\+]?[0-2]?\d{1,3})?$/', $value)) { $tValue = ltrim($value, '+-'); if (is_string($value) && strlen($tValue) > 1 && $tValue[0] === '0' && $tValue[1] !== '.') { return DataType::TYPE_STRING; } elseif ((strpos($value, '.') === false) && ($value > PHP_INT_MAX)) { return DataType::TYPE_STRING; } elseif (!is_numeric($value)) { return DataType::TYPE_STRING; } return DataType::TYPE_NUMERIC; } elseif (is_string($value)) { $errorCodes = DataType::getErrorCodes(); if (isset($errorCodes[$value])) { return DataType::TYPE_ERROR; } } return DataType::TYPE_STRING; } } phpspreadsheet/src/PhpSpreadsheet/Cell/Cell.php 0000644 00000054377 15060132323 0015553 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Cell; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; use PhpOffice\PhpSpreadsheet\Collection\Cells; use PhpOffice\PhpSpreadsheet\Exception; use PhpOffice\PhpSpreadsheet\RichText\RichText; use PhpOffice\PhpSpreadsheet\Shared\Date as SharedDate; use PhpOffice\PhpSpreadsheet\Shared\StringHelper; use PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\CellStyleAssessor; use PhpOffice\PhpSpreadsheet\Style\NumberFormat; use PhpOffice\PhpSpreadsheet\Style\Style; use PhpOffice\PhpSpreadsheet\Worksheet\Table; use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; class Cell { /** * Value binder to use. * * @var IValueBinder */ private static $valueBinder; /** * Value of the cell. * * @var mixed */ private $value; /** * Calculated value of the cell (used for caching) * This returns the value last calculated by MS Excel or whichever spreadsheet program was used to * create the original spreadsheet file. * Note that this value is not guaranteed to reflect the actual calculated value because it is * possible that auto-calculation was disabled in the original spreadsheet, and underlying data * values used by the formula have changed since it was last calculated. * * @var mixed */ private $calculatedValue; /** * Type of the cell data. * * @var string */ private $dataType; /** * The collection of cells that this cell belongs to (i.e. The Cell Collection for the parent Worksheet). * * @var ?Cells */ private $parent; /** * Index to the cellXf reference for the styling of this cell. * * @var int */ private $xfIndex = 0; /** * Attributes of the formula. * * @var mixed */ private $formulaAttributes; /** @var IgnoredErrors */ private $ignoredErrors; /** * Update the cell into the cell collection. * * @return $this */ public function updateInCollection(): self { $parent = $this->parent; if ($parent === null) { throw new Exception('Cannot update when cell is not bound to a worksheet'); } $parent->update($this); return $this; } public function detach(): void { $this->parent = null; } public function attach(Cells $parent): void { $this->parent = $parent; } /** * Create a new Cell. * * @param mixed $value */ public function __construct($value, ?string $dataType, Worksheet $worksheet) { // Initialise cell value $this->value = $value; // Set worksheet cache $this->parent = $worksheet->getCellCollection(); // Set datatype? if ($dataType !== null) { if ($dataType == DataType::TYPE_STRING2) { $dataType = DataType::TYPE_STRING; } $this->dataType = $dataType; } elseif (self::getValueBinder()->bindValue($this, $value) === false) { throw new Exception('Value could not be bound to cell.'); } $this->ignoredErrors = new IgnoredErrors(); } /** * Get cell coordinate column. * * @return string */ public function getColumn() { $parent = $this->parent; if ($parent === null) { throw new Exception('Cannot get column when cell is not bound to a worksheet'); } return $parent->getCurrentColumn(); } /** * Get cell coordinate row. * * @return int */ public function getRow() { $parent = $this->parent; if ($parent === null) { throw new Exception('Cannot get row when cell is not bound to a worksheet'); } return $parent->getCurrentRow(); } /** * Get cell coordinate. * * @return string */ public function getCoordinate() { $parent = $this->parent; if ($parent !== null) { $coordinate = $parent->getCurrentCoordinate(); } else { $coordinate = null; } if ($coordinate === null) { throw new Exception('Coordinate no longer exists'); } return $coordinate; } /** * Get cell value. * * @return mixed */ public function getValue() { return $this->value; } /** * Get cell value with formatting. */ public function getFormattedValue(): string { return (string) NumberFormat::toFormattedString( $this->getCalculatedValue(), (string) $this->getStyle()->getNumberFormat()->getFormatCode() ); } /** * @param mixed $oldValue * @param mixed $newValue */ protected static function updateIfCellIsTableHeader(?Worksheet $workSheet, self $cell, $oldValue, $newValue): void { if (StringHelper::strToLower($oldValue ?? '') === StringHelper::strToLower($newValue ?? '') || $workSheet === null) { return; } foreach ($workSheet->getTableCollection() as $table) { /** @var Table $table */ if ($cell->isInRange($table->getRange())) { $rangeRowsColumns = Coordinate::getRangeBoundaries($table->getRange()); if ($cell->getRow() === (int) $rangeRowsColumns[0][1]) { Table\Column::updateStructuredReferences($workSheet, $oldValue, $newValue); } return; } } } /** * Set cell value. * * Sets the value for a cell, automatically determining the datatype using the value binder * * @param mixed $value Value * @param null|IValueBinder $binder Value Binder to override the currently set Value Binder * * @throws Exception * * @return $this */ public function setValue($value, ?IValueBinder $binder = null): self { $binder ??= self::getValueBinder(); if (!$binder->bindValue($this, $value)) { throw new Exception('Value could not be bound to cell.'); } return $this; } /** * Set the value for a cell, with the explicit data type passed to the method (bypassing any use of the value binder). * * @param mixed $value Value * @param string $dataType Explicit data type, see DataType::TYPE_* * Note that PhpSpreadsheet does not validate that the value and datatype are consistent, in using this * method, then it is your responsibility as an end-user developer to validate that the value and * the datatype match. * If you do mismatch value and datatype, then the value you enter may be changed to match the datatype * that you specify. * * @return Cell */ public function setValueExplicit($value, string $dataType = DataType::TYPE_STRING) { $oldValue = $this->value; // set the value according to data type switch ($dataType) { case DataType::TYPE_NULL: $this->value = null; break; case DataType::TYPE_STRING2: $dataType = DataType::TYPE_STRING; // no break case DataType::TYPE_STRING: // Synonym for string case DataType::TYPE_INLINE: // Rich text $this->value = DataType::checkString($value); break; case DataType::TYPE_NUMERIC: if (is_string($value) && !is_numeric($value)) { throw new Exception('Invalid numeric value for datatype Numeric'); } $this->value = 0 + $value; break; case DataType::TYPE_FORMULA: $this->value = (string) $value; break; case DataType::TYPE_BOOL: $this->value = (bool) $value; break; case DataType::TYPE_ISO_DATE: $this->value = SharedDate::convertIsoDate($value); $dataType = DataType::TYPE_NUMERIC; break; case DataType::TYPE_ERROR: $this->value = DataType::checkErrorCode($value); break; default: throw new Exception('Invalid datatype: ' . $dataType); } // set the datatype $this->dataType = $dataType; $this->updateInCollection(); $cellCoordinate = $this->getCoordinate(); self::updateIfCellIsTableHeader($this->getParent()->getParent(), $this, $oldValue, $value); // @phpstan-ignore-line return $this->getParent()->get($cellCoordinate); // @phpstan-ignore-line } public const CALCULATE_DATE_TIME_ASIS = 0; public const CALCULATE_DATE_TIME_FLOAT = 1; public const CALCULATE_TIME_FLOAT = 2; /** @var int */ private static $calculateDateTimeType = self::CALCULATE_DATE_TIME_ASIS; public static function getCalculateDateTimeType(): int { return self::$calculateDateTimeType; } public static function setCalculateDateTimeType(int $calculateDateTimeType): void { switch ($calculateDateTimeType) { case self::CALCULATE_DATE_TIME_ASIS: case self::CALCULATE_DATE_TIME_FLOAT: case self::CALCULATE_TIME_FLOAT: self::$calculateDateTimeType = $calculateDateTimeType; break; default: throw new \PhpOffice\PhpSpreadsheet\Calculation\Exception("Invalid value $calculateDateTimeType for calculated date time type"); } } /** * Convert date, time, or datetime from int to float if desired. * * @param mixed $result * * @return mixed */ private function convertDateTimeInt($result) { if (is_int($result)) { if (self::$calculateDateTimeType === self::CALCULATE_TIME_FLOAT) { if (SharedDate::isDateTime($this, $result, false)) { $result = (float) $result; } } elseif (self::$calculateDateTimeType === self::CALCULATE_DATE_TIME_FLOAT) { if (SharedDate::isDateTime($this, $result, true)) { $result = (float) $result; } } } return $result; } /** * Get calculated cell value. * * @param bool $resetLog Whether the calculation engine logger should be reset or not * * @return mixed */ public function getCalculatedValue(bool $resetLog = true) { if ($this->dataType === DataType::TYPE_FORMULA) { try { $index = $this->getWorksheet()->getParentOrThrow()->getActiveSheetIndex(); $selected = $this->getWorksheet()->getSelectedCells(); $result = Calculation::getInstance( $this->getWorksheet()->getParent() )->calculateCellValue($this, $resetLog); $result = $this->convertDateTimeInt($result); $this->getWorksheet()->setSelectedCells($selected); $this->getWorksheet()->getParentOrThrow()->setActiveSheetIndex($index); // We don't yet handle array returns if (is_array($result)) { while (is_array($result)) { $result = array_shift($result); } } } catch (Exception $ex) { if (($ex->getMessage() === 'Unable to access External Workbook') && ($this->calculatedValue !== null)) { return $this->calculatedValue; // Fallback for calculations referencing external files. } elseif (preg_match('/[Uu]ndefined (name|offset: 2|array key 2)/', $ex->getMessage()) === 1) { return ExcelError::NAME(); } throw new \PhpOffice\PhpSpreadsheet\Calculation\Exception( $this->getWorksheet()->getTitle() . '!' . $this->getCoordinate() . ' -> ' . $ex->getMessage(), $ex->getCode(), $ex ); } if ($result === '#Not Yet Implemented') { return $this->calculatedValue; // Fallback if calculation engine does not support the formula. } return $result; } elseif ($this->value instanceof RichText) { return $this->value->getPlainText(); } return $this->convertDateTimeInt($this->value); } /** * Set old calculated value (cached). * * @param mixed $originalValue Value */ public function setCalculatedValue($originalValue): self { if ($originalValue !== null) { $this->calculatedValue = (is_numeric($originalValue)) ? (float) $originalValue : $originalValue; } return $this->updateInCollection(); } /** * Get old calculated value (cached) * This returns the value last calculated by MS Excel or whichever spreadsheet program was used to * create the original spreadsheet file. * Note that this value is not guaranteed to reflect the actual calculated value because it is * possible that auto-calculation was disabled in the original spreadsheet, and underlying data * values used by the formula have changed since it was last calculated. * * @return mixed */ public function getOldCalculatedValue() { return $this->calculatedValue; } /** * Get cell data type. */ public function getDataType(): string { return $this->dataType; } /** * Set cell data type. * * @param string $dataType see DataType::TYPE_* */ public function setDataType($dataType): self { if ($dataType == DataType::TYPE_STRING2) { $dataType = DataType::TYPE_STRING; } $this->dataType = $dataType; return $this->updateInCollection(); } /** * Identify if the cell contains a formula. */ public function isFormula(): bool { return $this->dataType === DataType::TYPE_FORMULA && $this->getStyle()->getQuotePrefix() === false; } /** * Does this cell contain Data validation rules? */ public function hasDataValidation(): bool { if (!isset($this->parent)) { throw new Exception('Cannot check for data validation when cell is not bound to a worksheet'); } return $this->getWorksheet()->dataValidationExists($this->getCoordinate()); } /** * Get Data validation rules. */ public function getDataValidation(): DataValidation { if (!isset($this->parent)) { throw new Exception('Cannot get data validation for cell that is not bound to a worksheet'); } return $this->getWorksheet()->getDataValidation($this->getCoordinate()); } /** * Set Data validation rules. */ public function setDataValidation(?DataValidation $dataValidation = null): self { if (!isset($this->parent)) { throw new Exception('Cannot set data validation for cell that is not bound to a worksheet'); } $this->getWorksheet()->setDataValidation($this->getCoordinate(), $dataValidation); return $this->updateInCollection(); } /** * Does this cell contain valid value? */ public function hasValidValue(): bool { $validator = new DataValidator(); return $validator->isValid($this); } /** * Does this cell contain a Hyperlink? */ public function hasHyperlink(): bool { if (!isset($this->parent)) { throw new Exception('Cannot check for hyperlink when cell is not bound to a worksheet'); } return $this->getWorksheet()->hyperlinkExists($this->getCoordinate()); } /** * Get Hyperlink. */ public function getHyperlink(): Hyperlink { if (!isset($this->parent)) { throw new Exception('Cannot get hyperlink for cell that is not bound to a worksheet'); } return $this->getWorksheet()->getHyperlink($this->getCoordinate()); } /** * Set Hyperlink. */ public function setHyperlink(?Hyperlink $hyperlink = null): self { if (!isset($this->parent)) { throw new Exception('Cannot set hyperlink for cell that is not bound to a worksheet'); } $this->getWorksheet()->setHyperlink($this->getCoordinate(), $hyperlink); return $this->updateInCollection(); } /** * Get cell collection. * * @return ?Cells */ public function getParent() { return $this->parent; } /** * Get parent worksheet. */ public function getWorksheet(): Worksheet { $parent = $this->parent; if ($parent !== null) { $worksheet = $parent->getParent(); } else { $worksheet = null; } if ($worksheet === null) { throw new Exception('Worksheet no longer exists'); } return $worksheet; } public function getWorksheetOrNull(): ?Worksheet { $parent = $this->parent; if ($parent !== null) { $worksheet = $parent->getParent(); } else { $worksheet = null; } return $worksheet; } /** * Is this cell in a merge range. */ public function isInMergeRange(): bool { return (bool) $this->getMergeRange(); } /** * Is this cell the master (top left cell) in a merge range (that holds the actual data value). */ public function isMergeRangeValueCell(): bool { if ($mergeRange = $this->getMergeRange()) { $mergeRange = Coordinate::splitRange($mergeRange); [$startCell] = $mergeRange[0]; return $this->getCoordinate() === $startCell; } return false; } /** * If this cell is in a merge range, then return the range. * * @return false|string */ public function getMergeRange() { foreach ($this->getWorksheet()->getMergeCells() as $mergeRange) { if ($this->isInRange($mergeRange)) { return $mergeRange; } } return false; } /** * Get cell style. */ public function getStyle(): Style { return $this->getWorksheet()->getStyle($this->getCoordinate()); } /** * Get cell style. */ public function getAppliedStyle(): Style { if ($this->getWorksheet()->conditionalStylesExists($this->getCoordinate()) === false) { return $this->getStyle(); } $range = $this->getWorksheet()->getConditionalRange($this->getCoordinate()); if ($range === null) { return $this->getStyle(); } $matcher = new CellStyleAssessor($this, $range); return $matcher->matchConditions($this->getWorksheet()->getConditionalStyles($this->getCoordinate())); } /** * Re-bind parent. */ public function rebindParent(Worksheet $parent): self { $this->parent = $parent->getCellCollection(); return $this->updateInCollection(); } /** * Is cell in a specific range? * * @param string $range Cell range (e.g. A1:A1) */ public function isInRange(string $range): bool { [$rangeStart, $rangeEnd] = Coordinate::rangeBoundaries($range); // Translate properties $myColumn = Coordinate::columnIndexFromString($this->getColumn()); $myRow = $this->getRow(); // Verify if cell is in range return ($rangeStart[0] <= $myColumn) && ($rangeEnd[0] >= $myColumn) && ($rangeStart[1] <= $myRow) && ($rangeEnd[1] >= $myRow); } /** * Compare 2 cells. * * @param Cell $a Cell a * @param Cell $b Cell b * * @return int Result of comparison (always -1 or 1, never zero!) */ public static function compareCells(self $a, self $b): int { if ($a->getRow() < $b->getRow()) { return -1; } elseif ($a->getRow() > $b->getRow()) { return 1; } elseif (Coordinate::columnIndexFromString($a->getColumn()) < Coordinate::columnIndexFromString($b->getColumn())) { return -1; } return 1; } /** * Get value binder to use. */ public static function getValueBinder(): IValueBinder { if (self::$valueBinder === null) { self::$valueBinder = new DefaultValueBinder(); } return self::$valueBinder; } /** * Set value binder to use. */ public static function setValueBinder(IValueBinder $binder): void { self::$valueBinder = $binder; } /** * Implement PHP __clone to create a deep clone, not just a shallow copy. */ public function __clone() { $vars = get_object_vars($this); foreach ($vars as $propertyName => $propertyValue) { if ((is_object($propertyValue)) && ($propertyName !== 'parent')) { $this->$propertyName = clone $propertyValue; } else { $this->$propertyName = $propertyValue; } } } /** * Get index to cellXf. */ public function getXfIndex(): int { return $this->xfIndex; } /** * Set index to cellXf. */ public function setXfIndex(int $indexValue): self { $this->xfIndex = $indexValue; return $this->updateInCollection(); } /** * Set the formula attributes. * * @param mixed $attributes * * @return $this */ public function setFormulaAttributes($attributes): self { $this->formulaAttributes = $attributes; return $this; } /** * Get the formula attributes. * * @return mixed */ public function getFormulaAttributes() { return $this->formulaAttributes; } /** * Convert to string. * * @return string */ public function __toString() { return (string) $this->getValue(); } public function getIgnoredErrors(): IgnoredErrors { return $this->ignoredErrors; } } phpspreadsheet/src/PhpSpreadsheet/Cell/AdvancedValueBinder.php 0000644 00000020430 15060132323 0020501 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Cell; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Engine\FormattedNumber; use PhpOffice\PhpSpreadsheet\RichText\RichText; use PhpOffice\PhpSpreadsheet\Shared\Date; use PhpOffice\PhpSpreadsheet\Shared\StringHelper; use PhpOffice\PhpSpreadsheet\Style\NumberFormat; class AdvancedValueBinder extends DefaultValueBinder implements IValueBinder { /** * Bind value to a cell. * * @param Cell $cell Cell to bind value to * @param mixed $value Value to bind in cell * * @return bool */ public function bindValue(Cell $cell, $value = null) { if ($value === null) { return parent::bindValue($cell, $value); } elseif (is_string($value)) { // sanitize UTF-8 strings $value = StringHelper::sanitizeUTF8($value); } // Find out data type $dataType = parent::dataTypeForValue($value); // Style logic - strings if ($dataType === DataType::TYPE_STRING && !$value instanceof RichText) { // Test for booleans using locale-setting if (StringHelper::strToUpper($value) === Calculation::getTRUE()) { $cell->setValueExplicit(true, DataType::TYPE_BOOL); return true; } elseif (StringHelper::strToUpper($value) === Calculation::getFALSE()) { $cell->setValueExplicit(false, DataType::TYPE_BOOL); return true; } // Check for fractions if (preg_match('/^([+-]?)\s*(\d+)\s?\/\s*(\d+)$/', $value, $matches)) { return $this->setProperFraction($matches, $cell); } elseif (preg_match('/^([+-]?)(\d*) +(\d*)\s?\/\s*(\d*)$/', $value, $matches)) { return $this->setImproperFraction($matches, $cell); } $decimalSeparatorNoPreg = StringHelper::getDecimalSeparator(); $decimalSeparator = preg_quote($decimalSeparatorNoPreg, '/'); $thousandsSeparator = preg_quote(StringHelper::getThousandsSeparator(), '/'); // Check for percentage if (preg_match('/^\-?\d*' . $decimalSeparator . '?\d*\s?\%$/', preg_replace('/(\d)' . $thousandsSeparator . '(\d)/u', '$1$2', $value))) { return $this->setPercentage(preg_replace('/(\d)' . $thousandsSeparator . '(\d)/u', '$1$2', $value), $cell); } // Check for currency if (preg_match(FormattedNumber::currencyMatcherRegexp(), preg_replace('/(\d)' . $thousandsSeparator . '(\d)/u', '$1$2', $value), $matches, PREG_UNMATCHED_AS_NULL)) { // Convert value to number $sign = ($matches['PrefixedSign'] ?? $matches['PrefixedSign2'] ?? $matches['PostfixedSign']) ?? null; $currencyCode = $matches['PrefixedCurrency'] ?? $matches['PostfixedCurrency']; $value = (float) ($sign . trim(str_replace([$decimalSeparatorNoPreg, $currencyCode, ' ', '-'], ['.', '', '', ''], preg_replace('/(\d)' . $thousandsSeparator . '(\d)/u', '$1$2', $value)))); // @phpstan-ignore-line return $this->setCurrency($value, $cell, $currencyCode); // @phpstan-ignore-line } // Check for time without seconds e.g. '9:45', '09:45' if (preg_match('/^(\d|[0-1]\d|2[0-3]):[0-5]\d$/', $value)) { return $this->setTimeHoursMinutes($value, $cell); } // Check for time with seconds '9:45:59', '09:45:59' if (preg_match('/^(\d|[0-1]\d|2[0-3]):[0-5]\d:[0-5]\d$/', $value)) { return $this->setTimeHoursMinutesSeconds($value, $cell); } // Check for datetime, e.g. '2008-12-31', '2008-12-31 15:59', '2008-12-31 15:59:10' if (($d = Date::stringToExcel($value)) !== false) { // Convert value to number $cell->setValueExplicit($d, DataType::TYPE_NUMERIC); // Determine style. Either there is a time part or not. Look for ':' if (strpos($value, ':') !== false) { $formatCode = 'yyyy-mm-dd h:mm'; } else { $formatCode = 'yyyy-mm-dd'; } $cell->getWorksheet()->getStyle($cell->getCoordinate()) ->getNumberFormat()->setFormatCode($formatCode); return true; } // Check for newline character "\n" if (strpos($value, "\n") !== false) { $cell->setValueExplicit($value, DataType::TYPE_STRING); // Set style $cell->getWorksheet()->getStyle($cell->getCoordinate()) ->getAlignment()->setWrapText(true); return true; } } // Not bound yet? Use parent... return parent::bindValue($cell, $value); } protected function setImproperFraction(array $matches, Cell $cell): bool { // Convert value to number $value = $matches[2] + ($matches[3] / $matches[4]); if ($matches[1] === '-') { $value = 0 - $value; } $cell->setValueExplicit((float) $value, DataType::TYPE_NUMERIC); // Build the number format mask based on the size of the matched values $dividend = str_repeat('?', strlen($matches[3])); $divisor = str_repeat('?', strlen($matches[4])); $fractionMask = "# {$dividend}/{$divisor}"; // Set style $cell->getWorksheet()->getStyle($cell->getCoordinate()) ->getNumberFormat()->setFormatCode($fractionMask); return true; } protected function setProperFraction(array $matches, Cell $cell): bool { // Convert value to number $value = $matches[2] / $matches[3]; if ($matches[1] === '-') { $value = 0 - $value; } $cell->setValueExplicit((float) $value, DataType::TYPE_NUMERIC); // Build the number format mask based on the size of the matched values $dividend = str_repeat('?', strlen($matches[2])); $divisor = str_repeat('?', strlen($matches[3])); $fractionMask = "{$dividend}/{$divisor}"; // Set style $cell->getWorksheet()->getStyle($cell->getCoordinate()) ->getNumberFormat()->setFormatCode($fractionMask); return true; } protected function setPercentage(string $value, Cell $cell): bool { // Convert value to number $value = ((float) str_replace('%', '', $value)) / 100; $cell->setValueExplicit($value, DataType::TYPE_NUMERIC); // Set style $cell->getWorksheet()->getStyle($cell->getCoordinate()) ->getNumberFormat()->setFormatCode(NumberFormat::FORMAT_PERCENTAGE_00); return true; } protected function setCurrency(float $value, Cell $cell, string $currencyCode): bool { $cell->setValueExplicit($value, DataType::TYPE_NUMERIC); // Set style $cell->getWorksheet()->getStyle($cell->getCoordinate()) ->getNumberFormat()->setFormatCode( str_replace('$', '[$' . $currencyCode . ']', NumberFormat::FORMAT_CURRENCY_USD) ); return true; } protected function setTimeHoursMinutes(string $value, Cell $cell): bool { // Convert value to number [$hours, $minutes] = explode(':', $value); $hours = (int) $hours; $minutes = (int) $minutes; $days = ($hours / 24) + ($minutes / 1440); $cell->setValueExplicit($days, DataType::TYPE_NUMERIC); // Set style $cell->getWorksheet()->getStyle($cell->getCoordinate()) ->getNumberFormat()->setFormatCode(NumberFormat::FORMAT_DATE_TIME3); return true; } protected function setTimeHoursMinutesSeconds(string $value, Cell $cell): bool { // Convert value to number [$hours, $minutes, $seconds] = explode(':', $value); $hours = (int) $hours; $minutes = (int) $minutes; $seconds = (int) $seconds; $days = ($hours / 24) + ($minutes / 1440) + ($seconds / 86400); $cell->setValueExplicit($days, DataType::TYPE_NUMERIC); // Set style $cell->getWorksheet()->getStyle($cell->getCoordinate()) ->getNumberFormat()->setFormatCode(NumberFormat::FORMAT_DATE_TIME4); return true; } } phpspreadsheet/src/PhpSpreadsheet/DefinedName.php 0000644 00000014647 15060132323 0016150 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet; use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; abstract class DefinedName { protected const REGEXP_IDENTIFY_FORMULA = '[^_\p{N}\p{L}:, \$\'!]'; /** * Name. * * @var string */ protected $name; /** * Worksheet on which the defined name can be resolved. * * @var ?Worksheet */ protected $worksheet; /** * Value of the named object. * * @var string */ protected $value; /** * Is the defined named local? (i.e. can only be used on $this->worksheet). * * @var bool */ protected $localOnly; /** * Scope. * * @var ?Worksheet */ protected $scope; /** * Whether this is a named range or a named formula. * * @var bool */ protected $isFormula; /** * Create a new Defined Name. */ public function __construct( string $name, ?Worksheet $worksheet = null, ?string $value = null, bool $localOnly = false, ?Worksheet $scope = null ) { if ($worksheet === null) { $worksheet = $scope; } // Set local members $this->name = $name; $this->worksheet = $worksheet; $this->value = (string) $value; $this->localOnly = $localOnly; // If local only, then the scope will be set to worksheet unless a scope is explicitly set $this->scope = ($localOnly === true) ? (($scope === null) ? $worksheet : $scope) : null; // If the range string contains characters that aren't associated with the range definition (A-Z,1-9 // for cell references, and $, or the range operators (colon comma or space), quotes and ! for // worksheet names // then this is treated as a named formula, and not a named range $this->isFormula = self::testIfFormula($this->value); } /** * Create a new defined name, either a range or a formula. */ public static function createInstance( string $name, ?Worksheet $worksheet = null, ?string $value = null, bool $localOnly = false, ?Worksheet $scope = null ): self { $value = (string) $value; $isFormula = self::testIfFormula($value); if ($isFormula) { return new NamedFormula($name, $worksheet, $value, $localOnly, $scope); } return new NamedRange($name, $worksheet, $value, $localOnly, $scope); } public static function testIfFormula(string $value): bool { if (substr($value, 0, 1) === '=') { $value = substr($value, 1); } if (is_numeric($value)) { return true; } $segMatcher = false; foreach (explode("'", $value) as $subVal) { // Only test in alternate array entries (the non-quoted blocks) $segMatcher = $segMatcher === false; if ( $segMatcher && (preg_match('/' . self::REGEXP_IDENTIFY_FORMULA . '/miu', $subVal)) ) { return true; } } return false; } /** * Get name. */ public function getName(): string { return $this->name; } /** * Set name. */ public function setName(string $name): self { if (!empty($name)) { // Old title $oldTitle = $this->name; // Re-attach if ($this->worksheet !== null) { $this->worksheet->getParentOrThrow()->removeNamedRange($this->name, $this->worksheet); } $this->name = $name; if ($this->worksheet !== null) { $this->worksheet->getParentOrThrow()->addDefinedName($this); } if ($this->worksheet !== null) { // New title $newTitle = $this->name; ReferenceHelper::getInstance()->updateNamedFormulae($this->worksheet->getParentOrThrow(), $oldTitle, $newTitle); } } return $this; } /** * Get worksheet. */ public function getWorksheet(): ?Worksheet { return $this->worksheet; } /** * Set worksheet. */ public function setWorksheet(?Worksheet $worksheet): self { $this->worksheet = $worksheet; return $this; } /** * Get range or formula value. */ public function getValue(): string { return $this->value; } /** * Set range or formula value. */ public function setValue(string $value): self { $this->value = $value; return $this; } /** * Get localOnly. */ public function getLocalOnly(): bool { return $this->localOnly; } /** * Set localOnly. */ public function setLocalOnly(bool $localScope): self { $this->localOnly = $localScope; $this->scope = $localScope ? $this->worksheet : null; return $this; } /** * Get scope. */ public function getScope(): ?Worksheet { return $this->scope; } /** * Set scope. */ public function setScope(?Worksheet $worksheet): self { $this->scope = $worksheet; $this->localOnly = $worksheet !== null; return $this; } /** * Identify whether this is a named range or a named formula. */ public function isFormula(): bool { return $this->isFormula; } /** * Resolve a named range to a regular cell range or formula. */ public static function resolveName(string $definedName, Worksheet $worksheet, string $sheetName = ''): ?self { if ($sheetName === '') { $worksheet2 = $worksheet; } else { $worksheet2 = $worksheet->getParentOrThrow()->getSheetByName($sheetName); if ($worksheet2 === null) { return null; } } return $worksheet->getParentOrThrow()->getDefinedName($definedName, $worksheet2); } /** * 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; } } } } phpspreadsheet/src/PhpSpreadsheet/Style/Protection.php 0000644 00000011373 15060132323 0017230 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Style; class Protection extends Supervisor { /** Protection styles */ const PROTECTION_INHERIT = 'inherit'; const PROTECTION_PROTECTED = 'protected'; const PROTECTION_UNPROTECTED = 'unprotected'; /** * Locked. * * @var string */ protected $locked; /** * Hidden. * * @var string */ protected $hidden; /** * Create a new Protection. * * @param bool $isSupervisor Flag indicating if this is a supervisor or not * Leave this value at default unless you understand exactly what * its ramifications are * @param bool $isConditional Flag indicating if this is a conditional style or not * Leave this value at default unless you understand exactly what * its ramifications are */ public function __construct($isSupervisor = false, $isConditional = false) { // Supervisor? parent::__construct($isSupervisor); // Initialise values if (!$isConditional) { $this->locked = self::PROTECTION_INHERIT; $this->hidden = self::PROTECTION_INHERIT; } } /** * Get the shared style component for the currently active cell in currently active sheet. * Only used for style supervisor. * * @return Protection */ public function getSharedComponent() { /** @var Style */ $parent = $this->parent; return $parent->getSharedComponent()->getProtection(); } /** * Build style array from subcomponents. * * @param array $array * * @return array */ public function getStyleArray($array) { return ['protection' => $array]; } /** * Apply styles from array. * * <code> * $spreadsheet->getActiveSheet()->getStyle('B2')->getLocked()->applyFromArray( * [ * 'locked' => TRUE, * 'hidden' => FALSE * ] * ); * </code> * * @param array $styleArray Array containing style information * * @return $this */ public function applyFromArray(array $styleArray) { if ($this->isSupervisor) { $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($styleArray)); } else { if (isset($styleArray['locked'])) { $this->setLocked($styleArray['locked']); } if (isset($styleArray['hidden'])) { $this->setHidden($styleArray['hidden']); } } return $this; } /** * Get locked. * * @return string */ public function getLocked() { if ($this->isSupervisor) { return $this->getSharedComponent()->getLocked(); } return $this->locked; } /** * Set locked. * * @param string $lockType see self::PROTECTION_* * * @return $this */ public function setLocked($lockType) { if ($this->isSupervisor) { $styleArray = $this->getStyleArray(['locked' => $lockType]); $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); } else { $this->locked = $lockType; } return $this; } /** * Get hidden. * * @return string */ public function getHidden() { if ($this->isSupervisor) { return $this->getSharedComponent()->getHidden(); } return $this->hidden; } /** * Set hidden. * * @param string $hiddenType see self::PROTECTION_* * * @return $this */ public function setHidden($hiddenType) { if ($this->isSupervisor) { $styleArray = $this->getStyleArray(['hidden' => $hiddenType]); $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); } else { $this->hidden = $hiddenType; } return $this; } /** * Get hash code. * * @return string Hash code */ public function getHashCode() { if ($this->isSupervisor) { return $this->getSharedComponent()->getHashCode(); } return md5( $this->locked . $this->hidden . __CLASS__ ); } protected function exportArray1(): array { $exportedArray = []; $this->exportArray2($exportedArray, 'locked', $this->getLocked()); $this->exportArray2($exportedArray, 'hidden', $this->getHidden()); return $exportedArray; } } phpspreadsheet/src/PhpSpreadsheet/Style/Style.php 0000644 00000066014 15060132323 0016204 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Style; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Cell\Coordinate; use PhpOffice\PhpSpreadsheet\Exception; use PhpOffice\PhpSpreadsheet\Shared\StringHelper; use PhpOffice\PhpSpreadsheet\Spreadsheet; class Style extends Supervisor { /** * Font. * * @var Font */ protected $font; /** * Fill. * * @var Fill */ protected $fill; /** * Borders. * * @var Borders */ protected $borders; /** * Alignment. * * @var Alignment */ protected $alignment; /** * Number Format. * * @var NumberFormat */ protected $numberFormat; /** * Protection. * * @var Protection */ protected $protection; /** * Index of style in collection. Only used for real style. * * @var int */ protected $index; /** * Use Quote Prefix when displaying in cell editor. Only used for real style. * * @var bool */ protected $quotePrefix = false; /** * Internal cache for styles * Used when applying style on range of cells (column or row) and cleared when * all cells in range is styled. * * PhpSpreadsheet will always minimize the amount of styles used. So cells with * same styles will reference the same Style instance. To check if two styles * are similar Style::getHashCode() is used. This call is expensive. To minimize * the need to call this method we can cache the internal PHP object id of the * Style in the range. Style::getHashCode() will then only be called when we * encounter a unique style. * * @see Style::applyFromArray() * @see Style::getHashCode() * * @var null|array<string, array> */ private static $cachedStyles; /** * Create a new Style. * * @param bool $isSupervisor Flag indicating if this is a supervisor or not * Leave this value at default unless you understand exactly what * its ramifications are * @param bool $isConditional Flag indicating if this is a conditional style or not * Leave this value at default unless you understand exactly what * its ramifications are */ public function __construct($isSupervisor = false, $isConditional = false) { parent::__construct($isSupervisor); // Initialise values $this->font = new Font($isSupervisor, $isConditional); $this->fill = new Fill($isSupervisor, $isConditional); $this->borders = new Borders($isSupervisor, $isConditional); $this->alignment = new Alignment($isSupervisor, $isConditional); $this->numberFormat = new NumberFormat($isSupervisor, $isConditional); $this->protection = new Protection($isSupervisor, $isConditional); // bind parent if we are a supervisor if ($isSupervisor) { $this->font->bindParent($this); $this->fill->bindParent($this); $this->borders->bindParent($this); $this->alignment->bindParent($this); $this->numberFormat->bindParent($this); $this->protection->bindParent($this); } } /** * Get the shared style component for the currently active cell in currently active sheet. * Only used for style supervisor. */ public function getSharedComponent(): self { $activeSheet = $this->getActiveSheet(); $selectedCell = Functions::trimSheetFromCellReference($this->getActiveCell()); // e.g. 'A1' if ($activeSheet->cellExists($selectedCell)) { $xfIndex = $activeSheet->getCell($selectedCell)->getXfIndex(); } else { $xfIndex = 0; } return $activeSheet->getParentOrThrow()->getCellXfByIndex($xfIndex); } /** * Get parent. Only used for style supervisor. */ public function getParent(): Spreadsheet { return $this->getActiveSheet()->getParentOrThrow(); } /** * Build style array from subcomponents. * * @param array $array * * @return array */ public function getStyleArray($array) { return ['quotePrefix' => $array]; } /** * Apply styles from array. * * <code> * $spreadsheet->getActiveSheet()->getStyle('B2')->applyFromArray( * [ * 'font' => [ * 'name' => 'Arial', * 'bold' => true, * 'italic' => false, * 'underline' => Font::UNDERLINE_DOUBLE, * 'strikethrough' => false, * 'color' => [ * 'rgb' => '808080' * ] * ], * 'borders' => [ * 'bottom' => [ * 'borderStyle' => Border::BORDER_DASHDOT, * 'color' => [ * 'rgb' => '808080' * ] * ], * 'top' => [ * 'borderStyle' => Border::BORDER_DASHDOT, * 'color' => [ * 'rgb' => '808080' * ] * ] * ], * 'alignment' => [ * 'horizontal' => Alignment::HORIZONTAL_CENTER, * 'vertical' => Alignment::VERTICAL_CENTER, * 'wrapText' => true, * ], * 'quotePrefix' => true * ] * ); * </code> * * @param array $styleArray Array containing style information * @param bool $advancedBorders advanced mode for setting borders * * @return $this */ public function applyFromArray(array $styleArray, $advancedBorders = true) { if ($this->isSupervisor) { $pRange = $this->getSelectedCells(); // Uppercase coordinate and strip any Worksheet reference from the selected range $pRange = strtoupper($pRange); if (strpos($pRange, '!') !== false) { $pRangeWorksheet = StringHelper::strToUpper(trim(substr($pRange, 0, (int) strrpos($pRange, '!')), "'")); if ($pRangeWorksheet !== '' && StringHelper::strToUpper($this->getActiveSheet()->getTitle()) !== $pRangeWorksheet) { throw new Exception('Invalid Worksheet for specified Range'); } $pRange = strtoupper(Functions::trimSheetFromCellReference($pRange)); } // Is it a cell range or a single cell? if (strpos($pRange, ':') === false) { $rangeA = $pRange; $rangeB = $pRange; } else { [$rangeA, $rangeB] = explode(':', $pRange); } // Calculate range outer borders $rangeStart = Coordinate::coordinateFromString($rangeA); $rangeEnd = Coordinate::coordinateFromString($rangeB); $rangeStartIndexes = Coordinate::indexesFromString($rangeA); $rangeEndIndexes = Coordinate::indexesFromString($rangeB); $columnStart = $rangeStart[0]; $columnEnd = $rangeEnd[0]; // Make sure we can loop upwards on rows and columns if ($rangeStartIndexes[0] > $rangeEndIndexes[0] && $rangeStartIndexes[1] > $rangeEndIndexes[1]) { $tmp = $rangeStartIndexes; $rangeStartIndexes = $rangeEndIndexes; $rangeEndIndexes = $tmp; } // ADVANCED MODE: if ($advancedBorders && isset($styleArray['borders'])) { // 'allBorders' is a shorthand property for 'outline' and 'inside' and // it applies to components that have not been set explicitly if (isset($styleArray['borders']['allBorders'])) { foreach (['outline', 'inside'] as $component) { if (!isset($styleArray['borders'][$component])) { $styleArray['borders'][$component] = $styleArray['borders']['allBorders']; } } unset($styleArray['borders']['allBorders']); // not needed any more } // 'outline' is a shorthand property for 'top', 'right', 'bottom', 'left' // it applies to components that have not been set explicitly if (isset($styleArray['borders']['outline'])) { foreach (['top', 'right', 'bottom', 'left'] as $component) { if (!isset($styleArray['borders'][$component])) { $styleArray['borders'][$component] = $styleArray['borders']['outline']; } } unset($styleArray['borders']['outline']); // not needed any more } // 'inside' is a shorthand property for 'vertical' and 'horizontal' // it applies to components that have not been set explicitly if (isset($styleArray['borders']['inside'])) { foreach (['vertical', 'horizontal'] as $component) { if (!isset($styleArray['borders'][$component])) { $styleArray['borders'][$component] = $styleArray['borders']['inside']; } } unset($styleArray['borders']['inside']); // not needed any more } // width and height characteristics of selection, 1, 2, or 3 (for 3 or more) $xMax = min($rangeEndIndexes[0] - $rangeStartIndexes[0] + 1, 3); $yMax = min($rangeEndIndexes[1] - $rangeStartIndexes[1] + 1, 3); // loop through up to 3 x 3 = 9 regions for ($x = 1; $x <= $xMax; ++$x) { // start column index for region $colStart = ($x == 3) ? Coordinate::stringFromColumnIndex($rangeEndIndexes[0]) : Coordinate::stringFromColumnIndex($rangeStartIndexes[0] + $x - 1); // end column index for region $colEnd = ($x == 1) ? Coordinate::stringFromColumnIndex($rangeStartIndexes[0]) : Coordinate::stringFromColumnIndex($rangeEndIndexes[0] - $xMax + $x); for ($y = 1; $y <= $yMax; ++$y) { // which edges are touching the region $edges = []; if ($x == 1) { // are we at left edge $edges[] = 'left'; } if ($x == $xMax) { // are we at right edge $edges[] = 'right'; } if ($y == 1) { // are we at top edge? $edges[] = 'top'; } if ($y == $yMax) { // are we at bottom edge? $edges[] = 'bottom'; } // start row index for region $rowStart = ($y == 3) ? $rangeEndIndexes[1] : $rangeStartIndexes[1] + $y - 1; // end row index for region $rowEnd = ($y == 1) ? $rangeStartIndexes[1] : $rangeEndIndexes[1] - $yMax + $y; // build range for region $range = $colStart . $rowStart . ':' . $colEnd . $rowEnd; // retrieve relevant style array for region $regionStyles = $styleArray; unset($regionStyles['borders']['inside']); // what are the inner edges of the region when looking at the selection $innerEdges = array_diff(['top', 'right', 'bottom', 'left'], $edges); // inner edges that are not touching the region should take the 'inside' border properties if they have been set foreach ($innerEdges as $innerEdge) { switch ($innerEdge) { case 'top': case 'bottom': // should pick up 'horizontal' border property if set if (isset($styleArray['borders']['horizontal'])) { $regionStyles['borders'][$innerEdge] = $styleArray['borders']['horizontal']; } else { unset($regionStyles['borders'][$innerEdge]); } break; case 'left': case 'right': // should pick up 'vertical' border property if set if (isset($styleArray['borders']['vertical'])) { $regionStyles['borders'][$innerEdge] = $styleArray['borders']['vertical']; } else { unset($regionStyles['borders'][$innerEdge]); } break; } } // apply region style to region by calling applyFromArray() in simple mode $this->getActiveSheet()->getStyle($range)->applyFromArray($regionStyles, false); } } // restore initial cell selection range $this->getActiveSheet()->getStyle($pRange); return $this; } // SIMPLE MODE: // Selection type, inspect if (preg_match('/^[A-Z]+1:[A-Z]+1048576$/', $pRange)) { $selectionType = 'COLUMN'; // Enable caching of styles self::$cachedStyles = ['hashByObjId' => [], 'styleByHash' => []]; } elseif (preg_match('/^A\d+:XFD\d+$/', $pRange)) { $selectionType = 'ROW'; // Enable caching of styles self::$cachedStyles = ['hashByObjId' => [], 'styleByHash' => []]; } else { $selectionType = 'CELL'; } // First loop through columns, rows, or cells to find out which styles are affected by this operation $oldXfIndexes = $this->getOldXfIndexes($selectionType, $rangeStartIndexes, $rangeEndIndexes, $columnStart, $columnEnd, $styleArray); // clone each of the affected styles, apply the style array, and add the new styles to the workbook $workbook = $this->getActiveSheet()->getParentOrThrow(); $newXfIndexes = []; foreach ($oldXfIndexes as $oldXfIndex => $dummy) { $style = $workbook->getCellXfByIndex($oldXfIndex); // $cachedStyles is set when applying style for a range of cells, either column or row if (self::$cachedStyles === null) { // Clone the old style and apply style-array $newStyle = clone $style; $newStyle->applyFromArray($styleArray); // Look for existing style we can use instead (reduce memory usage) $existingStyle = $workbook->getCellXfByHashCode($newStyle->getHashCode()); } else { // Style cache is stored by Style::getHashCode(). But calling this method is // expensive. So we cache the php obj id -> hash. $objId = spl_object_id($style); // Look for the original HashCode $styleHash = self::$cachedStyles['hashByObjId'][$objId] ?? null; if ($styleHash === null) { // This object_id is not cached, store the hashcode in case encounter again $styleHash = self::$cachedStyles['hashByObjId'][$objId] = $style->getHashCode(); } // Find existing style by hash. $existingStyle = self::$cachedStyles['styleByHash'][$styleHash] ?? null; if (!$existingStyle) { // The old style combined with the new style array is not cached, so we create it now $newStyle = clone $style; $newStyle->applyFromArray($styleArray); // Look for similar style in workbook to reduce memory usage $existingStyle = $workbook->getCellXfByHashCode($newStyle->getHashCode()); // Cache the new style by original hashcode self::$cachedStyles['styleByHash'][$styleHash] = $existingStyle instanceof self ? $existingStyle : $newStyle; } } if ($existingStyle) { // there is already such cell Xf in our collection $newXfIndexes[$oldXfIndex] = $existingStyle->getIndex(); } else { if (!isset($newStyle)) { // Handle bug in PHPStan, see https://github.com/phpstan/phpstan/issues/5805 // $newStyle should always be defined. // This block might not be needed in the future // @codeCoverageIgnoreStart $newStyle = clone $style; $newStyle->applyFromArray($styleArray); // @codeCoverageIgnoreEnd } // we don't have such a cell Xf, need to add $workbook->addCellXf($newStyle); $newXfIndexes[$oldXfIndex] = $newStyle->getIndex(); } } // Loop through columns, rows, or cells again and update the XF index switch ($selectionType) { case 'COLUMN': for ($col = $rangeStartIndexes[0]; $col <= $rangeEndIndexes[0]; ++$col) { $columnDimension = $this->getActiveSheet()->getColumnDimensionByColumn($col); $oldXfIndex = $columnDimension->getXfIndex(); $columnDimension->setXfIndex($newXfIndexes[$oldXfIndex]); } // Disable caching of styles self::$cachedStyles = null; break; case 'ROW': for ($row = $rangeStartIndexes[1]; $row <= $rangeEndIndexes[1]; ++$row) { $rowDimension = $this->getActiveSheet()->getRowDimension($row); // row without explicit style should be formatted based on default style $oldXfIndex = $rowDimension->getXfIndex() ?? 0; $rowDimension->setXfIndex($newXfIndexes[$oldXfIndex]); } // Disable caching of styles self::$cachedStyles = null; break; case 'CELL': for ($col = $rangeStartIndexes[0]; $col <= $rangeEndIndexes[0]; ++$col) { for ($row = $rangeStartIndexes[1]; $row <= $rangeEndIndexes[1]; ++$row) { $cell = $this->getActiveSheet()->getCell([$col, $row]); $oldXfIndex = $cell->getXfIndex(); $cell->setXfIndex($newXfIndexes[$oldXfIndex]); } } break; } } else { // not a supervisor, just apply the style array directly on style object if (isset($styleArray['fill'])) { $this->getFill()->applyFromArray($styleArray['fill']); } if (isset($styleArray['font'])) { $this->getFont()->applyFromArray($styleArray['font']); } if (isset($styleArray['borders'])) { $this->getBorders()->applyFromArray($styleArray['borders']); } if (isset($styleArray['alignment'])) { $this->getAlignment()->applyFromArray($styleArray['alignment']); } if (isset($styleArray['numberFormat'])) { $this->getNumberFormat()->applyFromArray($styleArray['numberFormat']); } if (isset($styleArray['protection'])) { $this->getProtection()->applyFromArray($styleArray['protection']); } if (isset($styleArray['quotePrefix'])) { $this->quotePrefix = $styleArray['quotePrefix']; } } return $this; } private function getOldXfIndexes(string $selectionType, array $rangeStart, array $rangeEnd, string $columnStart, string $columnEnd, array $styleArray): array { $oldXfIndexes = []; switch ($selectionType) { case 'COLUMN': for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) { $oldXfIndexes[$this->getActiveSheet()->getColumnDimensionByColumn($col)->getXfIndex()] = true; } foreach ($this->getActiveSheet()->getColumnIterator($columnStart, $columnEnd) as $columnIterator) { $cellIterator = $columnIterator->getCellIterator(); $cellIterator->setIterateOnlyExistingCells(true); foreach ($cellIterator as $columnCell) { if ($columnCell !== null) { $columnCell->getStyle()->applyFromArray($styleArray); } } } break; case 'ROW': for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) { if ($this->getActiveSheet()->getRowDimension($row)->getXfIndex() === null) { $oldXfIndexes[0] = true; // row without explicit style should be formatted based on default style } else { $oldXfIndexes[$this->getActiveSheet()->getRowDimension($row)->getXfIndex()] = true; } } foreach ($this->getActiveSheet()->getRowIterator((int) $rangeStart[1], (int) $rangeEnd[1]) as $rowIterator) { $cellIterator = $rowIterator->getCellIterator(); $cellIterator->setIterateOnlyExistingCells(true); foreach ($cellIterator as $rowCell) { if ($rowCell !== null) { $rowCell->getStyle()->applyFromArray($styleArray); } } } break; case 'CELL': for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) { for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) { $oldXfIndexes[$this->getActiveSheet()->getCell([$col, $row])->getXfIndex()] = true; } } break; } return $oldXfIndexes; } /** * Get Fill. * * @return Fill */ public function getFill() { return $this->fill; } /** * Get Font. * * @return Font */ public function getFont() { return $this->font; } /** * Set font. * * @return $this */ public function setFont(Font $font) { $this->font = $font; return $this; } /** * Get Borders. * * @return Borders */ public function getBorders() { return $this->borders; } /** * Get Alignment. * * @return Alignment */ public function getAlignment() { return $this->alignment; } /** * Get Number Format. * * @return NumberFormat */ public function getNumberFormat() { return $this->numberFormat; } /** * Get Conditional Styles. Only used on supervisor. * * @return Conditional[] */ public function getConditionalStyles() { return $this->getActiveSheet()->getConditionalStyles($this->getActiveCell()); } /** * Set Conditional Styles. Only used on supervisor. * * @param Conditional[] $conditionalStyleArray Array of conditional styles * * @return $this */ public function setConditionalStyles(array $conditionalStyleArray) { $this->getActiveSheet()->setConditionalStyles($this->getSelectedCells(), $conditionalStyleArray); return $this; } /** * Get Protection. * * @return Protection */ public function getProtection() { return $this->protection; } /** * Get quote prefix. * * @return bool */ public function getQuotePrefix() { if ($this->isSupervisor) { return $this->getSharedComponent()->getQuotePrefix(); } return $this->quotePrefix; } /** * Set quote prefix. * * @param bool $quotePrefix * * @return $this */ public function setQuotePrefix($quotePrefix) { if ($quotePrefix == '') { $quotePrefix = false; } if ($this->isSupervisor) { $styleArray = ['quotePrefix' => $quotePrefix]; $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); } else { $this->quotePrefix = (bool) $quotePrefix; } return $this; } /** * Get hash code. * * @return string Hash code */ public function getHashCode() { return md5( $this->fill->getHashCode() . $this->font->getHashCode() . $this->borders->getHashCode() . $this->alignment->getHashCode() . $this->numberFormat->getHashCode() . $this->protection->getHashCode() . ($this->quotePrefix ? 't' : 'f') . __CLASS__ ); } /** * Get own index in style collection. * * @return int */ public function getIndex() { return $this->index; } /** * Set own index in style collection. * * @param int $index */ public function setIndex($index): void { $this->index = $index; } protected function exportArray1(): array { $exportedArray = []; $this->exportArray2($exportedArray, 'alignment', $this->getAlignment()); $this->exportArray2($exportedArray, 'borders', $this->getBorders()); $this->exportArray2($exportedArray, 'fill', $this->getFill()); $this->exportArray2($exportedArray, 'font', $this->getFont()); $this->exportArray2($exportedArray, 'numberFormat', $this->getNumberFormat()); $this->exportArray2($exportedArray, 'protection', $this->getProtection()); $this->exportArray2($exportedArray, 'quotePrefx', $this->getQuotePrefix()); return $exportedArray; } } phpspreadsheet/src/PhpSpreadsheet/Style/Supervisor.php 0000644 00000010615 15060132323 0017261 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Style; use PhpOffice\PhpSpreadsheet\IComparable; use PhpOffice\PhpSpreadsheet\Spreadsheet; use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; abstract class Supervisor implements IComparable { /** * Supervisor? * * @var bool */ protected $isSupervisor; /** * Parent. Only used for supervisor. * * @var Spreadsheet|Supervisor */ protected $parent; /** * Parent property name. * * @var null|string */ protected $parentPropertyName; /** * Create a new Supervisor. * * @param bool $isSupervisor Flag indicating if this is a supervisor or not * Leave this value at default unless you understand exactly what * its ramifications are */ public function __construct($isSupervisor = false) { // Supervisor? $this->isSupervisor = $isSupervisor; } /** * Bind parent. Only used for supervisor. * * @param Spreadsheet|Supervisor $parent * @param null|string $parentPropertyName * * @return $this */ public function bindParent($parent, $parentPropertyName = null) { $this->parent = $parent; $this->parentPropertyName = $parentPropertyName; return $this; } /** * Is this a supervisor or a cell style component? * * @return bool */ public function getIsSupervisor() { return $this->isSupervisor; } /** * Get the currently active sheet. Only used for supervisor. * * @return Worksheet */ public function getActiveSheet() { return $this->parent->getActiveSheet(); } /** * Get the currently active cell coordinate in currently active sheet. * Only used for supervisor. * * @return string E.g. 'A1' */ public function getSelectedCells() { return $this->getActiveSheet()->getSelectedCells(); } /** * Get the currently active cell coordinate in currently active sheet. * Only used for supervisor. * * @return string E.g. 'A1' */ public function getActiveCell() { return $this->getActiveSheet()->getActiveCell(); } /** * 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)) && ($key != 'parent')) { $this->$key = clone $value; } else { $this->$key = $value; } } } /** * Export style as array. * * Available to anything which extends this class: * Alignment, Border, Borders, Color, Fill, Font, * NumberFormat, Protection, and Style. */ final public function exportArray(): array { return $this->exportArray1(); } /** * Abstract method to be implemented in anything which * extends this class. * * This method invokes exportArray2 with the names and values * of all properties to be included in output array, * returning that array to exportArray, then to caller. */ abstract protected function exportArray1(): array; /** * Populate array from exportArray1. * This method is available to anything which extends this class. * The parameter index is the key to be added to the array. * The parameter objOrValue is either a primitive type, * which is the value added to the array, * or a Style object to be recursively added via exportArray. * * @param mixed $objOrValue */ final protected function exportArray2(array &$exportedArray, string $index, $objOrValue): void { if ($objOrValue instanceof self) { $exportedArray[$index] = $objOrValue->exportArray(); } else { $exportedArray[$index] = $objOrValue; } } /** * Get the shared style component for the currently active cell in currently active sheet. * Only used for style supervisor. * * @return mixed */ abstract public function getSharedComponent(); /** * Build style array from subcomponents. * * @param array $array * * @return array */ abstract public function getStyleArray($array); } phpspreadsheet/src/PhpSpreadsheet/Style/Color.php 0000644 00000033245 15060132323 0016162 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Style; class Color extends Supervisor { const NAMED_COLORS = [ 'Black', 'White', 'Red', 'Green', 'Blue', 'Yellow', 'Magenta', 'Cyan', ]; // Colors const COLOR_BLACK = 'FF000000'; const COLOR_WHITE = 'FFFFFFFF'; const COLOR_RED = 'FFFF0000'; const COLOR_DARKRED = 'FF800000'; const COLOR_BLUE = 'FF0000FF'; const COLOR_DARKBLUE = 'FF000080'; const COLOR_GREEN = 'FF00FF00'; const COLOR_DARKGREEN = 'FF008000'; const COLOR_YELLOW = 'FFFFFF00'; const COLOR_DARKYELLOW = 'FF808000'; const COLOR_MAGENTA = 'FFFF00FF'; const COLOR_CYAN = 'FF00FFFF'; const NAMED_COLOR_TRANSLATIONS = [ 'Black' => self::COLOR_BLACK, 'White' => self::COLOR_WHITE, 'Red' => self::COLOR_RED, 'Green' => self::COLOR_GREEN, 'Blue' => self::COLOR_BLUE, 'Yellow' => self::COLOR_YELLOW, 'Magenta' => self::COLOR_MAGENTA, 'Cyan' => self::COLOR_CYAN, ]; const VALIDATE_ARGB_SIZE = 8; const VALIDATE_RGB_SIZE = 6; const VALIDATE_COLOR_6 = '/^[A-F0-9]{6}$/i'; const VALIDATE_COLOR_8 = '/^[A-F0-9]{8}$/i'; private const INDEXED_COLORS = [ 1 => 'FF000000', // System Colour #1 - Black 2 => 'FFFFFFFF', // System Colour #2 - White 3 => 'FFFF0000', // System Colour #3 - Red 4 => 'FF00FF00', // System Colour #4 - Green 5 => 'FF0000FF', // System Colour #5 - Blue 6 => 'FFFFFF00', // System Colour #6 - Yellow 7 => 'FFFF00FF', // System Colour #7- Magenta 8 => 'FF00FFFF', // System Colour #8- Cyan 9 => 'FF800000', // Standard Colour #9 10 => 'FF008000', // Standard Colour #10 11 => 'FF000080', // Standard Colour #11 12 => 'FF808000', // Standard Colour #12 13 => 'FF800080', // Standard Colour #13 14 => 'FF008080', // Standard Colour #14 15 => 'FFC0C0C0', // Standard Colour #15 16 => 'FF808080', // Standard Colour #16 17 => 'FF9999FF', // Chart Fill Colour #17 18 => 'FF993366', // Chart Fill Colour #18 19 => 'FFFFFFCC', // Chart Fill Colour #19 20 => 'FFCCFFFF', // Chart Fill Colour #20 21 => 'FF660066', // Chart Fill Colour #21 22 => 'FFFF8080', // Chart Fill Colour #22 23 => 'FF0066CC', // Chart Fill Colour #23 24 => 'FFCCCCFF', // Chart Fill Colour #24 25 => 'FF000080', // Chart Line Colour #25 26 => 'FFFF00FF', // Chart Line Colour #26 27 => 'FFFFFF00', // Chart Line Colour #27 28 => 'FF00FFFF', // Chart Line Colour #28 29 => 'FF800080', // Chart Line Colour #29 30 => 'FF800000', // Chart Line Colour #30 31 => 'FF008080', // Chart Line Colour #31 32 => 'FF0000FF', // Chart Line Colour #32 33 => 'FF00CCFF', // Standard Colour #33 34 => 'FFCCFFFF', // Standard Colour #34 35 => 'FFCCFFCC', // Standard Colour #35 36 => 'FFFFFF99', // Standard Colour #36 37 => 'FF99CCFF', // Standard Colour #37 38 => 'FFFF99CC', // Standard Colour #38 39 => 'FFCC99FF', // Standard Colour #39 40 => 'FFFFCC99', // Standard Colour #40 41 => 'FF3366FF', // Standard Colour #41 42 => 'FF33CCCC', // Standard Colour #42 43 => 'FF99CC00', // Standard Colour #43 44 => 'FFFFCC00', // Standard Colour #44 45 => 'FFFF9900', // Standard Colour #45 46 => 'FFFF6600', // Standard Colour #46 47 => 'FF666699', // Standard Colour #47 48 => 'FF969696', // Standard Colour #48 49 => 'FF003366', // Standard Colour #49 50 => 'FF339966', // Standard Colour #50 51 => 'FF003300', // Standard Colour #51 52 => 'FF333300', // Standard Colour #52 53 => 'FF993300', // Standard Colour #53 54 => 'FF993366', // Standard Colour #54 55 => 'FF333399', // Standard Colour #55 56 => 'FF333333', // Standard Colour #56 ]; /** * ARGB - Alpha RGB. * * @var null|string */ protected $argb; /** @var bool */ private $hasChanged = false; /** * Create a new Color. * * @param string $colorValue ARGB value for the colour, or named colour * @param bool $isSupervisor Flag indicating if this is a supervisor or not * Leave this value at default unless you understand exactly what * its ramifications are * @param bool $isConditional Flag indicating if this is a conditional style or not * Leave this value at default unless you understand exactly what * its ramifications are */ public function __construct($colorValue = self::COLOR_BLACK, $isSupervisor = false, $isConditional = false) { // Supervisor? parent::__construct($isSupervisor); // Initialise values if (!$isConditional) { $this->argb = $this->validateColor($colorValue) ?: self::COLOR_BLACK; } } /** * Get the shared style component for the currently active cell in currently active sheet. * Only used for style supervisor. * * @return Color */ public function getSharedComponent() { /** @var Style */ $parent = $this->parent; /** @var Border|Fill $sharedComponent */ $sharedComponent = $parent->getSharedComponent(); if ($sharedComponent instanceof Fill) { if ($this->parentPropertyName === 'endColor') { return $sharedComponent->getEndColor(); } return $sharedComponent->getStartColor(); } return $sharedComponent->getColor(); } /** * Build style array from subcomponents. * * @param array $array * * @return array */ public function getStyleArray($array) { /** @var Style */ $parent = $this->parent; return $parent->/** @scrutinizer ignore-call */ getStyleArray([$this->parentPropertyName => $array]); } /** * Apply styles from array. * * <code> * $spreadsheet->getActiveSheet()->getStyle('B2')->getFont()->getColor()->applyFromArray(['rgb' => '808080']); * </code> * * @param array $styleArray Array containing style information * * @return $this */ public function applyFromArray(array $styleArray) { if ($this->isSupervisor) { $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($styleArray)); } else { if (isset($styleArray['rgb'])) { $this->setRGB($styleArray['rgb']); } if (isset($styleArray['argb'])) { $this->setARGB($styleArray['argb']); } } return $this; } private function validateColor(?string $colorValue): string { if ($colorValue === null || $colorValue === '') { return self::COLOR_BLACK; } $named = ucfirst(strtolower($colorValue)); if (array_key_exists($named, self::NAMED_COLOR_TRANSLATIONS)) { return self::NAMED_COLOR_TRANSLATIONS[$named]; } if (preg_match(self::VALIDATE_COLOR_8, $colorValue) === 1) { return $colorValue; } if (preg_match(self::VALIDATE_COLOR_6, $colorValue) === 1) { return 'FF' . $colorValue; } return ''; } /** * Get ARGB. */ public function getARGB(): ?string { if ($this->isSupervisor) { return $this->getSharedComponent()->getARGB(); } return $this->argb; } /** * Set ARGB. * * @param string $colorValue ARGB value, or a named color * * @return $this */ public function setARGB(?string $colorValue = self::COLOR_BLACK) { $this->hasChanged = true; $colorValue = $this->validateColor($colorValue); if ($colorValue === '') { return $this; } if ($this->isSupervisor) { $styleArray = $this->getStyleArray(['argb' => $colorValue]); $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); } else { $this->argb = $colorValue; } return $this; } /** * Get RGB. */ public function getRGB(): string { if ($this->isSupervisor) { return $this->getSharedComponent()->getRGB(); } return substr($this->argb ?? '', 2); } /** * Set RGB. * * @param string $colorValue RGB value, or a named color * * @return $this */ public function setRGB(?string $colorValue = self::COLOR_BLACK) { return $this->setARGB($colorValue); } /** * Get a specified colour component of an RGB value. * * @param string $rgbValue The colour as an RGB value (e.g. FF00CCCC or CCDDEE * @param int $offset Position within the RGB value to extract * @param bool $hex Flag indicating whether the component should be returned as a hex or a * decimal value * * @return int|string The extracted colour component */ private static function getColourComponent($rgbValue, $offset, $hex = true) { $colour = substr($rgbValue, $offset, 2) ?: ''; if (preg_match('/^[0-9a-f]{2}$/i', $colour) !== 1) { $colour = '00'; } return ($hex) ? $colour : (int) hexdec($colour); } /** * Get the red colour component of an RGB value. * * @param string $rgbValue The colour as an RGB value (e.g. FF00CCCC or CCDDEE * @param bool $hex Flag indicating whether the component should be returned as a hex or a * decimal value * * @return int|string The red colour component */ public static function getRed($rgbValue, $hex = true) { return self::getColourComponent($rgbValue, strlen($rgbValue) - 6, $hex); } /** * Get the green colour component of an RGB value. * * @param string $rgbValue The colour as an RGB value (e.g. FF00CCCC or CCDDEE * @param bool $hex Flag indicating whether the component should be returned as a hex or a * decimal value * * @return int|string The green colour component */ public static function getGreen($rgbValue, $hex = true) { return self::getColourComponent($rgbValue, strlen($rgbValue) - 4, $hex); } /** * Get the blue colour component of an RGB value. * * @param string $rgbValue The colour as an RGB value (e.g. FF00CCCC or CCDDEE * @param bool $hex Flag indicating whether the component should be returned as a hex or a * decimal value * * @return int|string The blue colour component */ public static function getBlue($rgbValue, $hex = true) { return self::getColourComponent($rgbValue, strlen($rgbValue) - 2, $hex); } /** * Adjust the brightness of a color. * * @param string $hexColourValue The colour as an RGBA or RGB value (e.g. FF00CCCC or CCDDEE) * @param float $adjustPercentage The percentage by which to adjust the colour as a float from -1 to 1 * * @return string The adjusted colour as an RGBA or RGB value (e.g. FF00CCCC or CCDDEE) */ public static function changeBrightness($hexColourValue, $adjustPercentage) { $rgba = (strlen($hexColourValue) === 8); $adjustPercentage = max(-1.0, min(1.0, $adjustPercentage)); /** @var int $red */ $red = self::getRed($hexColourValue, false); /** @var int $green */ $green = self::getGreen($hexColourValue, false); /** @var int $blue */ $blue = self::getBlue($hexColourValue, false); return (($rgba) ? 'FF' : '') . RgbTint::rgbAndTintToRgb($red, $green, $blue, $adjustPercentage); } /** * Get indexed color. * * @param int $colorIndex Index entry point into the colour array * @param bool $background Flag to indicate whether default background or foreground colour * should be returned if the indexed colour doesn't exist */ public static function indexedColor($colorIndex, $background = false, ?array $palette = null): self { // Clean parameter $colorIndex = (int) $colorIndex; if (empty($palette)) { if (isset(self::INDEXED_COLORS[$colorIndex])) { return new self(self::INDEXED_COLORS[$colorIndex]); } } else { if (isset($palette[$colorIndex])) { return new self($palette[$colorIndex]); } } return ($background) ? new self(self::COLOR_WHITE) : new self(self::COLOR_BLACK); } /** * Get hash code. * * @return string Hash code */ public function getHashCode(): string { if ($this->isSupervisor) { return $this->getSharedComponent()->getHashCode(); } return md5( $this->argb . __CLASS__ ); } protected function exportArray1(): array { $exportedArray = []; $this->exportArray2($exportedArray, 'argb', $this->getARGB()); return $exportedArray; } public function getHasChanged(): bool { if ($this->isSupervisor) { return $this->getSharedComponent()->hasChanged; } return $this->hasChanged; } } phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/Wizard/Expression.php 0000644 00000004367 15060132323 0025004 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\Wizard; use PhpOffice\PhpSpreadsheet\Exception; use PhpOffice\PhpSpreadsheet\Style\Conditional; use PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\Wizard; /** * @method Expression formula(string $expression) */ class Expression extends WizardAbstract implements WizardInterface { /** * @var string */ protected $expression; public function __construct(string $cellRange) { parent::__construct($cellRange); } public function expression(string $expression): self { $expression = $this->validateOperand($expression, Wizard::VALUE_TYPE_FORMULA); $this->expression = $expression; return $this; } public function getConditional(): Conditional { $expression = $this->adjustConditionsForCellReferences([$this->expression]); $conditional = new Conditional(); $conditional->setConditionType(Conditional::CONDITION_EXPRESSION); $conditional->setConditions($expression); $conditional->setStyle($this->getStyle()); $conditional->setStopIfTrue($this->getStopIfTrue()); return $conditional; } public static function fromConditional(Conditional $conditional, string $cellRange = 'A1'): WizardInterface { if ($conditional->getConditionType() !== Conditional::CONDITION_EXPRESSION) { throw new Exception('Conditional is not an Expression CF Rule conditional'); } $wizard = new self($cellRange); $wizard->style = $conditional->getStyle(); $wizard->stopIfTrue = $conditional->getStopIfTrue(); $wizard->expression = self::reverseAdjustCellRef((string) ($conditional->getConditions()[0]), $cellRange); return $wizard; } /** * @param string $methodName * @param mixed[] $arguments */ public function __call($methodName, $arguments): self { if ($methodName !== 'formula') { throw new Exception('Invalid Operation for Expression CF Rule Wizard'); } // Scrutinizer ignores its own recommendation //$this->expression(/** @scrutinizer ignore-type */ ...$arguments); $this->expression($arguments[0]); return $this; } } phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/Wizard/Errors.php 0000644 00000005253 15060132323 0024114 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\Wizard; use PhpOffice\PhpSpreadsheet\Exception; use PhpOffice\PhpSpreadsheet\Style\Conditional; use PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\Wizard; /** * @method Errors notError() * @method Errors isError() */ class Errors extends WizardAbstract implements WizardInterface { protected const OPERATORS = [ 'notError' => false, 'isError' => true, ]; protected const EXPRESSIONS = [ Wizard::NOT_ERRORS => 'NOT(ISERROR(%s))', Wizard::ERRORS => 'ISERROR(%s)', ]; /** * @var bool */ protected $inverse; public function __construct(string $cellRange, bool $inverse = false) { parent::__construct($cellRange); $this->inverse = $inverse; } protected function inverse(bool $inverse): void { $this->inverse = $inverse; } protected function getExpression(): void { $this->expression = sprintf( self::EXPRESSIONS[$this->inverse ? Wizard::ERRORS : Wizard::NOT_ERRORS], $this->referenceCell ); } public function getConditional(): Conditional { $this->getExpression(); $conditional = new Conditional(); $conditional->setConditionType( $this->inverse ? Conditional::CONDITION_CONTAINSERRORS : Conditional::CONDITION_NOTCONTAINSERRORS ); $conditional->setConditions([$this->expression]); $conditional->setStyle($this->getStyle()); $conditional->setStopIfTrue($this->getStopIfTrue()); return $conditional; } public static function fromConditional(Conditional $conditional, string $cellRange = 'A1'): WizardInterface { if ( $conditional->getConditionType() !== Conditional::CONDITION_CONTAINSERRORS && $conditional->getConditionType() !== Conditional::CONDITION_NOTCONTAINSERRORS ) { throw new Exception('Conditional is not an Errors CF Rule conditional'); } $wizard = new self($cellRange); $wizard->style = $conditional->getStyle(); $wizard->stopIfTrue = $conditional->getStopIfTrue(); $wizard->inverse = $conditional->getConditionType() === Conditional::CONDITION_CONTAINSERRORS; return $wizard; } /** * @param string $methodName * @param mixed[] $arguments */ public function __call($methodName, $arguments): self { if (!array_key_exists($methodName, self::OPERATORS)) { throw new Exception('Invalid Operation for Errors CF Rule Wizard'); } $this->inverse(self::OPERATORS[$methodName]); return $this; } } phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/Wizard/WizardAbstract.php 0000644 00000013344 15060132323 0025564 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\Wizard; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Cell\Coordinate; use PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\Wizard; use PhpOffice\PhpSpreadsheet\Style\Style; abstract class WizardAbstract { /** * @var ?Style */ protected $style; /** * @var string */ protected $expression; /** * @var string */ protected $cellRange; /** * @var string */ protected $referenceCell; /** * @var int */ protected $referenceRow; /** * @var bool */ protected $stopIfTrue = false; /** * @var int */ protected $referenceColumn; public function __construct(string $cellRange) { $this->setCellRange($cellRange); } public function getCellRange(): string { return $this->cellRange; } public function setCellRange(string $cellRange): void { $this->cellRange = $cellRange; $this->setReferenceCellForExpressions($cellRange); } protected function setReferenceCellForExpressions(string $conditionalRange): void { $conditionalRange = Coordinate::splitRange(str_replace('$', '', strtoupper($conditionalRange))); [$this->referenceCell] = $conditionalRange[0]; [$this->referenceColumn, $this->referenceRow] = Coordinate::indexesFromString($this->referenceCell); } public function getStopIfTrue(): bool { return $this->stopIfTrue; } public function setStopIfTrue(bool $stopIfTrue): void { $this->stopIfTrue = $stopIfTrue; } public function getStyle(): Style { return $this->style ?? new Style(false, true); } public function setStyle(Style $style): void { $this->style = $style; } protected function validateOperand(string $operand, string $operandValueType = Wizard::VALUE_TYPE_LITERAL): string { if ( $operandValueType === Wizard::VALUE_TYPE_LITERAL && substr($operand, 0, 1) === '"' && substr($operand, -1) === '"' ) { $operand = str_replace('""', '"', substr($operand, 1, -1)); } elseif ($operandValueType === Wizard::VALUE_TYPE_FORMULA && substr($operand, 0, 1) === '=') { $operand = substr($operand, 1); } return $operand; } protected static function reverseCellAdjustment(array $matches, int $referenceColumn, int $referenceRow): string { $worksheet = $matches[1]; $column = $matches[6]; $row = $matches[7]; if (strpos($column, '$') === false) { $column = Coordinate::columnIndexFromString($column); $column -= $referenceColumn - 1; $column = Coordinate::stringFromColumnIndex($column); } if (strpos($row, '$') === false) { $row -= $referenceRow - 1; } return "{$worksheet}{$column}{$row}"; } public static function reverseAdjustCellRef(string $condition, string $cellRange): string { $conditionalRange = Coordinate::splitRange(str_replace('$', '', strtoupper($cellRange))); [$referenceCell] = $conditionalRange[0]; [$referenceColumnIndex, $referenceRow] = Coordinate::indexesFromString($referenceCell); $splitCondition = explode(Calculation::FORMULA_STRING_QUOTE, $condition); $i = false; foreach ($splitCondition as &$value) { // Only count/replace in alternating array entries (ie. not in quoted strings) $i = $i === false; if ($i) { $value = (string) preg_replace_callback( '/' . Calculation::CALCULATION_REGEXP_CELLREF_RELATIVE . '/i', function ($matches) use ($referenceColumnIndex, $referenceRow) { return self::reverseCellAdjustment($matches, $referenceColumnIndex, $referenceRow); }, $value ); } } unset($value); // Then rebuild the condition string to return it return implode(Calculation::FORMULA_STRING_QUOTE, $splitCondition); } protected function conditionCellAdjustment(array $matches): string { $worksheet = $matches[1]; $column = $matches[6]; $row = $matches[7]; if (strpos($column, '$') === false) { $column = Coordinate::columnIndexFromString($column); $column += $this->referenceColumn - 1; $column = Coordinate::stringFromColumnIndex($column); } if (strpos($row, '$') === false) { $row += $this->referenceRow - 1; } return "{$worksheet}{$column}{$row}"; } protected function cellConditionCheck(string $condition): string { $splitCondition = explode(Calculation::FORMULA_STRING_QUOTE, $condition); $i = false; foreach ($splitCondition as &$value) { // Only count/replace in alternating array entries (ie. not in quoted strings) $i = $i === false; if ($i) { $value = (string) preg_replace_callback( '/' . Calculation::CALCULATION_REGEXP_CELLREF_RELATIVE . '/i', [$this, 'conditionCellAdjustment'], $value ); } } unset($value); // Then rebuild the condition string to return it return implode(Calculation::FORMULA_STRING_QUOTE, $splitCondition); } protected function adjustConditionsForCellReferences(array $conditions): array { return array_map( [$this, 'cellConditionCheck'], $conditions ); } } phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/Wizard/Blanks.php 0000644 00000005434 15060132323 0024053 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\Wizard; use PhpOffice\PhpSpreadsheet\Exception; use PhpOffice\PhpSpreadsheet\Style\Conditional; use PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\Wizard; /** * @method Blanks notBlank() * @method Blanks notEmpty() * @method Blanks isBlank() * @method Blanks isEmpty() */ class Blanks extends WizardAbstract implements WizardInterface { protected const OPERATORS = [ 'notBlank' => false, 'isBlank' => true, 'notEmpty' => false, 'empty' => true, ]; protected const EXPRESSIONS = [ Wizard::NOT_BLANKS => 'LEN(TRIM(%s))>0', Wizard::BLANKS => 'LEN(TRIM(%s))=0', ]; /** * @var bool */ protected $inverse; public function __construct(string $cellRange, bool $inverse = false) { parent::__construct($cellRange); $this->inverse = $inverse; } protected function inverse(bool $inverse): void { $this->inverse = $inverse; } protected function getExpression(): void { $this->expression = sprintf( self::EXPRESSIONS[$this->inverse ? Wizard::BLANKS : Wizard::NOT_BLANKS], $this->referenceCell ); } public function getConditional(): Conditional { $this->getExpression(); $conditional = new Conditional(); $conditional->setConditionType( $this->inverse ? Conditional::CONDITION_CONTAINSBLANKS : Conditional::CONDITION_NOTCONTAINSBLANKS ); $conditional->setConditions([$this->expression]); $conditional->setStyle($this->getStyle()); $conditional->setStopIfTrue($this->getStopIfTrue()); return $conditional; } public static function fromConditional(Conditional $conditional, string $cellRange = 'A1'): WizardInterface { if ( $conditional->getConditionType() !== Conditional::CONDITION_CONTAINSBLANKS && $conditional->getConditionType() !== Conditional::CONDITION_NOTCONTAINSBLANKS ) { throw new Exception('Conditional is not a Blanks CF Rule conditional'); } $wizard = new self($cellRange); $wizard->style = $conditional->getStyle(); $wizard->stopIfTrue = $conditional->getStopIfTrue(); $wizard->inverse = $conditional->getConditionType() === Conditional::CONDITION_CONTAINSBLANKS; return $wizard; } /** * @param string $methodName * @param mixed[] $arguments */ public function __call($methodName, $arguments): self { if (!array_key_exists($methodName, self::OPERATORS)) { throw new Exception('Invalid Operation for Blanks CF Rule Wizard'); } $this->inverse(self::OPERATORS[$methodName]); return $this; } } phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/Wizard/TextValue.php 0000644 00000014176 15060132323 0024565 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\Wizard; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Exception; use PhpOffice\PhpSpreadsheet\Style\Conditional; use PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\Wizard; /** * @method TextValue contains(string $value, string $operandValueType = Wizard::VALUE_TYPE_LITERAL) * @method TextValue doesNotContain(string $value, string $operandValueType = Wizard::VALUE_TYPE_LITERAL) * @method TextValue doesntContain(string $value, string $operandValueType = Wizard::VALUE_TYPE_LITERAL) * @method TextValue beginsWith(string $value, string $operandValueType = Wizard::VALUE_TYPE_LITERAL) * @method TextValue startsWith(string $value, string $operandValueType = Wizard::VALUE_TYPE_LITERAL) * @method TextValue endsWith(string $value, string $operandValueType = Wizard::VALUE_TYPE_LITERAL) */ class TextValue extends WizardAbstract implements WizardInterface { protected const MAGIC_OPERATIONS = [ 'contains' => Conditional::OPERATOR_CONTAINSTEXT, 'doesntContain' => Conditional::OPERATOR_NOTCONTAINS, 'doesNotContain' => Conditional::OPERATOR_NOTCONTAINS, 'beginsWith' => Conditional::OPERATOR_BEGINSWITH, 'startsWith' => Conditional::OPERATOR_BEGINSWITH, 'endsWith' => Conditional::OPERATOR_ENDSWITH, ]; protected const OPERATORS = [ Conditional::OPERATOR_CONTAINSTEXT => Conditional::CONDITION_CONTAINSTEXT, Conditional::OPERATOR_NOTCONTAINS => Conditional::CONDITION_NOTCONTAINSTEXT, Conditional::OPERATOR_BEGINSWITH => Conditional::CONDITION_BEGINSWITH, Conditional::OPERATOR_ENDSWITH => Conditional::CONDITION_ENDSWITH, ]; protected const EXPRESSIONS = [ Conditional::OPERATOR_CONTAINSTEXT => 'NOT(ISERROR(SEARCH(%s,%s)))', Conditional::OPERATOR_NOTCONTAINS => 'ISERROR(SEARCH(%s,%s))', Conditional::OPERATOR_BEGINSWITH => 'LEFT(%s,LEN(%s))=%s', Conditional::OPERATOR_ENDSWITH => 'RIGHT(%s,LEN(%s))=%s', ]; /** @var string */ protected $operator; /** @var string */ protected $operand; /** * @var string */ protected $operandValueType; public function __construct(string $cellRange) { parent::__construct($cellRange); } protected function operator(string $operator): void { if (!isset(self::OPERATORS[$operator])) { throw new Exception('Invalid Operator for Text Value CF Rule Wizard'); } $this->operator = $operator; } protected function operand(string $operand, string $operandValueType = Wizard::VALUE_TYPE_LITERAL): void { $operand = $this->validateOperand($operand, $operandValueType); $this->operand = $operand; $this->operandValueType = $operandValueType; } protected function wrapValue(string $value): string { return '"' . $value . '"'; } protected function setExpression(): void { $operand = $this->operandValueType === Wizard::VALUE_TYPE_LITERAL ? $this->wrapValue(str_replace('"', '""', $this->operand)) : $this->cellConditionCheck($this->operand); if ( $this->operator === Conditional::OPERATOR_CONTAINSTEXT || $this->operator === Conditional::OPERATOR_NOTCONTAINS ) { $this->expression = sprintf(self::EXPRESSIONS[$this->operator], $operand, $this->referenceCell); } else { $this->expression = sprintf(self::EXPRESSIONS[$this->operator], $this->referenceCell, $operand, $operand); } } public function getConditional(): Conditional { $this->setExpression(); $conditional = new Conditional(); $conditional->setConditionType(self::OPERATORS[$this->operator]); $conditional->setOperatorType($this->operator); $conditional->setText( $this->operandValueType !== Wizard::VALUE_TYPE_LITERAL ? $this->cellConditionCheck($this->operand) : $this->operand ); $conditional->setConditions([$this->expression]); $conditional->setStyle($this->getStyle()); $conditional->setStopIfTrue($this->getStopIfTrue()); return $conditional; } public static function fromConditional(Conditional $conditional, string $cellRange = 'A1'): WizardInterface { if (!in_array($conditional->getConditionType(), self::OPERATORS, true)) { throw new Exception('Conditional is not a Text Value CF Rule conditional'); } $wizard = new self($cellRange); $wizard->operator = (string) array_search($conditional->getConditionType(), self::OPERATORS, true); $wizard->style = $conditional->getStyle(); $wizard->stopIfTrue = $conditional->getStopIfTrue(); // Best-guess to try and identify if the text is a string literal, a cell reference or a formula? $wizard->operandValueType = Wizard::VALUE_TYPE_LITERAL; $condition = $conditional->getText(); if (preg_match('/^' . Calculation::CALCULATION_REGEXP_CELLREF_RELATIVE . '$/i', $condition)) { $wizard->operandValueType = Wizard::VALUE_TYPE_CELL; $condition = self::reverseAdjustCellRef($condition, $cellRange); } elseif ( preg_match('/\(\)/', $condition) || preg_match('/' . Calculation::CALCULATION_REGEXP_CELLREF_RELATIVE . '/i', $condition) ) { $wizard->operandValueType = Wizard::VALUE_TYPE_FORMULA; } $wizard->operand = $condition; return $wizard; } /** * @param string $methodName * @param mixed[] $arguments */ public function __call($methodName, $arguments): self { if (!isset(self::MAGIC_OPERATIONS[$methodName])) { throw new Exception('Invalid Operation for Text Value CF Rule Wizard'); } $this->operator(self::MAGIC_OPERATIONS[$methodName]); //$this->operand(...$arguments); if (count($arguments) < 2) { $this->operand($arguments[0]); } else { $this->operand($arguments[0], $arguments[1]); } return $this; } } phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/Wizard/Duplicates.php 0000644 00000004213 15060132323 0024730 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\Wizard; use PhpOffice\PhpSpreadsheet\Exception; use PhpOffice\PhpSpreadsheet\Style\Conditional; /** * @method Errors duplicates() * @method Errors unique() */ class Duplicates extends WizardAbstract implements WizardInterface { protected const OPERATORS = [ 'duplicates' => false, 'unique' => true, ]; /** * @var bool */ protected $inverse; public function __construct(string $cellRange, bool $inverse = false) { parent::__construct($cellRange); $this->inverse = $inverse; } protected function inverse(bool $inverse): void { $this->inverse = $inverse; } public function getConditional(): Conditional { $conditional = new Conditional(); $conditional->setConditionType( $this->inverse ? Conditional::CONDITION_UNIQUE : Conditional::CONDITION_DUPLICATES ); $conditional->setStyle($this->getStyle()); $conditional->setStopIfTrue($this->getStopIfTrue()); return $conditional; } public static function fromConditional(Conditional $conditional, string $cellRange = 'A1'): WizardInterface { if ( $conditional->getConditionType() !== Conditional::CONDITION_DUPLICATES && $conditional->getConditionType() !== Conditional::CONDITION_UNIQUE ) { throw new Exception('Conditional is not a Duplicates CF Rule conditional'); } $wizard = new self($cellRange); $wizard->style = $conditional->getStyle(); $wizard->stopIfTrue = $conditional->getStopIfTrue(); $wizard->inverse = $conditional->getConditionType() === Conditional::CONDITION_UNIQUE; return $wizard; } /** * @param string $methodName * @param mixed[] $arguments */ public function __call($methodName, $arguments): self { if (!array_key_exists($methodName, self::OPERATORS)) { throw new Exception('Invalid Operation for Errors CF Rule Wizard'); } $this->inverse(self::OPERATORS[$methodName]); return $this; } } phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/Wizard/WizardInterface.php 0000644 00000001216 15060132323 0025714 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\Wizard; use PhpOffice\PhpSpreadsheet\Style\Conditional; use PhpOffice\PhpSpreadsheet\Style\Style; interface WizardInterface { public function getCellRange(): string; public function setCellRange(string $cellRange): void; public function getStyle(): Style; public function setStyle(Style $style): void; public function getStopIfTrue(): bool; public function setStopIfTrue(bool $stopIfTrue): void; public function getConditional(): Conditional; public static function fromConditional(Conditional $conditional, string $cellRange = 'A1'): self; } phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/Wizard/CellValue.php 0000644 00000016655 15060132323 0024524 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\Wizard; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Exception; use PhpOffice\PhpSpreadsheet\Style\Conditional; use PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\CellMatcher; use PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\Wizard; /** * @method CellValue equals($value, string $operandValueType = Wizard::VALUE_TYPE_LITERAL) * @method CellValue notEquals($value, string $operandValueType = Wizard::VALUE_TYPE_LITERAL) * @method CellValue greaterThan($value, string $operandValueType = Wizard::VALUE_TYPE_LITERAL) * @method CellValue greaterThanOrEqual($value, string $operandValueType = Wizard::VALUE_TYPE_LITERAL) * @method CellValue lessThan($value, string $operandValueType = Wizard::VALUE_TYPE_LITERAL) * @method CellValue lessThanOrEqual($value, string $operandValueType = Wizard::VALUE_TYPE_LITERAL) * @method CellValue between($value, string $operandValueType = Wizard::VALUE_TYPE_LITERAL) * @method CellValue notBetween($value, string $operandValueType = Wizard::VALUE_TYPE_LITERAL) * @method CellValue and($value, string $operandValueType = Wizard::VALUE_TYPE_LITERAL) */ class CellValue extends WizardAbstract implements WizardInterface { protected const MAGIC_OPERATIONS = [ 'equals' => Conditional::OPERATOR_EQUAL, 'notEquals' => Conditional::OPERATOR_NOTEQUAL, 'greaterThan' => Conditional::OPERATOR_GREATERTHAN, 'greaterThanOrEqual' => Conditional::OPERATOR_GREATERTHANOREQUAL, 'lessThan' => Conditional::OPERATOR_LESSTHAN, 'lessThanOrEqual' => Conditional::OPERATOR_LESSTHANOREQUAL, 'between' => Conditional::OPERATOR_BETWEEN, 'notBetween' => Conditional::OPERATOR_NOTBETWEEN, ]; protected const SINGLE_OPERATORS = CellMatcher::COMPARISON_OPERATORS; protected const RANGE_OPERATORS = CellMatcher::COMPARISON_RANGE_OPERATORS; /** @var string */ protected $operator = Conditional::OPERATOR_EQUAL; /** @var array */ protected $operand = [0]; /** * @var string[] */ protected $operandValueType = []; public function __construct(string $cellRange) { parent::__construct($cellRange); } protected function operator(string $operator): void { if ((!isset(self::SINGLE_OPERATORS[$operator])) && (!isset(self::RANGE_OPERATORS[$operator]))) { throw new Exception('Invalid Operator for Cell Value CF Rule Wizard'); } $this->operator = $operator; } /** * @param mixed $operand */ protected function operand(int $index, $operand, string $operandValueType = Wizard::VALUE_TYPE_LITERAL): void { if (is_string($operand)) { $operand = $this->validateOperand($operand, $operandValueType); } $this->operand[$index] = $operand; $this->operandValueType[$index] = $operandValueType; } /** * @param mixed $value * * @return float|int|string */ protected function wrapValue($value, string $operandValueType) { if (!is_numeric($value) && !is_bool($value) && null !== $value) { if ($operandValueType === Wizard::VALUE_TYPE_LITERAL) { return '"' . str_replace('"', '""', $value) . '"'; } return $this->cellConditionCheck($value); } if (null === $value) { $value = 'NULL'; } elseif (is_bool($value)) { $value = $value ? 'TRUE' : 'FALSE'; } return $value; } public function getConditional(): Conditional { if (!isset(self::RANGE_OPERATORS[$this->operator])) { unset($this->operand[1], $this->operandValueType[1]); } $values = array_map([$this, 'wrapValue'], $this->operand, $this->operandValueType); $conditional = new Conditional(); $conditional->setConditionType(Conditional::CONDITION_CELLIS); $conditional->setOperatorType($this->operator); $conditional->setConditions($values); $conditional->setStyle($this->getStyle()); $conditional->setStopIfTrue($this->getStopIfTrue()); return $conditional; } protected static function unwrapString(string $condition): string { if ((strpos($condition, '"') === 0) && (strpos(strrev($condition), '"') === 0)) { $condition = substr($condition, 1, -1); } return str_replace('""', '"', $condition); } public static function fromConditional(Conditional $conditional, string $cellRange = 'A1'): WizardInterface { if ($conditional->getConditionType() !== Conditional::CONDITION_CELLIS) { throw new Exception('Conditional is not a Cell Value CF Rule conditional'); } $wizard = new self($cellRange); $wizard->style = $conditional->getStyle(); $wizard->stopIfTrue = $conditional->getStopIfTrue(); $wizard->operator = $conditional->getOperatorType(); $conditions = $conditional->getConditions(); foreach ($conditions as $index => $condition) { // Best-guess to try and identify if the text is a string literal, a cell reference or a formula? $operandValueType = Wizard::VALUE_TYPE_LITERAL; if (is_string($condition)) { if (Calculation::keyInExcelConstants($condition)) { $condition = Calculation::getExcelConstants($condition); } elseif (preg_match('/^' . Calculation::CALCULATION_REGEXP_CELLREF_RELATIVE . '$/i', $condition)) { $operandValueType = Wizard::VALUE_TYPE_CELL; $condition = self::reverseAdjustCellRef($condition, $cellRange); } elseif ( preg_match('/\(\)/', $condition) || preg_match('/' . Calculation::CALCULATION_REGEXP_CELLREF_RELATIVE . '/i', $condition) ) { $operandValueType = Wizard::VALUE_TYPE_FORMULA; $condition = self::reverseAdjustCellRef($condition, $cellRange); } else { $condition = self::unwrapString($condition); } } $wizard->operand($index, $condition, $operandValueType); } return $wizard; } /** * @param string $methodName * @param mixed[] $arguments */ public function __call($methodName, $arguments): self { if (!isset(self::MAGIC_OPERATIONS[$methodName]) && $methodName !== 'and') { throw new Exception('Invalid Operator for Cell Value CF Rule Wizard'); } if ($methodName === 'and') { if (!isset(self::RANGE_OPERATORS[$this->operator])) { throw new Exception('AND Value is only appropriate for range operators'); } // Scrutinizer ignores its own suggested workaround. //$this->operand(1, /** @scrutinizer ignore-type */ ...$arguments); if (count($arguments) < 2) { $this->operand(1, $arguments[0]); } else { $this->operand(1, $arguments[0], $arguments[1]); } return $this; } $this->operator(self::MAGIC_OPERATIONS[$methodName]); //$this->operand(0, ...$arguments); if (count($arguments) < 2) { $this->operand(0, $arguments[0]); } else { $this->operand(0, $arguments[0], $arguments[1]); } return $this; } } phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/Wizard/DateValue.php 0000644 00000010361 15060132323 0024506 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\Wizard; use PhpOffice\PhpSpreadsheet\Exception; use PhpOffice\PhpSpreadsheet\Style\Conditional; /** * @method DateValue yesterday() * @method DateValue today() * @method DateValue tomorrow() * @method DateValue lastSevenDays() * @method DateValue lastWeek() * @method DateValue thisWeek() * @method DateValue nextWeek() * @method DateValue lastMonth() * @method DateValue thisMonth() * @method DateValue nextMonth() */ class DateValue extends WizardAbstract implements WizardInterface { protected const MAGIC_OPERATIONS = [ 'yesterday' => Conditional::TIMEPERIOD_YESTERDAY, 'today' => Conditional::TIMEPERIOD_TODAY, 'tomorrow' => Conditional::TIMEPERIOD_TOMORROW, 'lastSevenDays' => Conditional::TIMEPERIOD_LAST_7_DAYS, 'last7Days' => Conditional::TIMEPERIOD_LAST_7_DAYS, 'lastWeek' => Conditional::TIMEPERIOD_LAST_WEEK, 'thisWeek' => Conditional::TIMEPERIOD_THIS_WEEK, 'nextWeek' => Conditional::TIMEPERIOD_NEXT_WEEK, 'lastMonth' => Conditional::TIMEPERIOD_LAST_MONTH, 'thisMonth' => Conditional::TIMEPERIOD_THIS_MONTH, 'nextMonth' => Conditional::TIMEPERIOD_NEXT_MONTH, ]; protected const EXPRESSIONS = [ Conditional::TIMEPERIOD_YESTERDAY => 'FLOOR(%s,1)=TODAY()-1', Conditional::TIMEPERIOD_TODAY => 'FLOOR(%s,1)=TODAY()', Conditional::TIMEPERIOD_TOMORROW => 'FLOOR(%s,1)=TODAY()+1', Conditional::TIMEPERIOD_LAST_7_DAYS => 'AND(TODAY()-FLOOR(%s,1)<=6,FLOOR(%s,1)<=TODAY())', Conditional::TIMEPERIOD_LAST_WEEK => 'AND(TODAY()-ROUNDDOWN(%s,0)>=(WEEKDAY(TODAY())),TODAY()-ROUNDDOWN(%s,0)<(WEEKDAY(TODAY())+7))', Conditional::TIMEPERIOD_THIS_WEEK => 'AND(TODAY()-ROUNDDOWN(%s,0)<=WEEKDAY(TODAY())-1,ROUNDDOWN(%s,0)-TODAY()<=7-WEEKDAY(TODAY()))', Conditional::TIMEPERIOD_NEXT_WEEK => 'AND(ROUNDDOWN(%s,0)-TODAY()>(7-WEEKDAY(TODAY())),ROUNDDOWN(%s,0)-TODAY()<(15-WEEKDAY(TODAY())))', Conditional::TIMEPERIOD_LAST_MONTH => 'AND(MONTH(%s)=MONTH(EDATE(TODAY(),0-1)),YEAR(%s)=YEAR(EDATE(TODAY(),0-1)))', Conditional::TIMEPERIOD_THIS_MONTH => 'AND(MONTH(%s)=MONTH(TODAY()),YEAR(%s)=YEAR(TODAY()))', Conditional::TIMEPERIOD_NEXT_MONTH => 'AND(MONTH(%s)=MONTH(EDATE(TODAY(),0+1)),YEAR(%s)=YEAR(EDATE(TODAY(),0+1)))', ]; /** @var string */ protected $operator; public function __construct(string $cellRange) { parent::__construct($cellRange); } protected function operator(string $operator): void { $this->operator = $operator; } protected function setExpression(): void { $referenceCount = substr_count(self::EXPRESSIONS[$this->operator], '%s'); $references = array_fill(0, $referenceCount, $this->referenceCell); $this->expression = sprintf(self::EXPRESSIONS[$this->operator], ...$references); } public function getConditional(): Conditional { $this->setExpression(); $conditional = new Conditional(); $conditional->setConditionType(Conditional::CONDITION_TIMEPERIOD); $conditional->setText($this->operator); $conditional->setConditions([$this->expression]); $conditional->setStyle($this->getStyle()); $conditional->setStopIfTrue($this->getStopIfTrue()); return $conditional; } public static function fromConditional(Conditional $conditional, string $cellRange = 'A1'): WizardInterface { if ($conditional->getConditionType() !== Conditional::CONDITION_TIMEPERIOD) { throw new Exception('Conditional is not a Date Value CF Rule conditional'); } $wizard = new self($cellRange); $wizard->style = $conditional->getStyle(); $wizard->stopIfTrue = $conditional->getStopIfTrue(); $wizard->operator = $conditional->getText(); return $wizard; } /** * @param string $methodName * @param mixed[] $arguments */ public function __call($methodName, $arguments): self { if (!isset(self::MAGIC_OPERATIONS[$methodName])) { throw new Exception('Invalid Operation for Date Value CF Rule Wizard'); } $this->operator(self::MAGIC_OPERATIONS[$methodName]); return $this; } } phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/CellMatcher.php 0000644 00000024366 15060132323 0023571 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Exception; use PhpOffice\PhpSpreadsheet\Cell\Cell; use PhpOffice\PhpSpreadsheet\Cell\Coordinate; use PhpOffice\PhpSpreadsheet\Style\Conditional; use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; class CellMatcher { public const COMPARISON_OPERATORS = [ Conditional::OPERATOR_EQUAL => '=', Conditional::OPERATOR_GREATERTHAN => '>', Conditional::OPERATOR_GREATERTHANOREQUAL => '>=', Conditional::OPERATOR_LESSTHAN => '<', Conditional::OPERATOR_LESSTHANOREQUAL => '<=', Conditional::OPERATOR_NOTEQUAL => '<>', ]; public const COMPARISON_RANGE_OPERATORS = [ Conditional::OPERATOR_BETWEEN => 'IF(AND(A1>=%s,A1<=%s),TRUE,FALSE)', Conditional::OPERATOR_NOTBETWEEN => 'IF(AND(A1>=%s,A1<=%s),FALSE,TRUE)', ]; public const COMPARISON_DUPLICATES_OPERATORS = [ Conditional::CONDITION_DUPLICATES => "COUNTIF('%s'!%s,%s)>1", Conditional::CONDITION_UNIQUE => "COUNTIF('%s'!%s,%s)=1", ]; /** * @var Cell */ protected $cell; /** * @var int */ protected $cellRow; /** * @var Worksheet */ protected $worksheet; /** * @var int */ protected $cellColumn; /** * @var string */ protected $conditionalRange; /** * @var string */ protected $referenceCell; /** * @var int */ protected $referenceRow; /** * @var int */ protected $referenceColumn; /** * @var Calculation */ protected $engine; public function __construct(Cell $cell, string $conditionalRange) { $this->cell = $cell; $this->worksheet = $cell->getWorksheet(); [$this->cellColumn, $this->cellRow] = Coordinate::indexesFromString($this->cell->getCoordinate()); $this->setReferenceCellForExpressions($conditionalRange); $this->engine = Calculation::getInstance($this->worksheet->getParent()); } protected function setReferenceCellForExpressions(string $conditionalRange): void { $conditionalRange = Coordinate::splitRange(str_replace('$', '', strtoupper($conditionalRange))); [$this->referenceCell] = $conditionalRange[0]; [$this->referenceColumn, $this->referenceRow] = Coordinate::indexesFromString($this->referenceCell); // Convert our conditional range to an absolute conditional range, so it can be used "pinned" in formulae $rangeSets = []; foreach ($conditionalRange as $rangeSet) { $absoluteRangeSet = array_map( [Coordinate::class, 'absoluteCoordinate'], $rangeSet ); $rangeSets[] = implode(':', $absoluteRangeSet); } $this->conditionalRange = implode(',', $rangeSets); } public function evaluateConditional(Conditional $conditional): bool { // Some calculations may modify the stored cell; so reset it before every evaluation. $cellColumn = Coordinate::stringFromColumnIndex($this->cellColumn); $cellAddress = "{$cellColumn}{$this->cellRow}"; $this->cell = $this->worksheet->getCell($cellAddress); switch ($conditional->getConditionType()) { case Conditional::CONDITION_CELLIS: return $this->processOperatorComparison($conditional); case Conditional::CONDITION_DUPLICATES: case Conditional::CONDITION_UNIQUE: return $this->processDuplicatesComparison($conditional); case Conditional::CONDITION_CONTAINSTEXT: // Expression is NOT(ISERROR(SEARCH("<TEXT>",<Cell Reference>))) case Conditional::CONDITION_NOTCONTAINSTEXT: // Expression is ISERROR(SEARCH("<TEXT>",<Cell Reference>)) case Conditional::CONDITION_BEGINSWITH: // Expression is LEFT(<Cell Reference>,LEN("<TEXT>"))="<TEXT>" case Conditional::CONDITION_ENDSWITH: // Expression is RIGHT(<Cell Reference>,LEN("<TEXT>"))="<TEXT>" case Conditional::CONDITION_CONTAINSBLANKS: // Expression is LEN(TRIM(<Cell Reference>))=0 case Conditional::CONDITION_NOTCONTAINSBLANKS: // Expression is LEN(TRIM(<Cell Reference>))>0 case Conditional::CONDITION_CONTAINSERRORS: // Expression is ISERROR(<Cell Reference>) case Conditional::CONDITION_NOTCONTAINSERRORS: // Expression is NOT(ISERROR(<Cell Reference>)) case Conditional::CONDITION_TIMEPERIOD: // Expression varies, depending on specified timePeriod value, e.g. // Yesterday FLOOR(<Cell Reference>,1)=TODAY()-1 // Today FLOOR(<Cell Reference>,1)=TODAY() // Tomorrow FLOOR(<Cell Reference>,1)=TODAY()+1 // Last 7 Days AND(TODAY()-FLOOR(<Cell Reference>,1)<=6,FLOOR(<Cell Reference>,1)<=TODAY()) case Conditional::CONDITION_EXPRESSION: return $this->processExpression($conditional); } return false; } /** * @param mixed $value * * @return float|int|string */ protected function wrapValue($value) { if (!is_numeric($value)) { if (is_bool($value)) { return $value ? 'TRUE' : 'FALSE'; } elseif ($value === null) { return 'NULL'; } return '"' . $value . '"'; } return $value; } /** * @return float|int|string */ protected function wrapCellValue() { return $this->wrapValue($this->cell->getCalculatedValue()); } /** * @return float|int|string */ protected function conditionCellAdjustment(array $matches) { $column = $matches[6]; $row = $matches[7]; if (strpos($column, '$') === false) { $column = Coordinate::columnIndexFromString($column); $column += $this->cellColumn - $this->referenceColumn; $column = Coordinate::stringFromColumnIndex($column); } if (strpos($row, '$') === false) { $row += $this->cellRow - $this->referenceRow; } if (!empty($matches[4])) { $worksheet = $this->worksheet->getParentOrThrow()->getSheetByName(trim($matches[4], "'")); if ($worksheet === null) { return $this->wrapValue(null); } return $this->wrapValue( $worksheet ->getCell(str_replace('$', '', "{$column}{$row}")) ->getCalculatedValue() ); } return $this->wrapValue( $this->worksheet ->getCell(str_replace('$', '', "{$column}{$row}")) ->getCalculatedValue() ); } protected function cellConditionCheck(string $condition): string { $splitCondition = explode(Calculation::FORMULA_STRING_QUOTE, $condition); $i = false; foreach ($splitCondition as &$value) { // Only count/replace in alternating array entries (ie. not in quoted strings) $i = $i === false; if ($i) { $value = (string) preg_replace_callback( '/' . Calculation::CALCULATION_REGEXP_CELLREF_RELATIVE . '/i', [$this, 'conditionCellAdjustment'], $value ); } } unset($value); // Then rebuild the condition string to return it return implode(Calculation::FORMULA_STRING_QUOTE, $splitCondition); } protected function adjustConditionsForCellReferences(array $conditions): array { return array_map( [$this, 'cellConditionCheck'], $conditions ); } protected function processOperatorComparison(Conditional $conditional): bool { if (array_key_exists($conditional->getOperatorType(), self::COMPARISON_RANGE_OPERATORS)) { return $this->processRangeOperator($conditional); } $operator = self::COMPARISON_OPERATORS[$conditional->getOperatorType()]; $conditions = $this->adjustConditionsForCellReferences($conditional->getConditions()); $expression = sprintf('%s%s%s', (string) $this->wrapCellValue(), $operator, (string) array_pop($conditions)); return $this->evaluateExpression($expression); } protected function processRangeOperator(Conditional $conditional): bool { $conditions = $this->adjustConditionsForCellReferences($conditional->getConditions()); sort($conditions); $expression = sprintf( (string) preg_replace( '/\bA1\b/i', (string) $this->wrapCellValue(), self::COMPARISON_RANGE_OPERATORS[$conditional->getOperatorType()] ), ...$conditions ); return $this->evaluateExpression($expression); } protected function processDuplicatesComparison(Conditional $conditional): bool { $worksheetName = $this->cell->getWorksheet()->getTitle(); $expression = sprintf( self::COMPARISON_DUPLICATES_OPERATORS[$conditional->getConditionType()], $worksheetName, $this->conditionalRange, $this->cellConditionCheck($this->cell->getCalculatedValue()) ); return $this->evaluateExpression($expression); } protected function processExpression(Conditional $conditional): bool { $conditions = $this->adjustConditionsForCellReferences($conditional->getConditions()); $expression = array_pop($conditions); $expression = (string) preg_replace( '/\b' . $this->referenceCell . '\b/i', (string) $this->wrapCellValue(), $expression ); return $this->evaluateExpression($expression); } protected function evaluateExpression(string $expression): bool { $expression = "={$expression}"; try { $this->engine->flushInstance(); $result = (bool) $this->engine->calculateFormula($expression); } catch (Exception $e) { return false; } return $result; } } phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalDataBar.php 0000644 00000004375 15060132323 0025066 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting; class ConditionalDataBar { /** <dataBar> attribute */ /** @var null|bool */ private $showValue; /** <dataBar> children */ /** @var ?ConditionalFormatValueObject */ private $minimumConditionalFormatValueObject; /** @var ?ConditionalFormatValueObject */ private $maximumConditionalFormatValueObject; /** @var string */ private $color; /** <extLst> */ /** @var ?ConditionalFormattingRuleExtension */ private $conditionalFormattingRuleExt; /** * @return null|bool */ public function getShowValue() { return $this->showValue; } /** * @param bool $showValue */ public function setShowValue($showValue): self { $this->showValue = $showValue; return $this; } public function getMinimumConditionalFormatValueObject(): ?ConditionalFormatValueObject { return $this->minimumConditionalFormatValueObject; } public function setMinimumConditionalFormatValueObject(ConditionalFormatValueObject $minimumConditionalFormatValueObject): self { $this->minimumConditionalFormatValueObject = $minimumConditionalFormatValueObject; return $this; } public function getMaximumConditionalFormatValueObject(): ?ConditionalFormatValueObject { return $this->maximumConditionalFormatValueObject; } public function setMaximumConditionalFormatValueObject(ConditionalFormatValueObject $maximumConditionalFormatValueObject): self { $this->maximumConditionalFormatValueObject = $maximumConditionalFormatValueObject; return $this; } public function getColor(): string { return $this->color; } public function setColor(string $color): self { $this->color = $color; return $this; } public function getConditionalFormattingRuleExt(): ?ConditionalFormattingRuleExtension { return $this->conditionalFormattingRuleExt; } public function setConditionalFormattingRuleExt(ConditionalFormattingRuleExtension $conditionalFormattingRuleExt): self { $this->conditionalFormattingRuleExt = $conditionalFormattingRuleExt; return $this; } } phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/Wizard.php 0000644 00000007763 15060132323 0022650 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting; use PhpOffice\PhpSpreadsheet\Exception; use PhpOffice\PhpSpreadsheet\Style\Conditional; use PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\Wizard\WizardInterface; class Wizard { public const CELL_VALUE = 'cellValue'; public const TEXT_VALUE = 'textValue'; public const BLANKS = Conditional::CONDITION_CONTAINSBLANKS; public const NOT_BLANKS = Conditional::CONDITION_NOTCONTAINSBLANKS; public const ERRORS = Conditional::CONDITION_CONTAINSERRORS; public const NOT_ERRORS = Conditional::CONDITION_NOTCONTAINSERRORS; public const EXPRESSION = Conditional::CONDITION_EXPRESSION; public const FORMULA = Conditional::CONDITION_EXPRESSION; public const DATES_OCCURRING = 'DateValue'; public const DUPLICATES = Conditional::CONDITION_DUPLICATES; public const UNIQUE = Conditional::CONDITION_UNIQUE; public const VALUE_TYPE_LITERAL = 'value'; public const VALUE_TYPE_CELL = 'cell'; public const VALUE_TYPE_FORMULA = 'formula'; /** * @var string */ protected $cellRange; public function __construct(string $cellRange) { $this->cellRange = $cellRange; } public function newRule(string $ruleType): WizardInterface { switch ($ruleType) { case self::CELL_VALUE: return new Wizard\CellValue($this->cellRange); case self::TEXT_VALUE: return new Wizard\TextValue($this->cellRange); case self::BLANKS: return new Wizard\Blanks($this->cellRange, true); case self::NOT_BLANKS: return new Wizard\Blanks($this->cellRange, false); case self::ERRORS: return new Wizard\Errors($this->cellRange, true); case self::NOT_ERRORS: return new Wizard\Errors($this->cellRange, false); case self::EXPRESSION: case self::FORMULA: return new Wizard\Expression($this->cellRange); case self::DATES_OCCURRING: return new Wizard\DateValue($this->cellRange); case self::DUPLICATES: return new Wizard\Duplicates($this->cellRange, false); case self::UNIQUE: return new Wizard\Duplicates($this->cellRange, true); default: throw new Exception('No wizard exists for this CF rule type'); } } public static function fromConditional(Conditional $conditional, string $cellRange = 'A1'): WizardInterface { $conditionalType = $conditional->getConditionType(); switch ($conditionalType) { case Conditional::CONDITION_CELLIS: return Wizard\CellValue::fromConditional($conditional, $cellRange); case Conditional::CONDITION_CONTAINSTEXT: case Conditional::CONDITION_NOTCONTAINSTEXT: case Conditional::CONDITION_BEGINSWITH: case Conditional::CONDITION_ENDSWITH: return Wizard\TextValue::fromConditional($conditional, $cellRange); case Conditional::CONDITION_CONTAINSBLANKS: case Conditional::CONDITION_NOTCONTAINSBLANKS: return Wizard\Blanks::fromConditional($conditional, $cellRange); case Conditional::CONDITION_CONTAINSERRORS: case Conditional::CONDITION_NOTCONTAINSERRORS: return Wizard\Errors::fromConditional($conditional, $cellRange); case Conditional::CONDITION_TIMEPERIOD: return Wizard\DateValue::fromConditional($conditional, $cellRange); case Conditional::CONDITION_EXPRESSION: return Wizard\Expression::fromConditional($conditional, $cellRange); case Conditional::CONDITION_DUPLICATES: case Conditional::CONDITION_UNIQUE: return Wizard\Duplicates::fromConditional($conditional, $cellRange); default: throw new Exception('No wizard exists for this CF rule type'); } } } phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalDataBarExtension.php 0000644 00000014174 15060132323 0026761 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting; class ConditionalDataBarExtension { /** <dataBar> attributes */ /** @var int */ private $minLength; /** @var int */ private $maxLength; /** @var null|bool */ private $border; /** @var null|bool */ private $gradient; /** @var string */ private $direction; /** @var null|bool */ private $negativeBarBorderColorSameAsPositive; /** @var string */ private $axisPosition; // <dataBar> children /** @var ConditionalFormatValueObject */ private $maximumConditionalFormatValueObject; /** @var ConditionalFormatValueObject */ private $minimumConditionalFormatValueObject; /** @var string */ private $borderColor; /** @var string */ private $negativeFillColor; /** @var string */ private $negativeBorderColor; /** @var array */ private $axisColor = [ 'rgb' => null, 'theme' => null, 'tint' => null, ]; public function getXmlAttributes(): array { $ret = []; foreach (['minLength', 'maxLength', 'direction', 'axisPosition'] as $attrKey) { if (null !== $this->{$attrKey}) { $ret[$attrKey] = $this->{$attrKey}; } } foreach (['border', 'gradient', 'negativeBarBorderColorSameAsPositive'] as $attrKey) { if (null !== $this->{$attrKey}) { $ret[$attrKey] = $this->{$attrKey} ? '1' : '0'; } } return $ret; } public function getXmlElements(): array { $ret = []; $elms = ['borderColor', 'negativeFillColor', 'negativeBorderColor']; foreach ($elms as $elmKey) { if (null !== $this->{$elmKey}) { $ret[$elmKey] = ['rgb' => $this->{$elmKey}]; } } foreach (array_filter($this->axisColor) as $attrKey => $axisColorAttr) { if (!isset($ret['axisColor'])) { $ret['axisColor'] = []; } $ret['axisColor'][$attrKey] = $axisColorAttr; } return $ret; } /** * @return int */ public function getMinLength() { return $this->minLength; } public function setMinLength(int $minLength): self { $this->minLength = $minLength; return $this; } /** * @return int */ public function getMaxLength() { return $this->maxLength; } public function setMaxLength(int $maxLength): self { $this->maxLength = $maxLength; return $this; } /** * @return null|bool */ public function getBorder() { return $this->border; } public function setBorder(bool $border): self { $this->border = $border; return $this; } /** * @return null|bool */ public function getGradient() { return $this->gradient; } public function setGradient(bool $gradient): self { $this->gradient = $gradient; return $this; } /** * @return string */ public function getDirection() { return $this->direction; } public function setDirection(string $direction): self { $this->direction = $direction; return $this; } /** * @return null|bool */ public function getNegativeBarBorderColorSameAsPositive() { return $this->negativeBarBorderColorSameAsPositive; } public function setNegativeBarBorderColorSameAsPositive(bool $negativeBarBorderColorSameAsPositive): self { $this->negativeBarBorderColorSameAsPositive = $negativeBarBorderColorSameAsPositive; return $this; } /** * @return string */ public function getAxisPosition() { return $this->axisPosition; } public function setAxisPosition(string $axisPosition): self { $this->axisPosition = $axisPosition; return $this; } /** * @return ConditionalFormatValueObject */ public function getMaximumConditionalFormatValueObject() { return $this->maximumConditionalFormatValueObject; } public function setMaximumConditionalFormatValueObject(ConditionalFormatValueObject $maximumConditionalFormatValueObject): self { $this->maximumConditionalFormatValueObject = $maximumConditionalFormatValueObject; return $this; } /** * @return ConditionalFormatValueObject */ public function getMinimumConditionalFormatValueObject() { return $this->minimumConditionalFormatValueObject; } public function setMinimumConditionalFormatValueObject(ConditionalFormatValueObject $minimumConditionalFormatValueObject): self { $this->minimumConditionalFormatValueObject = $minimumConditionalFormatValueObject; return $this; } /** * @return string */ public function getBorderColor() { return $this->borderColor; } public function setBorderColor(string $borderColor): self { $this->borderColor = $borderColor; return $this; } /** * @return string */ public function getNegativeFillColor() { return $this->negativeFillColor; } public function setNegativeFillColor(string $negativeFillColor): self { $this->negativeFillColor = $negativeFillColor; return $this; } /** * @return string */ public function getNegativeBorderColor() { return $this->negativeBorderColor; } public function setNegativeBorderColor(string $negativeBorderColor): self { $this->negativeBorderColor = $negativeBorderColor; return $this; } public function getAxisColor(): array { return $this->axisColor; } /** * @param mixed $rgb * @param null|mixed $theme * @param null|mixed $tint */ public function setAxisColor($rgb, $theme = null, $tint = null): self { $this->axisColor = [ 'rgb' => $rgb, 'theme' => $theme, 'tint' => $tint, ]; return $this; } } phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/CellStyleAssessor.php 0000644 00000002353 15060132323 0025021 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting; use PhpOffice\PhpSpreadsheet\Cell\Cell; use PhpOffice\PhpSpreadsheet\Style\Conditional; use PhpOffice\PhpSpreadsheet\Style\Style; class CellStyleAssessor { /** * @var CellMatcher */ protected $cellMatcher; /** * @var StyleMerger */ protected $styleMerger; public function __construct(Cell $cell, string $conditionalRange) { $this->cellMatcher = new CellMatcher($cell, $conditionalRange); $this->styleMerger = new StyleMerger($cell->getStyle()); } /** * @param Conditional[] $conditionalStyles */ public function matchConditions(array $conditionalStyles = []): Style { foreach ($conditionalStyles as $conditional) { /** @var Conditional $conditional */ if ($this->cellMatcher->evaluateConditional($conditional) === true) { // Merging the conditional style into the base style goes in here $this->styleMerger->mergeStyle($conditional->getStyle()); if ($conditional->getStopIfTrue() === true) { break; } } } return $this->styleMerger->getStyle(); } } phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/StyleMerger.php 0000644 00000007474 15060132323 0023651 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting; use PhpOffice\PhpSpreadsheet\Style\Border; use PhpOffice\PhpSpreadsheet\Style\Borders; use PhpOffice\PhpSpreadsheet\Style\Fill; use PhpOffice\PhpSpreadsheet\Style\Font; use PhpOffice\PhpSpreadsheet\Style\Style; class StyleMerger { /** * @var Style */ protected $baseStyle; public function __construct(Style $baseStyle) { $this->baseStyle = $baseStyle; } public function getStyle(): Style { return $this->baseStyle; } public function mergeStyle(Style $style): void { if ($style->getNumberFormat() !== null && $style->getNumberFormat()->getFormatCode() !== null) { $this->baseStyle->getNumberFormat()->setFormatCode($style->getNumberFormat()->getFormatCode()); } if ($style->getFont() !== null) { $this->mergeFontStyle($this->baseStyle->getFont(), $style->getFont()); } if ($style->getFill() !== null) { $this->mergeFillStyle($this->baseStyle->getFill(), $style->getFill()); } if ($style->getBorders() !== null) { $this->mergeBordersStyle($this->baseStyle->getBorders(), $style->getBorders()); } } protected function mergeFontStyle(Font $baseFontStyle, Font $fontStyle): void { if ($fontStyle->getBold() !== null) { $baseFontStyle->setBold($fontStyle->getBold()); } if ($fontStyle->getItalic() !== null) { $baseFontStyle->setItalic($fontStyle->getItalic()); } if ($fontStyle->getStrikethrough() !== null) { $baseFontStyle->setStrikethrough($fontStyle->getStrikethrough()); } if ($fontStyle->getUnderline() !== null) { $baseFontStyle->setUnderline($fontStyle->getUnderline()); } if ($fontStyle->getColor() !== null && $fontStyle->getColor()->getARGB() !== null) { $baseFontStyle->setColor($fontStyle->getColor()); } } protected function mergeFillStyle(Fill $baseFillStyle, Fill $fillStyle): void { if ($fillStyle->getFillType() !== null) { $baseFillStyle->setFillType($fillStyle->getFillType()); } //if ($fillStyle->getRotation() !== null) { $baseFillStyle->setRotation($fillStyle->getRotation()); //} if ($fillStyle->getStartColor() !== null && $fillStyle->getStartColor()->getARGB() !== null) { $baseFillStyle->setStartColor($fillStyle->getStartColor()); } if ($fillStyle->getEndColor() !== null && $fillStyle->getEndColor()->getARGB() !== null) { $baseFillStyle->setEndColor($fillStyle->getEndColor()); } } protected function mergeBordersStyle(Borders $baseBordersStyle, Borders $bordersStyle): void { if ($bordersStyle->getTop() !== null) { $this->mergeBorderStyle($baseBordersStyle->getTop(), $bordersStyle->getTop()); } if ($bordersStyle->getBottom() !== null) { $this->mergeBorderStyle($baseBordersStyle->getBottom(), $bordersStyle->getBottom()); } if ($bordersStyle->getLeft() !== null) { $this->mergeBorderStyle($baseBordersStyle->getLeft(), $bordersStyle->getLeft()); } if ($bordersStyle->getRight() !== null) { $this->mergeBorderStyle($baseBordersStyle->getRight(), $bordersStyle->getRight()); } } protected function mergeBorderStyle(Border $baseBorderStyle, Border $borderStyle): void { //if ($borderStyle->getBorderStyle() !== null) { $baseBorderStyle->setBorderStyle($borderStyle->getBorderStyle()); //} if ($borderStyle->getColor() !== null && $borderStyle->getColor()->getARGB() !== null) { $baseBorderStyle->setColor($borderStyle->getColor()); } } } phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalFormatValueObject.php 0000644 00000002616 15060132323 0027140 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting; class ConditionalFormatValueObject { /** @var mixed */ private $type; /** @var mixed */ private $value; /** @var mixed */ private $cellFormula; /** * ConditionalFormatValueObject constructor. * * @param mixed $type * @param mixed $value * @param null|mixed $cellFormula */ public function __construct($type, $value = null, $cellFormula = null) { $this->type = $type; $this->value = $value; $this->cellFormula = $cellFormula; } /** * @return mixed */ public function getType() { return $this->type; } /** * @param mixed $type */ public function setType($type): self { $this->type = $type; return $this; } /** * @return mixed */ public function getValue() { return $this->value; } /** * @param mixed $value */ public function setValue($value): self { $this->value = $value; return $this; } /** * @return mixed */ public function getCellFormula() { return $this->cellFormula; } /** * @param mixed $cellFormula */ public function setCellFormula($cellFormula): self { $this->cellFormula = $cellFormula; return $this; } } phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalFormattingRuleExtension.php0000644 00000017327 15060132323 0030430 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting; use PhpOffice\PhpSpreadsheet\Style\Conditional; use SimpleXMLElement; class ConditionalFormattingRuleExtension { const CONDITION_EXTENSION_DATABAR = 'dataBar'; /** <conditionalFormatting> attributes */ /** @var string */ private $id; /** @var string Conditional Formatting Rule */ private $cfRule; /** <conditionalFormatting> children */ /** @var ConditionalDataBarExtension */ private $dataBar; /** @var string Sequence of References */ private $sqref; /** * ConditionalFormattingRuleExtension constructor. */ public function __construct(?string $id = null, string $cfRule = self::CONDITION_EXTENSION_DATABAR) { if (null === $id) { $this->id = '{' . $this->generateUuid() . '}'; } else { $this->id = $id; } $this->cfRule = $cfRule; } private function generateUuid(): string { $chars = str_split('xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'); foreach ($chars as $i => $char) { if ($char === 'x') { $chars[$i] = dechex(random_int(0, 15)); } elseif ($char === 'y') { $chars[$i] = dechex(random_int(8, 11)); } } return implode('', /** @scrutinizer ignore-type */ $chars); } public static function parseExtLstXml(?SimpleXMLElement $extLstXml): array { $conditionalFormattingRuleExtensions = []; $conditionalFormattingRuleExtensionXml = null; if ($extLstXml instanceof SimpleXMLElement) { foreach ((count($extLstXml) > 0 ? $extLstXml : [$extLstXml]) as $extLst) { //this uri is conditionalFormattings //https://docs.microsoft.com/en-us/openspecs/office_standards/ms-xlsx/07d607af-5618-4ca2-b683-6a78dc0d9627 if (isset($extLst->ext['uri']) && (string) $extLst->ext['uri'] === '{78C0D931-6437-407d-A8EE-F0AAD7539E65}') { $conditionalFormattingRuleExtensionXml = $extLst->ext; } } if ($conditionalFormattingRuleExtensionXml) { $ns = $conditionalFormattingRuleExtensionXml->getNamespaces(true); $extFormattingsXml = $conditionalFormattingRuleExtensionXml->children($ns['x14']); foreach ($extFormattingsXml->children($ns['x14']) as $extFormattingXml) { $extCfRuleXml = $extFormattingXml->cfRule; $attributes = $extCfRuleXml->attributes(); if (!$attributes || ((string) $attributes->type) !== Conditional::CONDITION_DATABAR) { continue; } $extFormattingRuleObj = new self((string) $attributes->id); $extFormattingRuleObj->setSqref((string) $extFormattingXml->children($ns['xm'])->sqref); $conditionalFormattingRuleExtensions[$extFormattingRuleObj->getId()] = $extFormattingRuleObj; $extDataBarObj = new ConditionalDataBarExtension(); $extFormattingRuleObj->setDataBarExt($extDataBarObj); $dataBarXml = $extCfRuleXml->dataBar; self::parseExtDataBarAttributesFromXml($extDataBarObj, $dataBarXml); self::parseExtDataBarElementChildrenFromXml($extDataBarObj, $dataBarXml, $ns); } } } return $conditionalFormattingRuleExtensions; } private static function parseExtDataBarAttributesFromXml( ConditionalDataBarExtension $extDataBarObj, SimpleXMLElement $dataBarXml ): void { $dataBarAttribute = $dataBarXml->attributes(); if ($dataBarAttribute === null) { return; } if ($dataBarAttribute->minLength) { $extDataBarObj->setMinLength((int) $dataBarAttribute->minLength); } if ($dataBarAttribute->maxLength) { $extDataBarObj->setMaxLength((int) $dataBarAttribute->maxLength); } if ($dataBarAttribute->border) { $extDataBarObj->setBorder((bool) (string) $dataBarAttribute->border); } if ($dataBarAttribute->gradient) { $extDataBarObj->setGradient((bool) (string) $dataBarAttribute->gradient); } if ($dataBarAttribute->direction) { $extDataBarObj->setDirection((string) $dataBarAttribute->direction); } if ($dataBarAttribute->negativeBarBorderColorSameAsPositive) { $extDataBarObj->setNegativeBarBorderColorSameAsPositive((bool) (string) $dataBarAttribute->negativeBarBorderColorSameAsPositive); } if ($dataBarAttribute->axisPosition) { $extDataBarObj->setAxisPosition((string) $dataBarAttribute->axisPosition); } } /** @param array|SimpleXMLElement $ns */ private static function parseExtDataBarElementChildrenFromXml(ConditionalDataBarExtension $extDataBarObj, SimpleXMLElement $dataBarXml, $ns): void { if ($dataBarXml->borderColor) { $attributes = $dataBarXml->borderColor->attributes(); if ($attributes !== null) { $extDataBarObj->setBorderColor((string) $attributes['rgb']); } } if ($dataBarXml->negativeFillColor) { $attributes = $dataBarXml->negativeFillColor->attributes(); if ($attributes !== null) { $extDataBarObj->setNegativeFillColor((string) $attributes['rgb']); } } if ($dataBarXml->negativeBorderColor) { $attributes = $dataBarXml->negativeBorderColor->attributes(); if ($attributes !== null) { $extDataBarObj->setNegativeBorderColor((string) $attributes['rgb']); } } if ($dataBarXml->axisColor) { $axisColorAttr = $dataBarXml->axisColor->attributes(); if ($axisColorAttr !== null) { $extDataBarObj->setAxisColor((string) $axisColorAttr['rgb'], (string) $axisColorAttr['theme'], (string) $axisColorAttr['tint']); } } $cfvoIndex = 0; foreach ($dataBarXml->cfvo as $cfvo) { $f = (string) $cfvo->/** @scrutinizer ignore-call */ children($ns['xm'])->f; /** @scrutinizer ignore-call */ $attributes = $cfvo->attributes(); if (!($attributes)) { continue; } if ($cfvoIndex === 0) { $extDataBarObj->setMinimumConditionalFormatValueObject(new ConditionalFormatValueObject((string) $attributes['type'], null, (empty($f) ? null : $f))); } if ($cfvoIndex === 1) { $extDataBarObj->setMaximumConditionalFormatValueObject(new ConditionalFormatValueObject((string) $attributes['type'], null, (empty($f) ? null : $f))); } ++$cfvoIndex; } } /** * @return mixed */ public function getId() { return $this->id; } /** * @param mixed $id */ public function setId($id): self { $this->id = $id; return $this; } public function getCfRule(): string { return $this->cfRule; } public function setCfRule(string $cfRule): self { $this->cfRule = $cfRule; return $this; } public function getDataBarExt(): ConditionalDataBarExtension { return $this->dataBar; } public function setDataBarExt(ConditionalDataBarExtension $dataBar): self { $this->dataBar = $dataBar; return $this; } public function getSqref(): string { return $this->sqref; } public function setSqref(string $sqref): self { $this->sqref = $sqref; return $this; } } phpspreadsheet/src/PhpSpreadsheet/Style/Font.php 0000644 00000055337 15060132323 0016020 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Style; use PhpOffice\PhpSpreadsheet\Chart\ChartColor; class Font extends Supervisor { // Underline types const UNDERLINE_NONE = 'none'; const UNDERLINE_DOUBLE = 'double'; const UNDERLINE_DOUBLEACCOUNTING = 'doubleAccounting'; const UNDERLINE_SINGLE = 'single'; const UNDERLINE_SINGLEACCOUNTING = 'singleAccounting'; /** * Font Name. * * @var null|string */ protected $name = 'Calibri'; /** * The following 7 are used only for chart titles, I think. * *@var string */ private $latin = ''; /** @var string */ private $eastAsian = ''; /** @var string */ private $complexScript = ''; /** @var int */ private $baseLine = 0; /** @var string */ private $strikeType = ''; /** @var ?ChartColor */ private $underlineColor; /** @var ?ChartColor */ private $chartColor; // end of chart title items /** * Font Size. * * @var null|float */ protected $size = 11; /** * Bold. * * @var null|bool */ protected $bold = false; /** * Italic. * * @var null|bool */ protected $italic = false; /** * Superscript. * * @var null|bool */ protected $superscript = false; /** * Subscript. * * @var null|bool */ protected $subscript = false; /** * Underline. * * @var null|string */ protected $underline = self::UNDERLINE_NONE; /** * Strikethrough. * * @var null|bool */ protected $strikethrough = false; /** * Foreground color. * * @var Color */ protected $color; /** * @var null|int */ public $colorIndex; /** @var string */ protected $scheme = ''; /** * Create a new Font. * * @param bool $isSupervisor Flag indicating if this is a supervisor or not * Leave this value at default unless you understand exactly what * its ramifications are * @param bool $isConditional Flag indicating if this is a conditional style or not * Leave this value at default unless you understand exactly what * its ramifications are */ public function __construct($isSupervisor = false, $isConditional = false) { // Supervisor? parent::__construct($isSupervisor); // Initialise values if ($isConditional) { $this->name = null; $this->size = null; $this->bold = null; $this->italic = null; $this->superscript = null; $this->subscript = null; $this->underline = null; $this->strikethrough = null; $this->color = new Color(Color::COLOR_BLACK, $isSupervisor, $isConditional); } else { $this->color = new Color(Color::COLOR_BLACK, $isSupervisor); } // bind parent if we are a supervisor if ($isSupervisor) { $this->color->bindParent($this, 'color'); } } /** * Get the shared style component for the currently active cell in currently active sheet. * Only used for style supervisor. * * @return Font */ public function getSharedComponent() { /** @var Style */ $parent = $this->parent; return $parent->getSharedComponent()->getFont(); } /** * Build style array from subcomponents. * * @param array $array * * @return array */ public function getStyleArray($array) { return ['font' => $array]; } /** * Apply styles from array. * * <code> * $spreadsheet->getActiveSheet()->getStyle('B2')->getFont()->applyFromArray( * [ * 'name' => 'Arial', * 'bold' => TRUE, * 'italic' => FALSE, * 'underline' => \PhpOffice\PhpSpreadsheet\Style\Font::UNDERLINE_DOUBLE, * 'strikethrough' => FALSE, * 'color' => [ * 'rgb' => '808080' * ] * ] * ); * </code> * * @param array $styleArray Array containing style information * * @return $this */ public function applyFromArray(array $styleArray) { if ($this->isSupervisor) { $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($styleArray)); } else { if (isset($styleArray['name'])) { $this->setName($styleArray['name']); } if (isset($styleArray['latin'])) { $this->setLatin($styleArray['latin']); } if (isset($styleArray['eastAsian'])) { $this->setEastAsian($styleArray['eastAsian']); } if (isset($styleArray['complexScript'])) { $this->setComplexScript($styleArray['complexScript']); } if (isset($styleArray['bold'])) { $this->setBold($styleArray['bold']); } if (isset($styleArray['italic'])) { $this->setItalic($styleArray['italic']); } if (isset($styleArray['superscript'])) { $this->setSuperscript($styleArray['superscript']); } if (isset($styleArray['subscript'])) { $this->setSubscript($styleArray['subscript']); } if (isset($styleArray['underline'])) { $this->setUnderline($styleArray['underline']); } if (isset($styleArray['strikethrough'])) { $this->setStrikethrough($styleArray['strikethrough']); } if (isset($styleArray['color'])) { $this->getColor()->applyFromArray($styleArray['color']); } if (isset($styleArray['size'])) { $this->setSize($styleArray['size']); } if (isset($styleArray['chartColor'])) { $this->chartColor = $styleArray['chartColor']; } if (isset($styleArray['scheme'])) { $this->setScheme($styleArray['scheme']); } } return $this; } /** * Get Name. * * @return null|string */ public function getName() { if ($this->isSupervisor) { return $this->getSharedComponent()->getName(); } return $this->name; } public function getLatin(): string { if ($this->isSupervisor) { return $this->getSharedComponent()->getLatin(); } return $this->latin; } public function getEastAsian(): string { if ($this->isSupervisor) { return $this->getSharedComponent()->getEastAsian(); } return $this->eastAsian; } public function getComplexScript(): string { if ($this->isSupervisor) { return $this->getSharedComponent()->getComplexScript(); } return $this->complexScript; } /** * Set Name and turn off Scheme. * * @param string $fontname */ public function setName($fontname): self { if ($fontname == '') { $fontname = 'Calibri'; } if ($this->isSupervisor) { $styleArray = $this->getStyleArray(['name' => $fontname]); $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); } else { $this->name = $fontname; } return $this->setScheme(''); } public function setLatin(string $fontname): self { if ($fontname == '') { $fontname = 'Calibri'; } if (!$this->isSupervisor) { $this->latin = $fontname; } else { // should never be true // @codeCoverageIgnoreStart $styleArray = $this->getStyleArray(['latin' => $fontname]); $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); // @codeCoverageIgnoreEnd } return $this; } public function setEastAsian(string $fontname): self { if ($fontname == '') { $fontname = 'Calibri'; } if (!$this->isSupervisor) { $this->eastAsian = $fontname; } else { // should never be true // @codeCoverageIgnoreStart $styleArray = $this->getStyleArray(['eastAsian' => $fontname]); $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); // @codeCoverageIgnoreEnd } return $this; } public function setComplexScript(string $fontname): self { if ($fontname == '') { $fontname = 'Calibri'; } if (!$this->isSupervisor) { $this->complexScript = $fontname; } else { // should never be true // @codeCoverageIgnoreStart $styleArray = $this->getStyleArray(['complexScript' => $fontname]); $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); // @codeCoverageIgnoreEnd } return $this; } /** * Get Size. * * @return null|float */ public function getSize() { if ($this->isSupervisor) { return $this->getSharedComponent()->getSize(); } return $this->size; } /** * Set Size. * * @param mixed $sizeInPoints A float representing the value of a positive measurement in points (1/72 of an inch) * * @return $this */ public function setSize($sizeInPoints, bool $nullOk = false) { if (is_string($sizeInPoints) || is_int($sizeInPoints)) { $sizeInPoints = (float) $sizeInPoints; // $pValue = 0 if given string is not numeric } // Size must be a positive floating point number // ECMA-376-1:2016, part 1, chapter 18.4.11 sz (Font Size), p. 1536 if (!is_float($sizeInPoints) || !($sizeInPoints > 0)) { if (!$nullOk || $sizeInPoints !== null) { $sizeInPoints = 10.0; } } if ($this->isSupervisor) { $styleArray = $this->getStyleArray(['size' => $sizeInPoints]); $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); } else { $this->size = $sizeInPoints; } return $this; } /** * Get Bold. * * @return null|bool */ public function getBold() { if ($this->isSupervisor) { return $this->getSharedComponent()->getBold(); } return $this->bold; } /** * Set Bold. * * @param bool $bold * * @return $this */ public function setBold($bold) { if ($bold == '') { $bold = false; } if ($this->isSupervisor) { $styleArray = $this->getStyleArray(['bold' => $bold]); $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); } else { $this->bold = $bold; } return $this; } /** * Get Italic. * * @return null|bool */ public function getItalic() { if ($this->isSupervisor) { return $this->getSharedComponent()->getItalic(); } return $this->italic; } /** * Set Italic. * * @param bool $italic * * @return $this */ public function setItalic($italic) { if ($italic == '') { $italic = false; } if ($this->isSupervisor) { $styleArray = $this->getStyleArray(['italic' => $italic]); $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); } else { $this->italic = $italic; } return $this; } /** * Get Superscript. * * @return null|bool */ public function getSuperscript() { if ($this->isSupervisor) { return $this->getSharedComponent()->getSuperscript(); } return $this->superscript; } /** * Set Superscript. * * @return $this */ public function setSuperscript(bool $superscript) { if ($this->isSupervisor) { $styleArray = $this->getStyleArray(['superscript' => $superscript]); $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); } else { $this->superscript = $superscript; if ($this->superscript) { $this->subscript = false; } } return $this; } /** * Get Subscript. * * @return null|bool */ public function getSubscript() { if ($this->isSupervisor) { return $this->getSharedComponent()->getSubscript(); } return $this->subscript; } /** * Set Subscript. * * @return $this */ public function setSubscript(bool $subscript) { if ($this->isSupervisor) { $styleArray = $this->getStyleArray(['subscript' => $subscript]); $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); } else { $this->subscript = $subscript; if ($this->subscript) { $this->superscript = false; } } return $this; } public function getBaseLine(): int { if ($this->isSupervisor) { return $this->getSharedComponent()->getBaseLine(); } return $this->baseLine; } public function setBaseLine(int $baseLine): self { if (!$this->isSupervisor) { $this->baseLine = $baseLine; } else { // should never be true // @codeCoverageIgnoreStart $styleArray = $this->getStyleArray(['baseLine' => $baseLine]); $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); // @codeCoverageIgnoreEnd } return $this; } public function getStrikeType(): string { if ($this->isSupervisor) { return $this->getSharedComponent()->getStrikeType(); } return $this->strikeType; } public function setStrikeType(string $strikeType): self { if (!$this->isSupervisor) { $this->strikeType = $strikeType; } else { // should never be true // @codeCoverageIgnoreStart $styleArray = $this->getStyleArray(['strikeType' => $strikeType]); $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); // @codeCoverageIgnoreEnd } return $this; } public function getUnderlineColor(): ?ChartColor { if ($this->isSupervisor) { return $this->getSharedComponent()->getUnderlineColor(); } return $this->underlineColor; } public function setUnderlineColor(array $colorArray): self { if (!$this->isSupervisor) { $this->underlineColor = new ChartColor($colorArray); } else { // should never be true // @codeCoverageIgnoreStart $styleArray = $this->getStyleArray(['underlineColor' => $colorArray]); $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); // @codeCoverageIgnoreEnd } return $this; } public function getChartColor(): ?ChartColor { if ($this->isSupervisor) { return $this->getSharedComponent()->getChartColor(); } return $this->chartColor; } public function setChartColor(array $colorArray): self { if (!$this->isSupervisor) { $this->chartColor = new ChartColor($colorArray); } else { // should never be true // @codeCoverageIgnoreStart $styleArray = $this->getStyleArray(['chartColor' => $colorArray]); $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); // @codeCoverageIgnoreEnd } return $this; } public function setChartColorFromObject(?ChartColor $chartColor): self { $this->chartColor = $chartColor; return $this; } /** * Get Underline. * * @return null|string */ public function getUnderline() { if ($this->isSupervisor) { return $this->getSharedComponent()->getUnderline(); } return $this->underline; } /** * Set Underline. * * @param bool|string $underlineStyle \PhpOffice\PhpSpreadsheet\Style\Font underline type * If a boolean is passed, then TRUE equates to UNDERLINE_SINGLE, * false equates to UNDERLINE_NONE * * @return $this */ public function setUnderline($underlineStyle) { if (is_bool($underlineStyle)) { $underlineStyle = ($underlineStyle) ? self::UNDERLINE_SINGLE : self::UNDERLINE_NONE; } elseif ($underlineStyle == '') { $underlineStyle = self::UNDERLINE_NONE; } if ($this->isSupervisor) { $styleArray = $this->getStyleArray(['underline' => $underlineStyle]); $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); } else { $this->underline = $underlineStyle; } return $this; } /** * Get Strikethrough. * * @return null|bool */ public function getStrikethrough() { if ($this->isSupervisor) { return $this->getSharedComponent()->getStrikethrough(); } return $this->strikethrough; } /** * Set Strikethrough. * * @param bool $strikethru * * @return $this */ public function setStrikethrough($strikethru) { if ($strikethru == '') { $strikethru = false; } if ($this->isSupervisor) { $styleArray = $this->getStyleArray(['strikethrough' => $strikethru]); $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); } else { $this->strikethrough = $strikethru; } return $this; } /** * Get Color. * * @return Color */ public function getColor() { return $this->color; } /** * Set Color. * * @return $this */ public function setColor(Color $color) { // make sure parameter is a real color and not a supervisor $color = $color->getIsSupervisor() ? $color->getSharedComponent() : $color; if ($this->isSupervisor) { $styleArray = $this->getColor()->getStyleArray(['argb' => $color->getARGB()]); $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); } else { $this->color = $color; } return $this; } private function hashChartColor(?ChartColor $underlineColor): string { if ($underlineColor === null) { return ''; } return $underlineColor->getValue() . $underlineColor->getType() . (string) $underlineColor->getAlpha(); } /** * Get hash code. * * @return string Hash code */ public function getHashCode() { if ($this->isSupervisor) { return $this->getSharedComponent()->getHashCode(); } return md5( $this->name . $this->size . ($this->bold ? 't' : 'f') . ($this->italic ? 't' : 'f') . ($this->superscript ? 't' : 'f') . ($this->subscript ? 't' : 'f') . $this->underline . ($this->strikethrough ? 't' : 'f') . $this->color->getHashCode() . $this->scheme . implode( '*', [ $this->latin, $this->eastAsian, $this->complexScript, $this->strikeType, $this->hashChartColor($this->chartColor), $this->hashChartColor($this->underlineColor), (string) $this->baseLine, ] ) . __CLASS__ ); } protected function exportArray1(): array { $exportedArray = []; $this->exportArray2($exportedArray, 'baseLine', $this->getBaseLine()); $this->exportArray2($exportedArray, 'bold', $this->getBold()); $this->exportArray2($exportedArray, 'chartColor', $this->getChartColor()); $this->exportArray2($exportedArray, 'color', $this->getColor()); $this->exportArray2($exportedArray, 'complexScript', $this->getComplexScript()); $this->exportArray2($exportedArray, 'eastAsian', $this->getEastAsian()); $this->exportArray2($exportedArray, 'italic', $this->getItalic()); $this->exportArray2($exportedArray, 'latin', $this->getLatin()); $this->exportArray2($exportedArray, 'name', $this->getName()); $this->exportArray2($exportedArray, 'scheme', $this->getScheme()); $this->exportArray2($exportedArray, 'size', $this->getSize()); $this->exportArray2($exportedArray, 'strikethrough', $this->getStrikethrough()); $this->exportArray2($exportedArray, 'strikeType', $this->getStrikeType()); $this->exportArray2($exportedArray, 'subscript', $this->getSubscript()); $this->exportArray2($exportedArray, 'superscript', $this->getSuperscript()); $this->exportArray2($exportedArray, 'underline', $this->getUnderline()); $this->exportArray2($exportedArray, 'underlineColor', $this->getUnderlineColor()); return $exportedArray; } public function getScheme(): string { if ($this->isSupervisor) { return $this->getSharedComponent()->getScheme(); } return $this->scheme; } public function setScheme(string $scheme): self { if ($scheme === '' || $scheme === 'major' || $scheme === 'minor') { if ($this->isSupervisor) { $styleArray = $this->getStyleArray(['scheme' => $scheme]); $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); } else { $this->scheme = $scheme; } } return $this; } } phpspreadsheet/src/PhpSpreadsheet/Style/NumberFormat/Wizard/Scientific.php 0000644 00000002146 15060132323 0023021 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Style\NumberFormat\Wizard; use PhpOffice\PhpSpreadsheet\Exception; class Scientific extends NumberBase implements Wizard { /** * @param int $decimals number of decimal places to display, in the range 0-30 * @param ?string $locale Set the locale for the scientific format; or leave as the default null. * Locale has no effect for Scientific Format values, and is retained here for compatibility * with the other Wizards. * If provided, Locale values must be a valid formatted locale string (e.g. 'en-GB', 'fr', uz-Arab-AF). * * @throws Exception If a provided locale code is not a valid format */ public function __construct(int $decimals = 2, ?string $locale = null) { $this->setDecimals($decimals); $this->setLocale($locale); } protected function getLocaleFormat(): string { return $this->format(); } public function format(): string { return sprintf('0%sE+00', $this->decimals > 0 ? '.' . str_repeat('0', $this->decimals) : null); } } phpspreadsheet/src/PhpSpreadsheet/Style/NumberFormat/Wizard/Duration.php 0000644 00000011177 15060132323 0022532 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Style\NumberFormat\Wizard; class Duration extends DateTimeWizard { public const DAYS_DURATION = 'd'; /** * Hours as a duration (can exceed 24), e.g. 29. */ public const HOURS_DURATION = '[h]'; /** * Hours without a leading zero, e.g. 9. */ public const HOURS_SHORT = 'h'; /** * Hours with a leading zero, e.g. 09. */ public const HOURS_LONG = 'hh'; /** * Minutes as a duration (can exceed 60), e.g. 109. */ public const MINUTES_DURATION = '[m]'; /** * Minutes without a leading zero, e.g. 5. */ public const MINUTES_SHORT = 'm'; /** * Minutes with a leading zero, e.g. 05. */ public const MINUTES_LONG = 'mm'; /** * Seconds as a duration (can exceed 60), e.g. 129. */ public const SECONDS_DURATION = '[s]'; /** * Seconds without a leading zero, e.g. 2. */ public const SECONDS_SHORT = 's'; /** * Seconds with a leading zero, e.g. 02. */ public const SECONDS_LONG = 'ss'; protected const DURATION_BLOCKS = [ self::DAYS_DURATION, self::HOURS_DURATION, self::HOURS_LONG, self::HOURS_SHORT, self::MINUTES_DURATION, self::MINUTES_LONG, self::MINUTES_SHORT, self::SECONDS_DURATION, self::SECONDS_LONG, self::SECONDS_SHORT, ]; protected const DURATION_MASKS = [ self::DAYS_DURATION => self::DAYS_DURATION, self::HOURS_DURATION => self::HOURS_SHORT, self::MINUTES_DURATION => self::MINUTES_LONG, self::SECONDS_DURATION => self::SECONDS_LONG, ]; protected const DURATION_DEFAULTS = [ self::HOURS_LONG => self::HOURS_DURATION, self::HOURS_SHORT => self::HOURS_DURATION, self::MINUTES_LONG => self::MINUTES_DURATION, self::MINUTES_SHORT => self::MINUTES_DURATION, self::SECONDS_LONG => self::SECONDS_DURATION, self::SECONDS_SHORT => self::SECONDS_DURATION, ]; public const SEPARATOR_COLON = ':'; public const SEPARATOR_SPACE_NONBREAKING = "\u{a0}"; public const SEPARATOR_SPACE = ' '; public const DURATION_DEFAULT = [ self::HOURS_DURATION, self::MINUTES_LONG, self::SECONDS_LONG, ]; /** * @var string[] */ protected array $separators; /** * @var string[] */ protected array $formatBlocks; protected bool $durationIsSet = false; /** * @param null|string|string[] $separators * If you want to use the same separator for all format blocks, then it can be passed as a string literal; * if you wish to use different separators, then they should be passed as an array. * If you want to use only a single format block, then pass a null as the separator argument */ public function __construct($separators = self::SEPARATOR_COLON, string ...$formatBlocks) { $separators ??= self::SEPARATOR_COLON; $formatBlocks = (count($formatBlocks) === 0) ? self::DURATION_DEFAULT : $formatBlocks; $this->separators = $this->padSeparatorArray( is_array($separators) ? $separators : [$separators], count($formatBlocks) - 1 ); $this->formatBlocks = array_map([$this, 'mapFormatBlocks'], $formatBlocks); if ($this->durationIsSet === false) { // We need at least one duration mask, so if none has been set we change the first mask element // to a duration. $this->formatBlocks[0] = self::DURATION_DEFAULTS[mb_strtolower($this->formatBlocks[0])]; } } private function mapFormatBlocks(string $value): string { // Any duration masking codes are returned as lower case values if (in_array(mb_strtolower($value), self::DURATION_BLOCKS, true)) { if (array_key_exists(mb_strtolower($value), self::DURATION_MASKS)) { if ($this->durationIsSet) { // We should only have a single duration mask, the first defined in the mask set, // so convert any additional duration masks to standard time masks. $value = self::DURATION_MASKS[mb_strtolower($value)]; } $this->durationIsSet = true; } return mb_strtolower($value); } // Wrap any string literals in quotes, so that they're clearly defined as string literals return $this->wrapLiteral($value); } public function format(): string { return implode('', array_map([$this, 'intersperse'], $this->formatBlocks, $this->separators)); } } phpspreadsheet/src/PhpSpreadsheet/Style/NumberFormat/Wizard/DateTimeWizard.php 0000644 00000002243 15060132323 0023614 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Style\NumberFormat\Wizard; abstract class DateTimeWizard implements Wizard { protected const NO_ESCAPING_NEEDED = "$+-/():!^&'~{}<>= "; protected function padSeparatorArray(array $separators, int $count): array { $lastSeparator = array_pop($separators); return $separators + array_fill(0, $count, $lastSeparator); } protected function escapeSingleCharacter(string $value): string { if (strpos(self::NO_ESCAPING_NEEDED, $value) !== false) { return $value; } return "\\{$value}"; } protected function wrapLiteral(string $value): string { if (mb_strlen($value, 'UTF-8') === 1) { return $this->escapeSingleCharacter($value); } // Wrap any other string literals in quotes, so that they're clearly defined as string literals return '"' . str_replace('"', '""', $value) . '"'; } protected function intersperse(string $formatBlock, ?string $separator): string { return "{$formatBlock}{$separator}"; } public function __toString(): string { return $this->format(); } } phpspreadsheet/src/PhpSpreadsheet/Style/NumberFormat/Wizard/Locale.php 0000644 00000002116 15060132323 0022135 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Style\NumberFormat\Wizard; use NumberFormatter; use PhpOffice\PhpSpreadsheet\Exception; final class Locale { /** * Language code: ISO-639 2 character, alpha. * Optional script code: ISO-15924 4 alpha. * Optional country code: ISO-3166-1, 2 character alpha. * Separated by underscores or dashes. */ public const STRUCTURE = '/^(?P<language>[a-z]{2})([-_](?P<script>[a-z]{4}))?([-_](?P<country>[a-z]{2}))?$/i'; private NumberFormatter $formatter; public function __construct(?string $locale, int $style) { if (class_exists(NumberFormatter::class) === false) { throw new Exception(); } $formatterLocale = str_replace('-', '_', $locale ?? ''); $this->formatter = new NumberFormatter($formatterLocale, $style); if ($this->formatter->getLocale() !== $formatterLocale) { throw new Exception("Unable to read locale data for '{$locale}'"); } } public function format(): string { return $this->formatter->getPattern(); } } phpspreadsheet/src/PhpSpreadsheet/Style/NumberFormat/Wizard/Wizard.php 0000644 00000000201 15060132323 0022167 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Style\NumberFormat\Wizard; interface Wizard { public function format(): string; } phpspreadsheet/src/PhpSpreadsheet/Style/NumberFormat/Wizard/Percentage.php 0000644 00000002426 15060132323 0023017 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Style\NumberFormat\Wizard; use NumberFormatter; use PhpOffice\PhpSpreadsheet\Exception; class Percentage extends NumberBase implements Wizard { /** * @param int $decimals number of decimal places to display, in the range 0-30 * @param ?string $locale Set the locale for the percentage format; or leave as the default null. * If provided, Locale values must be a valid formatted locale string (e.g. 'en-GB', 'fr', uz-Arab-AF). * * @throws Exception If a provided locale code is not a valid format */ public function __construct(int $decimals = 2, ?string $locale = null) { $this->setDecimals($decimals); $this->setLocale($locale); } protected function getLocaleFormat(): string { $formatter = new Locale($this->fullLocale, NumberFormatter::PERCENT); return $this->decimals > 0 ? str_replace('0', '0.' . str_repeat('0', $this->decimals), $formatter->format()) : $formatter->format(); } public function format(): string { if ($this->localeFormat !== null) { return $this->localeFormat; } return sprintf('0%s%%', $this->decimals > 0 ? '.' . str_repeat('0', $this->decimals) : null); } } phpspreadsheet/src/PhpSpreadsheet/Style/NumberFormat/Wizard/Number.php 0000644 00000003637 15060132323 0022177 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Style\NumberFormat\Wizard; use PhpOffice\PhpSpreadsheet\Exception; class Number extends NumberBase implements Wizard { public const WITH_THOUSANDS_SEPARATOR = true; public const WITHOUT_THOUSANDS_SEPARATOR = false; protected bool $thousandsSeparator = true; /** * @param int $decimals number of decimal places to display, in the range 0-30 * @param bool $thousandsSeparator indicator whether the thousands separator should be used, or not * @param ?string $locale Set the locale for the number format; or leave as the default null. * Locale has no effect for Number Format values, and is retained here only for compatibility * with the other Wizards. * If provided, Locale values must be a valid formatted locale string (e.g. 'en-GB', 'fr', uz-Arab-AF). * * @throws Exception If a provided locale code is not a valid format */ public function __construct( int $decimals = 2, bool $thousandsSeparator = self::WITH_THOUSANDS_SEPARATOR, ?string $locale = null ) { $this->setDecimals($decimals); $this->setThousandsSeparator($thousandsSeparator); $this->setLocale($locale); } public function setThousandsSeparator(bool $thousandsSeparator = self::WITH_THOUSANDS_SEPARATOR): void { $this->thousandsSeparator = $thousandsSeparator; } /** * As MS Excel cannot easily handle Lakh, which is the only locale-specific Number format variant, * we don't use locale with Numbers. */ protected function getLocaleFormat(): string { return $this->format(); } public function format(): string { return sprintf( '%s0%s', $this->thousandsSeparator ? '#,##' : null, $this->decimals > 0 ? '.' . str_repeat('0', $this->decimals) : null ); } } phpspreadsheet/src/PhpSpreadsheet/Style/NumberFormat/Wizard/NumberBase.php 0000644 00000004413 15060132323 0022763 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Style\NumberFormat\Wizard; use NumberFormatter; use PhpOffice\PhpSpreadsheet\Exception; use PhpOffice\PhpSpreadsheet\Style\NumberFormat; abstract class NumberBase { protected const MAX_DECIMALS = 30; protected int $decimals = 2; protected ?string $locale = null; protected ?string $fullLocale = null; protected ?string $localeFormat = null; public function setDecimals(int $decimals = 2): void { $this->decimals = ($decimals > self::MAX_DECIMALS) ? self::MAX_DECIMALS : max($decimals, 0); } /** * Setting a locale will override any settings defined in this class. * * @throws Exception If the locale code is not a valid format */ public function setLocale(?string $locale = null): void { if ($locale === null) { $this->localeFormat = $this->locale = $this->fullLocale = null; return; } $this->locale = $this->validateLocale($locale); if (class_exists(NumberFormatter::class)) { $this->localeFormat = $this->getLocaleFormat(); } } /** * Stub: should be implemented as a concrete method in concrete wizards. */ abstract protected function getLocaleFormat(): string; /** * @throws Exception If the locale code is not a valid format */ private function validateLocale(string $locale): string { if (preg_match(Locale::STRUCTURE, $locale, $matches, PREG_UNMATCHED_AS_NULL) !== 1) { throw new Exception("Invalid locale code '{$locale}'"); } ['language' => $language, 'script' => $script, 'country' => $country] = $matches; // Set case and separator to match standardised locale case $language = strtolower($language ?? ''); $script = ($script === null) ? null : ucfirst(strtolower($script)); $country = ($country === null) ? null : strtoupper($country); $this->fullLocale = implode('-', array_filter([$language, $script, $country])); return $country === null ? $language : "{$language}-{$country}"; } public function format(): string { return NumberFormat::FORMAT_GENERAL; } public function __toString(): string { return $this->format(); } } phpspreadsheet/src/PhpSpreadsheet/Style/NumberFormat/Wizard/Currency.php 0000644 00000010442 15060132323 0022531 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Style\NumberFormat\Wizard; use NumberFormatter; use PhpOffice\PhpSpreadsheet\Exception; class Currency extends Number { public const LEADING_SYMBOL = true; public const TRAILING_SYMBOL = false; public const SYMBOL_WITH_SPACING = true; public const SYMBOL_WITHOUT_SPACING = false; protected string $currencyCode = '$'; protected bool $currencySymbolPosition = self::LEADING_SYMBOL; protected bool $currencySymbolSpacing = self::SYMBOL_WITHOUT_SPACING; /** * @param string $currencyCode the currency symbol or code to display for this mask * @param int $decimals number of decimal places to display, in the range 0-30 * @param bool $thousandsSeparator indicator whether the thousands separator should be used, or not * @param bool $currencySymbolPosition indicates whether the currency symbol comes before or after the value * Possible values are Currency::LEADING_SYMBOL and Currency::TRAILING_SYMBOL * @param bool $currencySymbolSpacing indicates whether there is spacing between the currency symbol and the value * Possible values are Currency::SYMBOL_WITH_SPACING and Currency::SYMBOL_WITHOUT_SPACING * @param ?string $locale Set the locale for the currency format; or leave as the default null. * If provided, Locale values must be a valid formatted locale string (e.g. 'en-GB', 'fr', uz-Arab-AF). * Note that setting a locale will override any other settings defined in this class * other than the currency code; or decimals (unless the decimals value is set to 0). * * @throws Exception If a provided locale code is not a valid format */ public function __construct( string $currencyCode = '$', int $decimals = 2, bool $thousandsSeparator = true, bool $currencySymbolPosition = self::LEADING_SYMBOL, bool $currencySymbolSpacing = self::SYMBOL_WITHOUT_SPACING, ?string $locale = null ) { $this->setCurrencyCode($currencyCode); $this->setThousandsSeparator($thousandsSeparator); $this->setDecimals($decimals); $this->setCurrencySymbolPosition($currencySymbolPosition); $this->setCurrencySymbolSpacing($currencySymbolSpacing); $this->setLocale($locale); } public function setCurrencyCode(string $currencyCode): void { $this->currencyCode = $currencyCode; } public function setCurrencySymbolPosition(bool $currencySymbolPosition = self::LEADING_SYMBOL): void { $this->currencySymbolPosition = $currencySymbolPosition; } public function setCurrencySymbolSpacing(bool $currencySymbolSpacing = self::SYMBOL_WITHOUT_SPACING): void { $this->currencySymbolSpacing = $currencySymbolSpacing; } protected function getLocaleFormat(): string { $formatter = new Locale($this->fullLocale, NumberFormatter::CURRENCY); $mask = $formatter->format(); if ($this->decimals === 0) { $mask = (string) preg_replace('/\.0+/miu', '', $mask); } return str_replace('¤', $this->formatCurrencyCode(), $mask); } private function formatCurrencyCode(): string { if ($this->locale === null) { return $this->currencyCode; } return "[\${$this->currencyCode}-{$this->locale}]"; } public function format(): string { if ($this->localeFormat !== null) { return $this->localeFormat; } return sprintf( '%s%s%s0%s%s%s', $this->currencySymbolPosition === self::LEADING_SYMBOL ? $this->formatCurrencyCode() : null, ( $this->currencySymbolPosition === self::LEADING_SYMBOL && $this->currencySymbolSpacing === self::SYMBOL_WITH_SPACING ) ? "\u{a0}" : '', $this->thousandsSeparator ? '#,##' : null, $this->decimals > 0 ? '.' . str_repeat('0', $this->decimals) : null, ( $this->currencySymbolPosition === self::TRAILING_SYMBOL && $this->currencySymbolSpacing === self::SYMBOL_WITH_SPACING ) ? "\u{a0}" : '', $this->currencySymbolPosition === self::TRAILING_SYMBOL ? $this->formatCurrencyCode() : null ); } } phpspreadsheet/src/PhpSpreadsheet/Style/NumberFormat/Wizard/Accounting.php 0000644 00000010174 15060132323 0023033 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Style\NumberFormat\Wizard; use NumberFormatter; use PhpOffice\PhpSpreadsheet\Exception; class Accounting extends Currency { /** * @param string $currencyCode the currency symbol or code to display for this mask * @param int $decimals number of decimal places to display, in the range 0-30 * @param bool $thousandsSeparator indicator whether the thousands separator should be used, or not * @param bool $currencySymbolPosition indicates whether the currency symbol comes before or after the value * Possible values are Currency::LEADING_SYMBOL and Currency::TRAILING_SYMBOL * @param bool $currencySymbolSpacing indicates whether there is spacing between the currency symbol and the value * Possible values are Currency::SYMBOL_WITH_SPACING and Currency::SYMBOL_WITHOUT_SPACING * @param ?string $locale Set the locale for the currency format; or leave as the default null. * If provided, Locale values must be a valid formatted locale string (e.g. 'en-GB', 'fr', uz-Arab-AF). * Note that setting a locale will override any other settings defined in this class * other than the currency code; or decimals (unless the decimals value is set to 0). * * @throws Exception If a provided locale code is not a valid format */ public function __construct( string $currencyCode = '$', int $decimals = 2, bool $thousandsSeparator = true, bool $currencySymbolPosition = self::LEADING_SYMBOL, bool $currencySymbolSpacing = self::SYMBOL_WITHOUT_SPACING, ?string $locale = null ) { $this->setCurrencyCode($currencyCode); $this->setThousandsSeparator($thousandsSeparator); $this->setDecimals($decimals); $this->setCurrencySymbolPosition($currencySymbolPosition); $this->setCurrencySymbolSpacing($currencySymbolSpacing); $this->setLocale($locale); } /** * @throws Exception if the Intl extension and ICU version don't support Accounting formats */ protected function getLocaleFormat(): string { if (version_compare(PHP_VERSION, '7.4.1', '<')) { throw new Exception('The Intl extension does not support Accounting Formats below PHP 7.4.1'); } if ($this->icuVersion() < 53.0) { throw new Exception('The Intl extension does not support Accounting Formats without ICU 53'); } // Scrutinizer does not recognize CURRENCY_ACCOUNTING $formatter = new Locale($this->fullLocale, NumberFormatter::CURRENCY_ACCOUNTING); $mask = $formatter->format(); if ($this->decimals === 0) { $mask = (string) preg_replace('/\.0+/miu', '', $mask); } return str_replace('¤', $this->formatCurrencyCode(), $mask); } private function icuVersion(): float { [$major, $minor] = explode('.', INTL_ICU_VERSION); return (float) "{$major}.{$minor}"; } private function formatCurrencyCode(): string { if ($this->locale === null) { return $this->currencyCode . '*'; } return "[\${$this->currencyCode}-{$this->locale}]"; } public function format(): string { if ($this->localeFormat !== null) { return $this->localeFormat; } return sprintf( '_-%s%s%s0%s%s%s_-', $this->currencySymbolPosition === self::LEADING_SYMBOL ? $this->formatCurrencyCode() : null, ( $this->currencySymbolPosition === self::LEADING_SYMBOL && $this->currencySymbolSpacing === self::SYMBOL_WITH_SPACING ) ? "\u{a0}" : '', $this->thousandsSeparator ? '#,##' : null, $this->decimals > 0 ? '.' . str_repeat('0', $this->decimals) : null, ( $this->currencySymbolPosition === self::TRAILING_SYMBOL && $this->currencySymbolSpacing === self::SYMBOL_WITH_SPACING ) ? "\u{a0}" : '', $this->currencySymbolPosition === self::TRAILING_SYMBOL ? $this->formatCurrencyCode() : null ); } } phpspreadsheet/src/PhpSpreadsheet/Style/NumberFormat/Wizard/Date.php 0000644 00000006704 15060132323 0021622 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Style\NumberFormat\Wizard; class Date extends DateTimeWizard { /** * Year (4 digits), e.g. 2023. */ public const YEAR_FULL = 'yyyy'; /** * Year (last 2 digits), e.g. 23. */ public const YEAR_SHORT = 'yy'; public const MONTH_FIRST_LETTER = 'mmmmm'; /** * Month name, long form, e.g. January. */ public const MONTH_NAME_FULL = 'mmmm'; /** * Month name, short form, e.g. Jan. */ public const MONTH_NAME_SHORT = 'mmm'; /** * Month number with a leading zero if required, e.g. 01. */ public const MONTH_NUMBER_LONG = 'mm'; /** * Month number without a leading zero, e.g. 1. */ public const MONTH_NUMBER_SHORT = 'm'; /** * Day of the week, full form, e.g. Tuesday. */ public const WEEKDAY_NAME_LONG = 'dddd'; /** * Day of the week, short form, e.g. Tue. */ public const WEEKDAY_NAME_SHORT = 'ddd'; /** * Day number with a leading zero, e.g. 03. */ public const DAY_NUMBER_LONG = 'dd'; /** * Day number without a leading zero, e.g. 3. */ public const DAY_NUMBER_SHORT = 'd'; protected const DATE_BLOCKS = [ self::YEAR_FULL, self::YEAR_SHORT, self::MONTH_FIRST_LETTER, self::MONTH_NAME_FULL, self::MONTH_NAME_SHORT, self::MONTH_NUMBER_LONG, self::MONTH_NUMBER_SHORT, self::WEEKDAY_NAME_LONG, self::WEEKDAY_NAME_SHORT, self::DAY_NUMBER_LONG, self::DAY_NUMBER_SHORT, ]; public const SEPARATOR_DASH = '-'; public const SEPARATOR_DOT = '.'; public const SEPARATOR_SLASH = '/'; public const SEPARATOR_SPACE_NONBREAKING = "\u{a0}"; public const SEPARATOR_SPACE = ' '; protected const DATE_DEFAULT = [ self::YEAR_FULL, self::MONTH_NUMBER_LONG, self::DAY_NUMBER_LONG, ]; /** * @var string[] */ protected array $separators; /** * @var string[] */ protected array $formatBlocks; /** * @param null|string|string[] $separators * If you want to use the same separator for all format blocks, then it can be passed as a string literal; * if you wish to use different separators, then they should be passed as an array. * If you want to use only a single format block, then pass a null as the separator argument */ public function __construct($separators = self::SEPARATOR_DASH, string ...$formatBlocks) { $separators ??= self::SEPARATOR_DASH; $formatBlocks = (count($formatBlocks) === 0) ? self::DATE_DEFAULT : $formatBlocks; $this->separators = $this->padSeparatorArray( is_array($separators) ? $separators : [$separators], count($formatBlocks) - 1 ); $this->formatBlocks = array_map([$this, 'mapFormatBlocks'], $formatBlocks); } private function mapFormatBlocks(string $value): string { // Any date masking codes are returned as lower case values if (in_array(mb_strtolower($value), self::DATE_BLOCKS, true)) { return mb_strtolower($value); } // Wrap any string literals in quotes, so that they're clearly defined as string literals return $this->wrapLiteral($value); } public function format(): string { return implode('', array_map([$this, 'intersperse'], $this->formatBlocks, $this->separators)); } } phpspreadsheet/src/PhpSpreadsheet/Style/NumberFormat/Wizard/Time.php 0000644 00000005711 15060132323 0021640 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Style\NumberFormat\Wizard; class Time extends DateTimeWizard { /** * Hours without a leading zero, e.g. 9. */ public const HOURS_SHORT = 'h'; /** * Hours with a leading zero, e.g. 09. */ public const HOURS_LONG = 'hh'; /** * Minutes without a leading zero, e.g. 5. */ public const MINUTES_SHORT = 'm'; /** * Minutes with a leading zero, e.g. 05. */ public const MINUTES_LONG = 'mm'; /** * Seconds without a leading zero, e.g. 2. */ public const SECONDS_SHORT = 's'; /** * Seconds with a leading zero, e.g. 02. */ public const SECONDS_LONG = 'ss'; public const MORNING_AFTERNOON = 'AM/PM'; protected const TIME_BLOCKS = [ self::HOURS_LONG, self::HOURS_SHORT, self::MINUTES_LONG, self::MINUTES_SHORT, self::SECONDS_LONG, self::SECONDS_SHORT, self::MORNING_AFTERNOON, ]; public const SEPARATOR_COLON = ':'; public const SEPARATOR_SPACE_NONBREAKING = "\u{a0}"; public const SEPARATOR_SPACE = ' '; protected const TIME_DEFAULT = [ self::HOURS_LONG, self::MINUTES_LONG, self::SECONDS_LONG, ]; /** * @var string[] */ protected array $separators; /** * @var string[] */ protected array $formatBlocks; /** * @param null|string|string[] $separators * If you want to use the same separator for all format blocks, then it can be passed as a string literal; * if you wish to use different separators, then they should be passed as an array. * If you want to use only a single format block, then pass a null as the separator argument */ public function __construct($separators = self::SEPARATOR_COLON, string ...$formatBlocks) { $separators ??= self::SEPARATOR_COLON; $formatBlocks = (count($formatBlocks) === 0) ? self::TIME_DEFAULT : $formatBlocks; $this->separators = $this->padSeparatorArray( is_array($separators) ? $separators : [$separators], count($formatBlocks) - 1 ); $this->formatBlocks = array_map([$this, 'mapFormatBlocks'], $formatBlocks); } private function mapFormatBlocks(string $value): string { // Any date masking codes are returned as lower case values // except for AM/PM, which is set to uppercase if (in_array(mb_strtolower($value), self::TIME_BLOCKS, true)) { return mb_strtolower($value); } elseif (mb_strtoupper($value) === self::MORNING_AFTERNOON) { return mb_strtoupper($value); } // Wrap any string literals in quotes, so that they're clearly defined as string literals return $this->wrapLiteral($value); } public function format(): string { return implode('', array_map([$this, 'intersperse'], $this->formatBlocks, $this->separators)); } } phpspreadsheet/src/PhpSpreadsheet/Style/NumberFormat/Wizard/DateTime.php 0000644 00000002656 15060132323 0022443 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Style\NumberFormat\Wizard; class DateTime extends DateTimeWizard { /** * @var string[] */ protected array $separators; /** * @var array<DateTimeWizard|string> */ protected array $formatBlocks; /** * @param null|string|string[] $separators * If you want to use only a single format block, then pass a null as the separator argument * @param DateTimeWizard|string ...$formatBlocks */ public function __construct($separators, ...$formatBlocks) { $this->separators = $this->padSeparatorArray( is_array($separators) ? $separators : [$separators], count($formatBlocks) - 1 ); $this->formatBlocks = array_map([$this, 'mapFormatBlocks'], $formatBlocks); } /** * @param DateTimeWizard|string $value */ private function mapFormatBlocks($value): string { // Any date masking codes are returned as lower case values if (is_object($value)) { // We can't explicitly test for Stringable until PHP >= 8.0 return $value; } // Wrap any string literals in quotes, so that they're clearly defined as string literals return $this->wrapLiteral($value); } public function format(): string { return implode('', array_map([$this, 'intersperse'], $this->formatBlocks, $this->separators)); } } phpspreadsheet/src/PhpSpreadsheet/Style/NumberFormat/BaseFormatter.php 0000644 00000000524 15060132323 0022235 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Style\NumberFormat; abstract class BaseFormatter { protected static function stripQuotes(string $format): string { // Some non-number strings are quoted, so we'll get rid of the quotes, likewise any positional * symbols return str_replace(['"', '*'], '', $format); } } phpspreadsheet/src/PhpSpreadsheet/Style/NumberFormat/FractionFormatter.php 0000644 00000004455 15060132323 0023137 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Style\NumberFormat; use PhpOffice\PhpSpreadsheet\Calculation\MathTrig; class FractionFormatter extends BaseFormatter { /** * @param mixed $value */ public static function format($value, string $format): string { $format = self::stripQuotes($format); $value = (float) $value; $absValue = abs($value); $sign = ($value < 0.0) ? '-' : ''; $integerPart = floor($absValue); $decimalPart = self::getDecimal((string) $absValue); if ($decimalPart === '0') { return "{$sign}{$integerPart}"; } $decimalLength = strlen($decimalPart); $decimalDivisor = 10 ** $decimalLength; preg_match('/(#?.*\?)\/(\?+|\d+)/', $format, $matches); $formatIntegerPart = $matches[1]; if (is_numeric($matches[2])) { $fractionDivisor = 100 / (int) $matches[2]; } else { /** @var float */ $fractionDivisor = MathTrig\Gcd::evaluate((int) $decimalPart, $decimalDivisor); } $adjustedDecimalPart = (int) round((int) $decimalPart / $fractionDivisor, 0); $adjustedDecimalDivisor = $decimalDivisor / $fractionDivisor; if ((strpos($formatIntegerPart, '0') !== false)) { return "{$sign}{$integerPart} {$adjustedDecimalPart}/{$adjustedDecimalDivisor}"; } elseif ((strpos($formatIntegerPart, '#') !== false)) { if ($integerPart == 0) { return "{$sign}{$adjustedDecimalPart}/{$adjustedDecimalDivisor}"; } return "{$sign}{$integerPart} {$adjustedDecimalPart}/{$adjustedDecimalDivisor}"; } elseif ((substr($formatIntegerPart, 0, 3) == '? ?')) { if ($integerPart == 0) { $integerPart = ''; } return "{$sign}{$integerPart} {$adjustedDecimalPart}/{$adjustedDecimalDivisor}"; } $adjustedDecimalPart += $integerPart * $adjustedDecimalDivisor; return "{$sign}{$adjustedDecimalPart}/{$adjustedDecimalDivisor}"; } private static function getDecimal(string $value): string { $decimalPart = '0'; if (preg_match('/^\\d*[.](\\d*[1-9])0*$/', $value, $matches) === 1) { $decimalPart = $matches[1]; } return $decimalPart; } } phpspreadsheet/src/PhpSpreadsheet/Style/NumberFormat/NumberFormatter.php 0000644 00000027464 15060132323 0022627 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Style\NumberFormat; use PhpOffice\PhpSpreadsheet\Shared\StringHelper; use PhpOffice\PhpSpreadsheet\Style\NumberFormat; class NumberFormatter { private const NUMBER_REGEX = '/(0+)(\\.?)(0*)/'; private static function mergeComplexNumberFormatMasks(array $numbers, array $masks): array { $decimalCount = strlen($numbers[1]); $postDecimalMasks = []; do { $tempMask = array_pop($masks); if ($tempMask !== null) { $postDecimalMasks[] = $tempMask; $decimalCount -= strlen($tempMask); } } while ($tempMask !== null && $decimalCount > 0); return [ implode('.', $masks), implode('.', array_reverse($postDecimalMasks)), ]; } /** * @param mixed $number */ private static function processComplexNumberFormatMask($number, string $mask): string { /** @var string */ $result = $number; $maskingBlockCount = preg_match_all('/0+/', $mask, $maskingBlocks, PREG_OFFSET_CAPTURE); if ($maskingBlockCount > 1) { $maskingBlocks = array_reverse($maskingBlocks[0]); $offset = 0; foreach ($maskingBlocks as $block) { $size = strlen($block[0]); $divisor = 10 ** $size; $offset = $block[1]; /** @var float */ $numberFloat = $number; $blockValue = sprintf("%0{$size}d", fmod($numberFloat, $divisor)); $number = floor($numberFloat / $divisor); $mask = substr_replace($mask, $blockValue, $offset, $size); } /** @var string */ $numberString = $number; if ($number > 0) { $mask = substr_replace($mask, $numberString, $offset, 0); } $result = $mask; } return self::makeString($result); } /** * @param mixed $number */ private static function complexNumberFormatMask($number, string $mask, bool $splitOnPoint = true): string { /** @var float */ $numberFloat = $number; if ($splitOnPoint) { $masks = explode('.', $mask); if (count($masks) <= 2) { $decmask = $masks[1] ?? ''; $decpos = substr_count($decmask, '0'); $numberFloat = round($numberFloat, $decpos); } } $sign = ($numberFloat < 0.0) ? '-' : ''; $number = self::f2s(abs($numberFloat)); if ($splitOnPoint && strpos($mask, '.') !== false && strpos($number, '.') !== false) { $numbers = explode('.', $number); $masks = explode('.', $mask); if (count($masks) > 2) { $masks = self::mergeComplexNumberFormatMasks($numbers, $masks); } $integerPart = self::complexNumberFormatMask($numbers[0], $masks[0], false); $numlen = strlen($numbers[1]); $msklen = strlen($masks[1]); if ($numlen < $msklen) { $numbers[1] .= str_repeat('0', $msklen - $numlen); } $decimalPart = strrev(self::complexNumberFormatMask(strrev($numbers[1]), strrev($masks[1]), false)); $decimalPart = substr($decimalPart, 0, $msklen); return "{$sign}{$integerPart}.{$decimalPart}"; } if (strlen($number) < strlen($mask)) { $number = str_repeat('0', strlen($mask) - strlen($number)) . $number; } $result = self::processComplexNumberFormatMask($number, $mask); return "{$sign}{$result}"; } public static function f2s(float $f): string { return self::floatStringConvertScientific((string) $f); } public static function floatStringConvertScientific(string $s): string { // convert only normalized form of scientific notation: // optional sign, single digit 1-9, // decimal point and digits (allowed to be omitted), // E (e permitted), optional sign, one or more digits if (preg_match('/^([+-])?([1-9])([.]([0-9]+))?[eE]([+-]?[0-9]+)$/', $s, $matches) === 1) { $exponent = (int) $matches[5]; $sign = ($matches[1] === '-') ? '-' : ''; if ($exponent >= 0) { $exponentPlus1 = $exponent + 1; $out = $matches[2] . $matches[4]; $len = strlen($out); if ($len < $exponentPlus1) { $out .= str_repeat('0', $exponentPlus1 - $len); } $out = substr($out, 0, $exponentPlus1) . ((strlen($out) === $exponentPlus1) ? '' : ('.' . substr($out, $exponentPlus1))); $s = "$sign$out"; } else { $s = $sign . '0.' . str_repeat('0', -$exponent - 1) . $matches[2] . $matches[4]; } } return $s; } /** * @param mixed $value */ private static function formatStraightNumericValue($value, string $format, array $matches, bool $useThousands): string { /** @var float */ $valueFloat = $value; $left = $matches[1]; $dec = $matches[2]; $right = $matches[3]; // minimun width of formatted number (including dot) $minWidth = strlen($left) + strlen($dec) + strlen($right); if ($useThousands) { $value = number_format( $valueFloat, strlen($right), StringHelper::getDecimalSeparator(), StringHelper::getThousandsSeparator() ); return self::pregReplace(self::NUMBER_REGEX, $value, $format); } if (preg_match('/[0#]E[+-]0/i', $format)) { // Scientific format $decimals = strlen($right); $size = $decimals + 3; return sprintf("%{$size}.{$decimals}E", $valueFloat); } elseif (preg_match('/0([^\d\.]+)0/', $format) || substr_count($format, '.') > 1) { if ($valueFloat == floor($valueFloat) && substr_count($format, '.') === 1) { $value *= 10 ** strlen(explode('.', $format)[1]); } $result = self::complexNumberFormatMask($value, $format); if (strpos($result, 'E') !== false) { // This is a hack and doesn't match Excel. // It will, at least, be an accurate representation, // even if formatted incorrectly. // This is needed for absolute values >=1E18. $result = self::f2s($valueFloat); } return $result; } $sprintf_pattern = "%0$minWidth." . strlen($right) . 'f'; /** @var float */ $valueFloat = $value; $value = sprintf($sprintf_pattern, round($valueFloat, strlen($right))); return self::pregReplace(self::NUMBER_REGEX, $value, $format); } /** * @param mixed $value */ public static function format($value, string $format): string { // The "_" in this string has already been stripped out, // so this test is never true. Furthermore, testing // on Excel shows this format uses Euro symbol, not "EUR". // if ($format === NumberFormat::FORMAT_CURRENCY_EUR_SIMPLE) { // return 'EUR ' . sprintf('%1.2f', $value); // } $baseFormat = $format; $useThousands = self::areThousandsRequired($format); $scale = self::scaleThousandsMillions($format); if (preg_match('/[#\?0]?.*[#\?0]\/(\?+|\d+|#)/', $format)) { // It's a dirty hack; but replace # and 0 digit placeholders with ? $format = (string) preg_replace('/[#0]+\//', '?/', $format); $format = (string) preg_replace('/\/[#0]+/', '/?', $format); $value = FractionFormatter::format($value, $format); } else { // Handle the number itself // scale number $value = $value / $scale; $paddingPlaceholder = (strpos($format, '?') !== false); // Replace # or ? with 0 $format = self::pregReplace('/[\\#\?](?=(?:[^"]*"[^"]*")*[^"]*\Z)/', '0', $format); // Remove locale code [$-###] for an LCID $format = self::pregReplace('/\[\$\-.*\]/', '', $format); $n = '/\\[[^\\]]+\\]/'; $m = self::pregReplace($n, '', $format); // Some non-number strings are quoted, so we'll get rid of the quotes, likewise any positional * symbols $format = self::makeString(str_replace(['"', '*'], '', $format)); if (preg_match(self::NUMBER_REGEX, $m, $matches)) { // There are placeholders for digits, so inject digits from the value into the mask $value = self::formatStraightNumericValue($value, $format, $matches, $useThousands); if ($paddingPlaceholder === true) { $value = self::padValue($value, $baseFormat); } } elseif ($format !== NumberFormat::FORMAT_GENERAL) { // Yes, I know that this is basically just a hack; // if there's no placeholders for digits, just return the format mask "as is" $value = self::makeString(str_replace('?', '', $format)); } } if (preg_match('/\[\$(.*)\]/u', $format, $m)) { // Currency or Accounting $currencyCode = $m[1]; [$currencyCode] = explode('-', $currencyCode); if ($currencyCode == '') { $currencyCode = StringHelper::getCurrencyCode(); } $value = self::pregReplace('/\[\$([^\]]*)\]/u', $currencyCode, (string) $value); } if ( (strpos((string) $value, '0.') !== false) && ((strpos($baseFormat, '#.') !== false) || (strpos($baseFormat, '?.') !== false)) ) { $value = preg_replace('/(\b)0\.|([^\d])0\./', '${2}.', (string) $value); } return (string) $value; } /** * @param array|string $value */ private static function makeString($value): string { return is_array($value) ? '' : "$value"; } private static function pregReplace(string $pattern, string $replacement, string $subject): string { return self::makeString(preg_replace($pattern, $replacement, $subject) ?? ''); } public static function padValue(string $value, string $baseFormat): string { /** @phpstan-ignore-next-line */ [$preDecimal, $postDecimal] = preg_split('/\.(?=(?:[^"]*"[^"]*")*[^"]*\Z)/miu', $baseFormat . '.?'); $length = strlen($value); if (strpos($postDecimal, '?') !== false) { $value = str_pad(rtrim($value, '0. '), $length, ' ', STR_PAD_RIGHT); } if (strpos($preDecimal, '?') !== false) { $value = str_pad(ltrim($value, '0, '), $length, ' ', STR_PAD_LEFT); } return $value; } /** * Find out if we need thousands separator * This is indicated by a comma enclosed by a digit placeholders: #, 0 or ? */ public static function areThousandsRequired(string &$format): bool { $useThousands = (bool) preg_match('/([#\?0]),([#\?0])/', $format); if ($useThousands) { $format = self::pregReplace('/([#\?0]),([#\?0])/', '${1}${2}', $format); } return $useThousands; } /** * Scale thousands, millions,... * This is indicated by a number of commas after a digit placeholder: #, or 0.0,, or ?,. */ public static function scaleThousandsMillions(string &$format): int { $scale = 1; // same as no scale if (preg_match('/(#|0|\?)(,+)/', $format, $matches)) { $scale = 1000 ** strlen($matches[2]); // strip the commas $format = self::pregReplace('/([#\?0]),+/', '${1}', $format); } return $scale; } } phpspreadsheet/src/PhpSpreadsheet/Style/NumberFormat/Formatter.php 0000644 00000020466 15060132323 0021451 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Style\NumberFormat; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Reader\Xls\Color\BIFF8; use PhpOffice\PhpSpreadsheet\RichText\RichText; use PhpOffice\PhpSpreadsheet\Style\Color; use PhpOffice\PhpSpreadsheet\Style\NumberFormat; class Formatter { /** * Matches any @ symbol that isn't enclosed in quotes. */ private const SYMBOL_AT = '/@(?=(?:[^"]*"[^"]*")*[^"]*\Z)/miu'; /** * Matches any ; symbol that isn't enclosed in quotes, for a "section" split. */ private const SECTION_SPLIT = '/;(?=(?:[^"]*"[^"]*")*[^"]*\Z)/miu'; /** * @param mixed $value * @param mixed $comparisonValue * @param mixed $defaultComparisonValue */ private static function splitFormatComparison( $value, ?string $condition, $comparisonValue, string $defaultCondition, $defaultComparisonValue ): bool { if (!$condition) { $condition = $defaultCondition; $comparisonValue = $defaultComparisonValue; } switch ($condition) { case '>': return $value > $comparisonValue; case '<': return $value < $comparisonValue; case '<=': return $value <= $comparisonValue; case '<>': return $value != $comparisonValue; case '=': return $value == $comparisonValue; } return $value >= $comparisonValue; } /** @param mixed $value */ private static function splitFormatForSectionSelection(array $sections, $value): array { // Extract the relevant section depending on whether number is positive, negative, or zero? // Text not supported yet. // Here is how the sections apply to various values in Excel: // 1 section: [POSITIVE/NEGATIVE/ZERO/TEXT] // 2 sections: [POSITIVE/ZERO/TEXT] [NEGATIVE] // 3 sections: [POSITIVE/TEXT] [NEGATIVE] [ZERO] // 4 sections: [POSITIVE] [NEGATIVE] [ZERO] [TEXT] $sectionCount = count($sections); // Colour could be a named colour, or a numeric index entry in the colour-palette $color_regex = '/\\[(' . implode('|', Color::NAMED_COLORS) . '|color\\s*(\\d+))\\]/mui'; $cond_regex = '/\\[(>|>=|<|<=|=|<>)([+-]?\\d+([.]\\d+)?)\\]/'; $colors = ['', '', '', '', '']; $conditionOperations = ['', '', '', '', '']; $conditionComparisonValues = [0, 0, 0, 0, 0]; for ($idx = 0; $idx < $sectionCount; ++$idx) { if (preg_match($color_regex, $sections[$idx], $matches)) { if (isset($matches[2])) { $colors[$idx] = '#' . BIFF8::lookup((int) $matches[2] + 7)['rgb']; } else { $colors[$idx] = $matches[0]; } $sections[$idx] = (string) preg_replace($color_regex, '', $sections[$idx]); } if (preg_match($cond_regex, $sections[$idx], $matches)) { $conditionOperations[$idx] = $matches[1]; $conditionComparisonValues[$idx] = $matches[2]; $sections[$idx] = (string) preg_replace($cond_regex, '', $sections[$idx]); } } $color = $colors[0]; $format = $sections[0]; $absval = $value; switch ($sectionCount) { case 2: $absval = abs($value); if (!self::splitFormatComparison($value, $conditionOperations[0], $conditionComparisonValues[0], '>=', 0)) { $color = $colors[1]; $format = $sections[1]; } break; case 3: case 4: $absval = abs($value); if (!self::splitFormatComparison($value, $conditionOperations[0], $conditionComparisonValues[0], '>', 0)) { if (self::splitFormatComparison($value, $conditionOperations[1], $conditionComparisonValues[1], '<', 0)) { $color = $colors[1]; $format = $sections[1]; } else { $color = $colors[2]; $format = $sections[2]; } } break; } return [$color, $format, $absval]; } /** * Convert a value in a pre-defined format to a PHP string. * * @param null|bool|float|int|RichText|string $value Value to format * @param string $format Format code: see = self::FORMAT_* for predefined values; * or can be any valid MS Excel custom format string * @param array $callBack Callback function for additional formatting of string * * @return string Formatted string */ public static function toFormattedString($value, $format, $callBack = null) { if (is_bool($value)) { return $value ? Calculation::getTRUE() : Calculation::getFALSE(); } // For now we do not treat strings in sections, although section 4 of a format code affects strings // Process a single block format code containing @ for text substitution if (preg_match(self::SECTION_SPLIT, $format) === 0 && preg_match(self::SYMBOL_AT, $format) === 1) { return str_replace('"', '', preg_replace(self::SYMBOL_AT, (string) $value, $format) ?? ''); } // If we have a text value, return it "as is" if (!is_numeric($value)) { return (string) $value; } // For 'General' format code, we just pass the value although this is not entirely the way Excel does it, // it seems to round numbers to a total of 10 digits. if (($format === NumberFormat::FORMAT_GENERAL) || ($format === NumberFormat::FORMAT_TEXT)) { return (string) $value; } // Ignore square-$-brackets prefix in format string, like "[$-411]ge.m.d", "[$-010419]0%", etc $format = (string) preg_replace('/^\[\$-[^\]]*\]/', '', $format); $format = (string) preg_replace_callback( '/(["])(?:(?=(\\\\?))\\2.)*?\\1/u', function ($matches) { return str_replace('.', chr(0x00), $matches[0]); }, $format ); // Convert any other escaped characters to quoted strings, e.g. (\T to "T") $format = (string) preg_replace('/(\\\(((.)(?!((AM\/PM)|(A\/P))))|([^ ])))(?=(?:[^"]|"[^"]*")*$)/ui', '"${2}"', $format); // Get the sections, there can be up to four sections, separated with a semi-colon (but only if not a quoted literal) $sections = preg_split(self::SECTION_SPLIT, $format) ?: []; [$colors, $format, $value] = self::splitFormatForSectionSelection($sections, $value); // In Excel formats, "_" is used to add spacing, // The following character indicates the size of the spacing, which we can't do in HTML, so we just use a standard space $format = (string) preg_replace('/_.?/ui', ' ', $format); // Let's begin inspecting the format and converting the value to a formatted string if ( // Check for date/time characters (not inside quotes) (preg_match('/(\[\$[A-Z]*-[0-9A-F]*\])*[hmsdy](?=(?:[^"]|"[^"]*")*$)/miu', $format)) // A date/time with a decimal time shouldn't have a digit placeholder before the decimal point && (preg_match('/[0\?#]\.(?![^\[]*\])/miu', $format) === 0) ) { // datetime format $value = DateFormatter::format($value, $format); } else { if (substr($format, 0, 1) === '"' && substr($format, -1, 1) === '"' && substr_count($format, '"') === 2) { $value = substr($format, 1, -1); } elseif (preg_match('/[0#, ]%/', $format)) { // % number format - avoid weird '-0' problem $value = PercentageFormatter::format(0 + (float) $value, $format); } else { $value = NumberFormatter::format($value, $format); } } // Additional formatting provided by callback function if ($callBack !== null) { [$writerInstance, $function] = $callBack; $value = $writerInstance->$function($value, $colors); } return str_replace(chr(0x00), '.', $value); } } phpspreadsheet/src/PhpSpreadsheet/Style/NumberFormat/DateFormatter.php 0000644 00000014775 15060132323 0022255 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Style\NumberFormat; use PhpOffice\PhpSpreadsheet\Shared\Date; class DateFormatter { /** * Search/replace values to convert Excel date/time format masks to PHP format masks. */ private const DATE_FORMAT_REPLACEMENTS = [ // first remove escapes related to non-format characters '\\' => '', // 12-hour suffix 'am/pm' => 'A', // 4-digit year 'e' => 'Y', 'yyyy' => 'Y', // 2-digit year 'yy' => 'y', // first letter of month - no php equivalent 'mmmmm' => 'M', // full month name 'mmmm' => 'F', // short month name 'mmm' => 'M', // mm is minutes if time, but can also be month w/leading zero // so we try to identify times be the inclusion of a : separator in the mask // It isn't perfect, but the best way I know how ':mm' => ':i', 'mm:' => 'i:', // full day of week name 'dddd' => 'l', // short day of week name 'ddd' => 'D', // days leading zero 'dd' => 'd', // days no leading zero 'd' => 'j', // fractional seconds - no php equivalent '.s' => '', ]; /** * Search/replace values to convert Excel date/time format masks hours to PHP format masks (24 hr clock). */ private const DATE_FORMAT_REPLACEMENTS24 = [ 'hh' => 'H', 'h' => 'G', // month leading zero 'mm' => 'm', // month no leading zero 'm' => 'n', // seconds 'ss' => 's', ]; /** * Search/replace values to convert Excel date/time format masks hours to PHP format masks (12 hr clock). */ private const DATE_FORMAT_REPLACEMENTS12 = [ 'hh' => 'h', 'h' => 'g', // month leading zero 'mm' => 'm', // month no leading zero 'm' => 'n', // seconds 'ss' => 's', ]; private const HOURS_IN_DAY = 24; private const MINUTES_IN_DAY = 60 * self::HOURS_IN_DAY; private const SECONDS_IN_DAY = 60 * self::MINUTES_IN_DAY; private const INTERVAL_PRECISION = 10; private const INTERVAL_LEADING_ZERO = [ '[hh]', '[mm]', '[ss]', ]; private const INTERVAL_ROUND_PRECISION = [ // hours and minutes truncate '[h]' => self::INTERVAL_PRECISION, '[hh]' => self::INTERVAL_PRECISION, '[m]' => self::INTERVAL_PRECISION, '[mm]' => self::INTERVAL_PRECISION, // seconds round '[s]' => 0, '[ss]' => 0, ]; private const INTERVAL_MULTIPLIER = [ '[h]' => self::HOURS_IN_DAY, '[hh]' => self::HOURS_IN_DAY, '[m]' => self::MINUTES_IN_DAY, '[mm]' => self::MINUTES_IN_DAY, '[s]' => self::SECONDS_IN_DAY, '[ss]' => self::SECONDS_IN_DAY, ]; /** @param mixed $value */ private static function tryInterval(bool &$seekingBracket, string &$block, $value, string $format): void { if ($seekingBracket) { if (false !== strpos($block, $format)) { $hours = (string) (int) round( self::INTERVAL_MULTIPLIER[$format] * $value, self::INTERVAL_ROUND_PRECISION[$format] ); if (strlen($hours) === 1 && in_array($format, self::INTERVAL_LEADING_ZERO, true)) { $hours = "0$hours"; } $block = str_replace($format, $hours, $block); $seekingBracket = false; } } } /** @param mixed $value */ public static function format($value, string $format): string { // strip off first part containing e.g. [$-F800] or [$USD-409] // general syntax: [$<Currency string>-<language info>] // language info is in hexadecimal // strip off chinese part like [DBNum1][$-804] $format = (string) preg_replace('/^(\[DBNum\d\])*(\[\$[^\]]*\])/i', '', $format); // OpenOffice.org uses upper-case number formats, e.g. 'YYYY', convert to lower-case; // but we don't want to change any quoted strings /** @var callable */ $callable = [self::class, 'setLowercaseCallback']; $format = (string) preg_replace_callback('/(?:^|")([^"]*)(?:$|")/', $callable, $format); // Only process the non-quoted blocks for date format characters $blocks = explode('"', $format); foreach ($blocks as $key => &$block) { if ($key % 2 == 0) { $block = strtr($block, self::DATE_FORMAT_REPLACEMENTS); if (!strpos($block, 'A')) { // 24-hour time format // when [h]:mm format, the [h] should replace to the hours of the value * 24 $seekingBracket = true; self::tryInterval($seekingBracket, $block, $value, '[h]'); self::tryInterval($seekingBracket, $block, $value, '[hh]'); self::tryInterval($seekingBracket, $block, $value, '[mm]'); self::tryInterval($seekingBracket, $block, $value, '[m]'); self::tryInterval($seekingBracket, $block, $value, '[s]'); self::tryInterval($seekingBracket, $block, $value, '[ss]'); $block = strtr($block, self::DATE_FORMAT_REPLACEMENTS24); } else { // 12-hour time format $block = strtr($block, self::DATE_FORMAT_REPLACEMENTS12); } } } $format = implode('"', $blocks); // escape any quoted characters so that DateTime format() will render them correctly /** @var callable */ $callback = [self::class, 'escapeQuotesCallback']; $format = (string) preg_replace_callback('/"(.*)"/U', $callback, $format); $dateObj = Date::excelToDateTimeObject($value); // If the colon preceding minute had been quoted, as happens in // Excel 2003 XML formats, m will not have been changed to i above. // Change it now. $format = (string) \preg_replace('/\\\\:m/', ':i', $format); return $dateObj->format($format); } private static function setLowercaseCallback(array $matches): string { return mb_strtolower($matches[0]); } private static function escapeQuotesCallback(array $matches): string { return '\\' . implode('\\', /** @scrutinizer ignore-type */ str_split($matches[1])); } } phpspreadsheet/src/PhpSpreadsheet/Style/NumberFormat/PercentageFormatter.php 0000644 00000003412 15060132323 0023437 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Style\NumberFormat; use PhpOffice\PhpSpreadsheet\Style\NumberFormat; class PercentageFormatter extends BaseFormatter { /** @param float|int $value */ public static function format($value, string $format): string { if ($format === NumberFormat::FORMAT_PERCENTAGE) { return round((100 * $value), 0) . '%'; } $value *= 100; $format = self::stripQuotes($format); [, $vDecimals] = explode('.', ((string) $value) . '.'); $vDecimalCount = strlen(rtrim($vDecimals, '0')); $format = str_replace('%', '%%', $format); $wholePartSize = strlen((string) floor($value)); $decimalPartSize = 0; $placeHolders = ''; // Number of decimals if (preg_match('/\.([?0]+)/u', $format, $matches)) { $decimalPartSize = strlen($matches[1]); $vMinDecimalCount = strlen(rtrim($matches[1], '?')); $decimalPartSize = min(max($vMinDecimalCount, $vDecimalCount), $decimalPartSize); $placeHolders = str_repeat(' ', strlen($matches[1]) - $decimalPartSize); } // Number of digits to display before the decimal if (preg_match('/([#0,]+)\.?/u', $format, $matches)) { $firstZero = preg_replace('/^[#,]*/', '', $matches[1]) ?? ''; $wholePartSize = max($wholePartSize, strlen($firstZero)); } $wholePartSize += $decimalPartSize + (int) ($decimalPartSize > 0); $replacement = "0{$wholePartSize}.{$decimalPartSize}"; $mask = (string) preg_replace('/[#0,]+\.?[?#0,]*/ui', "%{$replacement}f{$placeHolders}", $format); /** @var float */ $valueFloat = $value; return sprintf($mask, round($valueFloat, $decimalPartSize)); } } phpspreadsheet/src/PhpSpreadsheet/Style/Fill.php 0000644 00000022745 15060132323 0015775 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Style; class Fill extends Supervisor { // Fill types const FILL_NONE = 'none'; const FILL_SOLID = 'solid'; const FILL_GRADIENT_LINEAR = 'linear'; const FILL_GRADIENT_PATH = 'path'; const FILL_PATTERN_DARKDOWN = 'darkDown'; const FILL_PATTERN_DARKGRAY = 'darkGray'; const FILL_PATTERN_DARKGRID = 'darkGrid'; const FILL_PATTERN_DARKHORIZONTAL = 'darkHorizontal'; const FILL_PATTERN_DARKTRELLIS = 'darkTrellis'; const FILL_PATTERN_DARKUP = 'darkUp'; const FILL_PATTERN_DARKVERTICAL = 'darkVertical'; const FILL_PATTERN_GRAY0625 = 'gray0625'; const FILL_PATTERN_GRAY125 = 'gray125'; const FILL_PATTERN_LIGHTDOWN = 'lightDown'; const FILL_PATTERN_LIGHTGRAY = 'lightGray'; const FILL_PATTERN_LIGHTGRID = 'lightGrid'; const FILL_PATTERN_LIGHTHORIZONTAL = 'lightHorizontal'; const FILL_PATTERN_LIGHTTRELLIS = 'lightTrellis'; const FILL_PATTERN_LIGHTUP = 'lightUp'; const FILL_PATTERN_LIGHTVERTICAL = 'lightVertical'; const FILL_PATTERN_MEDIUMGRAY = 'mediumGray'; /** * @var null|int */ public $startcolorIndex; /** * @var null|int */ public $endcolorIndex; /** * Fill type. * * @var null|string */ protected $fillType = self::FILL_NONE; /** * Rotation. * * @var float */ protected $rotation = 0.0; /** * Start color. * * @var Color */ protected $startColor; /** * End color. * * @var Color */ protected $endColor; /** @var bool */ private $colorChanged = false; /** * Create a new Fill. * * @param bool $isSupervisor Flag indicating if this is a supervisor or not * Leave this value at default unless you understand exactly what * its ramifications are * @param bool $isConditional Flag indicating if this is a conditional style or not * Leave this value at default unless you understand exactly what * its ramifications are */ public function __construct($isSupervisor = false, $isConditional = false) { // Supervisor? parent::__construct($isSupervisor); // Initialise values if ($isConditional) { $this->fillType = null; } $this->startColor = new Color(Color::COLOR_WHITE, $isSupervisor, $isConditional); $this->endColor = new Color(Color::COLOR_BLACK, $isSupervisor, $isConditional); // bind parent if we are a supervisor if ($isSupervisor) { $this->startColor->bindParent($this, 'startColor'); $this->endColor->bindParent($this, 'endColor'); } } /** * Get the shared style component for the currently active cell in currently active sheet. * Only used for style supervisor. * * @return Fill */ public function getSharedComponent() { /** @var Style */ $parent = $this->parent; return $parent->getSharedComponent()->getFill(); } /** * Build style array from subcomponents. * * @param array $array * * @return array */ public function getStyleArray($array) { return ['fill' => $array]; } /** * Apply styles from array. * * <code> * $spreadsheet->getActiveSheet()->getStyle('B2')->getFill()->applyFromArray( * [ * 'fillType' => Fill::FILL_GRADIENT_LINEAR, * 'rotation' => 0.0, * 'startColor' => [ * 'rgb' => '000000' * ], * 'endColor' => [ * 'argb' => 'FFFFFFFF' * ] * ] * ); * </code> * * @param array $styleArray Array containing style information * * @return $this */ public function applyFromArray(array $styleArray) { if ($this->isSupervisor) { $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($styleArray)); } else { if (isset($styleArray['fillType'])) { $this->setFillType($styleArray['fillType']); } if (isset($styleArray['rotation'])) { $this->setRotation($styleArray['rotation']); } if (isset($styleArray['startColor'])) { $this->getStartColor()->applyFromArray($styleArray['startColor']); } if (isset($styleArray['endColor'])) { $this->getEndColor()->applyFromArray($styleArray['endColor']); } if (isset($styleArray['color'])) { $this->getStartColor()->applyFromArray($styleArray['color']); $this->getEndColor()->applyFromArray($styleArray['color']); } } return $this; } /** * Get Fill Type. * * @return null|string */ public function getFillType() { if ($this->isSupervisor) { return $this->getSharedComponent()->getFillType(); } return $this->fillType; } /** * Set Fill Type. * * @param string $fillType Fill type, see self::FILL_* * * @return $this */ public function setFillType($fillType) { if ($this->isSupervisor) { $styleArray = $this->getStyleArray(['fillType' => $fillType]); $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); } else { $this->fillType = $fillType; } return $this; } /** * Get Rotation. * * @return float */ public function getRotation() { if ($this->isSupervisor) { return $this->getSharedComponent()->getRotation(); } return $this->rotation; } /** * Set Rotation. * * @param float $angleInDegrees * * @return $this */ public function setRotation($angleInDegrees) { if ($this->isSupervisor) { $styleArray = $this->getStyleArray(['rotation' => $angleInDegrees]); $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); } else { $this->rotation = $angleInDegrees; } return $this; } /** * Get Start Color. * * @return Color */ public function getStartColor() { return $this->startColor; } /** * Set Start Color. * * @return $this */ public function setStartColor(Color $color) { $this->colorChanged = true; // make sure parameter is a real color and not a supervisor $color = $color->getIsSupervisor() ? $color->getSharedComponent() : $color; if ($this->isSupervisor) { $styleArray = $this->getStartColor()->getStyleArray(['argb' => $color->getARGB()]); $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); } else { $this->startColor = $color; } return $this; } /** * Get End Color. * * @return Color */ public function getEndColor() { return $this->endColor; } /** * Set End Color. * * @return $this */ public function setEndColor(Color $color) { $this->colorChanged = true; // make sure parameter is a real color and not a supervisor $color = $color->getIsSupervisor() ? $color->getSharedComponent() : $color; if ($this->isSupervisor) { $styleArray = $this->getEndColor()->getStyleArray(['argb' => $color->getARGB()]); $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); } else { $this->endColor = $color; } return $this; } public function getColorsChanged(): bool { if ($this->isSupervisor) { $changed = $this->getSharedComponent()->colorChanged; } else { $changed = $this->colorChanged; } return $changed || $this->startColor->getHasChanged() || $this->endColor->getHasChanged(); } /** * Get hash code. * * @return string Hash code */ public function getHashCode() { if ($this->isSupervisor) { return $this->getSharedComponent()->getHashCode(); } // Note that we don't care about colours for fill type NONE, but could have duplicate NONEs with // different hashes if we don't explicitly prevent this return md5( $this->getFillType() . $this->getRotation() . ($this->getFillType() !== self::FILL_NONE ? $this->getStartColor()->getHashCode() : '') . ($this->getFillType() !== self::FILL_NONE ? $this->getEndColor()->getHashCode() : '') . ((string) $this->getColorsChanged()) . __CLASS__ ); } protected function exportArray1(): array { $exportedArray = []; $this->exportArray2($exportedArray, 'fillType', $this->getFillType()); $this->exportArray2($exportedArray, 'rotation', $this->getRotation()); if ($this->getColorsChanged()) { $this->exportArray2($exportedArray, 'endColor', $this->getEndColor()); $this->exportArray2($exportedArray, 'startColor', $this->getStartColor()); } return $exportedArray; } } phpspreadsheet/src/PhpSpreadsheet/Style/Conditional.php 0000644 00000017021 15060132323 0017341 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Style; use PhpOffice\PhpSpreadsheet\IComparable; use PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\ConditionalDataBar; class Conditional implements IComparable { // Condition types const CONDITION_NONE = 'none'; const CONDITION_BEGINSWITH = 'beginsWith'; const CONDITION_CELLIS = 'cellIs'; const CONDITION_CONTAINSBLANKS = 'containsBlanks'; const CONDITION_CONTAINSERRORS = 'containsErrors'; const CONDITION_CONTAINSTEXT = 'containsText'; const CONDITION_DATABAR = 'dataBar'; const CONDITION_ENDSWITH = 'endsWith'; const CONDITION_EXPRESSION = 'expression'; const CONDITION_NOTCONTAINSBLANKS = 'notContainsBlanks'; const CONDITION_NOTCONTAINSERRORS = 'notContainsErrors'; const CONDITION_NOTCONTAINSTEXT = 'notContainsText'; const CONDITION_TIMEPERIOD = 'timePeriod'; const CONDITION_DUPLICATES = 'duplicateValues'; const CONDITION_UNIQUE = 'uniqueValues'; private const CONDITION_TYPES = [ self::CONDITION_BEGINSWITH, self::CONDITION_CELLIS, self::CONDITION_CONTAINSBLANKS, self::CONDITION_CONTAINSERRORS, self::CONDITION_CONTAINSTEXT, self::CONDITION_DATABAR, self::CONDITION_DUPLICATES, self::CONDITION_ENDSWITH, self::CONDITION_EXPRESSION, self::CONDITION_NONE, self::CONDITION_NOTCONTAINSBLANKS, self::CONDITION_NOTCONTAINSERRORS, self::CONDITION_NOTCONTAINSTEXT, self::CONDITION_TIMEPERIOD, self::CONDITION_UNIQUE, ]; // Operator types const OPERATOR_NONE = ''; const OPERATOR_BEGINSWITH = 'beginsWith'; const OPERATOR_ENDSWITH = 'endsWith'; const OPERATOR_EQUAL = 'equal'; const OPERATOR_GREATERTHAN = 'greaterThan'; const OPERATOR_GREATERTHANOREQUAL = 'greaterThanOrEqual'; const OPERATOR_LESSTHAN = 'lessThan'; const OPERATOR_LESSTHANOREQUAL = 'lessThanOrEqual'; const OPERATOR_NOTEQUAL = 'notEqual'; const OPERATOR_CONTAINSTEXT = 'containsText'; const OPERATOR_NOTCONTAINS = 'notContains'; const OPERATOR_BETWEEN = 'between'; const OPERATOR_NOTBETWEEN = 'notBetween'; const TIMEPERIOD_TODAY = 'today'; const TIMEPERIOD_YESTERDAY = 'yesterday'; const TIMEPERIOD_TOMORROW = 'tomorrow'; const TIMEPERIOD_LAST_7_DAYS = 'last7Days'; const TIMEPERIOD_LAST_WEEK = 'lastWeek'; const TIMEPERIOD_THIS_WEEK = 'thisWeek'; const TIMEPERIOD_NEXT_WEEK = 'nextWeek'; const TIMEPERIOD_LAST_MONTH = 'lastMonth'; const TIMEPERIOD_THIS_MONTH = 'thisMonth'; const TIMEPERIOD_NEXT_MONTH = 'nextMonth'; /** * Condition type. * * @var string */ private $conditionType = self::CONDITION_NONE; /** * Operator type. * * @var string */ private $operatorType = self::OPERATOR_NONE; /** * Text. * * @var string */ private $text; /** * Stop on this condition, if it matches. * * @var bool */ private $stopIfTrue = false; /** * Condition. * * @var (bool|float|int|string)[] */ private $condition = []; /** * @var ConditionalDataBar */ private $dataBar; /** * Style. * * @var Style */ private $style; /** @var bool */ private $noFormatSet = false; /** * Create a new Conditional. */ public function __construct() { // Initialise values $this->style = new Style(false, true); } public function getNoFormatSet(): bool { return $this->noFormatSet; } public function setNoFormatSet(bool $noFormatSet): self { $this->noFormatSet = $noFormatSet; return $this; } /** * Get Condition type. * * @return string */ public function getConditionType() { return $this->conditionType; } /** * Set Condition type. * * @param string $type Condition type, see self::CONDITION_* * * @return $this */ public function setConditionType($type) { $this->conditionType = $type; return $this; } /** * Get Operator type. * * @return string */ public function getOperatorType() { return $this->operatorType; } /** * Set Operator type. * * @param string $type Conditional operator type, see self::OPERATOR_* * * @return $this */ public function setOperatorType($type) { $this->operatorType = $type; return $this; } /** * Get text. * * @return string */ public function getText() { return $this->text; } /** * Set text. * * @param string $text * * @return $this */ public function setText($text) { $this->text = $text; return $this; } /** * Get StopIfTrue. * * @return bool */ public function getStopIfTrue() { return $this->stopIfTrue; } /** * Set StopIfTrue. * * @param bool $stopIfTrue * * @return $this */ public function setStopIfTrue($stopIfTrue) { $this->stopIfTrue = $stopIfTrue; return $this; } /** * Get Conditions. * * @return (bool|float|int|string)[] */ public function getConditions() { return $this->condition; } /** * Set Conditions. * * @param (bool|float|int|string)[]|bool|float|int|string $conditions Condition * * @return $this */ public function setConditions($conditions) { if (!is_array($conditions)) { $conditions = [$conditions]; } $this->condition = $conditions; return $this; } /** * Add Condition. * * @param bool|float|int|string $condition Condition * * @return $this */ public function addCondition($condition) { $this->condition[] = $condition; return $this; } /** * Get Style. * * @return Style */ public function getStyle() { return $this->style; } /** * Set Style. * * @return $this */ public function setStyle(Style $style) { $this->style = $style; return $this; } /** * get DataBar. * * @return null|ConditionalDataBar */ public function getDataBar() { return $this->dataBar; } /** * set DataBar. * * @return $this */ public function setDataBar(ConditionalDataBar $dataBar) { $this->dataBar = $dataBar; return $this; } /** * Get hash code. * * @return string Hash code */ public function getHashCode() { return md5( $this->conditionType . $this->operatorType . implode(';', $this->condition) . $this->style->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 (is_object($value)) { $this->$key = clone $value; } else { $this->$key = $value; } } } /** * Verify if param is valid condition type. */ public static function isValidConditionType(string $type): bool { return in_array($type, self::CONDITION_TYPES); } } phpspreadsheet/src/PhpSpreadsheet/Style/Border.php 0000644 00000014712 15060132323 0016317 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Style; use PhpOffice\PhpSpreadsheet\Exception as PhpSpreadsheetException; class Border extends Supervisor { // Border style const BORDER_NONE = 'none'; const BORDER_DASHDOT = 'dashDot'; const BORDER_DASHDOTDOT = 'dashDotDot'; const BORDER_DASHED = 'dashed'; const BORDER_DOTTED = 'dotted'; const BORDER_DOUBLE = 'double'; const BORDER_HAIR = 'hair'; const BORDER_MEDIUM = 'medium'; const BORDER_MEDIUMDASHDOT = 'mediumDashDot'; const BORDER_MEDIUMDASHDOTDOT = 'mediumDashDotDot'; const BORDER_MEDIUMDASHED = 'mediumDashed'; const BORDER_SLANTDASHDOT = 'slantDashDot'; const BORDER_THICK = 'thick'; const BORDER_THIN = 'thin'; const BORDER_OMIT = 'omit'; // should be used only for Conditional /** * Border style. * * @var string */ protected $borderStyle = self::BORDER_NONE; /** * Border color. * * @var Color */ protected $color; /** * @var null|int */ public $colorIndex; /** * Create a new Border. * * @param bool $isSupervisor Flag indicating if this is a supervisor or not * Leave this value at default unless you understand exactly what * its ramifications are */ public function __construct($isSupervisor = false, bool $isConditional = false) { // Supervisor? parent::__construct($isSupervisor); // Initialise values $this->color = new Color(Color::COLOR_BLACK, $isSupervisor); // bind parent if we are a supervisor if ($isSupervisor) { $this->color->bindParent($this, 'color'); } if ($isConditional) { $this->borderStyle = self::BORDER_OMIT; } } /** * Get the shared style component for the currently active cell in currently active sheet. * Only used for style supervisor. * * @return Border */ public function getSharedComponent() { /** @var Style */ $parent = $this->parent; /** @var Borders $sharedComponent */ $sharedComponent = $parent->getSharedComponent(); switch ($this->parentPropertyName) { case 'bottom': return $sharedComponent->getBottom(); case 'diagonal': return $sharedComponent->getDiagonal(); case 'left': return $sharedComponent->getLeft(); case 'right': return $sharedComponent->getRight(); case 'top': return $sharedComponent->getTop(); } throw new PhpSpreadsheetException('Cannot get shared component for a pseudo-border.'); } /** * Build style array from subcomponents. * * @param array $array * * @return array */ public function getStyleArray($array) { /** @var Style */ $parent = $this->parent; return $parent->/** @scrutinizer ignore-call */ getStyleArray([$this->parentPropertyName => $array]); } /** * Apply styles from array. * * <code> * $spreadsheet->getActiveSheet()->getStyle('B2')->getBorders()->getTop()->applyFromArray( * [ * 'borderStyle' => Border::BORDER_DASHDOT, * 'color' => [ * 'rgb' => '808080' * ] * ] * ); * </code> * * @param array $styleArray Array containing style information * * @return $this */ public function applyFromArray(array $styleArray) { if ($this->isSupervisor) { $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($styleArray)); } else { if (isset($styleArray['borderStyle'])) { $this->setBorderStyle($styleArray['borderStyle']); } if (isset($styleArray['color'])) { $this->getColor()->applyFromArray($styleArray['color']); } } return $this; } /** * Get Border style. * * @return string */ public function getBorderStyle() { if ($this->isSupervisor) { return $this->getSharedComponent()->getBorderStyle(); } return $this->borderStyle; } /** * Set Border style. * * @param bool|string $style * When passing a boolean, FALSE equates Border::BORDER_NONE * and TRUE to Border::BORDER_MEDIUM * * @return $this */ public function setBorderStyle($style) { if (empty($style)) { $style = self::BORDER_NONE; } elseif (is_bool($style)) { $style = self::BORDER_MEDIUM; } if ($this->isSupervisor) { $styleArray = $this->getStyleArray(['borderStyle' => $style]); $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); } else { $this->borderStyle = $style; } return $this; } /** * Get Border Color. * * @return Color */ public function getColor() { return $this->color; } /** * Set Border Color. * * @return $this */ public function setColor(Color $color) { // make sure parameter is a real color and not a supervisor $color = $color->getIsSupervisor() ? $color->getSharedComponent() : $color; if ($this->isSupervisor) { $styleArray = $this->getColor()->getStyleArray(['argb' => $color->getARGB()]); $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); } else { $this->color = $color; } return $this; } /** * Get hash code. * * @return string Hash code */ public function getHashCode() { if ($this->isSupervisor) { return $this->getSharedComponent()->getHashCode(); } return md5( $this->borderStyle . $this->color->getHashCode() . __CLASS__ ); } protected function exportArray1(): array { $exportedArray = []; $this->exportArray2($exportedArray, 'borderStyle', $this->getBorderStyle()); $this->exportArray2($exportedArray, 'color', $this->getColor()); return $exportedArray; } } phpspreadsheet/src/PhpSpreadsheet/Style/Borders.php 0000644 00000025316 15060132323 0016504 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Style; use PhpOffice\PhpSpreadsheet\Exception as PhpSpreadsheetException; class Borders extends Supervisor { // Diagonal directions const DIAGONAL_NONE = 0; const DIAGONAL_UP = 1; const DIAGONAL_DOWN = 2; const DIAGONAL_BOTH = 3; /** * Left. * * @var Border */ protected $left; /** * Right. * * @var Border */ protected $right; /** * Top. * * @var Border */ protected $top; /** * Bottom. * * @var Border */ protected $bottom; /** * Diagonal. * * @var Border */ protected $diagonal; /** * DiagonalDirection. * * @var int */ protected $diagonalDirection; /** * All borders pseudo-border. Only applies to supervisor. * * @var Border */ protected $allBorders; /** * Outline pseudo-border. Only applies to supervisor. * * @var Border */ protected $outline; /** * Inside pseudo-border. Only applies to supervisor. * * @var Border */ protected $inside; /** * Vertical pseudo-border. Only applies to supervisor. * * @var Border */ protected $vertical; /** * Horizontal pseudo-border. Only applies to supervisor. * * @var Border */ protected $horizontal; /** * Create a new Borders. * * @param bool $isSupervisor Flag indicating if this is a supervisor or not * Leave this value at default unless you understand exactly what * its ramifications are */ public function __construct($isSupervisor = false, bool $isConditional = false) { // Supervisor? parent::__construct($isSupervisor); // Initialise values $this->left = new Border($isSupervisor, $isConditional); $this->right = new Border($isSupervisor, $isConditional); $this->top = new Border($isSupervisor, $isConditional); $this->bottom = new Border($isSupervisor, $isConditional); $this->diagonal = new Border($isSupervisor, $isConditional); $this->diagonalDirection = self::DIAGONAL_NONE; // Specially for supervisor if ($isSupervisor) { // Initialize pseudo-borders $this->allBorders = new Border(true, $isConditional); $this->outline = new Border(true, $isConditional); $this->inside = new Border(true, $isConditional); $this->vertical = new Border(true, $isConditional); $this->horizontal = new Border(true, $isConditional); // bind parent if we are a supervisor $this->left->bindParent($this, 'left'); $this->right->bindParent($this, 'right'); $this->top->bindParent($this, 'top'); $this->bottom->bindParent($this, 'bottom'); $this->diagonal->bindParent($this, 'diagonal'); $this->allBorders->bindParent($this, 'allBorders'); $this->outline->bindParent($this, 'outline'); $this->inside->bindParent($this, 'inside'); $this->vertical->bindParent($this, 'vertical'); $this->horizontal->bindParent($this, 'horizontal'); } } /** * Get the shared style component for the currently active cell in currently active sheet. * Only used for style supervisor. * * @return Borders */ public function getSharedComponent() { /** @var Style */ $parent = $this->parent; return $parent->getSharedComponent()->getBorders(); } /** * Build style array from subcomponents. * * @param array $array * * @return array */ public function getStyleArray($array) { return ['borders' => $array]; } /** * Apply styles from array. * * <code> * $spreadsheet->getActiveSheet()->getStyle('B2')->getBorders()->applyFromArray( * [ * 'bottom' => [ * 'borderStyle' => Border::BORDER_DASHDOT, * 'color' => [ * 'rgb' => '808080' * ] * ], * 'top' => [ * 'borderStyle' => Border::BORDER_DASHDOT, * 'color' => [ * 'rgb' => '808080' * ] * ] * ] * ); * </code> * * <code> * $spreadsheet->getActiveSheet()->getStyle('B2')->getBorders()->applyFromArray( * [ * 'allBorders' => [ * 'borderStyle' => Border::BORDER_DASHDOT, * 'color' => [ * 'rgb' => '808080' * ] * ] * ] * ); * </code> * * @param array $styleArray Array containing style information * * @return $this */ public function applyFromArray(array $styleArray) { if ($this->isSupervisor) { $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($styleArray)); } else { if (isset($styleArray['left'])) { $this->getLeft()->applyFromArray($styleArray['left']); } if (isset($styleArray['right'])) { $this->getRight()->applyFromArray($styleArray['right']); } if (isset($styleArray['top'])) { $this->getTop()->applyFromArray($styleArray['top']); } if (isset($styleArray['bottom'])) { $this->getBottom()->applyFromArray($styleArray['bottom']); } if (isset($styleArray['diagonal'])) { $this->getDiagonal()->applyFromArray($styleArray['diagonal']); } if (isset($styleArray['diagonalDirection'])) { $this->setDiagonalDirection($styleArray['diagonalDirection']); } if (isset($styleArray['allBorders'])) { $this->getLeft()->applyFromArray($styleArray['allBorders']); $this->getRight()->applyFromArray($styleArray['allBorders']); $this->getTop()->applyFromArray($styleArray['allBorders']); $this->getBottom()->applyFromArray($styleArray['allBorders']); } } return $this; } /** * Get Left. * * @return Border */ public function getLeft() { return $this->left; } /** * Get Right. * * @return Border */ public function getRight() { return $this->right; } /** * Get Top. * * @return Border */ public function getTop() { return $this->top; } /** * Get Bottom. * * @return Border */ public function getBottom() { return $this->bottom; } /** * Get Diagonal. * * @return Border */ public function getDiagonal() { return $this->diagonal; } /** * Get AllBorders (pseudo-border). Only applies to supervisor. * * @return Border */ public function getAllBorders() { if (!$this->isSupervisor) { throw new PhpSpreadsheetException('Can only get pseudo-border for supervisor.'); } return $this->allBorders; } /** * Get Outline (pseudo-border). Only applies to supervisor. * * @return Border */ public function getOutline() { if (!$this->isSupervisor) { throw new PhpSpreadsheetException('Can only get pseudo-border for supervisor.'); } return $this->outline; } /** * Get Inside (pseudo-border). Only applies to supervisor. * * @return Border */ public function getInside() { if (!$this->isSupervisor) { throw new PhpSpreadsheetException('Can only get pseudo-border for supervisor.'); } return $this->inside; } /** * Get Vertical (pseudo-border). Only applies to supervisor. * * @return Border */ public function getVertical() { if (!$this->isSupervisor) { throw new PhpSpreadsheetException('Can only get pseudo-border for supervisor.'); } return $this->vertical; } /** * Get Horizontal (pseudo-border). Only applies to supervisor. * * @return Border */ public function getHorizontal() { if (!$this->isSupervisor) { throw new PhpSpreadsheetException('Can only get pseudo-border for supervisor.'); } return $this->horizontal; } /** * Get DiagonalDirection. * * @return int */ public function getDiagonalDirection() { if ($this->isSupervisor) { return $this->getSharedComponent()->getDiagonalDirection(); } return $this->diagonalDirection; } /** * Set DiagonalDirection. * * @param int $direction see self::DIAGONAL_* * * @return $this */ public function setDiagonalDirection($direction) { if ($direction == '') { $direction = self::DIAGONAL_NONE; } if ($this->isSupervisor) { $styleArray = $this->getStyleArray(['diagonalDirection' => $direction]); $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); } else { $this->diagonalDirection = $direction; } return $this; } /** * Get hash code. * * @return string Hash code */ public function getHashCode() { if ($this->isSupervisor) { return $this->getSharedComponent()->getHashcode(); } return md5( $this->getLeft()->getHashCode() . $this->getRight()->getHashCode() . $this->getTop()->getHashCode() . $this->getBottom()->getHashCode() . $this->getDiagonal()->getHashCode() . $this->getDiagonalDirection() . __CLASS__ ); } protected function exportArray1(): array { $exportedArray = []; $this->exportArray2($exportedArray, 'bottom', $this->getBottom()); $this->exportArray2($exportedArray, 'diagonal', $this->getDiagonal()); $this->exportArray2($exportedArray, 'diagonalDirection', $this->getDiagonalDirection()); $this->exportArray2($exportedArray, 'left', $this->getLeft()); $this->exportArray2($exportedArray, 'right', $this->getRight()); $this->exportArray2($exportedArray, 'top', $this->getTop()); return $exportedArray; } } phpspreadsheet/src/PhpSpreadsheet/Style/RgbTint.php 0000644 00000012522 15060132323 0016450 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Style; /** * Class to handle tint applied to color. * Code borrows heavily from some Python projects. * * @see https://docs.python.org/3/library/colorsys.html * @see https://gist.github.com/Mike-Honey/b36e651e9a7f1d2e1d60ce1c63b9b633 */ class RgbTint { private const ONE_THIRD = 1.0 / 3.0; private const ONE_SIXTH = 1.0 / 6.0; private const TWO_THIRD = 2.0 / 3.0; private const RGBMAX = 255.0; /** * MS excel's tint function expects that HLS is base 240. * * @see https://social.msdn.microsoft.com/Forums/en-US/e9d8c136-6d62-4098-9b1b-dac786149f43/excel-color-tint-algorithm-incorrect?forum=os_binaryfile#d3c2ac95-52e0-476b-86f1-e2a697f24969 */ private const HLSMAX = 240.0; /** * Convert red/green/blue to hue/luminance/saturation. * * @param float $red 0.0 through 1.0 * @param float $green 0.0 through 1.0 * @param float $blue 0.0 through 1.0 * * @return float[] */ private static function rgbToHls(float $red, float $green, float $blue): array { $maxc = max($red, $green, $blue); $minc = min($red, $green, $blue); $luminance = ($minc + $maxc) / 2.0; if ($minc === $maxc) { return [0.0, $luminance, 0.0]; } $maxMinusMin = $maxc - $minc; if ($luminance <= 0.5) { $s = $maxMinusMin / ($maxc + $minc); } else { $s = $maxMinusMin / (2.0 - $maxc - $minc); } $rc = ($maxc - $red) / $maxMinusMin; $gc = ($maxc - $green) / $maxMinusMin; $bc = ($maxc - $blue) / $maxMinusMin; if ($red === $maxc) { $h = $bc - $gc; } elseif ($green === $maxc) { $h = 2.0 + $rc - $bc; } else { $h = 4.0 + $gc - $rc; } $h = self::positiveDecimalPart($h / 6.0); return [$h, $luminance, $s]; } /** @var mixed */ private static $scrutinizerZeroPointZero = 0.0; /** * Convert hue/luminance/saturation to red/green/blue. * * @param float $hue 0.0 through 1.0 * @param float $luminance 0.0 through 1.0 * @param float $saturation 0.0 through 1.0 * * @return float[] */ private static function hlsToRgb($hue, $luminance, $saturation): array { if ($saturation === self::$scrutinizerZeroPointZero) { return [$luminance, $luminance, $luminance]; } if ($luminance <= 0.5) { $m2 = $luminance * (1.0 + $saturation); } else { $m2 = $luminance + $saturation - ($luminance * $saturation); } $m1 = 2.0 * $luminance - $m2; return [ self::vFunction($m1, $m2, $hue + self::ONE_THIRD), self::vFunction($m1, $m2, $hue), self::vFunction($m1, $m2, $hue - self::ONE_THIRD), ]; } private static function vFunction(float $m1, float $m2, float $hue): float { $hue = self::positiveDecimalPart($hue); if ($hue < self::ONE_SIXTH) { return $m1 + ($m2 - $m1) * $hue * 6.0; } if ($hue < 0.5) { return $m2; } if ($hue < self::TWO_THIRD) { return $m1 + ($m2 - $m1) * (self::TWO_THIRD - $hue) * 6.0; } return $m1; } private static function positiveDecimalPart(float $hue): float { $hue = fmod($hue, 1.0); return ($hue >= 0.0) ? $hue : (1.0 + $hue); } /** * Convert red/green/blue to HLSMAX-based hue/luminance/saturation. * * @return int[] */ private static function rgbToMsHls(int $red, int $green, int $blue): array { $red01 = $red / self::RGBMAX; $green01 = $green / self::RGBMAX; $blue01 = $blue / self::RGBMAX; [$hue, $luminance, $saturation] = self::rgbToHls($red01, $green01, $blue01); return [ (int) round($hue * self::HLSMAX), (int) round($luminance * self::HLSMAX), (int) round($saturation * self::HLSMAX), ]; } /** * Converts HLSMAX based HLS values to rgb values in the range (0,1). * * @return float[] */ private static function msHlsToRgb(int $hue, int $lightness, int $saturation): array { return self::hlsToRgb($hue / self::HLSMAX, $lightness / self::HLSMAX, $saturation / self::HLSMAX); } /** * Tints HLSMAX based luminance. * * @see http://ciintelligence.blogspot.co.uk/2012/02/converting-excel-theme-color-and-tint.html */ private static function tintLuminance(float $tint, float $luminance): int { if ($tint < 0) { return (int) round($luminance * (1.0 + $tint)); } return (int) round($luminance * (1.0 - $tint) + (self::HLSMAX - self::HLSMAX * (1.0 - $tint))); } /** * Return result of tinting supplied rgb as 6 hex digits. */ public static function rgbAndTintToRgb(int $red, int $green, int $blue, float $tint): string { [$hue, $luminance, $saturation] = self::rgbToMsHls($red, $green, $blue); [$red, $green, $blue] = self::msHlsToRgb($hue, self::tintLuminance($tint, $luminance), $saturation); return sprintf( '%02X%02X%02X', (int) round($red * self::RGBMAX), (int) round($green * self::RGBMAX), (int) round($blue * self::RGBMAX) ); } } phpspreadsheet/src/PhpSpreadsheet/Style/Alignment.php 0000644 00000037163 15060132323 0017025 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Style; use PhpOffice\PhpSpreadsheet\Exception as PhpSpreadsheetException; class Alignment extends Supervisor { // Horizontal alignment styles const HORIZONTAL_GENERAL = 'general'; const HORIZONTAL_LEFT = 'left'; const HORIZONTAL_RIGHT = 'right'; const HORIZONTAL_CENTER = 'center'; const HORIZONTAL_CENTER_CONTINUOUS = 'centerContinuous'; const HORIZONTAL_JUSTIFY = 'justify'; const HORIZONTAL_FILL = 'fill'; const HORIZONTAL_DISTRIBUTED = 'distributed'; // Excel2007 only private const HORIZONTAL_CENTER_CONTINUOUS_LC = 'centercontinuous'; // Mapping for horizontal alignment const HORIZONTAL_ALIGNMENT_FOR_XLSX = [ self::HORIZONTAL_LEFT => self::HORIZONTAL_LEFT, self::HORIZONTAL_RIGHT => self::HORIZONTAL_RIGHT, self::HORIZONTAL_CENTER => self::HORIZONTAL_CENTER, self::HORIZONTAL_CENTER_CONTINUOUS => self::HORIZONTAL_CENTER_CONTINUOUS, self::HORIZONTAL_JUSTIFY => self::HORIZONTAL_JUSTIFY, self::HORIZONTAL_FILL => self::HORIZONTAL_FILL, self::HORIZONTAL_DISTRIBUTED => self::HORIZONTAL_DISTRIBUTED, ]; // Mapping for horizontal alignment CSS const HORIZONTAL_ALIGNMENT_FOR_HTML = [ self::HORIZONTAL_LEFT => self::HORIZONTAL_LEFT, self::HORIZONTAL_RIGHT => self::HORIZONTAL_RIGHT, self::HORIZONTAL_CENTER => self::HORIZONTAL_CENTER, self::HORIZONTAL_CENTER_CONTINUOUS => self::HORIZONTAL_CENTER, self::HORIZONTAL_JUSTIFY => self::HORIZONTAL_JUSTIFY, //self::HORIZONTAL_FILL => self::HORIZONTAL_FILL, // no reasonable equivalent for fill self::HORIZONTAL_DISTRIBUTED => self::HORIZONTAL_JUSTIFY, ]; // Vertical alignment styles const VERTICAL_BOTTOM = 'bottom'; const VERTICAL_TOP = 'top'; const VERTICAL_CENTER = 'center'; const VERTICAL_JUSTIFY = 'justify'; const VERTICAL_DISTRIBUTED = 'distributed'; // Excel2007 only // Vertical alignment CSS private const VERTICAL_BASELINE = 'baseline'; private const VERTICAL_MIDDLE = 'middle'; private const VERTICAL_SUB = 'sub'; private const VERTICAL_SUPER = 'super'; private const VERTICAL_TEXT_BOTTOM = 'text-bottom'; private const VERTICAL_TEXT_TOP = 'text-top'; // Mapping for vertical alignment const VERTICAL_ALIGNMENT_FOR_XLSX = [ self::VERTICAL_BOTTOM => self::VERTICAL_BOTTOM, self::VERTICAL_TOP => self::VERTICAL_TOP, self::VERTICAL_CENTER => self::VERTICAL_CENTER, self::VERTICAL_JUSTIFY => self::VERTICAL_JUSTIFY, self::VERTICAL_DISTRIBUTED => self::VERTICAL_DISTRIBUTED, // css settings that arent't in sync with Excel self::VERTICAL_BASELINE => self::VERTICAL_BOTTOM, self::VERTICAL_MIDDLE => self::VERTICAL_CENTER, self::VERTICAL_SUB => self::VERTICAL_BOTTOM, self::VERTICAL_SUPER => self::VERTICAL_TOP, self::VERTICAL_TEXT_BOTTOM => self::VERTICAL_BOTTOM, self::VERTICAL_TEXT_TOP => self::VERTICAL_TOP, ]; // Mapping for vertical alignment for Html const VERTICAL_ALIGNMENT_FOR_HTML = [ self::VERTICAL_BOTTOM => self::VERTICAL_BOTTOM, self::VERTICAL_TOP => self::VERTICAL_TOP, self::VERTICAL_CENTER => self::VERTICAL_MIDDLE, self::VERTICAL_JUSTIFY => self::VERTICAL_MIDDLE, self::VERTICAL_DISTRIBUTED => self::VERTICAL_MIDDLE, // css settings that arent't in sync with Excel self::VERTICAL_BASELINE => self::VERTICAL_BASELINE, self::VERTICAL_MIDDLE => self::VERTICAL_MIDDLE, self::VERTICAL_SUB => self::VERTICAL_SUB, self::VERTICAL_SUPER => self::VERTICAL_SUPER, self::VERTICAL_TEXT_BOTTOM => self::VERTICAL_TEXT_BOTTOM, self::VERTICAL_TEXT_TOP => self::VERTICAL_TEXT_TOP, ]; // Read order const READORDER_CONTEXT = 0; const READORDER_LTR = 1; const READORDER_RTL = 2; // Special value for Text Rotation const TEXTROTATION_STACK_EXCEL = 255; const TEXTROTATION_STACK_PHPSPREADSHEET = -165; // 90 - 255 /** * Horizontal alignment. * * @var null|string */ protected $horizontal = self::HORIZONTAL_GENERAL; /** * Vertical alignment. * * @var null|string */ protected $vertical = self::VERTICAL_BOTTOM; /** * Text rotation. * * @var null|int */ protected $textRotation = 0; /** * Wrap text. * * @var bool */ protected $wrapText = false; /** * Shrink to fit. * * @var bool */ protected $shrinkToFit = false; /** * Indent - only possible with horizontal alignment left and right. * * @var int */ protected $indent = 0; /** * Read order. * * @var int */ protected $readOrder = 0; /** * Create a new Alignment. * * @param bool $isSupervisor Flag indicating if this is a supervisor or not * Leave this value at default unless you understand exactly what * its ramifications are * @param bool $isConditional Flag indicating if this is a conditional style or not * Leave this value at default unless you understand exactly what * its ramifications are */ public function __construct($isSupervisor = false, $isConditional = false) { // Supervisor? parent::__construct($isSupervisor); if ($isConditional) { $this->horizontal = null; $this->vertical = null; $this->textRotation = null; } } /** * Get the shared style component for the currently active cell in currently active sheet. * Only used for style supervisor. * * @return Alignment */ public function getSharedComponent() { /** @var Style */ $parent = $this->parent; return $parent->getSharedComponent()->getAlignment(); } /** * Build style array from subcomponents. * * @param array $array * * @return array */ public function getStyleArray($array) { return ['alignment' => $array]; } /** * Apply styles from array. * * <code> * $spreadsheet->getActiveSheet()->getStyle('B2')->getAlignment()->applyFromArray( * [ * 'horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER, * 'vertical' => \PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_CENTER, * 'textRotation' => 0, * 'wrapText' => TRUE * ] * ); * </code> * * @param array $styleArray Array containing style information * * @return $this */ public function applyFromArray(array $styleArray) { if ($this->isSupervisor) { $this->getActiveSheet()->getStyle($this->getSelectedCells()) ->applyFromArray($this->getStyleArray($styleArray)); } else { if (isset($styleArray['horizontal'])) { $this->setHorizontal($styleArray['horizontal']); } if (isset($styleArray['vertical'])) { $this->setVertical($styleArray['vertical']); } if (isset($styleArray['textRotation'])) { $this->setTextRotation($styleArray['textRotation']); } if (isset($styleArray['wrapText'])) { $this->setWrapText($styleArray['wrapText']); } if (isset($styleArray['shrinkToFit'])) { $this->setShrinkToFit($styleArray['shrinkToFit']); } if (isset($styleArray['indent'])) { $this->setIndent($styleArray['indent']); } if (isset($styleArray['readOrder'])) { $this->setReadOrder($styleArray['readOrder']); } } return $this; } /** * Get Horizontal. * * @return null|string */ public function getHorizontal() { if ($this->isSupervisor) { return $this->getSharedComponent()->getHorizontal(); } return $this->horizontal; } /** * Set Horizontal. * * @param string $horizontalAlignment see self::HORIZONTAL_* * * @return $this */ public function setHorizontal(string $horizontalAlignment) { $horizontalAlignment = strtolower($horizontalAlignment); if ($horizontalAlignment === self::HORIZONTAL_CENTER_CONTINUOUS_LC) { $horizontalAlignment = self::HORIZONTAL_CENTER_CONTINUOUS; } if ($this->isSupervisor) { $styleArray = $this->getStyleArray(['horizontal' => $horizontalAlignment]); $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); } else { $this->horizontal = $horizontalAlignment; } return $this; } /** * Get Vertical. * * @return null|string */ public function getVertical() { if ($this->isSupervisor) { return $this->getSharedComponent()->getVertical(); } return $this->vertical; } /** * Set Vertical. * * @param string $verticalAlignment see self::VERTICAL_* * * @return $this */ public function setVertical($verticalAlignment) { $verticalAlignment = strtolower($verticalAlignment); if ($this->isSupervisor) { $styleArray = $this->getStyleArray(['vertical' => $verticalAlignment]); $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); } else { $this->vertical = $verticalAlignment; } return $this; } /** * Get TextRotation. * * @return null|int */ public function getTextRotation() { if ($this->isSupervisor) { return $this->getSharedComponent()->getTextRotation(); } return $this->textRotation; } /** * Set TextRotation. * * @param int $angleInDegrees * * @return $this */ public function setTextRotation($angleInDegrees) { // Excel2007 value 255 => PhpSpreadsheet value -165 if ($angleInDegrees == self::TEXTROTATION_STACK_EXCEL) { $angleInDegrees = self::TEXTROTATION_STACK_PHPSPREADSHEET; } // Set rotation if (($angleInDegrees >= -90 && $angleInDegrees <= 90) || $angleInDegrees == self::TEXTROTATION_STACK_PHPSPREADSHEET) { if ($this->isSupervisor) { $styleArray = $this->getStyleArray(['textRotation' => $angleInDegrees]); $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); } else { $this->textRotation = $angleInDegrees; } } else { throw new PhpSpreadsheetException('Text rotation should be a value between -90 and 90.'); } return $this; } /** * Get Wrap Text. * * @return bool */ public function getWrapText() { if ($this->isSupervisor) { return $this->getSharedComponent()->getWrapText(); } return $this->wrapText; } /** * Set Wrap Text. * * @param bool $wrapped * * @return $this */ public function setWrapText($wrapped) { if ($wrapped == '') { $wrapped = false; } if ($this->isSupervisor) { $styleArray = $this->getStyleArray(['wrapText' => $wrapped]); $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); } else { $this->wrapText = $wrapped; } return $this; } /** * Get Shrink to fit. * * @return bool */ public function getShrinkToFit() { if ($this->isSupervisor) { return $this->getSharedComponent()->getShrinkToFit(); } return $this->shrinkToFit; } /** * Set Shrink to fit. * * @param bool $shrink * * @return $this */ public function setShrinkToFit($shrink) { if ($shrink == '') { $shrink = false; } if ($this->isSupervisor) { $styleArray = $this->getStyleArray(['shrinkToFit' => $shrink]); $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); } else { $this->shrinkToFit = $shrink; } return $this; } /** * Get indent. * * @return int */ public function getIndent() { if ($this->isSupervisor) { return $this->getSharedComponent()->getIndent(); } return $this->indent; } /** * Set indent. * * @param int $indent * * @return $this */ public function setIndent($indent) { if ($indent > 0) { if ( $this->getHorizontal() != self::HORIZONTAL_GENERAL && $this->getHorizontal() != self::HORIZONTAL_LEFT && $this->getHorizontal() != self::HORIZONTAL_RIGHT && $this->getHorizontal() != self::HORIZONTAL_DISTRIBUTED ) { $indent = 0; // indent not supported } } if ($this->isSupervisor) { $styleArray = $this->getStyleArray(['indent' => $indent]); $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); } else { $this->indent = $indent; } return $this; } /** * Get read order. * * @return int */ public function getReadOrder() { if ($this->isSupervisor) { return $this->getSharedComponent()->getReadOrder(); } return $this->readOrder; } /** * Set read order. * * @param int $readOrder * * @return $this */ public function setReadOrder($readOrder) { if ($readOrder < 0 || $readOrder > 2) { $readOrder = 0; } if ($this->isSupervisor) { $styleArray = $this->getStyleArray(['readOrder' => $readOrder]); $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); } else { $this->readOrder = $readOrder; } return $this; } /** * Get hash code. * * @return string Hash code */ public function getHashCode() { if ($this->isSupervisor) { return $this->getSharedComponent()->getHashCode(); } return md5( $this->horizontal . $this->vertical . $this->textRotation . ($this->wrapText ? 't' : 'f') . ($this->shrinkToFit ? 't' : 'f') . $this->indent . $this->readOrder . __CLASS__ ); } protected function exportArray1(): array { $exportedArray = []; $this->exportArray2($exportedArray, 'horizontal', $this->getHorizontal()); $this->exportArray2($exportedArray, 'indent', $this->getIndent()); $this->exportArray2($exportedArray, 'readOrder', $this->getReadOrder()); $this->exportArray2($exportedArray, 'shrinkToFit', $this->getShrinkToFit()); $this->exportArray2($exportedArray, 'textRotation', $this->getTextRotation()); $this->exportArray2($exportedArray, 'vertical', $this->getVertical()); $this->exportArray2($exportedArray, 'wrapText', $this->getWrapText()); return $exportedArray; } } phpspreadsheet/src/PhpSpreadsheet/Style/NumberFormat.php 0000644 00000035353 15060132323 0017507 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Style; class NumberFormat extends Supervisor { // Pre-defined formats const FORMAT_GENERAL = 'General'; const FORMAT_TEXT = '@'; const FORMAT_NUMBER = '0'; const FORMAT_NUMBER_0 = '0.0'; const FORMAT_NUMBER_00 = '0.00'; const FORMAT_NUMBER_COMMA_SEPARATED1 = '#,##0.00'; const FORMAT_NUMBER_COMMA_SEPARATED2 = '#,##0.00_-'; const FORMAT_PERCENTAGE = '0%'; const FORMAT_PERCENTAGE_0 = '0.0%'; const FORMAT_PERCENTAGE_00 = '0.00%'; /** @deprecated 1.26 use FORMAT_DATE_YYYYMMDD instead */ const FORMAT_DATE_YYYYMMDD2 = 'yyyy-mm-dd'; const FORMAT_DATE_YYYYMMDD = 'yyyy-mm-dd'; const FORMAT_DATE_DDMMYYYY = 'dd/mm/yyyy'; const FORMAT_DATE_DMYSLASH = 'd/m/yy'; const FORMAT_DATE_DMYMINUS = 'd-m-yy'; const FORMAT_DATE_DMMINUS = 'd-m'; const FORMAT_DATE_MYMINUS = 'm-yy'; const FORMAT_DATE_XLSX14 = 'mm-dd-yy'; const FORMAT_DATE_XLSX15 = 'd-mmm-yy'; const FORMAT_DATE_XLSX16 = 'd-mmm'; const FORMAT_DATE_XLSX17 = 'mmm-yy'; const FORMAT_DATE_XLSX22 = 'm/d/yy h:mm'; const FORMAT_DATE_DATETIME = 'd/m/yy h:mm'; const FORMAT_DATE_TIME1 = 'h:mm AM/PM'; const FORMAT_DATE_TIME2 = 'h:mm:ss AM/PM'; const FORMAT_DATE_TIME3 = 'h:mm'; const FORMAT_DATE_TIME4 = 'h:mm:ss'; const FORMAT_DATE_TIME5 = 'mm:ss'; const FORMAT_DATE_TIME6 = 'h:mm:ss'; const FORMAT_DATE_TIME7 = 'i:s.S'; const FORMAT_DATE_TIME8 = 'h:mm:ss;@'; const FORMAT_DATE_YYYYMMDDSLASH = 'yyyy/mm/dd;@'; const DATE_TIME_OR_DATETIME_ARRAY = [ self::FORMAT_DATE_YYYYMMDD, self::FORMAT_DATE_DDMMYYYY, self::FORMAT_DATE_DMYSLASH, self::FORMAT_DATE_DMYMINUS, self::FORMAT_DATE_DMMINUS, self::FORMAT_DATE_MYMINUS, self::FORMAT_DATE_XLSX14, self::FORMAT_DATE_XLSX15, self::FORMAT_DATE_XLSX16, self::FORMAT_DATE_XLSX17, self::FORMAT_DATE_XLSX22, self::FORMAT_DATE_DATETIME, self::FORMAT_DATE_TIME1, self::FORMAT_DATE_TIME2, self::FORMAT_DATE_TIME3, self::FORMAT_DATE_TIME4, self::FORMAT_DATE_TIME5, self::FORMAT_DATE_TIME6, self::FORMAT_DATE_TIME7, self::FORMAT_DATE_TIME8, self::FORMAT_DATE_YYYYMMDDSLASH, ]; const TIME_OR_DATETIME_ARRAY = [ self::FORMAT_DATE_XLSX22, self::FORMAT_DATE_DATETIME, self::FORMAT_DATE_TIME1, self::FORMAT_DATE_TIME2, self::FORMAT_DATE_TIME3, self::FORMAT_DATE_TIME4, self::FORMAT_DATE_TIME5, self::FORMAT_DATE_TIME6, self::FORMAT_DATE_TIME7, self::FORMAT_DATE_TIME8, ]; /** @deprecated 1.28 use FORMAT_CURRENCY_USD_INTEGER instead */ const FORMAT_CURRENCY_USD_SIMPLE = '"$"#,##0_-'; const FORMAT_CURRENCY_USD_INTEGER = '$#,##0_-'; const FORMAT_CURRENCY_USD = '$#,##0.00_-'; /** @deprecated 1.28 use FORMAT_CURRENCY_EUR_INTEGER instead */ const FORMAT_CURRENCY_EUR_SIMPLE = '#,##0_-"€"'; const FORMAT_CURRENCY_EUR_INTEGER = '#,##0_-[$€]'; const FORMAT_CURRENCY_EUR = '#,##0.00_-[$€]'; const FORMAT_ACCOUNTING_USD = '_("$"* #,##0.00_);_("$"* \(#,##0.00\);_("$"* "-"??_);_(@_)'; const FORMAT_ACCOUNTING_EUR = '_("€"* #,##0.00_);_("€"* \(#,##0.00\);_("€"* "-"??_);_(@_)'; /** * Excel built-in number formats. * * @var array */ protected static $builtInFormats; /** * Excel built-in number formats (flipped, for faster lookups). * * @var array */ protected static $flippedBuiltInFormats; /** * Format Code. * * @var null|string */ protected $formatCode = self::FORMAT_GENERAL; /** * Built-in format Code. * * @var false|int */ protected $builtInFormatCode = 0; /** * Create a new NumberFormat. * * @param bool $isSupervisor Flag indicating if this is a supervisor or not * Leave this value at default unless you understand exactly what * its ramifications are * @param bool $isConditional Flag indicating if this is a conditional style or not * Leave this value at default unless you understand exactly what * its ramifications are */ public function __construct($isSupervisor = false, $isConditional = false) { // Supervisor? parent::__construct($isSupervisor); if ($isConditional) { $this->formatCode = null; $this->builtInFormatCode = false; } } /** * Get the shared style component for the currently active cell in currently active sheet. * Only used for style supervisor. * * @return NumberFormat */ public function getSharedComponent() { /** @var Style */ $parent = $this->parent; return $parent->getSharedComponent()->getNumberFormat(); } /** * Build style array from subcomponents. * * @param array $array * * @return array */ public function getStyleArray($array) { return ['numberFormat' => $array]; } /** * Apply styles from array. * * <code> * $spreadsheet->getActiveSheet()->getStyle('B2')->getNumberFormat()->applyFromArray( * [ * 'formatCode' => NumberFormat::FORMAT_CURRENCY_EUR_SIMPLE * ] * ); * </code> * * @param array $styleArray Array containing style information * * @return $this */ public function applyFromArray(array $styleArray) { if ($this->isSupervisor) { $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($styleArray)); } else { if (isset($styleArray['formatCode'])) { $this->setFormatCode($styleArray['formatCode']); } } return $this; } /** * Get Format Code. * * @return null|string */ public function getFormatCode() { if ($this->isSupervisor) { return $this->getSharedComponent()->getFormatCode(); } if (is_int($this->builtInFormatCode)) { return self::builtInFormatCode($this->builtInFormatCode); } return $this->formatCode; } /** * Set Format Code. * * @param string $formatCode see self::FORMAT_* * * @return $this */ public function setFormatCode(string $formatCode) { if ($formatCode == '') { $formatCode = self::FORMAT_GENERAL; } if ($this->isSupervisor) { $styleArray = $this->getStyleArray(['formatCode' => $formatCode]); $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); } else { $this->formatCode = $formatCode; $this->builtInFormatCode = self::builtInFormatCodeIndex($formatCode); } return $this; } /** * Get Built-In Format Code. * * @return false|int */ public function getBuiltInFormatCode() { if ($this->isSupervisor) { return $this->getSharedComponent()->getBuiltInFormatCode(); } // Scrutinizer says this could return true. It is wrong. return $this->builtInFormatCode; } /** * Set Built-In Format Code. * * @param int $formatCodeIndex Id of the built-in format code to use * * @return $this */ public function setBuiltInFormatCode(int $formatCodeIndex) { if ($this->isSupervisor) { $styleArray = $this->getStyleArray(['formatCode' => self::builtInFormatCode($formatCodeIndex)]); $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); } else { $this->builtInFormatCode = $formatCodeIndex; $this->formatCode = self::builtInFormatCode($formatCodeIndex); } return $this; } /** * Fill built-in format codes. */ private static function fillBuiltInFormatCodes(): void { // [MS-OI29500: Microsoft Office Implementation Information for ISO/IEC-29500 Standard Compliance] // 18.8.30. numFmt (Number Format) // // The ECMA standard defines built-in format IDs // 14: "mm-dd-yy" // 22: "m/d/yy h:mm" // 37: "#,##0 ;(#,##0)" // 38: "#,##0 ;[Red](#,##0)" // 39: "#,##0.00;(#,##0.00)" // 40: "#,##0.00;[Red](#,##0.00)" // 47: "mmss.0" // KOR fmt 55: "yyyy-mm-dd" // Excel defines built-in format IDs // 14: "m/d/yyyy" // 22: "m/d/yyyy h:mm" // 37: "#,##0_);(#,##0)" // 38: "#,##0_);[Red](#,##0)" // 39: "#,##0.00_);(#,##0.00)" // 40: "#,##0.00_);[Red](#,##0.00)" // 47: "mm:ss.0" // KOR fmt 55: "yyyy/mm/dd" // Built-in format codes if (empty(self::$builtInFormats)) { self::$builtInFormats = []; // General self::$builtInFormats[0] = self::FORMAT_GENERAL; self::$builtInFormats[1] = '0'; self::$builtInFormats[2] = '0.00'; self::$builtInFormats[3] = '#,##0'; self::$builtInFormats[4] = '#,##0.00'; self::$builtInFormats[9] = '0%'; self::$builtInFormats[10] = '0.00%'; self::$builtInFormats[11] = '0.00E+00'; self::$builtInFormats[12] = '# ?/?'; self::$builtInFormats[13] = '# ??/??'; self::$builtInFormats[14] = 'm/d/yyyy'; // Despite ECMA 'mm-dd-yy'; self::$builtInFormats[15] = 'd-mmm-yy'; self::$builtInFormats[16] = 'd-mmm'; self::$builtInFormats[17] = 'mmm-yy'; self::$builtInFormats[18] = 'h:mm AM/PM'; self::$builtInFormats[19] = 'h:mm:ss AM/PM'; self::$builtInFormats[20] = 'h:mm'; self::$builtInFormats[21] = 'h:mm:ss'; self::$builtInFormats[22] = 'm/d/yyyy h:mm'; // Despite ECMA 'm/d/yy h:mm'; self::$builtInFormats[37] = '#,##0_);(#,##0)'; // Despite ECMA '#,##0 ;(#,##0)'; self::$builtInFormats[38] = '#,##0_);[Red](#,##0)'; // Despite ECMA '#,##0 ;[Red](#,##0)'; self::$builtInFormats[39] = '#,##0.00_);(#,##0.00)'; // Despite ECMA '#,##0.00;(#,##0.00)'; self::$builtInFormats[40] = '#,##0.00_);[Red](#,##0.00)'; // Despite ECMA '#,##0.00;[Red](#,##0.00)'; self::$builtInFormats[44] = '_("$"* #,##0.00_);_("$"* \(#,##0.00\);_("$"* "-"??_);_(@_)'; self::$builtInFormats[45] = 'mm:ss'; self::$builtInFormats[46] = '[h]:mm:ss'; self::$builtInFormats[47] = 'mm:ss.0'; // Despite ECMA 'mmss.0'; self::$builtInFormats[48] = '##0.0E+0'; self::$builtInFormats[49] = '@'; // CHT self::$builtInFormats[27] = '[$-404]e/m/d'; self::$builtInFormats[30] = 'm/d/yy'; self::$builtInFormats[36] = '[$-404]e/m/d'; self::$builtInFormats[50] = '[$-404]e/m/d'; self::$builtInFormats[57] = '[$-404]e/m/d'; // THA self::$builtInFormats[59] = 't0'; self::$builtInFormats[60] = 't0.00'; self::$builtInFormats[61] = 't#,##0'; self::$builtInFormats[62] = 't#,##0.00'; self::$builtInFormats[67] = 't0%'; self::$builtInFormats[68] = 't0.00%'; self::$builtInFormats[69] = 't# ?/?'; self::$builtInFormats[70] = 't# ??/??'; // JPN self::$builtInFormats[28] = '[$-411]ggge"年"m"月"d"日"'; self::$builtInFormats[29] = '[$-411]ggge"年"m"月"d"日"'; self::$builtInFormats[31] = 'yyyy"年"m"月"d"日"'; self::$builtInFormats[32] = 'h"時"mm"分"'; self::$builtInFormats[33] = 'h"時"mm"分"ss"秒"'; self::$builtInFormats[34] = 'yyyy"年"m"月"'; self::$builtInFormats[35] = 'm"月"d"日"'; self::$builtInFormats[51] = '[$-411]ggge"年"m"月"d"日"'; self::$builtInFormats[52] = 'yyyy"年"m"月"'; self::$builtInFormats[53] = 'm"月"d"日"'; self::$builtInFormats[54] = '[$-411]ggge"年"m"月"d"日"'; self::$builtInFormats[55] = 'yyyy"年"m"月"'; self::$builtInFormats[56] = 'm"月"d"日"'; self::$builtInFormats[58] = '[$-411]ggge"年"m"月"d"日"'; // Flip array (for faster lookups) self::$flippedBuiltInFormats = array_flip(self::$builtInFormats); } } /** * Get built-in format code. * * @param int $index * * @return string */ public static function builtInFormatCode($index) { // Clean parameter $index = (int) $index; // Ensure built-in format codes are available self::fillBuiltInFormatCodes(); // Lookup format code if (isset(self::$builtInFormats[$index])) { return self::$builtInFormats[$index]; } return ''; } /** * Get built-in format code index. * * @param string $formatCodeIndex * * @return false|int */ public static function builtInFormatCodeIndex($formatCodeIndex) { // Ensure built-in format codes are available self::fillBuiltInFormatCodes(); // Lookup format code if (array_key_exists($formatCodeIndex, self::$flippedBuiltInFormats)) { return self::$flippedBuiltInFormats[$formatCodeIndex]; } return false; } /** * Get hash code. * * @return string Hash code */ public function getHashCode() { if ($this->isSupervisor) { return $this->getSharedComponent()->getHashCode(); } return md5( $this->formatCode . $this->builtInFormatCode . __CLASS__ ); } /** * Convert a value in a pre-defined format to a PHP string. * * @param mixed $value Value to format * @param string $format Format code: see = self::FORMAT_* for predefined values; * or can be any valid MS Excel custom format string * @param array $callBack Callback function for additional formatting of string * * @return string Formatted string */ public static function toFormattedString($value, $format, $callBack = null) { return NumberFormat\Formatter::toFormattedString($value, $format, $callBack); } protected function exportArray1(): array { $exportedArray = []; $this->exportArray2($exportedArray, 'formatCode', $this->getFormatCode()); return $exportedArray; } } phpspreadsheet/src/PhpSpreadsheet/Helper/TextGrid.php 0000644 00000010135 15060132323 0016746 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Helper; class TextGrid { /** * @var bool */ private $isCli = true; /** * @var array */ protected $matrix; /** * @var array */ protected $rows; /** * @var array */ protected $columns; /** * @var string */ private $gridDisplay; public function __construct(array $matrix, bool $isCli = true) { $this->rows = array_keys($matrix); $this->columns = array_keys($matrix[$this->rows[0]]); $matrix = array_values($matrix); array_walk( $matrix, function (&$row): void { $row = array_values($row); } ); $this->matrix = $matrix; $this->isCli = $isCli; } public function render(): string { $this->gridDisplay = $this->isCli ? '' : '<pre>'; $maxRow = max($this->rows); $maxRowLength = mb_strlen((string) $maxRow) + 1; $columnWidths = $this->getColumnWidths(); $this->renderColumnHeader($maxRowLength, $columnWidths); $this->renderRows($maxRowLength, $columnWidths); $this->renderFooter($maxRowLength, $columnWidths); $this->gridDisplay .= $this->isCli ? '' : '</pre>'; return $this->gridDisplay; } private function renderRows(int $maxRowLength, array $columnWidths): void { foreach ($this->matrix as $row => $rowData) { $this->gridDisplay .= '|' . str_pad((string) $this->rows[$row], $maxRowLength, ' ', STR_PAD_LEFT) . ' '; $this->renderCells($rowData, $columnWidths); $this->gridDisplay .= '|' . PHP_EOL; } } private function renderCells(array $rowData, array $columnWidths): void { foreach ($rowData as $column => $cell) { $displayCell = ($this->isCli) ? (string) $cell : htmlentities((string) $cell); $this->gridDisplay .= '| '; $this->gridDisplay .= $displayCell . str_repeat(' ', $columnWidths[$column] - mb_strlen($cell ?? '') + 1); } } private function renderColumnHeader(int $maxRowLength, array $columnWidths): void { $this->gridDisplay .= str_repeat(' ', $maxRowLength + 2); foreach ($this->columns as $column => $reference) { $this->gridDisplay .= '+-' . str_repeat('-', $columnWidths[$column] + 1); } $this->gridDisplay .= '+' . PHP_EOL; $this->gridDisplay .= str_repeat(' ', $maxRowLength + 2); foreach ($this->columns as $column => $reference) { $this->gridDisplay .= '| ' . str_pad((string) $reference, $columnWidths[$column] + 1, ' '); } $this->gridDisplay .= '|' . PHP_EOL; $this->renderFooter($maxRowLength, $columnWidths); } private function renderFooter(int $maxRowLength, array $columnWidths): void { $this->gridDisplay .= '+' . str_repeat('-', $maxRowLength + 1); foreach ($this->columns as $column => $reference) { $this->gridDisplay .= '+-'; $this->gridDisplay .= str_pad((string) '', $columnWidths[$column] + 1, '-'); } $this->gridDisplay .= '+' . PHP_EOL; } private function getColumnWidths(): array { $columnCount = count($this->matrix, COUNT_RECURSIVE) / count($this->matrix); $columnWidths = []; for ($column = 0; $column < $columnCount; ++$column) { $columnWidths[] = $this->getColumnWidth(array_column($this->matrix, $column)); } return $columnWidths; } private function getColumnWidth(array $columnData): int { $columnWidth = 0; $columnData = array_values($columnData); foreach ($columnData as $columnValue) { if (is_string($columnValue)) { $columnWidth = max($columnWidth, mb_strlen($columnValue)); } elseif (is_bool($columnValue)) { $columnWidth = max($columnWidth, mb_strlen($columnValue ? 'TRUE' : 'FALSE')); } $columnWidth = max($columnWidth, mb_strlen((string) $columnWidth)); } return $columnWidth; } } phpspreadsheet/src/PhpSpreadsheet/Helper/Html.php 0000644 00000062636 15060132323 0016135 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Helper; use DOMDocument; use DOMElement; use DOMNode; use DOMText; use PhpOffice\PhpSpreadsheet\RichText\RichText; use PhpOffice\PhpSpreadsheet\Style\Color; use PhpOffice\PhpSpreadsheet\Style\Font; class Html { private const COLOUR_MAP = [ 'aliceblue' => 'f0f8ff', 'antiquewhite' => 'faebd7', 'antiquewhite1' => 'ffefdb', 'antiquewhite2' => 'eedfcc', 'antiquewhite3' => 'cdc0b0', 'antiquewhite4' => '8b8378', 'aqua' => '00ffff', 'aquamarine1' => '7fffd4', 'aquamarine2' => '76eec6', 'aquamarine4' => '458b74', 'azure1' => 'f0ffff', 'azure2' => 'e0eeee', 'azure3' => 'c1cdcd', 'azure4' => '838b8b', 'beige' => 'f5f5dc', 'bisque1' => 'ffe4c4', 'bisque2' => 'eed5b7', 'bisque3' => 'cdb79e', 'bisque4' => '8b7d6b', 'black' => '000000', 'blanchedalmond' => 'ffebcd', 'blue' => '0000ff', 'blue1' => '0000ff', 'blue2' => '0000ee', 'blue4' => '00008b', 'blueviolet' => '8a2be2', 'brown' => 'a52a2a', 'brown1' => 'ff4040', 'brown2' => 'ee3b3b', 'brown3' => 'cd3333', 'brown4' => '8b2323', 'burlywood' => 'deb887', 'burlywood1' => 'ffd39b', 'burlywood2' => 'eec591', 'burlywood3' => 'cdaa7d', 'burlywood4' => '8b7355', 'cadetblue' => '5f9ea0', 'cadetblue1' => '98f5ff', 'cadetblue2' => '8ee5ee', 'cadetblue3' => '7ac5cd', 'cadetblue4' => '53868b', 'chartreuse1' => '7fff00', 'chartreuse2' => '76ee00', 'chartreuse3' => '66cd00', 'chartreuse4' => '458b00', 'chocolate' => 'd2691e', 'chocolate1' => 'ff7f24', 'chocolate2' => 'ee7621', 'chocolate3' => 'cd661d', 'coral' => 'ff7f50', 'coral1' => 'ff7256', 'coral2' => 'ee6a50', 'coral3' => 'cd5b45', 'coral4' => '8b3e2f', 'cornflowerblue' => '6495ed', 'cornsilk1' => 'fff8dc', 'cornsilk2' => 'eee8cd', 'cornsilk3' => 'cdc8b1', 'cornsilk4' => '8b8878', 'cyan1' => '00ffff', 'cyan2' => '00eeee', 'cyan3' => '00cdcd', 'cyan4' => '008b8b', 'darkgoldenrod' => 'b8860b', 'darkgoldenrod1' => 'ffb90f', 'darkgoldenrod2' => 'eead0e', 'darkgoldenrod3' => 'cd950c', 'darkgoldenrod4' => '8b6508', 'darkgreen' => '006400', 'darkkhaki' => 'bdb76b', 'darkolivegreen' => '556b2f', 'darkolivegreen1' => 'caff70', 'darkolivegreen2' => 'bcee68', 'darkolivegreen3' => 'a2cd5a', 'darkolivegreen4' => '6e8b3d', 'darkorange' => 'ff8c00', 'darkorange1' => 'ff7f00', 'darkorange2' => 'ee7600', 'darkorange3' => 'cd6600', 'darkorange4' => '8b4500', 'darkorchid' => '9932cc', 'darkorchid1' => 'bf3eff', 'darkorchid2' => 'b23aee', 'darkorchid3' => '9a32cd', 'darkorchid4' => '68228b', 'darksalmon' => 'e9967a', 'darkseagreen' => '8fbc8f', 'darkseagreen1' => 'c1ffc1', 'darkseagreen2' => 'b4eeb4', 'darkseagreen3' => '9bcd9b', 'darkseagreen4' => '698b69', 'darkslateblue' => '483d8b', 'darkslategray' => '2f4f4f', 'darkslategray1' => '97ffff', 'darkslategray2' => '8deeee', 'darkslategray3' => '79cdcd', 'darkslategray4' => '528b8b', 'darkturquoise' => '00ced1', 'darkviolet' => '9400d3', 'deeppink1' => 'ff1493', 'deeppink2' => 'ee1289', 'deeppink3' => 'cd1076', 'deeppink4' => '8b0a50', 'deepskyblue1' => '00bfff', 'deepskyblue2' => '00b2ee', 'deepskyblue3' => '009acd', 'deepskyblue4' => '00688b', 'dimgray' => '696969', 'dodgerblue1' => '1e90ff', 'dodgerblue2' => '1c86ee', 'dodgerblue3' => '1874cd', 'dodgerblue4' => '104e8b', 'firebrick' => 'b22222', 'firebrick1' => 'ff3030', 'firebrick2' => 'ee2c2c', 'firebrick3' => 'cd2626', 'firebrick4' => '8b1a1a', 'floralwhite' => 'fffaf0', 'forestgreen' => '228b22', 'fuchsia' => 'ff00ff', 'gainsboro' => 'dcdcdc', 'ghostwhite' => 'f8f8ff', 'gold1' => 'ffd700', 'gold2' => 'eec900', 'gold3' => 'cdad00', 'gold4' => '8b7500', 'goldenrod' => 'daa520', 'goldenrod1' => 'ffc125', 'goldenrod2' => 'eeb422', 'goldenrod3' => 'cd9b1d', 'goldenrod4' => '8b6914', 'gray' => 'bebebe', 'gray1' => '030303', 'gray10' => '1a1a1a', 'gray11' => '1c1c1c', 'gray12' => '1f1f1f', 'gray13' => '212121', 'gray14' => '242424', 'gray15' => '262626', 'gray16' => '292929', 'gray17' => '2b2b2b', 'gray18' => '2e2e2e', 'gray19' => '303030', 'gray2' => '050505', 'gray20' => '333333', 'gray21' => '363636', 'gray22' => '383838', 'gray23' => '3b3b3b', 'gray24' => '3d3d3d', 'gray25' => '404040', 'gray26' => '424242', 'gray27' => '454545', 'gray28' => '474747', 'gray29' => '4a4a4a', 'gray3' => '080808', 'gray30' => '4d4d4d', 'gray31' => '4f4f4f', 'gray32' => '525252', 'gray33' => '545454', 'gray34' => '575757', 'gray35' => '595959', 'gray36' => '5c5c5c', 'gray37' => '5e5e5e', 'gray38' => '616161', 'gray39' => '636363', 'gray4' => '0a0a0a', 'gray40' => '666666', 'gray41' => '696969', 'gray42' => '6b6b6b', 'gray43' => '6e6e6e', 'gray44' => '707070', 'gray45' => '737373', 'gray46' => '757575', 'gray47' => '787878', 'gray48' => '7a7a7a', 'gray49' => '7d7d7d', 'gray5' => '0d0d0d', 'gray50' => '7f7f7f', 'gray51' => '828282', 'gray52' => '858585', 'gray53' => '878787', 'gray54' => '8a8a8a', 'gray55' => '8c8c8c', 'gray56' => '8f8f8f', 'gray57' => '919191', 'gray58' => '949494', 'gray59' => '969696', 'gray6' => '0f0f0f', 'gray60' => '999999', 'gray61' => '9c9c9c', 'gray62' => '9e9e9e', 'gray63' => 'a1a1a1', 'gray64' => 'a3a3a3', 'gray65' => 'a6a6a6', 'gray66' => 'a8a8a8', 'gray67' => 'ababab', 'gray68' => 'adadad', 'gray69' => 'b0b0b0', 'gray7' => '121212', 'gray70' => 'b3b3b3', 'gray71' => 'b5b5b5', 'gray72' => 'b8b8b8', 'gray73' => 'bababa', 'gray74' => 'bdbdbd', 'gray75' => 'bfbfbf', 'gray76' => 'c2c2c2', 'gray77' => 'c4c4c4', 'gray78' => 'c7c7c7', 'gray79' => 'c9c9c9', 'gray8' => '141414', 'gray80' => 'cccccc', 'gray81' => 'cfcfcf', 'gray82' => 'd1d1d1', 'gray83' => 'd4d4d4', 'gray84' => 'd6d6d6', 'gray85' => 'd9d9d9', 'gray86' => 'dbdbdb', 'gray87' => 'dedede', 'gray88' => 'e0e0e0', 'gray89' => 'e3e3e3', 'gray9' => '171717', 'gray90' => 'e5e5e5', 'gray91' => 'e8e8e8', 'gray92' => 'ebebeb', 'gray93' => 'ededed', 'gray94' => 'f0f0f0', 'gray95' => 'f2f2f2', 'gray97' => 'f7f7f7', 'gray98' => 'fafafa', 'gray99' => 'fcfcfc', 'green' => '00ff00', 'green1' => '00ff00', 'green2' => '00ee00', 'green3' => '00cd00', 'green4' => '008b00', 'greenyellow' => 'adff2f', 'honeydew1' => 'f0fff0', 'honeydew2' => 'e0eee0', 'honeydew3' => 'c1cdc1', 'honeydew4' => '838b83', 'hotpink' => 'ff69b4', 'hotpink1' => 'ff6eb4', 'hotpink2' => 'ee6aa7', 'hotpink3' => 'cd6090', 'hotpink4' => '8b3a62', 'indianred' => 'cd5c5c', 'indianred1' => 'ff6a6a', 'indianred2' => 'ee6363', 'indianred3' => 'cd5555', 'indianred4' => '8b3a3a', 'ivory1' => 'fffff0', 'ivory2' => 'eeeee0', 'ivory3' => 'cdcdc1', 'ivory4' => '8b8b83', 'khaki' => 'f0e68c', 'khaki1' => 'fff68f', 'khaki2' => 'eee685', 'khaki3' => 'cdc673', 'khaki4' => '8b864e', 'lavender' => 'e6e6fa', 'lavenderblush1' => 'fff0f5', 'lavenderblush2' => 'eee0e5', 'lavenderblush3' => 'cdc1c5', 'lavenderblush4' => '8b8386', 'lawngreen' => '7cfc00', 'lemonchiffon1' => 'fffacd', 'lemonchiffon2' => 'eee9bf', 'lemonchiffon3' => 'cdc9a5', 'lemonchiffon4' => '8b8970', 'light' => 'eedd82', 'lightblue' => 'add8e6', 'lightblue1' => 'bfefff', 'lightblue2' => 'b2dfee', 'lightblue3' => '9ac0cd', 'lightblue4' => '68838b', 'lightcoral' => 'f08080', 'lightcyan1' => 'e0ffff', 'lightcyan2' => 'd1eeee', 'lightcyan3' => 'b4cdcd', 'lightcyan4' => '7a8b8b', 'lightgoldenrod1' => 'ffec8b', 'lightgoldenrod2' => 'eedc82', 'lightgoldenrod3' => 'cdbe70', 'lightgoldenrod4' => '8b814c', 'lightgoldenrodyellow' => 'fafad2', 'lightgray' => 'd3d3d3', 'lightpink' => 'ffb6c1', 'lightpink1' => 'ffaeb9', 'lightpink2' => 'eea2ad', 'lightpink3' => 'cd8c95', 'lightpink4' => '8b5f65', 'lightsalmon1' => 'ffa07a', 'lightsalmon2' => 'ee9572', 'lightsalmon3' => 'cd8162', 'lightsalmon4' => '8b5742', 'lightseagreen' => '20b2aa', 'lightskyblue' => '87cefa', 'lightskyblue1' => 'b0e2ff', 'lightskyblue2' => 'a4d3ee', 'lightskyblue3' => '8db6cd', 'lightskyblue4' => '607b8b', 'lightslateblue' => '8470ff', 'lightslategray' => '778899', 'lightsteelblue' => 'b0c4de', 'lightsteelblue1' => 'cae1ff', 'lightsteelblue2' => 'bcd2ee', 'lightsteelblue3' => 'a2b5cd', 'lightsteelblue4' => '6e7b8b', 'lightyellow1' => 'ffffe0', 'lightyellow2' => 'eeeed1', 'lightyellow3' => 'cdcdb4', 'lightyellow4' => '8b8b7a', 'lime' => '00ff00', 'limegreen' => '32cd32', 'linen' => 'faf0e6', 'magenta' => 'ff00ff', 'magenta2' => 'ee00ee', 'magenta3' => 'cd00cd', 'magenta4' => '8b008b', 'maroon' => 'b03060', 'maroon1' => 'ff34b3', 'maroon2' => 'ee30a7', 'maroon3' => 'cd2990', 'maroon4' => '8b1c62', 'medium' => '66cdaa', 'mediumaquamarine' => '66cdaa', 'mediumblue' => '0000cd', 'mediumorchid' => 'ba55d3', 'mediumorchid1' => 'e066ff', 'mediumorchid2' => 'd15fee', 'mediumorchid3' => 'b452cd', 'mediumorchid4' => '7a378b', 'mediumpurple' => '9370db', 'mediumpurple1' => 'ab82ff', 'mediumpurple2' => '9f79ee', 'mediumpurple3' => '8968cd', 'mediumpurple4' => '5d478b', 'mediumseagreen' => '3cb371', 'mediumslateblue' => '7b68ee', 'mediumspringgreen' => '00fa9a', 'mediumturquoise' => '48d1cc', 'mediumvioletred' => 'c71585', 'midnightblue' => '191970', 'mintcream' => 'f5fffa', 'mistyrose1' => 'ffe4e1', 'mistyrose2' => 'eed5d2', 'mistyrose3' => 'cdb7b5', 'mistyrose4' => '8b7d7b', 'moccasin' => 'ffe4b5', 'navajowhite1' => 'ffdead', 'navajowhite2' => 'eecfa1', 'navajowhite3' => 'cdb38b', 'navajowhite4' => '8b795e', 'navy' => '000080', 'navyblue' => '000080', 'oldlace' => 'fdf5e6', 'olive' => '808000', 'olivedrab' => '6b8e23', 'olivedrab1' => 'c0ff3e', 'olivedrab2' => 'b3ee3a', 'olivedrab4' => '698b22', 'orange' => 'ffa500', 'orange1' => 'ffa500', 'orange2' => 'ee9a00', 'orange3' => 'cd8500', 'orange4' => '8b5a00', 'orangered1' => 'ff4500', 'orangered2' => 'ee4000', 'orangered3' => 'cd3700', 'orangered4' => '8b2500', 'orchid' => 'da70d6', 'orchid1' => 'ff83fa', 'orchid2' => 'ee7ae9', 'orchid3' => 'cd69c9', 'orchid4' => '8b4789', 'pale' => 'db7093', 'palegoldenrod' => 'eee8aa', 'palegreen' => '98fb98', 'palegreen1' => '9aff9a', 'palegreen2' => '90ee90', 'palegreen3' => '7ccd7c', 'palegreen4' => '548b54', 'paleturquoise' => 'afeeee', 'paleturquoise1' => 'bbffff', 'paleturquoise2' => 'aeeeee', 'paleturquoise3' => '96cdcd', 'paleturquoise4' => '668b8b', 'palevioletred' => 'db7093', 'palevioletred1' => 'ff82ab', 'palevioletred2' => 'ee799f', 'palevioletred3' => 'cd6889', 'palevioletred4' => '8b475d', 'papayawhip' => 'ffefd5', 'peachpuff1' => 'ffdab9', 'peachpuff2' => 'eecbad', 'peachpuff3' => 'cdaf95', 'peachpuff4' => '8b7765', 'pink' => 'ffc0cb', 'pink1' => 'ffb5c5', 'pink2' => 'eea9b8', 'pink3' => 'cd919e', 'pink4' => '8b636c', 'plum' => 'dda0dd', 'plum1' => 'ffbbff', 'plum2' => 'eeaeee', 'plum3' => 'cd96cd', 'plum4' => '8b668b', 'powderblue' => 'b0e0e6', 'purple' => 'a020f0', 'rebeccapurple' => '663399', 'purple1' => '9b30ff', 'purple2' => '912cee', 'purple3' => '7d26cd', 'purple4' => '551a8b', 'red' => 'ff0000', 'red1' => 'ff0000', 'red2' => 'ee0000', 'red3' => 'cd0000', 'red4' => '8b0000', 'rosybrown' => 'bc8f8f', 'rosybrown1' => 'ffc1c1', 'rosybrown2' => 'eeb4b4', 'rosybrown3' => 'cd9b9b', 'rosybrown4' => '8b6969', 'royalblue' => '4169e1', 'royalblue1' => '4876ff', 'royalblue2' => '436eee', 'royalblue3' => '3a5fcd', 'royalblue4' => '27408b', 'saddlebrown' => '8b4513', 'salmon' => 'fa8072', 'salmon1' => 'ff8c69', 'salmon2' => 'ee8262', 'salmon3' => 'cd7054', 'salmon4' => '8b4c39', 'sandybrown' => 'f4a460', 'seagreen1' => '54ff9f', 'seagreen2' => '4eee94', 'seagreen3' => '43cd80', 'seagreen4' => '2e8b57', 'seashell1' => 'fff5ee', 'seashell2' => 'eee5de', 'seashell3' => 'cdc5bf', 'seashell4' => '8b8682', 'sienna' => 'a0522d', 'sienna1' => 'ff8247', 'sienna2' => 'ee7942', 'sienna3' => 'cd6839', 'sienna4' => '8b4726', 'silver' => 'c0c0c0', 'skyblue' => '87ceeb', 'skyblue1' => '87ceff', 'skyblue2' => '7ec0ee', 'skyblue3' => '6ca6cd', 'skyblue4' => '4a708b', 'slateblue' => '6a5acd', 'slateblue1' => '836fff', 'slateblue2' => '7a67ee', 'slateblue3' => '6959cd', 'slateblue4' => '473c8b', 'slategray' => '708090', 'slategray1' => 'c6e2ff', 'slategray2' => 'b9d3ee', 'slategray3' => '9fb6cd', 'slategray4' => '6c7b8b', 'snow1' => 'fffafa', 'snow2' => 'eee9e9', 'snow3' => 'cdc9c9', 'snow4' => '8b8989', 'springgreen1' => '00ff7f', 'springgreen2' => '00ee76', 'springgreen3' => '00cd66', 'springgreen4' => '008b45', 'steelblue' => '4682b4', 'steelblue1' => '63b8ff', 'steelblue2' => '5cacee', 'steelblue3' => '4f94cd', 'steelblue4' => '36648b', 'tan' => 'd2b48c', 'tan1' => 'ffa54f', 'tan2' => 'ee9a49', 'tan3' => 'cd853f', 'tan4' => '8b5a2b', 'teal' => '008080', 'thistle' => 'd8bfd8', 'thistle1' => 'ffe1ff', 'thistle2' => 'eed2ee', 'thistle3' => 'cdb5cd', 'thistle4' => '8b7b8b', 'tomato1' => 'ff6347', 'tomato2' => 'ee5c42', 'tomato3' => 'cd4f39', 'tomato4' => '8b3626', 'turquoise' => '40e0d0', 'turquoise1' => '00f5ff', 'turquoise2' => '00e5ee', 'turquoise3' => '00c5cd', 'turquoise4' => '00868b', 'violet' => 'ee82ee', 'violetred' => 'd02090', 'violetred1' => 'ff3e96', 'violetred2' => 'ee3a8c', 'violetred3' => 'cd3278', 'violetred4' => '8b2252', 'wheat' => 'f5deb3', 'wheat1' => 'ffe7ba', 'wheat2' => 'eed8ae', 'wheat3' => 'cdba96', 'wheat4' => '8b7e66', 'white' => 'ffffff', 'whitesmoke' => 'f5f5f5', 'yellow' => 'ffff00', 'yellow1' => 'ffff00', 'yellow2' => 'eeee00', 'yellow3' => 'cdcd00', 'yellow4' => '8b8b00', 'yellowgreen' => '9acd32', ]; /** @var ?string */ private $face; /** @var ?string */ private $size; /** @var ?string */ private $color; /** @var bool */ private $bold = false; /** @var bool */ private $italic = false; /** @var bool */ private $underline = false; /** @var bool */ private $superscript = false; /** @var bool */ private $subscript = false; /** @var bool */ private $strikethrough = false; private const START_TAG_CALLBACKS = [ 'font' => 'startFontTag', 'b' => 'startBoldTag', 'strong' => 'startBoldTag', 'i' => 'startItalicTag', 'em' => 'startItalicTag', 'u' => 'startUnderlineTag', 'ins' => 'startUnderlineTag', 'del' => 'startStrikethruTag', 'sup' => 'startSuperscriptTag', 'sub' => 'startSubscriptTag', ]; private const END_TAG_CALLBACKS = [ 'font' => 'endFontTag', 'b' => 'endBoldTag', 'strong' => 'endBoldTag', 'i' => 'endItalicTag', 'em' => 'endItalicTag', 'u' => 'endUnderlineTag', 'ins' => 'endUnderlineTag', 'del' => 'endStrikethruTag', 'sup' => 'endSuperscriptTag', 'sub' => 'endSubscriptTag', 'br' => 'breakTag', 'p' => 'breakTag', 'h1' => 'breakTag', 'h2' => 'breakTag', 'h3' => 'breakTag', 'h4' => 'breakTag', 'h5' => 'breakTag', 'h6' => 'breakTag', ]; /** @var array */ private $stack = []; /** @var string */ private $stringData = ''; /** * @var RichText */ private $richTextObject; private function initialise(): void { $this->face = $this->size = $this->color = null; $this->bold = $this->italic = $this->underline = $this->superscript = $this->subscript = $this->strikethrough = false; $this->stack = []; $this->stringData = ''; } /** * Parse HTML formatting and return the resulting RichText. * * @param string $html * * @return RichText */ public function toRichTextObject($html) { $this->initialise(); // Create a new DOM object $dom = new DOMDocument(); // Load the HTML file into the DOM object // Note the use of error suppression, because typically this will be an html fragment, so not fully valid markup $prefix = '<?xml encoding="UTF-8">'; /** @scrutinizer ignore-unhandled */ @$dom->loadHTML($prefix . $html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD); // Discard excess white space $dom->preserveWhiteSpace = false; $this->richTextObject = new RichText(); $this->parseElements($dom); // Clean any further spurious whitespace $this->cleanWhitespace(); return $this->richTextObject; } private function cleanWhitespace(): void { foreach ($this->richTextObject->getRichTextElements() as $key => $element) { $text = $element->getText(); // Trim any leading spaces on the first run if ($key == 0) { $text = ltrim($text); } // Trim any spaces immediately after a line break $text = (string) preg_replace('/\n */mu', "\n", $text); $element->setText($text); } } private function buildTextRun(): void { $text = $this->stringData; if (trim($text) === '') { return; } $richtextRun = $this->richTextObject->createTextRun($this->stringData); $font = $richtextRun->getFont(); if ($font !== null) { if ($this->face) { $font->setName($this->face); } if ($this->size) { $font->setSize($this->size); } if ($this->color) { $font->setColor(new Color('ff' . $this->color)); } if ($this->bold) { $font->setBold(true); } if ($this->italic) { $font->setItalic(true); } if ($this->underline) { $font->setUnderline(Font::UNDERLINE_SINGLE); } if ($this->superscript) { $font->setSuperscript(true); } if ($this->subscript) { $font->setSubscript(true); } if ($this->strikethrough) { $font->setStrikethrough(true); } } $this->stringData = ''; } private function rgbToColour(string $rgbValue): string { preg_match_all('/\d+/', $rgbValue, $values); foreach ($values[0] as &$value) { $value = str_pad(dechex($value), 2, '0', STR_PAD_LEFT); } return implode('', $values[0]); } public static function colourNameLookup(string $colorName): string { return self::COLOUR_MAP[$colorName] ?? ''; } protected function startFontTag(DOMElement $tag): void { $attrs = $tag->attributes; if ($attrs !== null) { foreach ($attrs as $attribute) { $attributeName = strtolower($attribute->name); $attributeValue = $attribute->value; if ($attributeName == 'color') { if (preg_match('/rgb\s*\(/', $attributeValue)) { $this->$attributeName = $this->rgbToColour($attributeValue); } elseif (strpos(trim($attributeValue), '#') === 0) { $this->$attributeName = ltrim($attributeValue, '#'); } else { $this->$attributeName = static::colourNameLookup($attributeValue); } } else { $this->$attributeName = $attributeValue; } } } } protected function endFontTag(): void { $this->face = $this->size = $this->color = null; } protected function startBoldTag(): void { $this->bold = true; } protected function endBoldTag(): void { $this->bold = false; } protected function startItalicTag(): void { $this->italic = true; } protected function endItalicTag(): void { $this->italic = false; } protected function startUnderlineTag(): void { $this->underline = true; } protected function endUnderlineTag(): void { $this->underline = false; } protected function startSubscriptTag(): void { $this->subscript = true; } protected function endSubscriptTag(): void { $this->subscript = false; } protected function startSuperscriptTag(): void { $this->superscript = true; } protected function endSuperscriptTag(): void { $this->superscript = false; } protected function startStrikethruTag(): void { $this->strikethrough = true; } protected function endStrikethruTag(): void { $this->strikethrough = false; } protected function breakTag(): void { $this->stringData .= "\n"; } private function parseTextNode(DOMText $textNode): void { $domText = (string) preg_replace( '/\s+/u', ' ', str_replace(["\r", "\n"], ' ', $textNode->nodeValue ?? '') ); $this->stringData .= $domText; $this->buildTextRun(); } /** * @param string $callbackTag */ private function handleCallback(DOMElement $element, $callbackTag, array $callbacks): void { if (isset($callbacks[$callbackTag])) { $elementHandler = $callbacks[$callbackTag]; if (method_exists($this, $elementHandler)) { /** @var callable */ $callable = [$this, $elementHandler]; call_user_func($callable, $element); } } } private function parseElementNode(DOMElement $element): void { $callbackTag = strtolower($element->nodeName); $this->stack[] = $callbackTag; $this->handleCallback($element, $callbackTag, self::START_TAG_CALLBACKS); $this->parseElements($element); array_pop($this->stack); $this->handleCallback($element, $callbackTag, self::END_TAG_CALLBACKS); } private function parseElements(DOMNode $element): void { foreach ($element->childNodes as $child) { if ($child instanceof DOMText) { $this->parseTextNode($child); } elseif ($child instanceof DOMElement) { $this->parseElementNode($child); } } } } phpspreadsheet/src/PhpSpreadsheet/Helper/Size.php 0000644 00000001636 15060132323 0016134 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Helper; class Size { const REGEXP_SIZE_VALIDATION = '/^(?P<size>\d*\.?\d+)(?P<unit>pt|px|em)?$/i'; /** * @var bool */ protected $valid; /** * @var string */ protected $size = ''; /** * @var string */ protected $unit = ''; public function __construct(string $size) { $this->valid = (bool) preg_match(self::REGEXP_SIZE_VALIDATION, $size, $matches); if ($this->valid) { $this->size = $matches['size']; $this->unit = $matches['unit'] ?? 'pt'; } } public function valid(): bool { return $this->valid; } public function size(): string { return $this->size; } public function unit(): string { return $this->unit; } public function __toString() { return $this->size . $this->unit; } } phpspreadsheet/src/PhpSpreadsheet/Helper/Handler.php 0000644 00000002013 15060132323 0016565 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Helper; class Handler { /** @var string */ private static $invalidHex = 'Y'; // A bunch of methods to show that we continue // to capture messages even using PhpUnit 10. public static function suppressed(): bool { return @trigger_error('hello'); } public static function deprecated(): string { return (string) hexdec(self::$invalidHex); } public static function notice(string $value): void { date_default_timezone_set($value); } public static function warning(): bool { return file_get_contents(__FILE__ . 'noexist') !== false; } public static function userDeprecated(): bool { return trigger_error('hello', E_USER_DEPRECATED); } public static function userNotice(): bool { return trigger_error('userNotice', E_USER_NOTICE); } public static function userWarning(): bool { return trigger_error('userWarning', E_USER_WARNING); } } phpspreadsheet/src/PhpSpreadsheet/Helper/Dimension.php 0000644 00000006351 15060132323 0017146 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Helper; use PhpOffice\PhpSpreadsheet\Exception; use PhpOffice\PhpSpreadsheet\Shared\Drawing; use PhpOffice\PhpSpreadsheet\Style\Font; class Dimension { public const UOM_CENTIMETERS = 'cm'; public const UOM_MILLIMETERS = 'mm'; public const UOM_INCHES = 'in'; public const UOM_PIXELS = 'px'; public const UOM_POINTS = 'pt'; public const UOM_PICA = 'pc'; /** * Based on 96 dpi. */ const ABSOLUTE_UNITS = [ self::UOM_CENTIMETERS => 96.0 / 2.54, self::UOM_MILLIMETERS => 96.0 / 25.4, self::UOM_INCHES => 96.0, self::UOM_PIXELS => 1.0, self::UOM_POINTS => 96.0 / 72, self::UOM_PICA => 96.0 * 12 / 72, ]; /** * Based on a standard column width of 8.54 units in MS Excel. */ const RELATIVE_UNITS = [ 'em' => 10.0 / 8.54, 'ex' => 10.0 / 8.54, 'ch' => 10.0 / 8.54, 'rem' => 10.0 / 8.54, 'vw' => 8.54, 'vh' => 8.54, 'vmin' => 8.54, 'vmax' => 8.54, '%' => 8.54 / 100, ]; /** * @var float|int If this is a width, then size is measured in pixels (if is set) * or in Excel's default column width units if $unit is null. * If this is a height, then size is measured in pixels () * or in points () if $unit is null. */ protected $size; /** * @var null|string */ protected $unit; /** * Phpstan bug has been fixed; this function allows us to * pass Phpstan whether fixed or not. * * @param mixed $value */ private static function stanBugFixed($value): array { return is_array($value) ? $value : [null, null]; } public function __construct(string $dimension) { [$size, $unit] = self::stanBugFixed(sscanf($dimension, '%[1234567890.]%s')); $unit = strtolower(trim($unit ?? '')); $size = (float) $size; // If a UoM is specified, then convert the size to pixels for internal storage if (isset(self::ABSOLUTE_UNITS[$unit])) { $size *= self::ABSOLUTE_UNITS[$unit]; $this->unit = self::UOM_PIXELS; } elseif (isset(self::RELATIVE_UNITS[$unit])) { $size *= self::RELATIVE_UNITS[$unit]; $size = round($size, 4); } $this->size = $size; } public function width(): float { return (float) ($this->unit === null) ? $this->size : round(Drawing::pixelsToCellDimension((int) $this->size, new Font(false)), 4); } public function height(): float { return (float) ($this->unit === null) ? $this->size : $this->toUnit(self::UOM_POINTS); } public function toUnit(string $unitOfMeasure): float { $unitOfMeasure = strtolower($unitOfMeasure); if (!array_key_exists($unitOfMeasure, self::ABSOLUTE_UNITS)) { throw new Exception("{$unitOfMeasure} is not a vaid unit of measure"); } $size = $this->size; if ($this->unit === null) { $size = Drawing::cellDimensionToPixels($size, new Font(false)); } return $size / self::ABSOLUTE_UNITS[$unitOfMeasure]; } } phpspreadsheet/src/PhpSpreadsheet/Helper/Sample.php 0000644 00000022341 15060132323 0016437 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Helper; use PhpOffice\PhpSpreadsheet\Chart\Chart; use PhpOffice\PhpSpreadsheet\IOFactory; use PhpOffice\PhpSpreadsheet\Settings; use PhpOffice\PhpSpreadsheet\Spreadsheet; use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; use PhpOffice\PhpSpreadsheet\Writer\IWriter; use RecursiveDirectoryIterator; use RecursiveIteratorIterator; use RecursiveRegexIterator; use ReflectionClass; use RegexIterator; use RuntimeException; use Throwable; /** * Helper class to be used in sample code. */ class Sample { /** * Returns whether we run on CLI or browser. * * @return bool */ public function isCli() { return PHP_SAPI === 'cli'; } /** * Return the filename currently being executed. * * @return string */ public function getScriptFilename() { return basename($_SERVER['SCRIPT_FILENAME'], '.php'); } /** * Whether we are executing the index page. * * @return bool */ public function isIndex() { return $this->getScriptFilename() === 'index'; } /** * Return the page title. * * @return string */ public function getPageTitle() { return $this->isIndex() ? 'PHPSpreadsheet' : $this->getScriptFilename(); } /** * Return the page heading. * * @return string */ public function getPageHeading() { return $this->isIndex() ? '' : '<h1>' . str_replace('_', ' ', $this->getScriptFilename()) . '</h1>'; } /** * Returns an array of all known samples. * * @return string[][] [$name => $path] */ public function getSamples() { // Populate samples $baseDir = realpath(__DIR__ . '/../../../samples'); if ($baseDir === false) { // @codeCoverageIgnoreStart throw new RuntimeException('realpath returned false'); // @codeCoverageIgnoreEnd } $directory = new RecursiveDirectoryIterator($baseDir); $iterator = new RecursiveIteratorIterator($directory); $regex = new RegexIterator($iterator, '/^.+\.php$/', RecursiveRegexIterator::GET_MATCH); $files = []; foreach ($regex as $file) { $file = str_replace(str_replace('\\', '/', $baseDir) . '/', '', str_replace('\\', '/', $file[0])); if (is_array($file)) { // @codeCoverageIgnoreStart throw new RuntimeException('str_replace returned array'); // @codeCoverageIgnoreEnd } $info = pathinfo($file); $category = str_replace('_', ' ', $info['dirname'] ?? ''); $name = str_replace('_', ' ', (string) preg_replace('/(|\.php)/', '', $info['filename'])); if (!in_array($category, ['.', 'boostrap', 'templates'])) { if (!isset($files[$category])) { $files[$category] = []; } $files[$category][$name] = $file; } } // Sort everything ksort($files); foreach ($files as &$f) { asort($f); } return $files; } /** * Write documents. * * @param string $filename * @param string[] $writers */ public function write(Spreadsheet $spreadsheet, $filename, array $writers = ['Xlsx', 'Xls'], bool $withCharts = false, ?callable $writerCallback = null): void { // Set active sheet index to the first sheet, so Excel opens this as the first sheet $spreadsheet->setActiveSheetIndex(0); // Write documents foreach ($writers as $writerType) { $path = $this->getFilename($filename, mb_strtolower($writerType)); $writer = IOFactory::createWriter($spreadsheet, $writerType); $writer->setIncludeCharts($withCharts); if ($writerCallback !== null) { $writerCallback($writer); } $callStartTime = microtime(true); $writer->save($path); $this->logWrite($writer, $path, /** @scrutinizer ignore-type */ $callStartTime); if ($this->isCli() === false) { echo '<a href="/download.php?type=' . pathinfo($path, PATHINFO_EXTENSION) . '&name=' . basename($path) . '">Download ' . basename($path) . '</a><br />'; } } $this->logEndingNotes(); } protected function isDirOrMkdir(string $folder): bool { return \is_dir($folder) || \mkdir($folder); } /** * Returns the temporary directory and make sure it exists. * * @return string */ public function getTemporaryFolder() { $tempFolder = sys_get_temp_dir() . '/phpspreadsheet'; if (!$this->isDirOrMkdir($tempFolder)) { throw new RuntimeException(sprintf('Directory "%s" was not created', $tempFolder)); } return $tempFolder; } /** * Returns the filename that should be used for sample output. * * @param string $filename * @param string $extension */ public function getFilename($filename, $extension = 'xlsx'): string { $originalExtension = pathinfo($filename, PATHINFO_EXTENSION); return $this->getTemporaryFolder() . '/' . str_replace('.' . /** @scrutinizer ignore-type */ $originalExtension, '.' . $extension, basename($filename)); } /** * Return a random temporary file name. * * @param string $extension * * @return string */ public function getTemporaryFilename($extension = 'xlsx') { $temporaryFilename = tempnam($this->getTemporaryFolder(), 'phpspreadsheet-'); if ($temporaryFilename === false) { // @codeCoverageIgnoreStart throw new RuntimeException('tempnam returned false'); // @codeCoverageIgnoreEnd } unlink($temporaryFilename); return $temporaryFilename . '.' . $extension; } public function log(string $message): void { $eol = $this->isCli() ? PHP_EOL : '<br />'; echo($this->isCli() ? date('H:i:s ') : '') . $message . $eol; } public function renderChart(Chart $chart, string $fileName): void { if ($this->isCli() === true) { return; } Settings::setChartRenderer(\PhpOffice\PhpSpreadsheet\Chart\Renderer\MtJpGraphRenderer::class); $fileName = $this->getFilename($fileName, 'png'); try { $chart->render($fileName); $this->log('Rendered image: ' . $fileName); $imageData = file_get_contents($fileName); if ($imageData !== false) { echo '<div><img src="data:image/gif;base64,' . base64_encode($imageData) . '" /></div>'; } } catch (Throwable $e) { $this->log('Error rendering chart: ' . $e->getMessage() . PHP_EOL); } } public function titles(string $category, string $functionName, ?string $description = null): void { $this->log(sprintf('%s Functions:', $category)); $description === null ? $this->log(sprintf('Function: %s()', rtrim($functionName, '()'))) : $this->log(sprintf('Function: %s() - %s.', rtrim($functionName, '()'), rtrim($description, '.'))); } public function displayGrid(array $matrix): void { $renderer = new TextGrid($matrix, $this->isCli()); echo $renderer->render(); } public function logCalculationResult( Worksheet $worksheet, string $functionName, string $formulaCell, ?string $descriptionCell = null ): void { if ($descriptionCell !== null) { $this->log($worksheet->getCell($descriptionCell)->getValue()); } $this->log($worksheet->getCell($formulaCell)->getValue()); $this->log(sprintf('%s() Result is ', $functionName) . $worksheet->getCell($formulaCell)->getCalculatedValue()); } /** * Log ending notes. */ public function logEndingNotes(): void { // Do not show execution time for index $this->log('Peak memory usage: ' . (memory_get_peak_usage(true) / 1024 / 1024) . 'MB'); } /** * Log a line about the write operation. * * @param string $path * @param float $callStartTime */ public function logWrite(IWriter $writer, $path, $callStartTime): void { $callEndTime = microtime(true); $callTime = $callEndTime - $callStartTime; $reflection = new ReflectionClass($writer); $format = $reflection->getShortName(); $message = ($this->isCli() === true) ? "Write {$format} format to {$path} in " . sprintf('%.4f', $callTime) . ' seconds' : "Write {$format} format to <code>{$path}</code> in " . sprintf('%.4f', $callTime) . ' seconds'; $this->log($message); } /** * Log a line about the read operation. * * @param string $format * @param string $path * @param float $callStartTime */ public function logRead($format, $path, $callStartTime): void { $callEndTime = microtime(true); $callTime = $callEndTime - $callStartTime; $message = "Read {$format} format from <code>{$path}</code> in " . sprintf('%.4f', $callTime) . ' seconds'; $this->log($message); } } phpspreadsheet/src/PhpSpreadsheet/Helper/Downloader.php 0000644 00000005300 15060132323 0017310 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Helper; use PhpOffice\PhpSpreadsheet\Exception; class Downloader { protected string $filepath; protected string $filename; protected string $filetype; protected const CONTENT_TYPES = [ 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'xls' => 'application/vnd.ms-excel', 'ods' => 'application/vnd.oasis.opendocument.spreadsheet', 'csv' => 'text/csv', 'html' => 'text/html', 'pdf' => 'application/pdf', ]; public function __construct(string $folder, string $filename, ?string $filetype = null) { if ((is_dir($folder) === false) || (is_readable($folder) === false)) { throw new Exception("Folder {$folder} is not accessable"); } $filepath = "{$folder}/{$filename}"; $this->filepath = (string) realpath($filepath); $this->filename = basename($filepath); if ((file_exists($this->filepath) === false) || (is_readable($this->filepath) === false)) { throw new Exception("{$this->filename} not found, or cannot be read"); } $filetype ??= pathinfo($filename, PATHINFO_EXTENSION); if (array_key_exists(strtolower($filetype), self::CONTENT_TYPES) === false) { throw new Exception("Invalid filetype: {$filetype} cannot be downloaded"); } $this->filetype = strtolower($filetype); } public function download(): void { $this->headers(); readfile($this->filepath); } public function headers(): void { ob_clean(); $this->contentType(); $this->contentDisposition(); $this->cacheHeaders(); $this->fileSize(); flush(); } protected function contentType(): void { header('Content-Type: ' . self::CONTENT_TYPES[$this->filetype]); } protected function contentDisposition(): void { header('Content-Disposition: attachment;filename="' . $this->filename . '"'); } protected function cacheHeaders(): void { header('Cache-Control: max-age=0'); // If you're serving to IE 9, then the following may be needed header('Cache-Control: max-age=1'); // If you're serving to IE over SSL, then the following may be needed header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Date in the past header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); // always modified header('Cache-Control: cache, must-revalidate'); // HTTP/1.1 header('Pragma: public'); // HTTP/1.0 } protected function fileSize(): void { header('Content-Length: ' . filesize($this->filepath)); } } phpspreadsheet/src/PhpSpreadsheet/Calculation/Functions.php 0000644 00000045401 15060132323 0020207 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Calculation; use PhpOffice\PhpSpreadsheet\Cell\Cell; use PhpOffice\PhpSpreadsheet\Shared\Date; class Functions { const PRECISION = 8.88E-016; /** * 2 / PI. */ const M_2DIVPI = 0.63661977236758134307553505349006; const COMPATIBILITY_EXCEL = 'Excel'; const COMPATIBILITY_GNUMERIC = 'Gnumeric'; const COMPATIBILITY_OPENOFFICE = 'OpenOfficeCalc'; /** Use of RETURNDATE_PHP_NUMERIC is discouraged - not 32-bit Y2038-safe, no timezone. */ const RETURNDATE_PHP_NUMERIC = 'P'; /** Use of RETURNDATE_UNIX_TIMESTAMP is discouraged - not 32-bit Y2038-safe, no timezone. */ const RETURNDATE_UNIX_TIMESTAMP = 'P'; const RETURNDATE_PHP_OBJECT = 'O'; const RETURNDATE_PHP_DATETIME_OBJECT = 'O'; const RETURNDATE_EXCEL = 'E'; /** * Compatibility mode to use for error checking and responses. * * @var string */ protected static $compatibilityMode = self::COMPATIBILITY_EXCEL; /** * Data Type to use when returning date values. * * @var string */ protected static $returnDateType = self::RETURNDATE_EXCEL; /** * Set the Compatibility Mode. * * @param string $compatibilityMode Compatibility Mode * Permitted values are: * Functions::COMPATIBILITY_EXCEL 'Excel' * Functions::COMPATIBILITY_GNUMERIC 'Gnumeric' * Functions::COMPATIBILITY_OPENOFFICE 'OpenOfficeCalc' * * @return bool (Success or Failure) */ public static function setCompatibilityMode($compatibilityMode) { if ( ($compatibilityMode == self::COMPATIBILITY_EXCEL) || ($compatibilityMode == self::COMPATIBILITY_GNUMERIC) || ($compatibilityMode == self::COMPATIBILITY_OPENOFFICE) ) { self::$compatibilityMode = $compatibilityMode; return true; } return false; } /** * Return the current Compatibility Mode. * * @return string Compatibility Mode * Possible Return values are: * Functions::COMPATIBILITY_EXCEL 'Excel' * Functions::COMPATIBILITY_GNUMERIC 'Gnumeric' * Functions::COMPATIBILITY_OPENOFFICE 'OpenOfficeCalc' */ public static function getCompatibilityMode() { return self::$compatibilityMode; } /** * Set the Return Date Format used by functions that return a date/time (Excel, PHP Serialized Numeric or PHP DateTime Object). * * @param string $returnDateType Return Date Format * Permitted values are: * Functions::RETURNDATE_UNIX_TIMESTAMP 'P' * Functions::RETURNDATE_PHP_DATETIME_OBJECT 'O' * Functions::RETURNDATE_EXCEL 'E' * * @return bool Success or failure */ public static function setReturnDateType($returnDateType) { if ( ($returnDateType == self::RETURNDATE_UNIX_TIMESTAMP) || ($returnDateType == self::RETURNDATE_PHP_DATETIME_OBJECT) || ($returnDateType == self::RETURNDATE_EXCEL) ) { self::$returnDateType = $returnDateType; return true; } return false; } /** * Return the current Return Date Format for functions that return a date/time (Excel, PHP Serialized Numeric or PHP Object). * * @return string Return Date Format * Possible Return values are: * Functions::RETURNDATE_UNIX_TIMESTAMP 'P' * Functions::RETURNDATE_PHP_DATETIME_OBJECT 'O' * Functions::RETURNDATE_EXCEL ' 'E' */ public static function getReturnDateType() { return self::$returnDateType; } /** * DUMMY. * * @return string #Not Yet Implemented */ public static function DUMMY() { return '#Not Yet Implemented'; } /** @param mixed $idx */ public static function isMatrixValue($idx): bool { return (substr_count($idx, '.') <= 1) || (preg_match('/\.[A-Z]/', $idx) > 0); } /** @param mixed $idx */ public static function isValue($idx): bool { return substr_count($idx, '.') === 0; } /** @param mixed $idx */ public static function isCellValue($idx): bool { return substr_count($idx, '.') > 1; } /** @param mixed $condition */ public static function ifCondition($condition): string { $condition = self::flattenSingleValue($condition); if ($condition === '') { return '=""'; } if (!is_string($condition) || !in_array($condition[0], ['>', '<', '='], true)) { $condition = self::operandSpecialHandling($condition); if (is_bool($condition)) { return '=' . ($condition ? 'TRUE' : 'FALSE'); } elseif (!is_numeric($condition)) { if ($condition !== '""') { // Not an empty string // Escape any quotes in the string value $condition = (string) preg_replace('/"/ui', '""', $condition); } $condition = Calculation::wrapResult(strtoupper($condition)); } return str_replace('""""', '""', '=' . $condition); } preg_match('/(=|<[>=]?|>=?)(.*)/', $condition, $matches); [, $operator, $operand] = $matches; $operand = self::operandSpecialHandling($operand); if (is_numeric(trim($operand, '"'))) { $operand = trim($operand, '"'); } elseif (!is_numeric($operand) && $operand !== 'FALSE' && $operand !== 'TRUE') { $operand = str_replace('"', '""', $operand); $operand = Calculation::wrapResult(strtoupper($operand)); } return str_replace('""""', '""', $operator . $operand); } /** * @param mixed $operand * * @return mixed */ private static function operandSpecialHandling($operand) { if (is_numeric($operand) || is_bool($operand)) { return $operand; } elseif (strtoupper($operand) === Calculation::getTRUE() || strtoupper($operand) === Calculation::getFALSE()) { return strtoupper($operand); } // Check for percentage if (preg_match('/^\-?\d*\.?\d*\s?\%$/', $operand)) { return ((float) rtrim($operand, '%')) / 100; } // Check for dates if (($dateValueOperand = Date::stringToExcel($operand)) !== false) { return $dateValueOperand; } return $operand; } /** * NULL. * * Returns the error value #NULL! * * @deprecated 1.23.0 Use the null() method in the Information\ExcelError class instead * @see Information\ExcelError::null() * * @return string #NULL! */ public static function null() { return Information\ExcelError::null(); } /** * NaN. * * Returns the error value #NUM! * * @deprecated 1.23.0 Use the NAN() method in the Information\Error class instead * @see Information\ExcelError::NAN() * * @return string #NUM! */ public static function NAN() { return Information\ExcelError::NAN(); } /** * REF. * * Returns the error value #REF! * * @deprecated 1.23.0 Use the REF() method in the Information\ExcelError class instead * @see Information\ExcelError::REF() * * @return string #REF! */ public static function REF() { return Information\ExcelError::REF(); } /** * NA. * * Excel Function: * =NA() * * Returns the error value #N/A * #N/A is the error value that means "no value is available." * * @deprecated 1.23.0 Use the NA() method in the Information\ExcelError class instead * @see Information\ExcelError::NA() * * @return string #N/A! */ public static function NA() { return Information\ExcelError::NA(); } /** * VALUE. * * Returns the error value #VALUE! * * @deprecated 1.23.0 Use the VALUE() method in the Information\ExcelError class instead * @see Information\ExcelError::VALUE() * * @return string #VALUE! */ public static function VALUE() { return Information\ExcelError::VALUE(); } /** * NAME. * * Returns the error value #NAME? * * @deprecated 1.23.0 Use the NAME() method in the Information\ExcelError class instead * @see Information\ExcelError::NAME() * * @return string #NAME? */ public static function NAME() { return Information\ExcelError::NAME(); } /** * DIV0. * * @deprecated 1.23.0 Use the DIV0() method in the Information\ExcelError class instead * @see Information\ExcelError::DIV0() * * @return string #Not Yet Implemented */ public static function DIV0() { return Information\ExcelError::DIV0(); } /** * ERROR_TYPE. * * @param mixed $value Value to check * * @deprecated 1.23.0 Use the type() method in the Information\ExcelError class instead * @see Information\ExcelError::type() * * @return array|int|string */ public static function errorType($value = '') { return Information\ExcelError::type($value); } /** * IS_BLANK. * * @param mixed $value Value to check * * @deprecated 1.23.0 Use the isBlank() method in the Information\Value class instead * @see Information\Value::isBlank() * * @return array|bool */ public static function isBlank($value = null) { return Information\Value::isBlank($value); } /** * IS_ERR. * * @param mixed $value Value to check * * @deprecated 1.23.0 Use the isErr() method in the Information\ErrorValue class instead * @see Information\ErrorValue::isErr() * * @return array|bool */ public static function isErr($value = '') { return Information\ErrorValue::isErr($value); } /** * IS_ERROR. * * @param mixed $value Value to check * * @deprecated 1.23.0 Use the isError() method in the Information\ErrorValue class instead * @see Information\ErrorValue::isError() * * @return array|bool */ public static function isError($value = '') { return Information\ErrorValue::isError($value); } /** * IS_NA. * * @param mixed $value Value to check * * @deprecated 1.23.0 Use the isNa() method in the Information\ErrorValue class instead * @see Information\ErrorValue::isNa() * * @return array|bool */ public static function isNa($value = '') { return Information\ErrorValue::isNa($value); } /** * IS_EVEN. * * @param mixed $value Value to check * * @deprecated 1.23.0 Use the isEven() method in the Information\Value class instead * @see Information\Value::isEven() * * @return array|bool|string */ public static function isEven($value = null) { return Information\Value::isEven($value); } /** * IS_ODD. * * @param mixed $value Value to check * * @deprecated 1.23.0 Use the isOdd() method in the Information\Value class instead * @see Information\Value::isOdd() * * @return array|bool|string */ public static function isOdd($value = null) { return Information\Value::isOdd($value); } /** * IS_NUMBER. * * @param mixed $value Value to check * * @deprecated 1.23.0 Use the isNumber() method in the Information\Value class instead * @see Information\Value::isNumber() * * @return array|bool */ public static function isNumber($value = null) { return Information\Value::isNumber($value); } /** * IS_LOGICAL. * * @param mixed $value Value to check * * @deprecated 1.23.0 Use the isLogical() method in the Information\Value class instead * @see Information\Value::isLogical() * * @return array|bool */ public static function isLogical($value = null) { return Information\Value::isLogical($value); } /** * IS_TEXT. * * @param mixed $value Value to check * * @deprecated 1.23.0 Use the isText() method in the Information\Value class instead * @see Information\Value::isText() * * @return array|bool */ public static function isText($value = null) { return Information\Value::isText($value); } /** * IS_NONTEXT. * * @param mixed $value Value to check * * @deprecated 1.23.0 Use the isNonText() method in the Information\Value class instead * @see Information\Value::isNonText() * * @return array|bool */ public static function isNonText($value = null) { return Information\Value::isNonText($value); } /** * N. * * Returns a value converted to a number * * @deprecated 1.23.0 Use the asNumber() method in the Information\Value class instead * @see Information\Value::asNumber() * * @param null|mixed $value The value you want converted * * @return number|string N converts values listed in the following table * If value is or refers to N returns * A number That number * A date The serial number of that date * TRUE 1 * FALSE 0 * An error value The error value * Anything else 0 */ public static function n($value = null) { return Information\Value::asNumber($value); } /** * TYPE. * * Returns a number that identifies the type of a value * * @deprecated 1.23.0 Use the type() method in the Information\Value class instead * @see Information\Value::type() * * @param null|mixed $value The value you want tested * * @return number N converts values listed in the following table * If value is or refers to N returns * A number 1 * Text 2 * Logical Value 4 * An error value 16 * Array or Matrix 64 */ public static function TYPE($value = null) { return Information\Value::type($value); } /** * Convert a multi-dimensional array to a simple 1-dimensional array. * * @param array|mixed $array Array to be flattened * * @return array Flattened array */ public static function flattenArray($array) { if (!is_array($array)) { return (array) $array; } $flattened = []; $stack = array_values($array); while (!empty($stack)) { $value = array_shift($stack); if (is_array($value)) { array_unshift($stack, ...array_values($value)); } else { $flattened[] = $value; } } return $flattened; } /** * @param mixed $value * * @return null|mixed */ public static function scalar($value) { if (!is_array($value)) { return $value; } do { $value = array_pop($value); } while (is_array($value)); return $value; } /** * Convert a multi-dimensional array to a simple 1-dimensional array, but retain an element of indexing. * * @param array|mixed $array Array to be flattened * * @return array Flattened array */ public static function flattenArrayIndexed($array) { if (!is_array($array)) { return (array) $array; } $arrayValues = []; foreach ($array as $k1 => $value) { if (is_array($value)) { foreach ($value as $k2 => $val) { if (is_array($val)) { foreach ($val as $k3 => $v) { $arrayValues[$k1 . '.' . $k2 . '.' . $k3] = $v; } } else { $arrayValues[$k1 . '.' . $k2] = $val; } } } else { $arrayValues[$k1] = $value; } } return $arrayValues; } /** * Convert an array to a single scalar value by extracting the first element. * * @param mixed $value Array or scalar value * * @return mixed */ public static function flattenSingleValue($value = '') { while (is_array($value)) { $value = array_shift($value); } return $value; } /** * ISFORMULA. * * @deprecated 1.23.0 Use the isFormula() method in the Information\Value class instead * @see Information\Value::isFormula() * * @param mixed $cellReference The cell to check * @param ?Cell $cell The current cell (containing this formula) * * @return array|bool|string */ public static function isFormula($cellReference = '', ?Cell $cell = null) { return Information\Value::isFormula($cellReference, $cell); } public static function expandDefinedName(string $coordinate, Cell $cell): string { $worksheet = $cell->getWorksheet(); $spreadsheet = $worksheet->getParentOrThrow(); // Uppercase coordinate $pCoordinatex = strtoupper($coordinate); // Eliminate leading equal sign $pCoordinatex = (string) preg_replace('/^=/', '', $pCoordinatex); $defined = $spreadsheet->getDefinedName($pCoordinatex, $worksheet); if ($defined !== null) { $worksheet2 = $defined->getWorkSheet(); if (!$defined->isFormula() && $worksheet2 !== null) { $coordinate = "'" . $worksheet2->getTitle() . "'!" . (string) preg_replace('/^=/', '', str_replace('$', '', $defined->getValue())); } } return $coordinate; } public static function trimTrailingRange(string $coordinate): string { return (string) preg_replace('/:[\\w\$]+$/', '', $coordinate); } public static function trimSheetFromCellReference(string $coordinate): string { if (strpos($coordinate, '!') !== false) { $coordinate = substr($coordinate, strrpos($coordinate, '!') + 1); } return $coordinate; } } phpspreadsheet/src/PhpSpreadsheet/Calculation/Database.php 0000644 00000056645 15060132323 0017757 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Calculation; /** * @deprecated 1.17.0 * * @codeCoverageIgnore */ class Database { /** * DAVERAGE. * * Averages the values in a column of a list or database that match conditions you specify. * * Excel Function: * DAVERAGE(database,field,criteria) * * @deprecated 1.17.0 * Use the evaluate() method in the Database\DAverage class instead * @see Database\DAverage::evaluate() * * @param mixed[] $database The range of cells that makes up the list or database. * A database is a list of related data in which rows of related * information are records, and columns of data are fields. The * first row of the list contains labels for each column. * @param int|string $field Indicates which column is used in the function. Enter the * column label enclosed between double quotation marks, such as * "Age" or "Yield," or a number (without quotation marks) that * represents the position of the column within the list: 1 for * the first column, 2 for the second column, and so on. * @param mixed[] $criteria The range of cells that contains the conditions you specify. * You can use any range for the criteria argument, as long as it * includes at least one column label and at least one cell below * the column label in which you specify a condition for the * column. * * @return float|string */ public static function DAVERAGE($database, $field, $criteria) { return Database\DAverage::evaluate($database, $field, $criteria); } /** * DCOUNT. * * Counts the cells that contain numbers in a column of a list or database that match conditions * that you specify. * * Excel Function: * DCOUNT(database,[field],criteria) * * @deprecated 1.17.0 * Use the evaluate() method in the Database\DCount class instead * @see Database\DCount::evaluate() * * @param mixed[] $database The range of cells that makes up the list or database. * A database is a list of related data in which rows of related * information are records, and columns of data are fields. The * first row of the list contains labels for each column. * @param null|int|string $field Indicates which column is used in the function. Enter the * column label enclosed between double quotation marks, such as * "Age" or "Yield," or a number (without quotation marks) that * represents the position of the column within the list: 1 for * the first column, 2 for the second column, and so on. * @param mixed[] $criteria The range of cells that contains the conditions you specify. * You can use any range for the criteria argument, as long as it * includes at least one column label and at least one cell below * the column label in which you specify a condition for the * column. * * @return int|string * * @TODO The field argument is optional. If field is omitted, DCOUNT counts all records in the * database that match the criteria. */ public static function DCOUNT($database, $field, $criteria) { return Database\DCount::evaluate($database, $field, $criteria); } /** * DCOUNTA. * * Counts the nonblank cells in a column of a list or database that match conditions that you specify. * * Excel Function: * DCOUNTA(database,[field],criteria) * * @deprecated 1.17.0 * Use the evaluate() method in the Database\DCountA class instead * @see Database\DCountA::evaluate() * * @param mixed[] $database The range of cells that makes up the list or database. * A database is a list of related data in which rows of related * information are records, and columns of data are fields. The * first row of the list contains labels for each column. * @param int|string $field Indicates which column is used in the function. Enter the * column label enclosed between double quotation marks, such as * "Age" or "Yield," or a number (without quotation marks) that * represents the position of the column within the list: 1 for * the first column, 2 for the second column, and so on. * @param mixed[] $criteria The range of cells that contains the conditions you specify. * You can use any range for the criteria argument, as long as it * includes at least one column label and at least one cell below * the column label in which you specify a condition for the * column. * * @return int|string */ public static function DCOUNTA($database, $field, $criteria) { return Database\DCountA::evaluate($database, $field, $criteria); } /** * DGET. * * Extracts a single value from a column of a list or database that matches conditions that you * specify. * * Excel Function: * DGET(database,field,criteria) * * @deprecated 1.17.0 * Use the evaluate() method in the Database\DGet class instead * @see Database\DGet::evaluate() * * @param mixed[] $database The range of cells that makes up the list or database. * A database is a list of related data in which rows of related * information are records, and columns of data are fields. The * first row of the list contains labels for each column. * @param int|string $field Indicates which column is used in the function. Enter the * column label enclosed between double quotation marks, such as * "Age" or "Yield," or a number (without quotation marks) that * represents the position of the column within the list: 1 for * the first column, 2 for the second column, and so on. * @param mixed[] $criteria The range of cells that contains the conditions you specify. * You can use any range for the criteria argument, as long as it * includes at least one column label and at least one cell below * the column label in which you specify a condition for the * column. * * @return mixed */ public static function DGET($database, $field, $criteria) { return Database\DGet::evaluate($database, $field, $criteria); } /** * DMAX. * * Returns the largest number in a column of a list or database that matches conditions you that * specify. * * Excel Function: * DMAX(database,field,criteria) * * @deprecated 1.17.0 * Use the evaluate() method in the Database\DMax class instead * @see Database\DMax::evaluate() * * @param mixed[] $database The range of cells that makes up the list or database. * A database is a list of related data in which rows of related * information are records, and columns of data are fields. The * first row of the list contains labels for each column. * @param int|string $field Indicates which column is used in the function. Enter the * column label enclosed between double quotation marks, such as * "Age" or "Yield," or a number (without quotation marks) that * represents the position of the column within the list: 1 for * the first column, 2 for the second column, and so on. * @param mixed[] $criteria The range of cells that contains the conditions you specify. * You can use any range for the criteria argument, as long as it * includes at least one column label and at least one cell below * the column label in which you specify a condition for the * column. * * @return null|float|string */ public static function DMAX($database, $field, $criteria) { return Database\DMax::evaluate($database, $field, $criteria); } /** * DMIN. * * Returns the smallest number in a column of a list or database that matches conditions you that * specify. * * Excel Function: * DMIN(database,field,criteria) * * @deprecated 1.17.0 * Use the evaluate() method in the Database\DMin class instead * @see Database\DMin::evaluate() * * @param mixed[] $database The range of cells that makes up the list or database. * A database is a list of related data in which rows of related * information are records, and columns of data are fields. The * first row of the list contains labels for each column. * @param int|string $field Indicates which column is used in the function. Enter the * column label enclosed between double quotation marks, such as * "Age" or "Yield," or a number (without quotation marks) that * represents the position of the column within the list: 1 for * the first column, 2 for the second column, and so on. * @param mixed[] $criteria The range of cells that contains the conditions you specify. * You can use any range for the criteria argument, as long as it * includes at least one column label and at least one cell below * the column label in which you specify a condition for the * column. * * @return null|float|string */ public static function DMIN($database, $field, $criteria) { return Database\DMin::evaluate($database, $field, $criteria); } /** * DPRODUCT. * * Multiplies the values in a column of a list or database that match conditions that you specify. * * Excel Function: * DPRODUCT(database,field,criteria) * * @deprecated 1.17.0 * Use the evaluate() method in the Database\DProduct class instead * @see Database\DProduct::evaluate() * * @param mixed[] $database The range of cells that makes up the list or database. * A database is a list of related data in which rows of related * information are records, and columns of data are fields. The * first row of the list contains labels for each column. * @param int|string $field Indicates which column is used in the function. Enter the * column label enclosed between double quotation marks, such as * "Age" or "Yield," or a number (without quotation marks) that * represents the position of the column within the list: 1 for * the first column, 2 for the second column, and so on. * @param mixed[] $criteria The range of cells that contains the conditions you specify. * You can use any range for the criteria argument, as long as it * includes at least one column label and at least one cell below * the column label in which you specify a condition for the * column. * * @return float|string */ public static function DPRODUCT($database, $field, $criteria) { return Database\DProduct::evaluate($database, $field, $criteria); } /** * DSTDEV. * * Estimates the standard deviation of a population based on a sample by using the numbers in a * column of a list or database that match conditions that you specify. * * Excel Function: * DSTDEV(database,field,criteria) * * @deprecated 1.17.0 * Use the evaluate() method in the Database\DStDev class instead * @see Database\DStDev::evaluate() * * @param mixed[] $database The range of cells that makes up the list or database. * A database is a list of related data in which rows of related * information are records, and columns of data are fields. The * first row of the list contains labels for each column. * @param int|string $field Indicates which column is used in the function. Enter the * column label enclosed between double quotation marks, such as * "Age" or "Yield," or a number (without quotation marks) that * represents the position of the column within the list: 1 for * the first column, 2 for the second column, and so on. * @param mixed[] $criteria The range of cells that contains the conditions you specify. * You can use any range for the criteria argument, as long as it * includes at least one column label and at least one cell below * the column label in which you specify a condition for the * column. * * @return float|string */ public static function DSTDEV($database, $field, $criteria) { return Database\DStDev::evaluate($database, $field, $criteria); } /** * DSTDEVP. * * Calculates the standard deviation of a population based on the entire population by using the * numbers in a column of a list or database that match conditions that you specify. * * Excel Function: * DSTDEVP(database,field,criteria) * * @deprecated 1.17.0 * Use the evaluate() method in the Database\DStDevP class instead * @see Database\DStDevP::evaluate() * * @param mixed[] $database The range of cells that makes up the list or database. * A database is a list of related data in which rows of related * information are records, and columns of data are fields. The * first row of the list contains labels for each column. * @param int|string $field Indicates which column is used in the function. Enter the * column label enclosed between double quotation marks, such as * "Age" or "Yield," or a number (without quotation marks) that * represents the position of the column within the list: 1 for * the first column, 2 for the second column, and so on. * @param mixed[] $criteria The range of cells that contains the conditions you specify. * You can use any range for the criteria argument, as long as it * includes at least one column label and at least one cell below * the column label in which you specify a condition for the * column. * * @return float|string */ public static function DSTDEVP($database, $field, $criteria) { return Database\DStDevP::evaluate($database, $field, $criteria); } /** * DSUM. * * Adds the numbers in a column of a list or database that match conditions that you specify. * * Excel Function: * DSUM(database,field,criteria) * * @deprecated 1.17.0 * Use the evaluate() method in the Database\DSum class instead * @see Database\DSum::evaluate() * * @param mixed[] $database The range of cells that makes up the list or database. * A database is a list of related data in which rows of related * information are records, and columns of data are fields. The * first row of the list contains labels for each column. * @param int|string $field Indicates which column is used in the function. Enter the * column label enclosed between double quotation marks, such as * "Age" or "Yield," or a number (without quotation marks) that * represents the position of the column within the list: 1 for * the first column, 2 for the second column, and so on. * @param mixed[] $criteria The range of cells that contains the conditions you specify. * You can use any range for the criteria argument, as long as it * includes at least one column label and at least one cell below * the column label in which you specify a condition for the * column. * * @return null|float|string */ public static function DSUM($database, $field, $criteria) { return Database\DSum::evaluate($database, $field, $criteria); } /** * DVAR. * * Estimates the variance of a population based on a sample by using the numbers in a column * of a list or database that match conditions that you specify. * * Excel Function: * DVAR(database,field,criteria) * * @deprecated 1.17.0 * Use the evaluate() method in the Database\DVar class instead * @see Database\DVar::evaluate() * * @param mixed[] $database The range of cells that makes up the list or database. * A database is a list of related data in which rows of related * information are records, and columns of data are fields. The * first row of the list contains labels for each column. * @param int|string $field Indicates which column is used in the function. Enter the * column label enclosed between double quotation marks, such as * "Age" or "Yield," or a number (without quotation marks) that * represents the position of the column within the list: 1 for * the first column, 2 for the second column, and so on. * @param mixed[] $criteria The range of cells that contains the conditions you specify. * You can use any range for the criteria argument, as long as it * includes at least one column label and at least one cell below * the column label in which you specify a condition for the * column. * * @return float|string (string if result is an error) */ public static function DVAR($database, $field, $criteria) { return Database\DVar::evaluate($database, $field, $criteria); } /** * DVARP. * * Calculates the variance of a population based on the entire population by using the numbers * in a column of a list or database that match conditions that you specify. * * Excel Function: * DVARP(database,field,criteria) * * @deprecated 1.17.0 * Use the evaluate() method in the Database\DVarP class instead * @see Database\DVarP::evaluate() * * @param mixed[] $database The range of cells that makes up the list or database. * A database is a list of related data in which rows of related * information are records, and columns of data are fields. The * first row of the list contains labels for each column. * @param int|string $field Indicates which column is used in the function. Enter the * column label enclosed between double quotation marks, such as * "Age" or "Yield," or a number (without quotation marks) that * represents the position of the column within the list: 1 for * the first column, 2 for the second column, and so on. * @param mixed[] $criteria The range of cells that contains the conditions you specify. * You can use any range for the criteria argument, as long as it * includes at least one column label and at least one cell below * the column label in which you specify a condition for the * column. * * @return float|string (string if result is an error) */ public static function DVARP($database, $field, $criteria) { return Database\DVarP::evaluate($database, $field, $criteria); } } phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/BesselI.php 0000644 00000011243 15060132323 0022014 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Calculation\Engineering; use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled; use PhpOffice\PhpSpreadsheet\Calculation\Exception; use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; class BesselI { use ArrayEnabled; /** * BESSELI. * * Returns the modified Bessel function In(x), which is equivalent to the Bessel function evaluated * for purely imaginary arguments * * Excel Function: * BESSELI(x,ord) * * NOTE: The MS Excel implementation of the BESSELI function is still not accurate. * This code provides a more accurate calculation * * @param mixed $x A float value at which to evaluate the function. * If x is nonnumeric, BESSELI returns the #VALUE! error value. * Or can be an array of values * @param mixed $ord The integer order of the Bessel function. * If ord is not an integer, it is truncated. * If $ord is nonnumeric, BESSELI returns the #VALUE! error value. * If $ord < 0, BESSELI returns the #NUM! error value. * Or can be an array of values * * @return array|float|string Result, or a string containing an error * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function BESSELI($x, $ord) { if (is_array($x) || is_array($ord)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $x, $ord); } try { $x = EngineeringValidations::validateFloat($x); $ord = EngineeringValidations::validateInt($ord); } catch (Exception $e) { return $e->getMessage(); } if ($ord < 0) { return ExcelError::NAN(); } $fResult = self::calculate($x, $ord); return (is_nan($fResult)) ? ExcelError::NAN() : $fResult; } private static function calculate(float $x, int $ord): float { // special cases switch ($ord) { case 0: return self::besselI0($x); case 1: return self::besselI1($x); } return self::besselI2($x, $ord); } private static function besselI0(float $x): float { $ax = abs($x); if ($ax < 3.75) { $y = $x / 3.75; $y = $y * $y; return 1.0 + $y * (3.5156229 + $y * (3.0899424 + $y * (1.2067492 + $y * (0.2659732 + $y * (0.360768e-1 + $y * 0.45813e-2))))); } $y = 3.75 / $ax; return (exp($ax) / sqrt($ax)) * (0.39894228 + $y * (0.1328592e-1 + $y * (0.225319e-2 + $y * (-0.157565e-2 + $y * (0.916281e-2 + $y * (-0.2057706e-1 + $y * (0.2635537e-1 + $y * (-0.1647633e-1 + $y * 0.392377e-2)))))))); } private static function besselI1(float $x): float { $ax = abs($x); if ($ax < 3.75) { $y = $x / 3.75; $y = $y * $y; $ans = $ax * (0.5 + $y * (0.87890594 + $y * (0.51498869 + $y * (0.15084934 + $y * (0.2658733e-1 + $y * (0.301532e-2 + $y * 0.32411e-3)))))); return ($x < 0.0) ? -$ans : $ans; } $y = 3.75 / $ax; $ans = 0.2282967e-1 + $y * (-0.2895312e-1 + $y * (0.1787654e-1 - $y * 0.420059e-2)); $ans = 0.39894228 + $y * (-0.3988024e-1 + $y * (-0.362018e-2 + $y * (0.163801e-2 + $y * (-0.1031555e-1 + $y * $ans)))); $ans *= exp($ax) / sqrt($ax); return ($x < 0.0) ? -$ans : $ans; } /** * Sop to Scrutinizer. * * @var float */ private static $zeroPointZero = 0.0; private static function besselI2(float $x, int $ord): float { if ($x === self::$zeroPointZero) { return 0.0; } $tox = 2.0 / abs($x); $bip = 0; $ans = 0.0; $bi = 1.0; for ($j = 2 * ($ord + (int) sqrt(40.0 * $ord)); $j > 0; --$j) { $bim = $bip + $j * $tox * $bi; $bip = $bi; $bi = $bim; if (abs($bi) > 1.0e+12) { $ans *= 1.0e-12; $bi *= 1.0e-12; $bip *= 1.0e-12; } if ($j === $ord) { $ans = $bip; } } $ans *= self::besselI0($x) / $bi; return ($x < 0.0 && (($ord % 2) === 1)) ? -$ans : $ans; } } phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/ComplexOperations.php 0000644 00000010511 15060132323 0024136 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Calculation\Engineering; use Complex\Complex as ComplexObject; use Complex\Exception as ComplexException; use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; class ComplexOperations { use ArrayEnabled; /** * IMDIV. * * Returns the quotient of two complex numbers in x + yi or x + yj text format. * * Excel Function: * IMDIV(complexDividend,complexDivisor) * * @param array|string $complexDividend the complex numerator or dividend * Or can be an array of values * @param array|string $complexDivisor the complex denominator or divisor * Or can be an array of values * * @return array|string * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function IMDIV($complexDividend, $complexDivisor) { if (is_array($complexDividend) || is_array($complexDivisor)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $complexDividend, $complexDivisor); } try { return (string) (new ComplexObject($complexDividend))->divideby(new ComplexObject($complexDivisor)); } catch (ComplexException $e) { return ExcelError::NAN(); } } /** * IMSUB. * * Returns the difference of two complex numbers in x + yi or x + yj text format. * * Excel Function: * IMSUB(complexNumber1,complexNumber2) * * @param array|string $complexNumber1 the complex number from which to subtract complexNumber2 * Or can be an array of values * @param array|string $complexNumber2 the complex number to subtract from complexNumber1 * Or can be an array of values * * @return array|string * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function IMSUB($complexNumber1, $complexNumber2) { if (is_array($complexNumber1) || is_array($complexNumber2)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $complexNumber1, $complexNumber2); } try { return (string) (new ComplexObject($complexNumber1))->subtract(new ComplexObject($complexNumber2)); } catch (ComplexException $e) { return ExcelError::NAN(); } } /** * IMSUM. * * Returns the sum of two or more complex numbers in x + yi or x + yj text format. * * Excel Function: * IMSUM(complexNumber[,complexNumber[,...]]) * * @param string ...$complexNumbers Series of complex numbers to add * * @return string */ public static function IMSUM(...$complexNumbers) { // Return value $returnValue = new ComplexObject(0.0); $aArgs = Functions::flattenArray($complexNumbers); try { // Loop through the arguments foreach ($aArgs as $complex) { $returnValue = $returnValue->add(new ComplexObject($complex)); } } catch (ComplexException $e) { return ExcelError::NAN(); } return (string) $returnValue; } /** * IMPRODUCT. * * Returns the product of two or more complex numbers in x + yi or x + yj text format. * * Excel Function: * IMPRODUCT(complexNumber[,complexNumber[,...]]) * * @param string ...$complexNumbers Series of complex numbers to multiply * * @return string */ public static function IMPRODUCT(...$complexNumbers) { // Return value $returnValue = new ComplexObject(1.0); $aArgs = Functions::flattenArray($complexNumbers); try { // Loop through the arguments foreach ($aArgs as $complex) { $returnValue = $returnValue->multiply(new ComplexObject($complex)); } } catch (ComplexException $e) { return ExcelError::NAN(); } return (string) $returnValue; } } phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/Compare.php 0000644 00000005620 15060132323 0022056 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Calculation\Engineering; use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled; use PhpOffice\PhpSpreadsheet\Calculation\Exception; class Compare { use ArrayEnabled; /** * DELTA. * * Excel Function: * DELTA(a[,b]) * * Tests whether two values are equal. Returns 1 if number1 = number2; returns 0 otherwise. * Use this function to filter a set of values. For example, by summing several DELTA * functions you calculate the count of equal pairs. This function is also known as the * Kronecker Delta function. * * @param array|float $a the first number * Or can be an array of values * @param array|float $b The second number. If omitted, b is assumed to be zero. * Or can be an array of values * * @return array|int|string (string in the event of an error) * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function DELTA($a, $b = 0.0) { if (is_array($a) || is_array($b)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $a, $b); } try { $a = EngineeringValidations::validateFloat($a); $b = EngineeringValidations::validateFloat($b); } catch (Exception $e) { return $e->getMessage(); } return (int) (abs($a - $b) < 1.0e-15); } /** * GESTEP. * * Excel Function: * GESTEP(number[,step]) * * Returns 1 if number >= step; returns 0 (zero) otherwise * Use this function to filter a set of values. For example, by summing several GESTEP * functions you calculate the count of values that exceed a threshold. * * @param array|float $number the value to test against step * Or can be an array of values * @param null|array|float $step The threshold value. If you omit a value for step, GESTEP uses zero. * Or can be an array of values * * @return array|int|string (string in the event of an error) * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function GESTEP($number, $step = 0.0) { if (is_array($number) || is_array($step)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $number, $step); } try { $number = EngineeringValidations::validateFloat($number); $step = EngineeringValidations::validateFloat($step ?? 0.0); } catch (Exception $e) { return $e->getMessage(); } return (int) ($number >= $step); } } phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/Complex.php 0000644 00000010224 15060132323 0022073 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Calculation\Engineering; use Complex\Complex as ComplexObject; use Complex\Exception as ComplexException; use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled; use PhpOffice\PhpSpreadsheet\Calculation\Exception; use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; class Complex { use ArrayEnabled; /** * COMPLEX. * * Converts real and imaginary coefficients into a complex number of the form x +/- yi or x +/- yj. * * Excel Function: * COMPLEX(realNumber,imaginary[,suffix]) * * @param mixed $realNumber the real float coefficient of the complex number * Or can be an array of values * @param mixed $imaginary the imaginary float coefficient of the complex number * Or can be an array of values * @param mixed $suffix The character suffix for the imaginary component of the complex number. * If omitted, the suffix is assumed to be "i". * Or can be an array of values * * @return array|string * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function COMPLEX($realNumber = 0.0, $imaginary = 0.0, $suffix = 'i') { if (is_array($realNumber) || is_array($imaginary) || is_array($suffix)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $realNumber, $imaginary, $suffix); } $realNumber = $realNumber ?? 0.0; $imaginary = $imaginary ?? 0.0; $suffix = $suffix ?? 'i'; try { $realNumber = EngineeringValidations::validateFloat($realNumber); $imaginary = EngineeringValidations::validateFloat($imaginary); } catch (Exception $e) { return $e->getMessage(); } if (($suffix === 'i') || ($suffix === 'j') || ($suffix === '')) { $complex = new ComplexObject($realNumber, $imaginary, $suffix); return (string) $complex; } return ExcelError::VALUE(); } /** * IMAGINARY. * * Returns the imaginary coefficient of a complex number in x + yi or x + yj text format. * * Excel Function: * IMAGINARY(complexNumber) * * @param array|string $complexNumber the complex number for which you want the imaginary * coefficient * Or can be an array of values * * @return array|float|string (string if an error) * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function IMAGINARY($complexNumber) { if (is_array($complexNumber)) { return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $complexNumber); } try { $complex = new ComplexObject($complexNumber); } catch (ComplexException $e) { return ExcelError::NAN(); } return $complex->getImaginary(); } /** * IMREAL. * * Returns the real coefficient of a complex number in x + yi or x + yj text format. * * Excel Function: * IMREAL(complexNumber) * * @param array|string $complexNumber the complex number for which you want the real coefficient * Or can be an array of values * * @return array|float|string (string if an error) * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function IMREAL($complexNumber) { if (is_array($complexNumber)) { return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $complexNumber); } try { $complex = new ComplexObject($complexNumber); } catch (ComplexException $e) { return ExcelError::NAN(); } return $complex->getReal(); } } phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/BesselK.php 0000644 00000010370 15060132323 0022016 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Calculation\Engineering; use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled; use PhpOffice\PhpSpreadsheet\Calculation\Exception; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; class BesselK { use ArrayEnabled; /** * BESSELK. * * Returns the modified Bessel function Kn(x), which is equivalent to the Bessel functions evaluated * for purely imaginary arguments. * * Excel Function: * BESSELK(x,ord) * * @param mixed $x A float value at which to evaluate the function. * If x is nonnumeric, BESSELK returns the #VALUE! error value. * Or can be an array of values * @param mixed $ord The integer order of the Bessel function. * If ord is not an integer, it is truncated. * If $ord is nonnumeric, BESSELK returns the #VALUE! error value. * If $ord < 0, BESSELKI returns the #NUM! error value. * Or can be an array of values * * @return array|float|string Result, or a string containing an error * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function BESSELK($x, $ord) { if (is_array($x) || is_array($ord)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $x, $ord); } try { $x = EngineeringValidations::validateFloat($x); $ord = EngineeringValidations::validateInt($ord); } catch (Exception $e) { return $e->getMessage(); } if (($ord < 0) || ($x <= 0.0)) { return ExcelError::NAN(); } $fBk = self::calculate($x, $ord); return (is_nan($fBk)) ? ExcelError::NAN() : $fBk; } private static function calculate(float $x, int $ord): float { // special cases switch ($ord) { case 0: return self::besselK0($x); case 1: return self::besselK1($x); } return self::besselK2($x, $ord); } /** * Mollify Phpstan. * * @codeCoverageIgnore */ private static function callBesselI(float $x, int $ord): float { $rslt = BesselI::BESSELI($x, $ord); if (!is_float($rslt)) { throw new Exception('Unexpected array or string'); } return $rslt; } private static function besselK0(float $x): float { if ($x <= 2) { $fNum2 = $x * 0.5; $y = ($fNum2 * $fNum2); return -log($fNum2) * self::callBesselI($x, 0) + (-0.57721566 + $y * (0.42278420 + $y * (0.23069756 + $y * (0.3488590e-1 + $y * (0.262698e-2 + $y * (0.10750e-3 + $y * 0.74e-5)))))); } $y = 2 / $x; return exp(-$x) / sqrt($x) * (1.25331414 + $y * (-0.7832358e-1 + $y * (0.2189568e-1 + $y * (-0.1062446e-1 + $y * (0.587872e-2 + $y * (-0.251540e-2 + $y * 0.53208e-3)))))); } private static function besselK1(float $x): float { if ($x <= 2) { $fNum2 = $x * 0.5; $y = ($fNum2 * $fNum2); return log($fNum2) * self::callBesselI($x, 1) + (1 + $y * (0.15443144 + $y * (-0.67278579 + $y * (-0.18156897 + $y * (-0.1919402e-1 + $y * (-0.110404e-2 + $y * (-0.4686e-4))))))) / $x; } $y = 2 / $x; return exp(-$x) / sqrt($x) * (1.25331414 + $y * (0.23498619 + $y * (-0.3655620e-1 + $y * (0.1504268e-1 + $y * (-0.780353e-2 + $y * (0.325614e-2 + $y * (-0.68245e-3))))))); } private static function besselK2(float $x, int $ord): float { $fTox = 2 / $x; $fBkm = self::besselK0($x); $fBk = self::besselK1($x); for ($n = 1; $n < $ord; ++$n) { $fBkp = $fBkm + $n * $fTox * $fBk; $fBkm = $fBk; $fBk = $fBkp; } return $fBk; } } phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/ConvertOctal.php 0000644 00000016615 15060132323 0023101 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Calculation\Engineering; use PhpOffice\PhpSpreadsheet\Calculation\Exception; use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; class ConvertOctal extends ConvertBase { /** * toBinary. * * Return an octal value as binary. * * Excel Function: * OCT2BIN(x[,places]) * * @param array|string $value The octal number you want to convert. Number may not * contain more than 10 characters. The most significant * bit of number is the sign bit. The remaining 29 bits * are magnitude bits. Negative numbers are represented * using two's-complement notation. * If number is negative, OCT2BIN ignores places and returns * a 10-character binary number. * If number is negative, it cannot be less than 7777777000, * and if number is positive, it cannot be greater than 777. * If number is not a valid octal number, OCT2BIN returns * the #NUM! error value. * If OCT2BIN requires more than places characters, it * returns the #NUM! error value. * Or can be an array of values * @param array|int $places The number of characters to use. If places is omitted, * OCT2BIN uses the minimum number of characters necessary. * Places is useful for padding the return value with * leading 0s (zeros). * If places is not an integer, it is truncated. * If places is nonnumeric, OCT2BIN returns the #VALUE! * error value. * If places is negative, OCT2BIN returns the #NUM! error * value. * Or can be an array of values * * @return array|string Result, or an error * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function toBinary($value, $places = null) { if (is_array($value) || is_array($places)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $value, $places); } try { $value = self::validateValue($value); $value = self::validateOctal($value); $places = self::validatePlaces($places); } catch (Exception $e) { return $e->getMessage(); } return ConvertDecimal::toBinary(self::toDecimal($value), $places); } /** * toDecimal. * * Return an octal value as decimal. * * Excel Function: * OCT2DEC(x) * * @param array|string $value The octal number you want to convert. Number may not contain * more than 10 octal characters (30 bits). The most significant * bit of number is the sign bit. The remaining 29 bits are * magnitude bits. Negative numbers are represented using * two's-complement notation. * If number is not a valid octal number, OCT2DEC returns the * #NUM! error value. * Or can be an array of values * * @return array|string Result, or an error * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function toDecimal($value) { if (is_array($value)) { return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $value); } try { $value = self::validateValue($value); $value = self::validateOctal($value); } catch (Exception $e) { return $e->getMessage(); } $binX = ''; foreach (str_split($value) as $char) { $binX .= str_pad(decbin((int) $char), 3, '0', STR_PAD_LEFT); } if (strlen($binX) == 30 && $binX[0] == '1') { for ($i = 0; $i < 30; ++$i) { $binX[$i] = ($binX[$i] == '1' ? '0' : '1'); } return (string) ((bindec($binX) + 1) * -1); } return (string) bindec($binX); } /** * toHex. * * Return an octal value as hex. * * Excel Function: * OCT2HEX(x[,places]) * * @param array|string $value The octal number you want to convert. Number may not contain * more than 10 octal characters (30 bits). The most significant * bit of number is the sign bit. The remaining 29 bits are * magnitude bits. Negative numbers are represented using * two's-complement notation. * If number is negative, OCT2HEX ignores places and returns a * 10-character hexadecimal number. * If number is not a valid octal number, OCT2HEX returns the * #NUM! error value. * If OCT2HEX requires more than places characters, it returns * the #NUM! error value. * Or can be an array of values * @param array|int $places The number of characters to use. If places is omitted, OCT2HEX * uses the minimum number of characters necessary. Places is useful * for padding the return value with leading 0s (zeros). * If places is not an integer, it is truncated. * If places is nonnumeric, OCT2HEX returns the #VALUE! error value. * If places is negative, OCT2HEX returns the #NUM! error value. * Or can be an array of values * * @return array|string Result, or an error * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function toHex($value, $places = null) { if (is_array($value) || is_array($places)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $value, $places); } try { $value = self::validateValue($value); $value = self::validateOctal($value); $places = self::validatePlaces($places); } catch (Exception $e) { return $e->getMessage(); } $hexVal = strtoupper(dechex((int) self::toDecimal($value))); $hexVal = (PHP_INT_SIZE === 4 && strlen($value) === 10 && $value[0] >= '4') ? "FF{$hexVal}" : $hexVal; return self::nbrConversionFormat($hexVal, $places); } protected static function validateOctal(string $value): string { $numDigits = (int) preg_match_all('/[01234567]/', $value); if (strlen($value) > $numDigits || $numDigits > 10) { throw new Exception(ExcelError::NAN()); } return $value; } } phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/ConvertDecimal.php 0000644 00000022401 15060132323 0023363 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Calculation\Engineering; use PhpOffice\PhpSpreadsheet\Calculation\Exception; use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; class ConvertDecimal extends ConvertBase { const LARGEST_OCTAL_IN_DECIMAL = 536870911; const SMALLEST_OCTAL_IN_DECIMAL = -536870912; const LARGEST_BINARY_IN_DECIMAL = 511; const SMALLEST_BINARY_IN_DECIMAL = -512; const LARGEST_HEX_IN_DECIMAL = 549755813887; const SMALLEST_HEX_IN_DECIMAL = -549755813888; /** * toBinary. * * Return a decimal value as binary. * * Excel Function: * DEC2BIN(x[,places]) * * @param array|string $value The decimal integer you want to convert. If number is negative, * valid place values are ignored and DEC2BIN returns a 10-character * (10-bit) binary number in which the most significant bit is the sign * bit. The remaining 9 bits are magnitude bits. Negative numbers are * represented using two's-complement notation. * If number < -512 or if number > 511, DEC2BIN returns the #NUM! error * value. * If number is nonnumeric, DEC2BIN returns the #VALUE! error value. * If DEC2BIN requires more than places characters, it returns the #NUM! * error value. * Or can be an array of values * @param array|int $places The number of characters to use. If places is omitted, DEC2BIN uses * the minimum number of characters necessary. Places is useful for * padding the return value with leading 0s (zeros). * If places is not an integer, it is truncated. * If places is nonnumeric, DEC2BIN returns the #VALUE! error value. * If places is zero or negative, DEC2BIN returns the #NUM! error value. * Or can be an array of values * * @return array|string Result, or an error * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function toBinary($value, $places = null) { if (is_array($value) || is_array($places)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $value, $places); } try { $value = self::validateValue($value); $value = self::validateDecimal($value); $places = self::validatePlaces($places); } catch (Exception $e) { return $e->getMessage(); } $value = (int) floor((float) $value); if ($value > self::LARGEST_BINARY_IN_DECIMAL || $value < self::SMALLEST_BINARY_IN_DECIMAL) { return ExcelError::NAN(); } $r = decbin($value); // Two's Complement $r = substr($r, -10); return self::nbrConversionFormat($r, $places); } /** * toHex. * * Return a decimal value as hex. * * Excel Function: * DEC2HEX(x[,places]) * * @param array|string $value The decimal integer you want to convert. If number is negative, * places is ignored and DEC2HEX returns a 10-character (40-bit) * hexadecimal number in which the most significant bit is the sign * bit. The remaining 39 bits are magnitude bits. Negative numbers * are represented using two's-complement notation. * If number < -549,755,813,888 or if number > 549,755,813,887, * DEC2HEX returns the #NUM! error value. * If number is nonnumeric, DEC2HEX returns the #VALUE! error value. * If DEC2HEX requires more than places characters, it returns the * #NUM! error value. * Or can be an array of values * @param array|int $places The number of characters to use. If places is omitted, DEC2HEX uses * the minimum number of characters necessary. Places is useful for * padding the return value with leading 0s (zeros). * If places is not an integer, it is truncated. * If places is nonnumeric, DEC2HEX returns the #VALUE! error value. * If places is zero or negative, DEC2HEX returns the #NUM! error value. * Or can be an array of values * * @return array|string Result, or an error * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function toHex($value, $places = null) { if (is_array($value) || is_array($places)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $value, $places); } try { $value = self::validateValue($value); $value = self::validateDecimal($value); $places = self::validatePlaces($places); } catch (Exception $e) { return $e->getMessage(); } $value = floor((float) $value); if ($value > self::LARGEST_HEX_IN_DECIMAL || $value < self::SMALLEST_HEX_IN_DECIMAL) { return ExcelError::NAN(); } $r = strtoupper(dechex((int) $value)); $r = self::hex32bit($value, $r); return self::nbrConversionFormat($r, $places); } public static function hex32bit(float $value, string $hexstr, bool $force = false): string { if (PHP_INT_SIZE === 4 || $force) { if ($value >= 2 ** 32) { $quotient = (int) ($value / (2 ** 32)); return strtoupper(substr('0' . dechex($quotient), -2) . $hexstr); } if ($value < -(2 ** 32)) { $quotient = 256 - (int) ceil((-$value) / (2 ** 32)); return strtoupper(substr('0' . dechex($quotient), -2) . substr("00000000$hexstr", -8)); } if ($value < 0) { return "FF$hexstr"; } } return $hexstr; } /** * toOctal. * * Return an decimal value as octal. * * Excel Function: * DEC2OCT(x[,places]) * * @param array|string $value The decimal integer you want to convert. If number is negative, * places is ignored and DEC2OCT returns a 10-character (30-bit) * octal number in which the most significant bit is the sign bit. * The remaining 29 bits are magnitude bits. Negative numbers are * represented using two's-complement notation. * If number < -536,870,912 or if number > 536,870,911, DEC2OCT * returns the #NUM! error value. * If number is nonnumeric, DEC2OCT returns the #VALUE! error value. * If DEC2OCT requires more than places characters, it returns the * #NUM! error value. * Or can be an array of values * @param array|int $places The number of characters to use. If places is omitted, DEC2OCT uses * the minimum number of characters necessary. Places is useful for * padding the return value with leading 0s (zeros). * If places is not an integer, it is truncated. * If places is nonnumeric, DEC2OCT returns the #VALUE! error value. * If places is zero or negative, DEC2OCT returns the #NUM! error value. * Or can be an array of values * * @return array|string Result, or an error * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function toOctal($value, $places = null) { if (is_array($value) || is_array($places)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $value, $places); } try { $value = self::validateValue($value); $value = self::validateDecimal($value); $places = self::validatePlaces($places); } catch (Exception $e) { return $e->getMessage(); } $value = (int) floor((float) $value); if ($value > self::LARGEST_OCTAL_IN_DECIMAL || $value < self::SMALLEST_OCTAL_IN_DECIMAL) { return ExcelError::NAN(); } $r = decoct($value); $r = substr($r, -10); return self::nbrConversionFormat($r, $places); } protected static function validateDecimal(string $value): string { if (strlen($value) > preg_match_all('/[-0123456789.]/', $value)) { throw new Exception(ExcelError::VALUE()); } return $value; } } phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/ComplexFunctions.php 0000644 00000046176 15060132323 0024003 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Calculation\Engineering; use Complex\Complex as ComplexObject; use Complex\Exception as ComplexException; use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled; use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; class ComplexFunctions { use ArrayEnabled; /** * IMABS. * * Returns the absolute value (modulus) of a complex number in x + yi or x + yj text format. * * Excel Function: * IMABS(complexNumber) * * @param array|string $complexNumber the complex number for which you want the absolute value * Or can be an array of values * * @return array|float|string * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function IMABS($complexNumber) { if (is_array($complexNumber)) { return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $complexNumber); } try { $complex = new ComplexObject($complexNumber); } catch (ComplexException $e) { return ExcelError::NAN(); } return $complex->abs(); } /** * IMARGUMENT. * * Returns the argument theta of a complex number, i.e. the angle in radians from the real * axis to the representation of the number in polar coordinates. * * Excel Function: * IMARGUMENT(complexNumber) * * @param array|string $complexNumber the complex number for which you want the argument theta * Or can be an array of values * * @return array|float|string * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function IMARGUMENT($complexNumber) { if (is_array($complexNumber)) { return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $complexNumber); } try { $complex = new ComplexObject($complexNumber); } catch (ComplexException $e) { return ExcelError::NAN(); } if ($complex->getReal() == 0.0 && $complex->getImaginary() == 0.0) { return ExcelError::DIV0(); } return $complex->argument(); } /** * IMCONJUGATE. * * Returns the complex conjugate of a complex number in x + yi or x + yj text format. * * Excel Function: * IMCONJUGATE(complexNumber) * * @param array|string $complexNumber the complex number for which you want the conjugate * Or can be an array of values * * @return array|string * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function IMCONJUGATE($complexNumber) { if (is_array($complexNumber)) { return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $complexNumber); } try { $complex = new ComplexObject($complexNumber); } catch (ComplexException $e) { return ExcelError::NAN(); } return (string) $complex->conjugate(); } /** * IMCOS. * * Returns the cosine of a complex number in x + yi or x + yj text format. * * Excel Function: * IMCOS(complexNumber) * * @param array|string $complexNumber the complex number for which you want the cosine * Or can be an array of values * * @return array|float|string * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function IMCOS($complexNumber) { if (is_array($complexNumber)) { return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $complexNumber); } try { $complex = new ComplexObject($complexNumber); } catch (ComplexException $e) { return ExcelError::NAN(); } return (string) $complex->cos(); } /** * IMCOSH. * * Returns the hyperbolic cosine of a complex number in x + yi or x + yj text format. * * Excel Function: * IMCOSH(complexNumber) * * @param array|string $complexNumber the complex number for which you want the hyperbolic cosine * Or can be an array of values * * @return array|float|string * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function IMCOSH($complexNumber) { if (is_array($complexNumber)) { return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $complexNumber); } try { $complex = new ComplexObject($complexNumber); } catch (ComplexException $e) { return ExcelError::NAN(); } return (string) $complex->cosh(); } /** * IMCOT. * * Returns the cotangent of a complex number in x + yi or x + yj text format. * * Excel Function: * IMCOT(complexNumber) * * @param array|string $complexNumber the complex number for which you want the cotangent * Or can be an array of values * * @return array|float|string * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function IMCOT($complexNumber) { if (is_array($complexNumber)) { return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $complexNumber); } try { $complex = new ComplexObject($complexNumber); } catch (ComplexException $e) { return ExcelError::NAN(); } return (string) $complex->cot(); } /** * IMCSC. * * Returns the cosecant of a complex number in x + yi or x + yj text format. * * Excel Function: * IMCSC(complexNumber) * * @param array|string $complexNumber the complex number for which you want the cosecant * Or can be an array of values * * @return array|float|string * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function IMCSC($complexNumber) { if (is_array($complexNumber)) { return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $complexNumber); } try { $complex = new ComplexObject($complexNumber); } catch (ComplexException $e) { return ExcelError::NAN(); } return (string) $complex->csc(); } /** * IMCSCH. * * Returns the hyperbolic cosecant of a complex number in x + yi or x + yj text format. * * Excel Function: * IMCSCH(complexNumber) * * @param array|string $complexNumber the complex number for which you want the hyperbolic cosecant * Or can be an array of values * * @return array|float|string * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function IMCSCH($complexNumber) { if (is_array($complexNumber)) { return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $complexNumber); } try { $complex = new ComplexObject($complexNumber); } catch (ComplexException $e) { return ExcelError::NAN(); } return (string) $complex->csch(); } /** * IMSIN. * * Returns the sine of a complex number in x + yi or x + yj text format. * * Excel Function: * IMSIN(complexNumber) * * @param array|string $complexNumber the complex number for which you want the sine * Or can be an array of values * * @return array|float|string * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function IMSIN($complexNumber) { if (is_array($complexNumber)) { return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $complexNumber); } try { $complex = new ComplexObject($complexNumber); } catch (ComplexException $e) { return ExcelError::NAN(); } return (string) $complex->sin(); } /** * IMSINH. * * Returns the hyperbolic sine of a complex number in x + yi or x + yj text format. * * Excel Function: * IMSINH(complexNumber) * * @param array|string $complexNumber the complex number for which you want the hyperbolic sine * Or can be an array of values * * @return array|float|string * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function IMSINH($complexNumber) { if (is_array($complexNumber)) { return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $complexNumber); } try { $complex = new ComplexObject($complexNumber); } catch (ComplexException $e) { return ExcelError::NAN(); } return (string) $complex->sinh(); } /** * IMSEC. * * Returns the secant of a complex number in x + yi or x + yj text format. * * Excel Function: * IMSEC(complexNumber) * * @param array|string $complexNumber the complex number for which you want the secant * Or can be an array of values * * @return array|float|string * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function IMSEC($complexNumber) { if (is_array($complexNumber)) { return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $complexNumber); } try { $complex = new ComplexObject($complexNumber); } catch (ComplexException $e) { return ExcelError::NAN(); } return (string) $complex->sec(); } /** * IMSECH. * * Returns the hyperbolic secant of a complex number in x + yi or x + yj text format. * * Excel Function: * IMSECH(complexNumber) * * @param array|string $complexNumber the complex number for which you want the hyperbolic secant * Or can be an array of values * * @return array|float|string * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function IMSECH($complexNumber) { if (is_array($complexNumber)) { return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $complexNumber); } try { $complex = new ComplexObject($complexNumber); } catch (ComplexException $e) { return ExcelError::NAN(); } return (string) $complex->sech(); } /** * IMTAN. * * Returns the tangent of a complex number in x + yi or x + yj text format. * * Excel Function: * IMTAN(complexNumber) * * @param array|string $complexNumber the complex number for which you want the tangent * Or can be an array of values * * @return array|float|string * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function IMTAN($complexNumber) { if (is_array($complexNumber)) { return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $complexNumber); } try { $complex = new ComplexObject($complexNumber); } catch (ComplexException $e) { return ExcelError::NAN(); } return (string) $complex->tan(); } /** * IMSQRT. * * Returns the square root of a complex number in x + yi or x + yj text format. * * Excel Function: * IMSQRT(complexNumber) * * @param array|string $complexNumber the complex number for which you want the square root * Or can be an array of values * * @return array|string * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function IMSQRT($complexNumber) { if (is_array($complexNumber)) { return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $complexNumber); } try { $complex = new ComplexObject($complexNumber); } catch (ComplexException $e) { return ExcelError::NAN(); } $theta = self::IMARGUMENT($complexNumber); if ($theta === ExcelError::DIV0()) { return '0'; } return (string) $complex->sqrt(); } /** * IMLN. * * Returns the natural logarithm of a complex number in x + yi or x + yj text format. * * Excel Function: * IMLN(complexNumber) * * @param array|string $complexNumber the complex number for which you want the natural logarithm * Or can be an array of values * * @return array|string * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function IMLN($complexNumber) { if (is_array($complexNumber)) { return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $complexNumber); } try { $complex = new ComplexObject($complexNumber); } catch (ComplexException $e) { return ExcelError::NAN(); } if ($complex->getReal() == 0.0 && $complex->getImaginary() == 0.0) { return ExcelError::NAN(); } return (string) $complex->ln(); } /** * IMLOG10. * * Returns the common logarithm (base 10) of a complex number in x + yi or x + yj text format. * * Excel Function: * IMLOG10(complexNumber) * * @param array|string $complexNumber the complex number for which you want the common logarithm * Or can be an array of values * * @return array|string * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function IMLOG10($complexNumber) { if (is_array($complexNumber)) { return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $complexNumber); } try { $complex = new ComplexObject($complexNumber); } catch (ComplexException $e) { return ExcelError::NAN(); } if ($complex->getReal() == 0.0 && $complex->getImaginary() == 0.0) { return ExcelError::NAN(); } return (string) $complex->log10(); } /** * IMLOG2. * * Returns the base-2 logarithm of a complex number in x + yi or x + yj text format. * * Excel Function: * IMLOG2(complexNumber) * * @param array|string $complexNumber the complex number for which you want the base-2 logarithm * Or can be an array of values * * @return array|string * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function IMLOG2($complexNumber) { if (is_array($complexNumber)) { return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $complexNumber); } try { $complex = new ComplexObject($complexNumber); } catch (ComplexException $e) { return ExcelError::NAN(); } if ($complex->getReal() == 0.0 && $complex->getImaginary() == 0.0) { return ExcelError::NAN(); } return (string) $complex->log2(); } /** * IMEXP. * * Returns the exponential of a complex number in x + yi or x + yj text format. * * Excel Function: * IMEXP(complexNumber) * * @param array|string $complexNumber the complex number for which you want the exponential * Or can be an array of values * * @return array|string * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function IMEXP($complexNumber) { if (is_array($complexNumber)) { return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $complexNumber); } try { $complex = new ComplexObject($complexNumber); } catch (ComplexException $e) { return ExcelError::NAN(); } return (string) $complex->exp(); } /** * IMPOWER. * * Returns a complex number in x + yi or x + yj text format raised to a power. * * Excel Function: * IMPOWER(complexNumber,realNumber) * * @param array|string $complexNumber the complex number you want to raise to a power * Or can be an array of values * @param array|float|int|string $realNumber the power to which you want to raise the complex number * Or can be an array of values * * @return array|string * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function IMPOWER($complexNumber, $realNumber) { if (is_array($complexNumber) || is_array($realNumber)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $complexNumber, $realNumber); } try { $complex = new ComplexObject($complexNumber); } catch (ComplexException $e) { return ExcelError::NAN(); } if (!is_numeric($realNumber)) { return ExcelError::VALUE(); } return (string) $complex->pow((float) $realNumber); } } phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/Erf.php 0000644 00000006723 15060132323 0021211 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Calculation\Engineering; use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; class Erf { use ArrayEnabled; private const TWO_SQRT_PI = 1.128379167095512574; /** * ERF. * * Returns the error function integrated between the lower and upper bound arguments. * * Note: In Excel 2007 or earlier, if you input a negative value for the upper or lower bound arguments, * the function would return a #NUM! error. However, in Excel 2010, the function algorithm was * improved, so that it can now calculate the function for both positive and negative ranges. * PhpSpreadsheet follows Excel 2010 behaviour, and accepts negative arguments. * * Excel Function: * ERF(lower[,upper]) * * @param mixed $lower Lower bound float for integrating ERF * Or can be an array of values * @param mixed $upper Upper bound float for integrating ERF. * If omitted, ERF integrates between zero and lower_limit * Or can be an array of values * * @return array|float|string * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function ERF($lower, $upper = null) { if (is_array($lower) || is_array($upper)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $lower, $upper); } if (is_numeric($lower)) { if ($upper === null) { return self::erfValue($lower); } if (is_numeric($upper)) { return self::erfValue($upper) - self::erfValue($lower); } } return ExcelError::VALUE(); } /** * ERFPRECISE. * * Returns the error function integrated between the lower and upper bound arguments. * * Excel Function: * ERF.PRECISE(limit) * * @param mixed $limit Float bound for integrating ERF, other bound is zero * Or can be an array of values * * @return array|float|string * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function ERFPRECISE($limit) { if (is_array($limit)) { return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $limit); } return self::ERF($limit); } /** * Method to calculate the erf value. * * @param float|int|string $value * * @return float */ public static function erfValue($value) { $value = (float) $value; if (abs($value) > 2.2) { return 1 - ErfC::ERFC($value); } $sum = $term = $value; $xsqr = ($value * $value); $j = 1; do { $term *= $xsqr / $j; $sum -= $term / (2 * $j + 1); ++$j; $term *= $xsqr / $j; $sum += $term / (2 * $j + 1); ++$j; if ($sum == 0.0) { break; } } while (abs($term / $sum) > Functions::PRECISION); return self::TWO_SQRT_PI * $sum; } } phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/ConvertUOM.php 0000644 00000105716 15060132323 0022500 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Calculation\Engineering; use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled; use PhpOffice\PhpSpreadsheet\Calculation\Exception; use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; class ConvertUOM { use ArrayEnabled; public const CATEGORY_WEIGHT_AND_MASS = 'Weight and Mass'; public const CATEGORY_DISTANCE = 'Distance'; public const CATEGORY_TIME = 'Time'; public const CATEGORY_PRESSURE = 'Pressure'; public const CATEGORY_FORCE = 'Force'; public const CATEGORY_ENERGY = 'Energy'; public const CATEGORY_POWER = 'Power'; public const CATEGORY_MAGNETISM = 'Magnetism'; public const CATEGORY_TEMPERATURE = 'Temperature'; public const CATEGORY_VOLUME = 'Volume and Liquid Measure'; public const CATEGORY_AREA = 'Area'; public const CATEGORY_INFORMATION = 'Information'; public const CATEGORY_SPEED = 'Speed'; /** * Details of the Units of measure that can be used in CONVERTUOM(). * * @var mixed[] */ private static $conversionUnits = [ // Weight and Mass 'g' => ['Group' => self::CATEGORY_WEIGHT_AND_MASS, 'Unit Name' => 'Gram', 'AllowPrefix' => true], 'sg' => ['Group' => self::CATEGORY_WEIGHT_AND_MASS, 'Unit Name' => 'Slug', 'AllowPrefix' => false], 'lbm' => ['Group' => self::CATEGORY_WEIGHT_AND_MASS, 'Unit Name' => 'Pound mass (avoirdupois)', 'AllowPrefix' => false], 'u' => ['Group' => self::CATEGORY_WEIGHT_AND_MASS, 'Unit Name' => 'U (atomic mass unit)', 'AllowPrefix' => true], 'ozm' => ['Group' => self::CATEGORY_WEIGHT_AND_MASS, 'Unit Name' => 'Ounce mass (avoirdupois)', 'AllowPrefix' => false], 'grain' => ['Group' => self::CATEGORY_WEIGHT_AND_MASS, 'Unit Name' => 'Grain', 'AllowPrefix' => false], 'cwt' => ['Group' => self::CATEGORY_WEIGHT_AND_MASS, 'Unit Name' => 'U.S. (short) hundredweight', 'AllowPrefix' => false], 'shweight' => ['Group' => self::CATEGORY_WEIGHT_AND_MASS, 'Unit Name' => 'U.S. (short) hundredweight', 'AllowPrefix' => false], 'uk_cwt' => ['Group' => self::CATEGORY_WEIGHT_AND_MASS, 'Unit Name' => 'Imperial hundredweight', 'AllowPrefix' => false], 'lcwt' => ['Group' => self::CATEGORY_WEIGHT_AND_MASS, 'Unit Name' => 'Imperial hundredweight', 'AllowPrefix' => false], 'hweight' => ['Group' => self::CATEGORY_WEIGHT_AND_MASS, 'Unit Name' => 'Imperial hundredweight', 'AllowPrefix' => false], 'stone' => ['Group' => self::CATEGORY_WEIGHT_AND_MASS, 'Unit Name' => 'Stone', 'AllowPrefix' => false], 'ton' => ['Group' => self::CATEGORY_WEIGHT_AND_MASS, 'Unit Name' => 'Ton', 'AllowPrefix' => false], 'uk_ton' => ['Group' => self::CATEGORY_WEIGHT_AND_MASS, 'Unit Name' => 'Imperial ton', 'AllowPrefix' => false], 'LTON' => ['Group' => self::CATEGORY_WEIGHT_AND_MASS, 'Unit Name' => 'Imperial ton', 'AllowPrefix' => false], 'brton' => ['Group' => self::CATEGORY_WEIGHT_AND_MASS, 'Unit Name' => 'Imperial ton', 'AllowPrefix' => false], // Distance 'm' => ['Group' => self::CATEGORY_DISTANCE, 'Unit Name' => 'Meter', 'AllowPrefix' => true], 'mi' => ['Group' => self::CATEGORY_DISTANCE, 'Unit Name' => 'Statute mile', 'AllowPrefix' => false], 'Nmi' => ['Group' => self::CATEGORY_DISTANCE, 'Unit Name' => 'Nautical mile', 'AllowPrefix' => false], 'in' => ['Group' => self::CATEGORY_DISTANCE, 'Unit Name' => 'Inch', 'AllowPrefix' => false], 'ft' => ['Group' => self::CATEGORY_DISTANCE, 'Unit Name' => 'Foot', 'AllowPrefix' => false], 'yd' => ['Group' => self::CATEGORY_DISTANCE, 'Unit Name' => 'Yard', 'AllowPrefix' => false], 'ang' => ['Group' => self::CATEGORY_DISTANCE, 'Unit Name' => 'Angstrom', 'AllowPrefix' => true], 'ell' => ['Group' => self::CATEGORY_DISTANCE, 'Unit Name' => 'Ell', 'AllowPrefix' => false], 'ly' => ['Group' => self::CATEGORY_DISTANCE, 'Unit Name' => 'Light Year', 'AllowPrefix' => false], 'parsec' => ['Group' => self::CATEGORY_DISTANCE, 'Unit Name' => 'Parsec', 'AllowPrefix' => false], 'pc' => ['Group' => self::CATEGORY_DISTANCE, 'Unit Name' => 'Parsec', 'AllowPrefix' => false], 'Pica' => ['Group' => self::CATEGORY_DISTANCE, 'Unit Name' => 'Pica (1/72 in)', 'AllowPrefix' => false], 'Picapt' => ['Group' => self::CATEGORY_DISTANCE, 'Unit Name' => 'Pica (1/72 in)', 'AllowPrefix' => false], 'pica' => ['Group' => self::CATEGORY_DISTANCE, 'Unit Name' => 'Pica (1/6 in)', 'AllowPrefix' => false], 'survey_mi' => ['Group' => self::CATEGORY_DISTANCE, 'Unit Name' => 'U.S survey mile (statute mile)', 'AllowPrefix' => false], // Time 'yr' => ['Group' => self::CATEGORY_TIME, 'Unit Name' => 'Year', 'AllowPrefix' => false], 'day' => ['Group' => self::CATEGORY_TIME, 'Unit Name' => 'Day', 'AllowPrefix' => false], 'd' => ['Group' => self::CATEGORY_TIME, 'Unit Name' => 'Day', 'AllowPrefix' => false], 'hr' => ['Group' => self::CATEGORY_TIME, 'Unit Name' => 'Hour', 'AllowPrefix' => false], 'mn' => ['Group' => self::CATEGORY_TIME, 'Unit Name' => 'Minute', 'AllowPrefix' => false], 'min' => ['Group' => self::CATEGORY_TIME, 'Unit Name' => 'Minute', 'AllowPrefix' => false], 'sec' => ['Group' => self::CATEGORY_TIME, 'Unit Name' => 'Second', 'AllowPrefix' => true], 's' => ['Group' => self::CATEGORY_TIME, 'Unit Name' => 'Second', 'AllowPrefix' => true], // Pressure 'Pa' => ['Group' => self::CATEGORY_PRESSURE, 'Unit Name' => 'Pascal', 'AllowPrefix' => true], 'p' => ['Group' => self::CATEGORY_PRESSURE, 'Unit Name' => 'Pascal', 'AllowPrefix' => true], 'atm' => ['Group' => self::CATEGORY_PRESSURE, 'Unit Name' => 'Atmosphere', 'AllowPrefix' => true], 'at' => ['Group' => self::CATEGORY_PRESSURE, 'Unit Name' => 'Atmosphere', 'AllowPrefix' => true], 'mmHg' => ['Group' => self::CATEGORY_PRESSURE, 'Unit Name' => 'mm of Mercury', 'AllowPrefix' => true], 'psi' => ['Group' => self::CATEGORY_PRESSURE, 'Unit Name' => 'PSI', 'AllowPrefix' => true], 'Torr' => ['Group' => self::CATEGORY_PRESSURE, 'Unit Name' => 'Torr', 'AllowPrefix' => true], // Force 'N' => ['Group' => self::CATEGORY_FORCE, 'Unit Name' => 'Newton', 'AllowPrefix' => true], 'dyn' => ['Group' => self::CATEGORY_FORCE, 'Unit Name' => 'Dyne', 'AllowPrefix' => true], 'dy' => ['Group' => self::CATEGORY_FORCE, 'Unit Name' => 'Dyne', 'AllowPrefix' => true], 'lbf' => ['Group' => self::CATEGORY_FORCE, 'Unit Name' => 'Pound force', 'AllowPrefix' => false], 'pond' => ['Group' => self::CATEGORY_FORCE, 'Unit Name' => 'Pond', 'AllowPrefix' => true], // Energy 'J' => ['Group' => self::CATEGORY_ENERGY, 'Unit Name' => 'Joule', 'AllowPrefix' => true], 'e' => ['Group' => self::CATEGORY_ENERGY, 'Unit Name' => 'Erg', 'AllowPrefix' => true], 'c' => ['Group' => self::CATEGORY_ENERGY, 'Unit Name' => 'Thermodynamic calorie', 'AllowPrefix' => true], 'cal' => ['Group' => self::CATEGORY_ENERGY, 'Unit Name' => 'IT calorie', 'AllowPrefix' => true], 'eV' => ['Group' => self::CATEGORY_ENERGY, 'Unit Name' => 'Electron volt', 'AllowPrefix' => true], 'ev' => ['Group' => self::CATEGORY_ENERGY, 'Unit Name' => 'Electron volt', 'AllowPrefix' => true], 'HPh' => ['Group' => self::CATEGORY_ENERGY, 'Unit Name' => 'Horsepower-hour', 'AllowPrefix' => false], 'hh' => ['Group' => self::CATEGORY_ENERGY, 'Unit Name' => 'Horsepower-hour', 'AllowPrefix' => false], 'Wh' => ['Group' => self::CATEGORY_ENERGY, 'Unit Name' => 'Watt-hour', 'AllowPrefix' => true], 'wh' => ['Group' => self::CATEGORY_ENERGY, 'Unit Name' => 'Watt-hour', 'AllowPrefix' => true], 'flb' => ['Group' => self::CATEGORY_ENERGY, 'Unit Name' => 'Foot-pound', 'AllowPrefix' => false], 'BTU' => ['Group' => self::CATEGORY_ENERGY, 'Unit Name' => 'BTU', 'AllowPrefix' => false], 'btu' => ['Group' => self::CATEGORY_ENERGY, 'Unit Name' => 'BTU', 'AllowPrefix' => false], // Power 'HP' => ['Group' => self::CATEGORY_POWER, 'Unit Name' => 'Horsepower', 'AllowPrefix' => false], 'h' => ['Group' => self::CATEGORY_POWER, 'Unit Name' => 'Horsepower', 'AllowPrefix' => false], 'W' => ['Group' => self::CATEGORY_POWER, 'Unit Name' => 'Watt', 'AllowPrefix' => true], 'w' => ['Group' => self::CATEGORY_POWER, 'Unit Name' => 'Watt', 'AllowPrefix' => true], 'PS' => ['Group' => self::CATEGORY_POWER, 'Unit Name' => 'Pferdestärke', 'AllowPrefix' => false], // Magnetism 'T' => ['Group' => self::CATEGORY_MAGNETISM, 'Unit Name' => 'Tesla', 'AllowPrefix' => true], 'ga' => ['Group' => self::CATEGORY_MAGNETISM, 'Unit Name' => 'Gauss', 'AllowPrefix' => true], // Temperature 'C' => ['Group' => self::CATEGORY_TEMPERATURE, 'Unit Name' => 'Degrees Celsius', 'AllowPrefix' => false], 'cel' => ['Group' => self::CATEGORY_TEMPERATURE, 'Unit Name' => 'Degrees Celsius', 'AllowPrefix' => false], 'F' => ['Group' => self::CATEGORY_TEMPERATURE, 'Unit Name' => 'Degrees Fahrenheit', 'AllowPrefix' => false], 'fah' => ['Group' => self::CATEGORY_TEMPERATURE, 'Unit Name' => 'Degrees Fahrenheit', 'AllowPrefix' => false], 'K' => ['Group' => self::CATEGORY_TEMPERATURE, 'Unit Name' => 'Kelvin', 'AllowPrefix' => false], 'kel' => ['Group' => self::CATEGORY_TEMPERATURE, 'Unit Name' => 'Kelvin', 'AllowPrefix' => false], 'Rank' => ['Group' => self::CATEGORY_TEMPERATURE, 'Unit Name' => 'Degrees Rankine', 'AllowPrefix' => false], 'Reau' => ['Group' => self::CATEGORY_TEMPERATURE, 'Unit Name' => 'Degrees Réaumur', 'AllowPrefix' => false], // Volume 'l' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Litre', 'AllowPrefix' => true], 'L' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Litre', 'AllowPrefix' => true], 'lt' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Litre', 'AllowPrefix' => true], 'tsp' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Teaspoon', 'AllowPrefix' => false], 'tspm' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Modern Teaspoon', 'AllowPrefix' => false], 'tbs' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Tablespoon', 'AllowPrefix' => false], 'oz' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Fluid Ounce', 'AllowPrefix' => false], 'cup' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Cup', 'AllowPrefix' => false], 'pt' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'U.S. Pint', 'AllowPrefix' => false], 'us_pt' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'U.S. Pint', 'AllowPrefix' => false], 'uk_pt' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'U.K. Pint', 'AllowPrefix' => false], 'qt' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Quart', 'AllowPrefix' => false], 'uk_qt' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Imperial Quart (UK)', 'AllowPrefix' => false], 'gal' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Gallon', 'AllowPrefix' => false], 'uk_gal' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Imperial Gallon (UK)', 'AllowPrefix' => false], 'ang3' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Cubic Angstrom', 'AllowPrefix' => true], 'ang^3' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Cubic Angstrom', 'AllowPrefix' => true], 'barrel' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'US Oil Barrel', 'AllowPrefix' => false], 'bushel' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'US Bushel', 'AllowPrefix' => false], 'in3' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Cubic Inch', 'AllowPrefix' => false], 'in^3' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Cubic Inch', 'AllowPrefix' => false], 'ft3' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Cubic Foot', 'AllowPrefix' => false], 'ft^3' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Cubic Foot', 'AllowPrefix' => false], 'ly3' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Cubic Light Year', 'AllowPrefix' => false], 'ly^3' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Cubic Light Year', 'AllowPrefix' => false], 'm3' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Cubic Meter', 'AllowPrefix' => true], 'm^3' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Cubic Meter', 'AllowPrefix' => true], 'mi3' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Cubic Mile', 'AllowPrefix' => false], 'mi^3' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Cubic Mile', 'AllowPrefix' => false], 'yd3' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Cubic Yard', 'AllowPrefix' => false], 'yd^3' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Cubic Yard', 'AllowPrefix' => false], 'Nmi3' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Cubic Nautical Mile', 'AllowPrefix' => false], 'Nmi^3' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Cubic Nautical Mile', 'AllowPrefix' => false], 'Pica3' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Cubic Pica', 'AllowPrefix' => false], 'Pica^3' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Cubic Pica', 'AllowPrefix' => false], 'Picapt3' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Cubic Pica', 'AllowPrefix' => false], 'Picapt^3' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Cubic Pica', 'AllowPrefix' => false], 'GRT' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Gross Registered Ton', 'AllowPrefix' => false], 'regton' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Gross Registered Ton', 'AllowPrefix' => false], 'MTON' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Measurement Ton (Freight Ton)', 'AllowPrefix' => false], // Area 'ha' => ['Group' => self::CATEGORY_AREA, 'Unit Name' => 'Hectare', 'AllowPrefix' => true], 'uk_acre' => ['Group' => self::CATEGORY_AREA, 'Unit Name' => 'International Acre', 'AllowPrefix' => false], 'us_acre' => ['Group' => self::CATEGORY_AREA, 'Unit Name' => 'US Survey/Statute Acre', 'AllowPrefix' => false], 'ang2' => ['Group' => self::CATEGORY_AREA, 'Unit Name' => 'Square Angstrom', 'AllowPrefix' => true], 'ang^2' => ['Group' => self::CATEGORY_AREA, 'Unit Name' => 'Square Angstrom', 'AllowPrefix' => true], 'ar' => ['Group' => self::CATEGORY_AREA, 'Unit Name' => 'Are', 'AllowPrefix' => true], 'ft2' => ['Group' => self::CATEGORY_AREA, 'Unit Name' => 'Square Feet', 'AllowPrefix' => false], 'ft^2' => ['Group' => self::CATEGORY_AREA, 'Unit Name' => 'Square Feet', 'AllowPrefix' => false], 'in2' => ['Group' => self::CATEGORY_AREA, 'Unit Name' => 'Square Inches', 'AllowPrefix' => false], 'in^2' => ['Group' => self::CATEGORY_AREA, 'Unit Name' => 'Square Inches', 'AllowPrefix' => false], 'ly2' => ['Group' => self::CATEGORY_AREA, 'Unit Name' => 'Square Light Years', 'AllowPrefix' => false], 'ly^2' => ['Group' => self::CATEGORY_AREA, 'Unit Name' => 'Square Light Years', 'AllowPrefix' => false], 'm2' => ['Group' => self::CATEGORY_AREA, 'Unit Name' => 'Square Meters', 'AllowPrefix' => true], 'm^2' => ['Group' => self::CATEGORY_AREA, 'Unit Name' => 'Square Meters', 'AllowPrefix' => true], 'Morgen' => ['Group' => self::CATEGORY_AREA, 'Unit Name' => 'Morgen', 'AllowPrefix' => false], 'mi2' => ['Group' => self::CATEGORY_AREA, 'Unit Name' => 'Square Miles', 'AllowPrefix' => false], 'mi^2' => ['Group' => self::CATEGORY_AREA, 'Unit Name' => 'Square Miles', 'AllowPrefix' => false], 'Nmi2' => ['Group' => self::CATEGORY_AREA, 'Unit Name' => 'Square Nautical Miles', 'AllowPrefix' => false], 'Nmi^2' => ['Group' => self::CATEGORY_AREA, 'Unit Name' => 'Square Nautical Miles', 'AllowPrefix' => false], 'Pica2' => ['Group' => self::CATEGORY_AREA, 'Unit Name' => 'Square Pica', 'AllowPrefix' => false], 'Pica^2' => ['Group' => self::CATEGORY_AREA, 'Unit Name' => 'Square Pica', 'AllowPrefix' => false], 'Picapt2' => ['Group' => self::CATEGORY_AREA, 'Unit Name' => 'Square Pica', 'AllowPrefix' => false], 'Picapt^2' => ['Group' => self::CATEGORY_AREA, 'Unit Name' => 'Square Pica', 'AllowPrefix' => false], 'yd2' => ['Group' => self::CATEGORY_AREA, 'Unit Name' => 'Square Yards', 'AllowPrefix' => false], 'yd^2' => ['Group' => self::CATEGORY_AREA, 'Unit Name' => 'Square Yards', 'AllowPrefix' => false], // Information 'byte' => ['Group' => self::CATEGORY_INFORMATION, 'Unit Name' => 'Byte', 'AllowPrefix' => true], 'bit' => ['Group' => self::CATEGORY_INFORMATION, 'Unit Name' => 'Bit', 'AllowPrefix' => true], // Speed 'm/s' => ['Group' => self::CATEGORY_SPEED, 'Unit Name' => 'Meters per second', 'AllowPrefix' => true], 'm/sec' => ['Group' => self::CATEGORY_SPEED, 'Unit Name' => 'Meters per second', 'AllowPrefix' => true], 'm/h' => ['Group' => self::CATEGORY_SPEED, 'Unit Name' => 'Meters per hour', 'AllowPrefix' => true], 'm/hr' => ['Group' => self::CATEGORY_SPEED, 'Unit Name' => 'Meters per hour', 'AllowPrefix' => true], 'mph' => ['Group' => self::CATEGORY_SPEED, 'Unit Name' => 'Miles per hour', 'AllowPrefix' => false], 'admkn' => ['Group' => self::CATEGORY_SPEED, 'Unit Name' => 'Admiralty Knot', 'AllowPrefix' => false], 'kn' => ['Group' => self::CATEGORY_SPEED, 'Unit Name' => 'Knot', 'AllowPrefix' => false], ]; /** * Details of the Multiplier prefixes that can be used with Units of Measure in CONVERTUOM(). * * @var mixed[] */ private static $conversionMultipliers = [ 'Y' => ['multiplier' => 1E24, 'name' => 'yotta'], 'Z' => ['multiplier' => 1E21, 'name' => 'zetta'], 'E' => ['multiplier' => 1E18, 'name' => 'exa'], 'P' => ['multiplier' => 1E15, 'name' => 'peta'], 'T' => ['multiplier' => 1E12, 'name' => 'tera'], 'G' => ['multiplier' => 1E9, 'name' => 'giga'], 'M' => ['multiplier' => 1E6, 'name' => 'mega'], 'k' => ['multiplier' => 1E3, 'name' => 'kilo'], 'h' => ['multiplier' => 1E2, 'name' => 'hecto'], 'e' => ['multiplier' => 1E1, 'name' => 'dekao'], 'da' => ['multiplier' => 1E1, 'name' => 'dekao'], 'd' => ['multiplier' => 1E-1, 'name' => 'deci'], 'c' => ['multiplier' => 1E-2, 'name' => 'centi'], 'm' => ['multiplier' => 1E-3, 'name' => 'milli'], 'u' => ['multiplier' => 1E-6, 'name' => 'micro'], 'n' => ['multiplier' => 1E-9, 'name' => 'nano'], 'p' => ['multiplier' => 1E-12, 'name' => 'pico'], 'f' => ['multiplier' => 1E-15, 'name' => 'femto'], 'a' => ['multiplier' => 1E-18, 'name' => 'atto'], 'z' => ['multiplier' => 1E-21, 'name' => 'zepto'], 'y' => ['multiplier' => 1E-24, 'name' => 'yocto'], ]; /** * Details of the Multiplier prefixes that can be used with Units of Measure in CONVERTUOM(). * * @var mixed[] */ private static $binaryConversionMultipliers = [ 'Yi' => ['multiplier' => 2 ** 80, 'name' => 'yobi'], 'Zi' => ['multiplier' => 2 ** 70, 'name' => 'zebi'], 'Ei' => ['multiplier' => 2 ** 60, 'name' => 'exbi'], 'Pi' => ['multiplier' => 2 ** 50, 'name' => 'pebi'], 'Ti' => ['multiplier' => 2 ** 40, 'name' => 'tebi'], 'Gi' => ['multiplier' => 2 ** 30, 'name' => 'gibi'], 'Mi' => ['multiplier' => 2 ** 20, 'name' => 'mebi'], 'ki' => ['multiplier' => 2 ** 10, 'name' => 'kibi'], ]; /** * Details of the Units of measure conversion factors, organised by group. * * @var mixed[] */ private static $unitConversions = [ // Conversion uses gram (g) as an intermediate unit self::CATEGORY_WEIGHT_AND_MASS => [ 'g' => 1.0, 'sg' => 6.85217658567918E-05, 'lbm' => 2.20462262184878E-03, 'u' => 6.02214179421676E+23, 'ozm' => 3.52739619495804E-02, 'grain' => 1.54323583529414E+01, 'cwt' => 2.20462262184878E-05, 'shweight' => 2.20462262184878E-05, 'uk_cwt' => 1.96841305522212E-05, 'lcwt' => 1.96841305522212E-05, 'hweight' => 1.96841305522212E-05, 'stone' => 1.57473044417770E-04, 'ton' => 1.10231131092439E-06, 'uk_ton' => 9.84206527611061E-07, 'LTON' => 9.84206527611061E-07, 'brton' => 9.84206527611061E-07, ], // Conversion uses meter (m) as an intermediate unit self::CATEGORY_DISTANCE => [ 'm' => 1.0, 'mi' => 6.21371192237334E-04, 'Nmi' => 5.39956803455724E-04, 'in' => 3.93700787401575E+01, 'ft' => 3.28083989501312E+00, 'yd' => 1.09361329833771E+00, 'ang' => 1.0E+10, 'ell' => 8.74890638670166E-01, 'ly' => 1.05700083402462E-16, 'parsec' => 3.24077928966473E-17, 'pc' => 3.24077928966473E-17, 'Pica' => 2.83464566929134E+03, 'Picapt' => 2.83464566929134E+03, 'pica' => 2.36220472440945E+02, 'survey_mi' => 6.21369949494950E-04, ], // Conversion uses second (s) as an intermediate unit self::CATEGORY_TIME => [ 'yr' => 3.16880878140289E-08, 'day' => 1.15740740740741E-05, 'd' => 1.15740740740741E-05, 'hr' => 2.77777777777778E-04, 'mn' => 1.66666666666667E-02, 'min' => 1.66666666666667E-02, 'sec' => 1.0, 's' => 1.0, ], // Conversion uses Pascal (Pa) as an intermediate unit self::CATEGORY_PRESSURE => [ 'Pa' => 1.0, 'p' => 1.0, 'atm' => 9.86923266716013E-06, 'at' => 9.86923266716013E-06, 'mmHg' => 7.50063755419211E-03, 'psi' => 1.45037737730209E-04, 'Torr' => 7.50061682704170E-03, ], // Conversion uses Newton (N) as an intermediate unit self::CATEGORY_FORCE => [ 'N' => 1.0, 'dyn' => 1.0E+5, 'dy' => 1.0E+5, 'lbf' => 2.24808923655339E-01, 'pond' => 1.01971621297793E+02, ], // Conversion uses Joule (J) as an intermediate unit self::CATEGORY_ENERGY => [ 'J' => 1.0, 'e' => 9.99999519343231E+06, 'c' => 2.39006249473467E-01, 'cal' => 2.38846190642017E-01, 'eV' => 6.24145700000000E+18, 'ev' => 6.24145700000000E+18, 'HPh' => 3.72506430801000E-07, 'hh' => 3.72506430801000E-07, 'Wh' => 2.77777916238711E-04, 'wh' => 2.77777916238711E-04, 'flb' => 2.37304222192651E+01, 'BTU' => 9.47815067349015E-04, 'btu' => 9.47815067349015E-04, ], // Conversion uses Horsepower (HP) as an intermediate unit self::CATEGORY_POWER => [ 'HP' => 1.0, 'h' => 1.0, 'W' => 7.45699871582270E+02, 'w' => 7.45699871582270E+02, 'PS' => 1.01386966542400E+00, ], // Conversion uses Tesla (T) as an intermediate unit self::CATEGORY_MAGNETISM => [ 'T' => 1.0, 'ga' => 10000.0, ], // Conversion uses litre (l) as an intermediate unit self::CATEGORY_VOLUME => [ 'l' => 1.0, 'L' => 1.0, 'lt' => 1.0, 'tsp' => 2.02884136211058E+02, 'tspm' => 2.0E+02, 'tbs' => 6.76280454036860E+01, 'oz' => 3.38140227018430E+01, 'cup' => 4.22675283773038E+00, 'pt' => 2.11337641886519E+00, 'us_pt' => 2.11337641886519E+00, 'uk_pt' => 1.75975398639270E+00, 'qt' => 1.05668820943259E+00, 'uk_qt' => 8.79876993196351E-01, 'gal' => 2.64172052358148E-01, 'uk_gal' => 2.19969248299088E-01, 'ang3' => 1.0E+27, 'ang^3' => 1.0E+27, 'barrel' => 6.28981077043211E-03, 'bushel' => 2.83775932584017E-02, 'in3' => 6.10237440947323E+01, 'in^3' => 6.10237440947323E+01, 'ft3' => 3.53146667214886E-02, 'ft^3' => 3.53146667214886E-02, 'ly3' => 1.18093498844171E-51, 'ly^3' => 1.18093498844171E-51, 'm3' => 1.0E-03, 'm^3' => 1.0E-03, 'mi3' => 2.39912758578928E-13, 'mi^3' => 2.39912758578928E-13, 'yd3' => 1.30795061931439E-03, 'yd^3' => 1.30795061931439E-03, 'Nmi3' => 1.57426214685811E-13, 'Nmi^3' => 1.57426214685811E-13, 'Pica3' => 2.27769904358706E+07, 'Pica^3' => 2.27769904358706E+07, 'Picapt3' => 2.27769904358706E+07, 'Picapt^3' => 2.27769904358706E+07, 'GRT' => 3.53146667214886E-04, 'regton' => 3.53146667214886E-04, 'MTON' => 8.82866668037215E-04, ], // Conversion uses hectare (ha) as an intermediate unit self::CATEGORY_AREA => [ 'ha' => 1.0, 'uk_acre' => 2.47105381467165E+00, 'us_acre' => 2.47104393046628E+00, 'ang2' => 1.0E+24, 'ang^2' => 1.0E+24, 'ar' => 1.0E+02, 'ft2' => 1.07639104167097E+05, 'ft^2' => 1.07639104167097E+05, 'in2' => 1.55000310000620E+07, 'in^2' => 1.55000310000620E+07, 'ly2' => 1.11725076312873E-28, 'ly^2' => 1.11725076312873E-28, 'm2' => 1.0E+04, 'm^2' => 1.0E+04, 'Morgen' => 4.0E+00, 'mi2' => 3.86102158542446E-03, 'mi^2' => 3.86102158542446E-03, 'Nmi2' => 2.91553349598123E-03, 'Nmi^2' => 2.91553349598123E-03, 'Pica2' => 8.03521607043214E+10, 'Pica^2' => 8.03521607043214E+10, 'Picapt2' => 8.03521607043214E+10, 'Picapt^2' => 8.03521607043214E+10, 'yd2' => 1.19599004630108E+04, 'yd^2' => 1.19599004630108E+04, ], // Conversion uses bit (bit) as an intermediate unit self::CATEGORY_INFORMATION => [ 'bit' => 1.0, 'byte' => 0.125, ], // Conversion uses Meters per Second (m/s) as an intermediate unit self::CATEGORY_SPEED => [ 'm/s' => 1.0, 'm/sec' => 1.0, 'm/h' => 3.60E+03, 'm/hr' => 3.60E+03, 'mph' => 2.23693629205440E+00, 'admkn' => 1.94260256941567E+00, 'kn' => 1.94384449244060E+00, ], ]; /** * getConversionGroups * Returns a list of the different conversion groups for UOM conversions. * * @return array */ public static function getConversionCategories() { $conversionGroups = []; foreach (self::$conversionUnits as $conversionUnit) { $conversionGroups[] = $conversionUnit['Group']; } return array_merge(array_unique($conversionGroups)); } /** * getConversionGroupUnits * Returns an array of units of measure, for a specified conversion group, or for all groups. * * @param string $category The group whose units of measure you want to retrieve * * @return array */ public static function getConversionCategoryUnits($category = null) { $conversionGroups = []; foreach (self::$conversionUnits as $conversionUnit => $conversionGroup) { if (($category === null) || ($conversionGroup['Group'] == $category)) { $conversionGroups[$conversionGroup['Group']][] = $conversionUnit; } } return $conversionGroups; } /** * getConversionGroupUnitDetails. * * @param string $category The group whose units of measure you want to retrieve * * @return array */ public static function getConversionCategoryUnitDetails($category = null) { $conversionGroups = []; foreach (self::$conversionUnits as $conversionUnit => $conversionGroup) { if (($category === null) || ($conversionGroup['Group'] == $category)) { $conversionGroups[$conversionGroup['Group']][] = [ 'unit' => $conversionUnit, 'description' => $conversionGroup['Unit Name'], ]; } } return $conversionGroups; } /** * getConversionMultipliers * Returns an array of the Multiplier prefixes that can be used with Units of Measure in CONVERTUOM(). * * @return mixed[] */ public static function getConversionMultipliers() { return self::$conversionMultipliers; } /** * getBinaryConversionMultipliers * Returns an array of the additional Multiplier prefixes that can be used with Information Units of Measure in CONVERTUOM(). * * @return mixed[] */ public static function getBinaryConversionMultipliers() { return self::$binaryConversionMultipliers; } /** * CONVERT. * * Converts a number from one measurement system to another. * For example, CONVERT can translate a table of distances in miles to a table of distances * in kilometers. * * Excel Function: * CONVERT(value,fromUOM,toUOM) * * @param array|float|int|string $value the value in fromUOM to convert * Or can be an array of values * @param array|string $fromUOM the units for value * Or can be an array of values * @param array|string $toUOM the units for the result * Or can be an array of values * * @return array|float|string Result, or a string containing an error * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function CONVERT($value, $fromUOM, $toUOM) { if (is_array($value) || is_array($fromUOM) || is_array($toUOM)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $value, $fromUOM, $toUOM); } if (!is_numeric($value)) { return ExcelError::VALUE(); } try { [$fromUOM, $fromCategory, $fromMultiplier] = self::getUOMDetails($fromUOM); [$toUOM, $toCategory, $toMultiplier] = self::getUOMDetails($toUOM); } catch (Exception $e) { return ExcelError::NA(); } if ($fromCategory !== $toCategory) { return ExcelError::NA(); } // @var float $value $value *= $fromMultiplier; if (($fromUOM === $toUOM) && ($fromMultiplier === $toMultiplier)) { // We've already factored $fromMultiplier into the value, so we need // to reverse it again return $value / $fromMultiplier; } elseif ($fromUOM === $toUOM) { return $value / $toMultiplier; } elseif ($fromCategory === self::CATEGORY_TEMPERATURE) { return self::convertTemperature($fromUOM, $toUOM, /** @scrutinizer ignore-type */ $value); } $baseValue = $value * (1.0 / self::$unitConversions[$fromCategory][$fromUOM]); return ($baseValue * self::$unitConversions[$fromCategory][$toUOM]) / $toMultiplier; } private static function getUOMDetails(string $uom): array { if (isset(self::$conversionUnits[$uom])) { $unitCategory = self::$conversionUnits[$uom]['Group']; return [$uom, $unitCategory, 1.0]; } // Check 1-character standard metric multiplier prefixes $multiplierType = substr($uom, 0, 1); $uom = substr($uom, 1); if (isset(self::$conversionUnits[$uom], self::$conversionMultipliers[$multiplierType])) { if (self::$conversionUnits[$uom]['AllowPrefix'] === false) { throw new Exception('Prefix not allowed for UoM'); } $unitCategory = self::$conversionUnits[$uom]['Group']; return [$uom, $unitCategory, self::$conversionMultipliers[$multiplierType]['multiplier']]; } $multiplierType .= substr($uom, 0, 1); $uom = substr($uom, 1); // Check 2-character standard metric multiplier prefixes if (isset(self::$conversionUnits[$uom], self::$conversionMultipliers[$multiplierType])) { if (self::$conversionUnits[$uom]['AllowPrefix'] === false) { throw new Exception('Prefix not allowed for UoM'); } $unitCategory = self::$conversionUnits[$uom]['Group']; return [$uom, $unitCategory, self::$conversionMultipliers[$multiplierType]['multiplier']]; } // Check 2-character binary multiplier prefixes if (isset(self::$conversionUnits[$uom], self::$binaryConversionMultipliers[$multiplierType])) { if (self::$conversionUnits[$uom]['AllowPrefix'] === false) { throw new Exception('Prefix not allowed for UoM'); } $unitCategory = self::$conversionUnits[$uom]['Group']; if ($unitCategory !== 'Information') { throw new Exception('Binary Prefix is only allowed for Information UoM'); } return [$uom, $unitCategory, self::$binaryConversionMultipliers[$multiplierType]['multiplier']]; } throw new Exception('UoM Not Found'); } /** * @param float|int $value * * @return float|int */ protected static function convertTemperature(string $fromUOM, string $toUOM, $value) { $fromUOM = self::resolveTemperatureSynonyms($fromUOM); $toUOM = self::resolveTemperatureSynonyms($toUOM); if ($fromUOM === $toUOM) { return $value; } // Convert to Kelvin switch ($fromUOM) { case 'F': $value = ($value - 32) / 1.8 + 273.15; break; case 'C': $value += 273.15; break; case 'Rank': $value /= 1.8; break; case 'Reau': $value = $value * 1.25 + 273.15; break; } // Convert from Kelvin switch ($toUOM) { case 'F': $value = ($value - 273.15) * 1.8 + 32.00; break; case 'C': $value -= 273.15; break; case 'Rank': $value *= 1.8; break; case 'Reau': $value = ($value - 273.15) * 0.80000; break; } return $value; } private static function resolveTemperatureSynonyms(string $uom): string { switch ($uom) { case 'fah': return 'F'; case 'cel': return 'C'; case 'kel': return 'K'; } return $uom; } } phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/ConvertHex.php 0000644 00000017056 15060132323 0022563 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Calculation\Engineering; use PhpOffice\PhpSpreadsheet\Calculation\Exception; use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; class ConvertHex extends ConvertBase { /** * toBinary. * * Return a hex value as binary. * * Excel Function: * HEX2BIN(x[,places]) * * @param array|string $value The hexadecimal number you want to convert. * Number cannot contain more than 10 characters. * The most significant bit of number is the sign bit (40th bit from the right). * The remaining 9 bits are magnitude bits. * Negative numbers are represented using two's-complement notation. * If number is negative, HEX2BIN ignores places and returns a 10-character binary number. * If number is negative, it cannot be less than FFFFFFFE00, * and if number is positive, it cannot be greater than 1FF. * If number is not a valid hexadecimal number, HEX2BIN returns the #NUM! error value. * If HEX2BIN requires more than places characters, it returns the #NUM! error value. * Or can be an array of values * @param array|int $places The number of characters to use. If places is omitted, * HEX2BIN uses the minimum number of characters necessary. Places * is useful for padding the return value with leading 0s (zeros). * If places is not an integer, it is truncated. * If places is nonnumeric, HEX2BIN returns the #VALUE! error value. * If places is negative, HEX2BIN returns the #NUM! error value. * Or can be an array of values * * @return array|string Result, or an error * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function toBinary($value, $places = null) { if (is_array($value) || is_array($places)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $value, $places); } try { $value = self::validateValue($value); $value = self::validateHex($value); $places = self::validatePlaces($places); } catch (Exception $e) { return $e->getMessage(); } $dec = self::toDecimal($value); return ConvertDecimal::toBinary($dec, $places); } /** * toDecimal. * * Return a hex value as decimal. * * Excel Function: * HEX2DEC(x) * * @param array|string $value The hexadecimal number you want to convert. This number cannot * contain more than 10 characters (40 bits). The most significant * bit of number is the sign bit. The remaining 39 bits are magnitude * bits. Negative numbers are represented using two's-complement * notation. * If number is not a valid hexadecimal number, HEX2DEC returns the * #NUM! error value. * Or can be an array of values * * @return array|string Result, or an error * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function toDecimal($value) { if (is_array($value)) { return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $value); } try { $value = self::validateValue($value); $value = self::validateHex($value); } catch (Exception $e) { return $e->getMessage(); } if (strlen($value) > 10) { return ExcelError::NAN(); } $binX = ''; foreach (str_split($value) as $char) { $binX .= str_pad(base_convert($char, 16, 2), 4, '0', STR_PAD_LEFT); } if (strlen($binX) == 40 && $binX[0] == '1') { for ($i = 0; $i < 40; ++$i) { $binX[$i] = ($binX[$i] == '1' ? '0' : '1'); } return (string) ((bindec($binX) + 1) * -1); } return (string) bindec($binX); } /** * toOctal. * * Return a hex value as octal. * * Excel Function: * HEX2OCT(x[,places]) * * @param array|string $value The hexadecimal number you want to convert. Number cannot * contain more than 10 characters. The most significant bit of * number is the sign bit. The remaining 39 bits are magnitude * bits. Negative numbers are represented using two's-complement * notation. * If number is negative, HEX2OCT ignores places and returns a * 10-character octal number. * If number is negative, it cannot be less than FFE0000000, and * if number is positive, it cannot be greater than 1FFFFFFF. * If number is not a valid hexadecimal number, HEX2OCT returns * the #NUM! error value. * If HEX2OCT requires more than places characters, it returns * the #NUM! error value. * Or can be an array of values * @param array|int $places The number of characters to use. If places is omitted, HEX2OCT * uses the minimum number of characters necessary. Places is * useful for padding the return value with leading 0s (zeros). * If places is not an integer, it is truncated. * If places is nonnumeric, HEX2OCT returns the #VALUE! error * value. * If places is negative, HEX2OCT returns the #NUM! error value. * Or can be an array of values * * @return array|string Result, or an error * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function toOctal($value, $places = null) { if (is_array($value) || is_array($places)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $value, $places); } try { $value = self::validateValue($value); $value = self::validateHex($value); $places = self::validatePlaces($places); } catch (Exception $e) { return $e->getMessage(); } $decimal = self::toDecimal($value); return ConvertDecimal::toOctal($decimal, $places); } protected static function validateHex(string $value): string { if (strlen($value) > preg_match_all('/[0123456789ABCDEF]/', $value)) { throw new Exception(ExcelError::NAN()); } return $value; } } phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/ConvertBase.php 0000644 00000003666 15060132323 0022713 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Calculation\Engineering; use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled; use PhpOffice\PhpSpreadsheet\Calculation\Exception; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; abstract class ConvertBase { use ArrayEnabled; /** @param mixed $value */ protected static function validateValue($value): string { if (is_bool($value)) { if (Functions::getCompatibilityMode() !== Functions::COMPATIBILITY_OPENOFFICE) { throw new Exception(ExcelError::VALUE()); } $value = (int) $value; } if (is_numeric($value)) { if (Functions::getCompatibilityMode() == Functions::COMPATIBILITY_GNUMERIC) { $value = floor((float) $value); } } return strtoupper((string) $value); } /** @param mixed $places */ protected static function validatePlaces($places = null): ?int { if ($places === null) { return $places; } if (is_numeric($places)) { if ($places < 0 || $places > 10) { throw new Exception(ExcelError::NAN()); } return (int) $places; } throw new Exception(ExcelError::VALUE()); } /** * Formats a number base string value with leading zeroes. * * @param string $value The "number" to pad * @param ?int $places The length that we want to pad this value * * @return string The padded "number" */ protected static function nbrConversionFormat(string $value, ?int $places): string { if ($places !== null) { if (strlen($value) <= $places) { return substr(str_pad($value, $places, '0', STR_PAD_LEFT), -10); } return ExcelError::NAN(); } return substr($value, -10); } } phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/EngineeringValidations.php 0000644 00000001311 15060132323 0025111 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Calculation\Engineering; use PhpOffice\PhpSpreadsheet\Calculation\Exception; use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; class EngineeringValidations { /** * @param mixed $value */ public static function validateFloat($value): float { if (!is_numeric($value)) { throw new Exception(ExcelError::VALUE()); } return (float) $value; } /** * @param mixed $value */ public static function validateInt($value): int { if (!is_numeric($value)) { throw new Exception(ExcelError::VALUE()); } return (int) floor((float) $value); } } phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/Constants.php 0000644 00000000247 15060132323 0022444 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Calculation\Engineering; class Constants { /** * EULER. */ public const EULER = 2.71828182845904523536; } phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/BesselJ.php 0000644 00000013442 15060132323 0022020 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Calculation\Engineering; use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled; use PhpOffice\PhpSpreadsheet\Calculation\Exception; use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; class BesselJ { use ArrayEnabled; /** * BESSELJ. * * Returns the Bessel function * * Excel Function: * BESSELJ(x,ord) * * NOTE: The MS Excel implementation of the BESSELJ function is still not accurate, particularly for higher order * values with x < -8 and x > 8. This code provides a more accurate calculation * * @param mixed $x A float value at which to evaluate the function. * If x is nonnumeric, BESSELJ returns the #VALUE! error value. * Or can be an array of values * @param mixed $ord The integer order of the Bessel function. * If ord is not an integer, it is truncated. * If $ord is nonnumeric, BESSELJ returns the #VALUE! error value. * If $ord < 0, BESSELJ returns the #NUM! error value. * Or can be an array of values * * @return array|float|string Result, or a string containing an error * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function BESSELJ($x, $ord) { if (is_array($x) || is_array($ord)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $x, $ord); } try { $x = EngineeringValidations::validateFloat($x); $ord = EngineeringValidations::validateInt($ord); } catch (Exception $e) { return $e->getMessage(); } if ($ord < 0) { return ExcelError::NAN(); } $fResult = self::calculate($x, $ord); return (is_nan($fResult)) ? ExcelError::NAN() : $fResult; } private static function calculate(float $x, int $ord): float { // special cases switch ($ord) { case 0: return self::besselJ0($x); case 1: return self::besselJ1($x); } return self::besselJ2($x, $ord); } private static function besselJ0(float $x): float { $ax = abs($x); if ($ax < 8.0) { $y = $x * $x; $ans1 = 57568490574.0 + $y * (-13362590354.0 + $y * (651619640.7 + $y * (-11214424.18 + $y * (77392.33017 + $y * (-184.9052456))))); $ans2 = 57568490411.0 + $y * (1029532985.0 + $y * (9494680.718 + $y * (59272.64853 + $y * (267.8532712 + $y * 1.0)))); return $ans1 / $ans2; } $z = 8.0 / $ax; $y = $z * $z; $xx = $ax - 0.785398164; $ans1 = 1.0 + $y * (-0.1098628627e-2 + $y * (0.2734510407e-4 + $y * (-0.2073370639e-5 + $y * 0.2093887211e-6))); $ans2 = -0.1562499995e-1 + $y * (0.1430488765e-3 + $y * (-0.6911147651e-5 + $y * (0.7621095161e-6 - $y * 0.934935152e-7))); return sqrt(0.636619772 / $ax) * (cos($xx) * $ans1 - $z * sin($xx) * $ans2); } private static function besselJ1(float $x): float { $ax = abs($x); if ($ax < 8.0) { $y = $x * $x; $ans1 = $x * (72362614232.0 + $y * (-7895059235.0 + $y * (242396853.1 + $y * (-2972611.439 + $y * (15704.48260 + $y * (-30.16036606)))))); $ans2 = 144725228442.0 + $y * (2300535178.0 + $y * (18583304.74 + $y * (99447.43394 + $y * (376.9991397 + $y * 1.0)))); return $ans1 / $ans2; } $z = 8.0 / $ax; $y = $z * $z; $xx = $ax - 2.356194491; $ans1 = 1.0 + $y * (0.183105e-2 + $y * (-0.3516396496e-4 + $y * (0.2457520174e-5 + $y * (-0.240337019e-6)))); $ans2 = 0.04687499995 + $y * (-0.2002690873e-3 + $y * (0.8449199096e-5 + $y * (-0.88228987e-6 + $y * 0.105787412e-6))); $ans = sqrt(0.636619772 / $ax) * (cos($xx) * $ans1 - $z * sin($xx) * $ans2); return ($x < 0.0) ? -$ans : $ans; } private static function besselJ2(float $x, int $ord): float { $ax = abs($x); if ($ax === 0.0) { return 0.0; } if ($ax > $ord) { return self::besselj2a($ax, $ord, $x); } return self::besselj2b($ax, $ord, $x); } private static function besselj2a(float $ax, int $ord, float $x): float { $tox = 2.0 / $ax; $bjm = self::besselJ0($ax); $bj = self::besselJ1($ax); for ($j = 1; $j < $ord; ++$j) { $bjp = $j * $tox * $bj - $bjm; $bjm = $bj; $bj = $bjp; } $ans = $bj; return ($x < 0.0 && ($ord % 2) == 1) ? -$ans : $ans; } private static function besselj2b(float $ax, int $ord, float $x): float { $tox = 2.0 / $ax; $jsum = false; $bjp = $ans = $sum = 0.0; $bj = 1.0; for ($j = 2 * ($ord + (int) sqrt(40.0 * $ord)); $j > 0; --$j) { $bjm = $j * $tox * $bj - $bjp; $bjp = $bj; $bj = $bjm; if (abs($bj) > 1.0e+10) { $bj *= 1.0e-10; $bjp *= 1.0e-10; $ans *= 1.0e-10; $sum *= 1.0e-10; } if ($jsum === true) { $sum += $bj; } $jsum = $jsum === false; if ($j === $ord) { $ans = $bjp; } } $sum = 2.0 * $sum - $bj; $ans /= $sum; return ($x < 0.0 && ($ord % 2) === 1) ? -$ans : $ans; } } phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/BitWise.php 0000644 00000020134 15060132323 0022033 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Calculation\Engineering; use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled; use PhpOffice\PhpSpreadsheet\Calculation\Exception; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; class BitWise { use ArrayEnabled; const SPLIT_DIVISOR = 2 ** 24; /** * Split a number into upper and lower portions for full 32-bit support. * * @param float|int $number * * @return int[] */ private static function splitNumber($number): array { return [(int) floor($number / self::SPLIT_DIVISOR), (int) fmod($number, self::SPLIT_DIVISOR)]; } /** * BITAND. * * Returns the bitwise AND of two integer values. * * Excel Function: * BITAND(number1, number2) * * @param array|int $number1 * Or can be an array of values * @param array|int $number2 * Or can be an array of values * * @return array|int|string * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function BITAND($number1, $number2) { if (is_array($number1) || is_array($number2)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $number1, $number2); } try { $number1 = self::validateBitwiseArgument($number1); $number2 = self::validateBitwiseArgument($number2); } catch (Exception $e) { return $e->getMessage(); } $split1 = self::splitNumber($number1); $split2 = self::splitNumber($number2); return self::SPLIT_DIVISOR * ($split1[0] & $split2[0]) + ($split1[1] & $split2[1]); } /** * BITOR. * * Returns the bitwise OR of two integer values. * * Excel Function: * BITOR(number1, number2) * * @param array|int $number1 * Or can be an array of values * @param array|int $number2 * Or can be an array of values * * @return array|int|string * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function BITOR($number1, $number2) { if (is_array($number1) || is_array($number2)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $number1, $number2); } try { $number1 = self::validateBitwiseArgument($number1); $number2 = self::validateBitwiseArgument($number2); } catch (Exception $e) { return $e->getMessage(); } $split1 = self::splitNumber($number1); $split2 = self::splitNumber($number2); return self::SPLIT_DIVISOR * ($split1[0] | $split2[0]) + ($split1[1] | $split2[1]); } /** * BITXOR. * * Returns the bitwise XOR of two integer values. * * Excel Function: * BITXOR(number1, number2) * * @param array|int $number1 * Or can be an array of values * @param array|int $number2 * Or can be an array of values * * @return array|int|string * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function BITXOR($number1, $number2) { if (is_array($number1) || is_array($number2)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $number1, $number2); } try { $number1 = self::validateBitwiseArgument($number1); $number2 = self::validateBitwiseArgument($number2); } catch (Exception $e) { return $e->getMessage(); } $split1 = self::splitNumber($number1); $split2 = self::splitNumber($number2); return self::SPLIT_DIVISOR * ($split1[0] ^ $split2[0]) + ($split1[1] ^ $split2[1]); } /** * BITLSHIFT. * * Returns the number value shifted left by shift_amount bits. * * Excel Function: * BITLSHIFT(number, shift_amount) * * @param array|int $number * Or can be an array of values * @param array|int $shiftAmount * Or can be an array of values * * @return array|float|int|string * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function BITLSHIFT($number, $shiftAmount) { if (is_array($number) || is_array($shiftAmount)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $number, $shiftAmount); } try { $number = self::validateBitwiseArgument($number); $shiftAmount = self::validateShiftAmount($shiftAmount); } catch (Exception $e) { return $e->getMessage(); } $result = floor($number * (2 ** $shiftAmount)); if ($result > 2 ** 48 - 1) { return ExcelError::NAN(); } return $result; } /** * BITRSHIFT. * * Returns the number value shifted right by shift_amount bits. * * Excel Function: * BITRSHIFT(number, shift_amount) * * @param array|int $number * Or can be an array of values * @param array|int $shiftAmount * Or can be an array of values * * @return array|float|int|string * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function BITRSHIFT($number, $shiftAmount) { if (is_array($number) || is_array($shiftAmount)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $number, $shiftAmount); } try { $number = self::validateBitwiseArgument($number); $shiftAmount = self::validateShiftAmount($shiftAmount); } catch (Exception $e) { return $e->getMessage(); } $result = floor($number / (2 ** $shiftAmount)); if ($result > 2 ** 48 - 1) { // possible because shiftAmount can be negative return ExcelError::NAN(); } return $result; } /** * Validate arguments passed to the bitwise functions. * * @param mixed $value * * @return float */ private static function validateBitwiseArgument($value) { $value = self::nullFalseTrueToNumber($value); if (is_numeric($value)) { $value = (float) $value; if ($value == floor($value)) { if (($value > 2 ** 48 - 1) || ($value < 0)) { throw new Exception(ExcelError::NAN()); } return floor($value); } throw new Exception(ExcelError::NAN()); } throw new Exception(ExcelError::VALUE()); } /** * Validate arguments passed to the bitwise functions. * * @param mixed $value * * @return int */ private static function validateShiftAmount($value) { $value = self::nullFalseTrueToNumber($value); if (is_numeric($value)) { if (abs($value) > 53) { throw new Exception(ExcelError::NAN()); } return (int) $value; } throw new Exception(ExcelError::VALUE()); } /** * Many functions accept null/false/true argument treated as 0/0/1. * * @param mixed $number * * @return mixed */ private static function nullFalseTrueToNumber(&$number) { if ($number === null) { $number = 0; } elseif (is_bool($number)) { $number = (int) $number; } return $number; } } phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/ConvertBinary.php 0000644 00000016134 15060132323 0023257 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Calculation\Engineering; use PhpOffice\PhpSpreadsheet\Calculation\Exception; use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; class ConvertBinary extends ConvertBase { /** * toDecimal. * * Return a binary value as decimal. * * Excel Function: * BIN2DEC(x) * * @param array|string $value The binary number (as a string) that you want to convert. The number * cannot contain more than 10 characters (10 bits). The most significant * bit of number is the sign bit. The remaining 9 bits are magnitude bits. * Negative numbers are represented using two's-complement notation. * If number is not a valid binary number, or if number contains more than * 10 characters (10 bits), BIN2DEC returns the #NUM! error value. * Or can be an array of values * * @return array|string Result, or an error * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function toDecimal($value) { if (is_array($value)) { return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $value); } try { $value = self::validateValue($value); $value = self::validateBinary($value); } catch (Exception $e) { return $e->getMessage(); } if (strlen($value) == 10 && $value[0] === '1') { // Two's Complement $value = substr($value, -9); return '-' . (512 - bindec($value)); } return (string) bindec($value); } /** * toHex. * * Return a binary value as hex. * * Excel Function: * BIN2HEX(x[,places]) * * @param array|string $value The binary number (as a string) that you want to convert. The number * cannot contain more than 10 characters (10 bits). The most significant * bit of number is the sign bit. The remaining 9 bits are magnitude bits. * Negative numbers are represented using two's-complement notation. * If number is not a valid binary number, or if number contains more than * 10 characters (10 bits), BIN2HEX returns the #NUM! error value. * Or can be an array of values * @param array|int $places The number of characters to use. If places is omitted, BIN2HEX uses the * minimum number of characters necessary. Places is useful for padding the * return value with leading 0s (zeros). * If places is not an integer, it is truncated. * If places is nonnumeric, BIN2HEX returns the #VALUE! error value. * If places is negative, BIN2HEX returns the #NUM! error value. * Or can be an array of values * * @return array|string Result, or an error * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function toHex($value, $places = null) { if (is_array($value) || is_array($places)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $value, $places); } try { $value = self::validateValue($value); $value = self::validateBinary($value); $places = self::validatePlaces($places); } catch (Exception $e) { return $e->getMessage(); } if (strlen($value) == 10 && $value[0] === '1') { $high2 = substr($value, 0, 2); $low8 = substr($value, 2); $xarr = ['00' => '00000000', '01' => '00000001', '10' => 'FFFFFFFE', '11' => 'FFFFFFFF']; return $xarr[$high2] . strtoupper(substr('0' . dechex((int) bindec($low8)), -2)); } $hexVal = (string) strtoupper(dechex((int) bindec($value))); return self::nbrConversionFormat($hexVal, $places); } /** * toOctal. * * Return a binary value as octal. * * Excel Function: * BIN2OCT(x[,places]) * * @param array|string $value The binary number (as a string) that you want to convert. The number * cannot contain more than 10 characters (10 bits). The most significant * bit of number is the sign bit. The remaining 9 bits are magnitude bits. * Negative numbers are represented using two's-complement notation. * If number is not a valid binary number, or if number contains more than * 10 characters (10 bits), BIN2OCT returns the #NUM! error value. * Or can be an array of values * @param array|int $places The number of characters to use. If places is omitted, BIN2OCT uses the * minimum number of characters necessary. Places is useful for padding the * return value with leading 0s (zeros). * If places is not an integer, it is truncated. * If places is nonnumeric, BIN2OCT returns the #VALUE! error value. * If places is negative, BIN2OCT returns the #NUM! error value. * Or can be an array of values * * @return array|string Result, or an error * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function toOctal($value, $places = null) { if (is_array($value) || is_array($places)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $value, $places); } try { $value = self::validateValue($value); $value = self::validateBinary($value); $places = self::validatePlaces($places); } catch (Exception $e) { return $e->getMessage(); } if (strlen($value) == 10 && $value[0] === '1') { // Two's Complement return str_repeat('7', 6) . strtoupper(decoct((int) bindec("11$value"))); } $octVal = (string) decoct((int) bindec($value)); return self::nbrConversionFormat($octVal, $places); } protected static function validateBinary(string $value): string { if ((strlen($value) > preg_match_all('/[01]/', $value)) || (strlen($value) > 10)) { throw new Exception(ExcelError::NAN()); } return $value; } } phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/ErfC.php 0000644 00000004623 15060132323 0021311 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Calculation\Engineering; use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; class ErfC { use ArrayEnabled; /** * ERFC. * * Returns the complementary ERF function integrated between x and infinity * * Note: In Excel 2007 or earlier, if you input a negative value for the lower bound argument, * the function would return a #NUM! error. However, in Excel 2010, the function algorithm was * improved, so that it can now calculate the function for both positive and negative x values. * PhpSpreadsheet follows Excel 2010 behaviour, and accepts nagative arguments. * * Excel Function: * ERFC(x) * * @param mixed $value The float lower bound for integrating ERFC * Or can be an array of values * * @return array|float|string * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function ERFC($value) { if (is_array($value)) { return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $value); } if (is_numeric($value)) { return self::erfcValue($value); } return ExcelError::VALUE(); } private const ONE_SQRT_PI = 0.564189583547756287; /** * Method to calculate the erfc value. * * @param float|int|string $value * * @return float */ private static function erfcValue($value) { $value = (float) $value; if (abs($value) < 2.2) { return 1 - Erf::erfValue($value); } if ($value < 0) { return 2 - self::erfcValue(-$value); } $a = $n = 1; $b = $c = $value; $d = ($value * $value) + 0.5; $q2 = $b / $d; do { $t = $a * $n + $b * $value; $a = $b; $b = $t; $t = $c * $n + $d * $value; $c = $d; $d = $t; $n += 0.5; $q1 = $q2; $q2 = $b / $d; } while ((abs($q1 - $q2) / $q2) > Functions::PRECISION); return self::ONE_SQRT_PI * exp(-$value * $value) * $q2; } } phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/BesselY.php 0000644 00000011464 15060132323 0022041 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Calculation\Engineering; use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled; use PhpOffice\PhpSpreadsheet\Calculation\Exception; use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; class BesselY { use ArrayEnabled; /** * BESSELY. * * Returns the Bessel function, which is also called the Weber function or the Neumann function. * * Excel Function: * BESSELY(x,ord) * * @param mixed $x A float value at which to evaluate the function. * If x is nonnumeric, BESSELY returns the #VALUE! error value. * Or can be an array of values * @param mixed $ord The integer order of the Bessel function. * If ord is not an integer, it is truncated. * If $ord is nonnumeric, BESSELY returns the #VALUE! error value. * If $ord < 0, BESSELY returns the #NUM! error value. * Or can be an array of values * * @return array|float|string Result, or a string containing an error * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function BESSELY($x, $ord) { if (is_array($x) || is_array($ord)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $x, $ord); } try { $x = EngineeringValidations::validateFloat($x); $ord = EngineeringValidations::validateInt($ord); } catch (Exception $e) { return $e->getMessage(); } if (($ord < 0) || ($x <= 0.0)) { return ExcelError::NAN(); } $fBy = self::calculate($x, $ord); return (is_nan($fBy)) ? ExcelError::NAN() : $fBy; } private static function calculate(float $x, int $ord): float { // special cases switch ($ord) { case 0: return self::besselY0($x); case 1: return self::besselY1($x); } return self::besselY2($x, $ord); } /** * Mollify Phpstan. * * @codeCoverageIgnore */ private static function callBesselJ(float $x, int $ord): float { $rslt = BesselJ::BESSELJ($x, $ord); if (!is_float($rslt)) { throw new Exception('Unexpected array or string'); } return $rslt; } private static function besselY0(float $x): float { if ($x < 8.0) { $y = ($x * $x); $ans1 = -2957821389.0 + $y * (7062834065.0 + $y * (-512359803.6 + $y * (10879881.29 + $y * (-86327.92757 + $y * 228.4622733)))); $ans2 = 40076544269.0 + $y * (745249964.8 + $y * (7189466.438 + $y * (47447.26470 + $y * (226.1030244 + $y)))); return $ans1 / $ans2 + 0.636619772 * self::callBesselJ($x, 0) * log($x); } $z = 8.0 / $x; $y = ($z * $z); $xx = $x - 0.785398164; $ans1 = 1 + $y * (-0.1098628627e-2 + $y * (0.2734510407e-4 + $y * (-0.2073370639e-5 + $y * 0.2093887211e-6))); $ans2 = -0.1562499995e-1 + $y * (0.1430488765e-3 + $y * (-0.6911147651e-5 + $y * (0.7621095161e-6 + $y * (-0.934945152e-7)))); return sqrt(0.636619772 / $x) * (sin($xx) * $ans1 + $z * cos($xx) * $ans2); } private static function besselY1(float $x): float { if ($x < 8.0) { $y = ($x * $x); $ans1 = $x * (-0.4900604943e13 + $y * (0.1275274390e13 + $y * (-0.5153438139e11 + $y * (0.7349264551e9 + $y * (-0.4237922726e7 + $y * 0.8511937935e4))))); $ans2 = 0.2499580570e14 + $y * (0.4244419664e12 + $y * (0.3733650367e10 + $y * (0.2245904002e8 + $y * (0.1020426050e6 + $y * (0.3549632885e3 + $y))))); return ($ans1 / $ans2) + 0.636619772 * (self::callBesselJ($x, 1) * log($x) - 1 / $x); } $z = 8.0 / $x; $y = $z * $z; $xx = $x - 2.356194491; $ans1 = 1.0 + $y * (0.183105e-2 + $y * (-0.3516396496e-4 + $y * (0.2457520174e-5 + $y * (-0.240337019e-6)))); $ans2 = 0.04687499995 + $y * (-0.2002690873e-3 + $y * (0.8449199096e-5 + $y * (-0.88228987e-6 + $y * 0.105787412e-6))); return sqrt(0.636619772 / $x) * (sin($xx) * $ans1 + $z * cos($xx) * $ans2); } private static function besselY2(float $x, int $ord): float { $fTox = 2.0 / $x; $fBym = self::besselY0($x); $fBy = self::besselY1($x); for ($n = 1; $n < $ord; ++$n) { $fByp = $n * $fTox * $fBy - $fBym; $fBym = $fBy; $fBy = $fByp; } return $fBy; } } phpspreadsheet/src/PhpSpreadsheet/Calculation/Logical.php 0000644 00000026626 15060132323 0017621 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Logical\Boolean; /** * @deprecated 1.17.0 */ class Logical { /** * TRUE. * * Returns the boolean TRUE. * * Excel Function: * =TRUE() * * @deprecated 1.17.0 * Use the TRUE() method in the Logical\Boolean class instead * @see Logical\Boolean::TRUE() * * @return bool True */ public static function true(): bool { return Boolean::true(); } /** * FALSE. * * Returns the boolean FALSE. * * Excel Function: * =FALSE() * * @deprecated 1.17.0 * Use the FALSE() method in the Logical\Boolean class instead * @see Logical\Boolean::FALSE() * * @return bool False */ public static function false(): bool { return Boolean::false(); } /** * LOGICAL_AND. * * Returns boolean TRUE if all its arguments are TRUE; returns FALSE if one or more argument is FALSE. * * Excel Function: * =AND(logical1[,logical2[, ...]]) * * The arguments must evaluate to logical values such as TRUE or FALSE, or the arguments must be arrays * or references that contain logical values. * * Boolean arguments are treated as True or False as appropriate * Integer or floating point arguments are treated as True, except for 0 or 0.0 which are False * If any argument value is a string, or a Null, the function returns a #VALUE! error, unless the string * holds the value TRUE or FALSE, in which case it is evaluated as the corresponding boolean value * * @deprecated 1.17.0 * Use the logicalAnd() method in the Logical\Operations class instead * @see Logical\Operations::logicalAnd() * * @param mixed ...$args Data values * * @return bool|string the logical AND of the arguments */ public static function logicalAnd(...$args) { return Logical\Operations::logicalAnd(...$args); } /** * LOGICAL_OR. * * Returns boolean TRUE if any argument is TRUE; returns FALSE if all arguments are FALSE. * * Excel Function: * =OR(logical1[,logical2[, ...]]) * * The arguments must evaluate to logical values such as TRUE or FALSE, or the arguments must be arrays * or references that contain logical values. * * Boolean arguments are treated as True or False as appropriate * Integer or floating point arguments are treated as True, except for 0 or 0.0 which are False * If any argument value is a string, or a Null, the function returns a #VALUE! error, unless the string * holds the value TRUE or FALSE, in which case it is evaluated as the corresponding boolean value * * @deprecated 1.17.0 * Use the logicalOr() method in the Logical\Operations class instead * @see Logical\Operations::logicalOr() * * @param mixed $args Data values * * @return bool|string the logical OR of the arguments */ public static function logicalOr(...$args) { return Logical\Operations::logicalOr(...$args); } /** * LOGICAL_XOR. * * Returns the Exclusive Or logical operation for one or more supplied conditions. * i.e. the Xor function returns TRUE if an odd number of the supplied conditions evaluate to TRUE, * and FALSE otherwise. * * Excel Function: * =XOR(logical1[,logical2[, ...]]) * * The arguments must evaluate to logical values such as TRUE or FALSE, or the arguments must be arrays * or references that contain logical values. * * Boolean arguments are treated as True or False as appropriate * Integer or floating point arguments are treated as True, except for 0 or 0.0 which are False * If any argument value is a string, or a Null, the function returns a #VALUE! error, unless the string * holds the value TRUE or FALSE, in which case it is evaluated as the corresponding boolean value * * @deprecated 1.17.0 * Use the logicalXor() method in the Logical\Operations class instead * @see Logical\Operations::logicalXor() * * @param mixed $args Data values * * @return bool|string the logical XOR of the arguments */ public static function logicalXor(...$args) { return Logical\Operations::logicalXor(...$args); } /** * NOT. * * Returns the boolean inverse of the argument. * * Excel Function: * =NOT(logical) * * The argument must evaluate to a logical value such as TRUE or FALSE * * Boolean arguments are treated as True or False as appropriate * Integer or floating point arguments are treated as True, except for 0 or 0.0 which are False * If any argument value is a string, or a Null, the function returns a #VALUE! error, unless the string * holds the value TRUE or FALSE, in which case it is evaluated as the corresponding boolean value * * @deprecated 1.17.0 * Use the NOT() method in the Logical\Operations class instead * @see Logical\Operations::NOT() * * @param mixed $logical A value or expression that can be evaluated to TRUE or FALSE * * @return array|bool|string the boolean inverse of the argument */ public static function NOT($logical = false) { return Logical\Operations::NOT($logical); } /** * STATEMENT_IF. * * Returns one value if a condition you specify evaluates to TRUE and another value if it evaluates to FALSE. * * Excel Function: * =IF(condition[,returnIfTrue[,returnIfFalse]]) * * Condition is any value or expression that can be evaluated to TRUE or FALSE. * For example, A10=100 is a logical expression; if the value in cell A10 is equal to 100, * the expression evaluates to TRUE. Otherwise, the expression evaluates to FALSE. * This argument can use any comparison calculation operator. * ReturnIfTrue is the value that is returned if condition evaluates to TRUE. * For example, if this argument is the text string "Within budget" and the condition argument * evaluates to TRUE, then the IF function returns the text "Within budget" * If condition is TRUE and ReturnIfTrue is blank, this argument returns 0 (zero). * To display the word TRUE, use the logical value TRUE for this argument. * ReturnIfTrue can be another formula. * ReturnIfFalse is the value that is returned if condition evaluates to FALSE. * For example, if this argument is the text string "Over budget" and the condition argument * evaluates to FALSE, then the IF function returns the text "Over budget". * If condition is FALSE and ReturnIfFalse is omitted, then the logical value FALSE is returned. * If condition is FALSE and ReturnIfFalse is blank, then the value 0 (zero) is returned. * ReturnIfFalse can be another formula. * * @deprecated 1.17.0 * Use the statementIf() method in the Logical\Conditional class instead * @see Logical\Conditional::statementIf() * * @param mixed $condition Condition to evaluate * @param mixed $returnIfTrue Value to return when condition is true * @param mixed $returnIfFalse Optional value to return when condition is false * * @return mixed The value of returnIfTrue or returnIfFalse determined by condition */ public static function statementIf($condition = true, $returnIfTrue = 0, $returnIfFalse = false) { return Logical\Conditional::statementIf($condition, $returnIfTrue, $returnIfFalse); } /** * STATEMENT_SWITCH. * * Returns corresponding with first match (any data type such as a string, numeric, date, etc). * * Excel Function: * =SWITCH (expression, value1, result1, value2, result2, ... value_n, result_n [, default]) * * Expression * The expression to compare to a list of values. * value1, value2, ... value_n * A list of values that are compared to expression. * The SWITCH function is looking for the first value that matches the expression. * result1, result2, ... result_n * A list of results. The SWITCH function returns the corresponding result when a value * matches expression. * default * Optional. It is the default to return if expression does not match any of the values * (value1, value2, ... value_n). * * @deprecated 1.17.0 * Use the statementSwitch() method in the Logical\Conditional class instead * @see Logical\Conditional::statementSwitch() * * @param mixed $arguments Statement arguments * * @return mixed The value of matched expression */ public static function statementSwitch(...$arguments) { return Logical\Conditional::statementSwitch(...$arguments); } /** * IFERROR. * * Excel Function: * =IFERROR(testValue,errorpart) * * @deprecated 1.17.0 * Use the IFERROR() method in the Logical\Conditional class instead * @see Logical\Conditional::IFERROR() * * @param mixed $testValue Value to check, is also the value returned when no error * @param mixed $errorpart Value to return when testValue is an error condition * * @return mixed The value of errorpart or testValue determined by error condition */ public static function IFERROR($testValue = '', $errorpart = '') { return Logical\Conditional::IFERROR($testValue, $errorpart); } /** * IFNA. * * Excel Function: * =IFNA(testValue,napart) * * @deprecated 1.17.0 * Use the IFNA() method in the Logical\Conditional class instead * @see Logical\Conditional::IFNA() * * @param mixed $testValue Value to check, is also the value returned when not an NA * @param mixed $napart Value to return when testValue is an NA condition * * @return mixed The value of errorpart or testValue determined by error condition */ public static function IFNA($testValue = '', $napart = '') { return Logical\Conditional::IFNA($testValue, $napart); } /** * IFS. * * Excel Function: * =IFS(testValue1;returnIfTrue1;testValue2;returnIfTrue2;...;testValue_n;returnIfTrue_n) * * testValue1 ... testValue_n * Conditions to Evaluate * returnIfTrue1 ... returnIfTrue_n * Value returned if corresponding testValue (nth) was true * * @deprecated 1.17.0 * Use the IFS() method in the Logical\Conditional class instead * @see Logical\Conditional::IFS() * * @param mixed ...$arguments Statement arguments * * @return mixed|string The value of returnIfTrue_n, if testValue_n was true. #N/A if none of testValues was true */ public static function IFS(...$arguments) { return Logical\Conditional::IFS(...$arguments); } } phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical.php 0000644 00000156157 15060132323 0020536 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Averages; use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Conditional; use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Confidence; use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Counts; use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Maximum; use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Minimum; use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Permutations; use PhpOffice\PhpSpreadsheet\Calculation\Statistical\StandardDeviations; use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Trends; use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Variances; /** * @deprecated 1.18.0 */ class Statistical { const LOG_GAMMA_X_MAX_VALUE = 2.55e305; const EPS = 2.22e-16; const MAX_VALUE = 1.2e308; const SQRT2PI = 2.5066282746310005024157652848110452530069867406099; /** * AVEDEV. * * Returns the average of the absolute deviations of data points from their mean. * AVEDEV is a measure of the variability in a data set. * * Excel Function: * AVEDEV(value1[,value2[, ...]]) * * @deprecated 1.17.0 * Use the averageDeviations() method in the Statistical\Averages class instead * @see Statistical\Averages::averageDeviations() * * @param mixed ...$args Data values * * @return float|string */ public static function AVEDEV(...$args) { return Averages::averageDeviations(...$args); } /** * AVERAGE. * * Returns the average (arithmetic mean) of the arguments * * Excel Function: * AVERAGE(value1[,value2[, ...]]) * * @deprecated 1.17.0 * Use the average() method in the Statistical\Averages class instead * @see Statistical\Averages::average() * * @param mixed ...$args Data values * * @return float|string */ public static function AVERAGE(...$args) { return Averages::average(...$args); } /** * AVERAGEA. * * Returns the average of its arguments, including numbers, text, and logical values * * Excel Function: * AVERAGEA(value1[,value2[, ...]]) * * @deprecated 1.17.0 * Use the averageA() method in the Statistical\Averages class instead * @see Statistical\Averages::averageA() * * @param mixed ...$args Data values * * @return float|string */ public static function AVERAGEA(...$args) { return Averages::averageA(...$args); } /** * AVERAGEIF. * * Returns the average value from a range of cells that contain numbers within the list of arguments * * Excel Function: * AVERAGEIF(value1[,value2[, ...]],condition) * * @deprecated 1.17.0 * Use the AVERAGEIF() method in the Statistical\Conditional class instead * @see Statistical\Conditional::AVERAGEIF() * * @param mixed $range Data values * @param string $condition the criteria that defines which cells will be checked * @param mixed[] $averageRange Data values * * @return null|float|string */ public static function AVERAGEIF($range, $condition, $averageRange = []) { return Conditional::AVERAGEIF($range, $condition, $averageRange); } /** * BETADIST. * * Returns the beta distribution. * * @deprecated 1.18.0 * Use the distribution() method in the Statistical\Distributions\Beta class instead * @see Statistical\Distributions\Beta::distribution() * * @param float $value Value at which you want to evaluate the distribution * @param float $alpha Parameter to the distribution * @param float $beta Parameter to the distribution * @param mixed $rMin * @param mixed $rMax * * @return array|float|string */ public static function BETADIST($value, $alpha, $beta, $rMin = 0, $rMax = 1) { return Statistical\Distributions\Beta::distribution($value, $alpha, $beta, $rMin, $rMax); } /** * BETAINV. * * Returns the inverse of the Beta distribution. * * @deprecated 1.18.0 * Use the inverse() method in the Statistical\Distributions\Beta class instead * @see Statistical\Distributions\Beta::inverse() * * @param float $probability Probability at which you want to evaluate the distribution * @param float $alpha Parameter to the distribution * @param float $beta Parameter to the distribution * @param float $rMin Minimum value * @param float $rMax Maximum value * * @return array|float|string */ public static function BETAINV($probability, $alpha, $beta, $rMin = 0, $rMax = 1) { return Statistical\Distributions\Beta::inverse($probability, $alpha, $beta, $rMin, $rMax); } /** * BINOMDIST. * * Returns the individual term binomial distribution probability. Use BINOMDIST in problems with * a fixed number of tests or trials, when the outcomes of any trial are only success or failure, * when trials are independent, and when the probability of success is constant throughout the * experiment. For example, BINOMDIST can calculate the probability that two of the next three * babies born are male. * * @deprecated 1.18.0 * Use the distribution() method in the Statistical\Distributions\Binomial class instead * @see Statistical\Distributions\Binomial::distribution() * * @param mixed $value Number of successes in trials * @param mixed $trials Number of trials * @param mixed $probability Probability of success on each trial * @param mixed $cumulative * * @return array|float|string */ public static function BINOMDIST($value, $trials, $probability, $cumulative) { return Statistical\Distributions\Binomial::distribution($value, $trials, $probability, $cumulative); } /** * CHIDIST. * * Returns the one-tailed probability of the chi-squared distribution. * * @deprecated 1.18.0 * Use the distributionRightTail() method in the Statistical\Distributions\ChiSquared class instead * @see Statistical\Distributions\ChiSquared::distributionRightTail() * * @param float $value Value for the function * @param float $degrees degrees of freedom * * @return array|float|string */ public static function CHIDIST($value, $degrees) { return Statistical\Distributions\ChiSquared::distributionRightTail($value, $degrees); } /** * CHIINV. * * Returns the one-tailed probability of the chi-squared distribution. * * @deprecated 1.18.0 * Use the inverseRightTail() method in the Statistical\Distributions\ChiSquared class instead * @see Statistical\Distributions\ChiSquared::inverseRightTail() * * @param float $probability Probability for the function * @param float $degrees degrees of freedom * * @return array|float|string */ public static function CHIINV($probability, $degrees) { return Statistical\Distributions\ChiSquared::inverseRightTail($probability, $degrees); } /** * CONFIDENCE. * * Returns the confidence interval for a population mean * * @deprecated 1.18.0 * Use the CONFIDENCE() method in the Statistical\Confidence class instead * @see Statistical\Confidence::CONFIDENCE() * * @param float $alpha * @param float $stdDev Standard Deviation * @param float $size * * @return array|float|string */ public static function CONFIDENCE($alpha, $stdDev, $size) { return Confidence::CONFIDENCE($alpha, $stdDev, $size); } /** * CORREL. * * Returns covariance, the average of the products of deviations for each data point pair. * * @deprecated 1.18.0 * Use the CORREL() method in the Statistical\Trends class instead * @see Statistical\Trends::CORREL() * * @param mixed $yValues array of mixed Data Series Y * @param null|mixed $xValues array of mixed Data Series X * * @return float|string */ public static function CORREL($yValues, $xValues = null) { return Trends::CORREL($xValues, $yValues); } /** * COUNT. * * Counts the number of cells that contain numbers within the list of arguments * * Excel Function: * COUNT(value1[,value2[, ...]]) * * @deprecated 1.17.0 * Use the COUNT() method in the Statistical\Counts class instead * @see Statistical\Counts::COUNT() * * @param mixed ...$args Data values * * @return int */ public static function COUNT(...$args) { return Counts::COUNT(...$args); } /** * COUNTA. * * Counts the number of cells that are not empty within the list of arguments * * Excel Function: * COUNTA(value1[,value2[, ...]]) * * @deprecated 1.17.0 * Use the COUNTA() method in the Statistical\Counts class instead * @see Statistical\Counts::COUNTA() * * @param mixed ...$args Data values * * @return int */ public static function COUNTA(...$args) { return Counts::COUNTA(...$args); } /** * COUNTBLANK. * * Counts the number of empty cells within the list of arguments * * Excel Function: * COUNTBLANK(value1[,value2[, ...]]) * * @deprecated 1.17.0 * Use the COUNTBLANK() method in the Statistical\Counts class instead * @see Statistical\Counts::COUNTBLANK() * * @param mixed $range Data values * * @return int */ public static function COUNTBLANK($range) { return Counts::COUNTBLANK($range); } /** * COUNTIF. * * Counts the number of cells that contain numbers within the list of arguments * * Excel Function: * COUNTIF(range,condition) * * @deprecated 1.17.0 * Use the COUNTIF() method in the Statistical\Conditional class instead * @see Statistical\Conditional::COUNTIF() * * @param mixed $range Data values * @param string $condition the criteria that defines which cells will be counted * * @return int|string */ public static function COUNTIF($range, $condition) { return Conditional::COUNTIF($range, $condition); } /** * COUNTIFS. * * Counts the number of cells that contain numbers within the list of arguments * * Excel Function: * COUNTIFS(criteria_range1, criteria1, [criteria_range2, criteria2]…) * * @deprecated 1.17.0 * Use the COUNTIFS() method in the Statistical\Conditional class instead * @see Statistical\Conditional::COUNTIFS() * * @param mixed $args Pairs of Ranges and Criteria * * @return int|string */ public static function COUNTIFS(...$args) { return Conditional::COUNTIFS(...$args); } /** * COVAR. * * Returns covariance, the average of the products of deviations for each data point pair. * * @deprecated 1.18.0 * Use the COVAR() method in the Statistical\Trends class instead * @see Statistical\Trends::COVAR() * * @param mixed $yValues array of mixed Data Series Y * @param mixed $xValues array of mixed Data Series X * * @return float|string */ public static function COVAR($yValues, $xValues) { return Trends::COVAR($yValues, $xValues); } /** * CRITBINOM. * * Returns the smallest value for which the cumulative binomial distribution is greater * than or equal to a criterion value * * See https://support.microsoft.com/en-us/help/828117/ for details of the algorithm used * * @deprecated 1.18.0 * Use the inverse() method in the Statistical\Distributions\Binomial class instead * @see Statistical\Distributions\Binomial::inverse() * * @param float $trials number of Bernoulli trials * @param float $probability probability of a success on each trial * @param float $alpha criterion value * * @return array|int|string */ public static function CRITBINOM($trials, $probability, $alpha) { return Statistical\Distributions\Binomial::inverse($trials, $probability, $alpha); } /** * DEVSQ. * * Returns the sum of squares of deviations of data points from their sample mean. * * Excel Function: * DEVSQ(value1[,value2[, ...]]) * * @deprecated 1.18.0 * Use the sumSquares() method in the Statistical\Deviations class instead * @see Statistical\Deviations::sumSquares() * * @param mixed ...$args Data values * * @return float|string */ public static function DEVSQ(...$args) { return Statistical\Deviations::sumSquares(...$args); } /** * EXPONDIST. * * Returns the exponential distribution. Use EXPONDIST to model the time between events, * such as how long an automated bank teller takes to deliver cash. For example, you can * use EXPONDIST to determine the probability that the process takes at most 1 minute. * * @deprecated 1.18.0 * Use the distribution() method in the Statistical\Distributions\Exponential class instead * @see Statistical\Distributions\Exponential::distribution() * * @param float $value Value of the function * @param float $lambda The parameter value * @param bool $cumulative * * @return array|float|string */ public static function EXPONDIST($value, $lambda, $cumulative) { return Statistical\Distributions\Exponential::distribution($value, $lambda, $cumulative); } /** * F.DIST. * * Returns the F probability distribution. * You can use this function to determine whether two data sets have different degrees of diversity. * For example, you can examine the test scores of men and women entering high school, and determine * if the variability in the females is different from that found in the males. * * @deprecated 1.18.0 * Use the distribution() method in the Statistical\Distributions\F class instead * @see Statistical\Distributions\F::distribution() * * @param float $value Value of the function * @param int $u The numerator degrees of freedom * @param int $v The denominator degrees of freedom * @param bool $cumulative If cumulative is TRUE, F.DIST returns the cumulative distribution function; * if FALSE, it returns the probability density function. * * @return array|float|string */ public static function FDIST2($value, $u, $v, $cumulative) { return Statistical\Distributions\F::distribution($value, $u, $v, $cumulative); } /** * FISHER. * * Returns the Fisher transformation at x. This transformation produces a function that * is normally distributed rather than skewed. Use this function to perform hypothesis * testing on the correlation coefficient. * * @deprecated 1.18.0 * Use the distribution() method in the Statistical\Distributions\Fisher class instead * @see Statistical\Distributions\Fisher::distribution() * * @param float $value * * @return array|float|string */ public static function FISHER($value) { return Statistical\Distributions\Fisher::distribution($value); } /** * FISHERINV. * * Returns the inverse of the Fisher transformation. Use this transformation when * analyzing correlations between ranges or arrays of data. If y = FISHER(x), then * FISHERINV(y) = x. * * @deprecated 1.18.0 * Use the inverse() method in the Statistical\Distributions\Fisher class instead * @see Statistical\Distributions\Fisher::inverse() * * @param float $value * * @return array|float|string */ public static function FISHERINV($value) { return Statistical\Distributions\Fisher::inverse($value); } /** * FORECAST. * * Calculates, or predicts, a future value by using existing values. The predicted value is a y-value for a given x-value. * * @deprecated 1.18.0 * Use the FORECAST() method in the Statistical\Trends class instead * @see Statistical\Trends::FORECAST() * * @param float $xValue Value of X for which we want to find Y * @param mixed $yValues array of mixed Data Series Y * @param mixed $xValues of mixed Data Series X * * @return array|bool|float|string */ public static function FORECAST($xValue, $yValues, $xValues) { return Trends::FORECAST($xValue, $yValues, $xValues); } /** * GAMMA. * * Returns the gamma function value. * * @deprecated 1.18.0 * Use the gamma() method in the Statistical\Distributions\Gamma class instead * @see Statistical\Distributions\Gamma::gamma() * * @param float $value * * @return array|float|string The result, or a string containing an error */ public static function GAMMAFunction($value) { return Statistical\Distributions\Gamma::gamma($value); } /** * GAMMADIST. * * Returns the gamma distribution. * * @deprecated 1.18.0 * Use the distribution() method in the Statistical\Distributions\Gamma class instead * @see Statistical\Distributions\Gamma::distribution() * * @param float $value Value at which you want to evaluate the distribution * @param float $a Parameter to the distribution * @param float $b Parameter to the distribution * @param bool $cumulative * * @return array|float|string */ public static function GAMMADIST($value, $a, $b, $cumulative) { return Statistical\Distributions\Gamma::distribution($value, $a, $b, $cumulative); } /** * GAMMAINV. * * Returns the inverse of the Gamma distribution. * * @deprecated 1.18.0 * Use the inverse() method in the Statistical\Distributions\Gamma class instead * @see Statistical\Distributions\Gamma::inverse() * * @param float $probability Probability at which you want to evaluate the distribution * @param float $alpha Parameter to the distribution * @param float $beta Parameter to the distribution * * @return array|float|string */ public static function GAMMAINV($probability, $alpha, $beta) { return Statistical\Distributions\Gamma::inverse($probability, $alpha, $beta); } /** * GAMMALN. * * Returns the natural logarithm of the gamma function. * * @deprecated 1.18.0 * Use the ln() method in the Statistical\Distributions\Gamma class instead * @see Statistical\Distributions\Gamma::ln() * * @param float $value * * @return array|float|string */ public static function GAMMALN($value) { return Statistical\Distributions\Gamma::ln($value); } /** * GAUSS. * * Calculates the probability that a member of a standard normal population will fall between * the mean and z standard deviations from the mean. * * @deprecated 1.18.0 * Use the gauss() method in the Statistical\Distributions\StandardNormal class instead * @see Statistical\Distributions\StandardNormal::gauss() * * @param float $value * * @return array|float|string The result, or a string containing an error */ public static function GAUSS($value) { return Statistical\Distributions\StandardNormal::gauss($value); } /** * GEOMEAN. * * Returns the geometric mean of an array or range of positive data. For example, you * can use GEOMEAN to calculate average growth rate given compound interest with * variable rates. * * Excel Function: * GEOMEAN(value1[,value2[, ...]]) * * @deprecated 1.18.0 * Use the geometric() method in the Statistical\Averages\Mean class instead * @see Statistical\Averages\Mean::geometric() * * @param mixed ...$args Data values * * @return float|string */ public static function GEOMEAN(...$args) { return Statistical\Averages\Mean::geometric(...$args); } /** * GROWTH. * * Returns values along a predicted exponential Trend * * @deprecated 1.18.0 * Use the GROWTH() method in the Statistical\Trends class instead * @see Statistical\Trends::GROWTH() * * @param mixed[] $yValues Data Series Y * @param mixed[] $xValues Data Series X * @param mixed[] $newValues Values of X for which we want to find Y * @param bool $const a logical value specifying whether to force the intersect to equal 0 * * @return float[] */ public static function GROWTH($yValues, $xValues = [], $newValues = [], $const = true) { return Trends::GROWTH($yValues, $xValues, $newValues, $const); } /** * HARMEAN. * * Returns the harmonic mean of a data set. The harmonic mean is the reciprocal of the * arithmetic mean of reciprocals. * * Excel Function: * HARMEAN(value1[,value2[, ...]]) * * @deprecated 1.18.0 * Use the harmonic() method in the Statistical\Averages\Mean class instead * @see Statistical\Averages\Mean::harmonic() * * @param mixed ...$args Data values * * @return float|string */ public static function HARMEAN(...$args) { return Statistical\Averages\Mean::harmonic(...$args); } /** * HYPGEOMDIST. * * Returns the hypergeometric distribution. HYPGEOMDIST returns the probability of a given number of * sample successes, given the sample size, population successes, and population size. * * @deprecated 1.18.0 * Use the distribution() method in the Statistical\Distributions\HyperGeometric class instead * @see Statistical\Distributions\HyperGeometric::distribution() * * @param mixed $sampleSuccesses Number of successes in the sample * @param mixed $sampleNumber Size of the sample * @param mixed $populationSuccesses Number of successes in the population * @param mixed $populationNumber Population size * * @return array|float|string */ public static function HYPGEOMDIST($sampleSuccesses, $sampleNumber, $populationSuccesses, $populationNumber) { return Statistical\Distributions\HyperGeometric::distribution( $sampleSuccesses, $sampleNumber, $populationSuccesses, $populationNumber ); } /** * INTERCEPT. * * Calculates the point at which a line will intersect the y-axis by using existing x-values and y-values. * * @deprecated 1.18.0 * Use the INTERCEPT() method in the Statistical\Trends class instead * @see Statistical\Trends::INTERCEPT() * * @param mixed[] $yValues Data Series Y * @param mixed[] $xValues Data Series X * * @return float|string */ public static function INTERCEPT($yValues, $xValues) { return Trends::INTERCEPT($yValues, $xValues); } /** * KURT. * * Returns the kurtosis of a data set. Kurtosis characterizes the relative peakedness * or flatness of a distribution compared with the normal distribution. Positive * kurtosis indicates a relatively peaked distribution. Negative kurtosis indicates a * relatively flat distribution. * * @deprecated 1.18.0 * Use the kurtosis() method in the Statistical\Deviations class instead * @see Statistical\Deviations::kurtosis() * * @param array ...$args Data Series * * @return float|string */ public static function KURT(...$args) { return Statistical\Deviations::kurtosis(...$args); } /** * LARGE. * * Returns the nth largest value in a data set. You can use this function to * select a value based on its relative standing. * * Excel Function: * LARGE(value1[,value2[, ...]],entry) * * @deprecated 1.18.0 * Use the large() method in the Statistical\Size class instead * @see Statistical\Size::large() * * @param mixed $args Data values * * @return float|string The result, or a string containing an error */ public static function LARGE(...$args) { return Statistical\Size::large(...$args); } /** * LINEST. * * Calculates the statistics for a line by using the "least squares" method to calculate a straight line that best fits your data, * and then returns an array that describes the line. * * @deprecated 1.18.0 * Use the LINEST() method in the Statistical\Trends class instead * @see Statistical\Trends::LINEST() * * @param mixed[] $yValues Data Series Y * @param null|mixed[] $xValues Data Series X * @param bool $const a logical value specifying whether to force the intersect to equal 0 * @param bool $stats a logical value specifying whether to return additional regression statistics * * @return array|int|string The result, or a string containing an error */ public static function LINEST($yValues, $xValues = null, $const = true, $stats = false) { return Trends::LINEST($yValues, $xValues, $const, $stats); } /** * LOGEST. * * Calculates an exponential curve that best fits the X and Y data series, * and then returns an array that describes the line. * * @deprecated 1.18.0 * Use the LOGEST() method in the Statistical\Trends class instead * @see Statistical\Trends::LOGEST() * * @param mixed[] $yValues Data Series Y * @param null|mixed[] $xValues Data Series X * @param bool $const a logical value specifying whether to force the intersect to equal 0 * @param bool $stats a logical value specifying whether to return additional regression statistics * * @return array|int|string The result, or a string containing an error */ public static function LOGEST($yValues, $xValues = null, $const = true, $stats = false) { return Trends::LOGEST($yValues, $xValues, $const, $stats); } /** * LOGINV. * * Returns the inverse of the normal cumulative distribution * * @deprecated 1.18.0 * Use the inverse() method in the Statistical\Distributions\LogNormal class instead * @see Statistical\Distributions\LogNormal::inverse() * * @param float $probability * @param float $mean * @param float $stdDev * * @return array|float|string The result, or a string containing an error * * @TODO Try implementing P J Acklam's refinement algorithm for greater * accuracy if I can get my head round the mathematics * (as described at) http://home.online.no/~pjacklam/notes/invnorm/ */ public static function LOGINV($probability, $mean, $stdDev) { return Statistical\Distributions\LogNormal::inverse($probability, $mean, $stdDev); } /** * LOGNORMDIST. * * Returns the cumulative lognormal distribution of x, where ln(x) is normally distributed * with parameters mean and standard_dev. * * @deprecated 1.18.0 * Use the cumulative() method in the Statistical\Distributions\LogNormal class instead * @see Statistical\Distributions\LogNormal::cumulative() * * @param float $value * @param float $mean * @param float $stdDev * * @return array|float|string The result, or a string containing an error */ public static function LOGNORMDIST($value, $mean, $stdDev) { return Statistical\Distributions\LogNormal::cumulative($value, $mean, $stdDev); } /** * LOGNORM.DIST. * * Returns the lognormal distribution of x, where ln(x) is normally distributed * with parameters mean and standard_dev. * * @deprecated 1.18.0 * Use the distribution() method in the Statistical\Distributions\LogNormal class instead * @see Statistical\Distributions\LogNormal::distribution() * * @param float $value * @param float $mean * @param float $stdDev * @param bool $cumulative * * @return array|float|string The result, or a string containing an error */ public static function LOGNORMDIST2($value, $mean, $stdDev, $cumulative = false) { return Statistical\Distributions\LogNormal::distribution($value, $mean, $stdDev, $cumulative); } /** * MAX. * * MAX returns the value of the element of the values passed that has the highest value, * with negative numbers considered smaller than positive numbers. * * Excel Function: * max(value1[,value2[, ...]]) * * @deprecated 1.17.0 * Use the MAX() method in the Statistical\Maximum class instead * @see Statistical\Maximum::max() * * @param mixed ...$args Data values * * @return float */ public static function MAX(...$args) { return Maximum::max(...$args); } /** * MAXA. * * Returns the greatest value in a list of arguments, including numbers, text, and logical values * * Excel Function: * maxA(value1[,value2[, ...]]) * * @deprecated 1.17.0 * Use the MAXA() method in the Statistical\Maximum class instead * @see Statistical\Maximum::maxA() * * @param mixed ...$args Data values * * @return float */ public static function MAXA(...$args) { return Maximum::maxA(...$args); } /** * MAXIFS. * * Counts the maximum value within a range of cells that contain numbers within the list of arguments * * Excel Function: * MAXIFS(max_range, criteria_range1, criteria1, [criteria_range2, criteria2], ...) * * @deprecated 1.17.0 * Use the MAXIFS() method in the Statistical\Conditional class instead * @see Statistical\Conditional::MAXIFS() * * @param mixed $args Data range and criterias * * @return null|float|string */ public static function MAXIFS(...$args) { return Conditional::MAXIFS(...$args); } /** * MEDIAN. * * Returns the median of the given numbers. The median is the number in the middle of a set of numbers. * * Excel Function: * MEDIAN(value1[,value2[, ...]]) * * @deprecated 1.18.0 * Use the median() method in the Statistical\Averages class instead * @see Statistical\Averages::median() * * @param mixed ...$args Data values * * @return float|string The result, or a string containing an error */ public static function MEDIAN(...$args) { return Statistical\Averages::median(...$args); } /** * MIN. * * MIN returns the value of the element of the values passed that has the smallest value, * with negative numbers considered smaller than positive numbers. * * Excel Function: * MIN(value1[,value2[, ...]]) * * @deprecated 1.17.0 * Use the min() method in the Statistical\Minimum class instead * @see Statistical\Minimum::min() * * @param mixed ...$args Data values * * @return float */ public static function MIN(...$args) { return Minimum::min(...$args); } /** * MINA. * * Returns the smallest value in a list of arguments, including numbers, text, and logical values * * Excel Function: * MINA(value1[,value2[, ...]]) * * @deprecated 1.17.0 * Use the minA() method in the Statistical\Minimum class instead * @see Statistical\Minimum::minA() * * @param mixed ...$args Data values * * @return float */ public static function MINA(...$args) { return Minimum::minA(...$args); } /** * MINIFS. * * Returns the minimum value within a range of cells that contain numbers within the list of arguments * * Excel Function: * MINIFS(min_range, criteria_range1, criteria1, [criteria_range2, criteria2], ...) * * @deprecated 1.17.0 * Use the MINIFS() method in the Statistical\Conditional class instead * @see Statistical\Conditional::MINIFS() * * @param mixed $args Data range and criterias * * @return null|float|string */ public static function MINIFS(...$args) { return Conditional::MINIFS(...$args); } /** * MODE. * * Returns the most frequently occurring, or repetitive, value in an array or range of data * * Excel Function: * MODE(value1[,value2[, ...]]) * * @deprecated 1.18.0 * Use the mode() method in the Statistical\Averages class instead * @see Statistical\Averages::mode() * * @param mixed ...$args Data values * * @return float|string The result, or a string containing an error */ public static function MODE(...$args) { return Statistical\Averages::mode(...$args); } /** * NEGBINOMDIST. * * Returns the negative binomial distribution. NEGBINOMDIST returns the probability that * there will be number_f failures before the number_s-th success, when the constant * probability of a success is probability_s. This function is similar to the binomial * distribution, except that the number of successes is fixed, and the number of trials is * variable. Like the binomial, trials are assumed to be independent. * * @deprecated 1.18.0 * Use the negative() method in the Statistical\Distributions\Binomial class instead * @see Statistical\Distributions\Binomial::negative() * * @param mixed $failures Number of Failures * @param mixed $successes Threshold number of Successes * @param mixed $probability Probability of success on each trial * * @return array|float|string The result, or a string containing an error */ public static function NEGBINOMDIST($failures, $successes, $probability) { return Statistical\Distributions\Binomial::negative($failures, $successes, $probability); } /** * NORMDIST. * * Returns the normal distribution for the specified mean and standard deviation. This * function has a very wide range of applications in statistics, including hypothesis * testing. * * @deprecated 1.18.0 * Use the distribution() method in the Statistical\Distributions\Normal class instead * @see Statistical\Distributions\Normal::distribution() * * @param mixed $value * @param mixed $mean Mean Value * @param mixed $stdDev Standard Deviation * @param mixed $cumulative * * @return array|float|string The result, or a string containing an error */ public static function NORMDIST($value, $mean, $stdDev, $cumulative) { return Statistical\Distributions\Normal::distribution($value, $mean, $stdDev, $cumulative); } /** * NORMINV. * * Returns the inverse of the normal cumulative distribution for the specified mean and standard deviation. * * @deprecated 1.18.0 * Use the inverse() method in the Statistical\Distributions\Normal class instead * @see Statistical\Distributions\Normal::inverse() * * @param mixed $probability * @param mixed $mean Mean Value * @param mixed $stdDev Standard Deviation * * @return array|float|string The result, or a string containing an error */ public static function NORMINV($probability, $mean, $stdDev) { return Statistical\Distributions\Normal::inverse($probability, $mean, $stdDev); } /** * NORMSDIST. * * Returns the standard normal cumulative distribution function. The distribution has * a mean of 0 (zero) and a standard deviation of one. Use this function in place of a * table of standard normal curve areas. * * @deprecated 1.18.0 * Use the cumulative() method in the Statistical\Distributions\StandardNormal class instead * @see Statistical\Distributions\StandardNormal::cumulative() * * @param mixed $value * * @return array|float|string The result, or a string containing an error */ public static function NORMSDIST($value) { return Statistical\Distributions\StandardNormal::cumulative($value); } /** * NORM.S.DIST. * * Returns the standard normal cumulative distribution function. The distribution has * a mean of 0 (zero) and a standard deviation of one. Use this function in place of a * table of standard normal curve areas. * * @deprecated 1.18.0 * Use the distribution() method in the Statistical\Distributions\StandardNormal class instead * @see Statistical\Distributions\StandardNormal::distribution() * * @param mixed $value * @param mixed $cumulative * * @return array|float|string The result, or a string containing an error */ public static function NORMSDIST2($value, $cumulative) { return Statistical\Distributions\StandardNormal::distribution($value, $cumulative); } /** * NORMSINV. * * Returns the inverse of the standard normal cumulative distribution * * @deprecated 1.18.0 * Use the inverse() method in the Statistical\Distributions\StandardNormal class instead * @see Statistical\Distributions\StandardNormal::inverse() * * @param mixed $value * * @return array|float|string The result, or a string containing an error */ public static function NORMSINV($value) { return Statistical\Distributions\StandardNormal::inverse($value); } /** * PERCENTILE. * * Returns the nth percentile of values in a range.. * * Excel Function: * PERCENTILE(value1[,value2[, ...]],entry) * * @deprecated 1.18.0 * Use the PERCENTILE() method in the Statistical\Percentiles class instead * @see Statistical\Percentiles::PERCENTILE() * * @param mixed $args Data values * * @return float|string The result, or a string containing an error */ public static function PERCENTILE(...$args) { return Statistical\Percentiles::PERCENTILE(...$args); } /** * PERCENTRANK. * * Returns the rank of a value in a data set as a percentage of the data set. * Note that the returned rank is simply rounded to the appropriate significant digits, * rather than floored (as MS Excel), so value 3 for a value set of 1, 2, 3, 4 will return * 0.667 rather than 0.666 * * @deprecated 1.18.0 * Use the PERCENTRANK() method in the Statistical\Percentiles class instead * @see Statistical\Percentiles::PERCENTRANK() * * @param mixed $valueSet An array of, or a reference to, a list of numbers * @param mixed $value the number whose rank you want to find * @param mixed $significance the number of significant digits for the returned percentage value * * @return float|string (string if result is an error) */ public static function PERCENTRANK($valueSet, $value, $significance = 3) { return Statistical\Percentiles::PERCENTRANK($valueSet, $value, $significance); } /** * PERMUT. * * Returns the number of permutations for a given number of objects that can be * selected from number objects. A permutation is any set or subset of objects or * events where internal order is significant. Permutations are different from * combinations, for which the internal order is not significant. Use this function * for lottery-style probability calculations. * * @deprecated 1.17.0 * Use the PERMUT() method in the Statistical\Permutations class instead * @see Statistical\Permutations::PERMUT() * * @param int $numObjs Number of different objects * @param int $numInSet Number of objects in each permutation * * @return array|float|int|string Number of permutations, or a string containing an error */ public static function PERMUT($numObjs, $numInSet) { return Permutations::PERMUT($numObjs, $numInSet); } /** * POISSON. * * Returns the Poisson distribution. A common application of the Poisson distribution * is predicting the number of events over a specific time, such as the number of * cars arriving at a toll plaza in 1 minute. * * @deprecated 1.18.0 * Use the distribution() method in the Statistical\Distributions\Poisson class instead * @see Statistical\Distributions\Poisson::distribution() * * @param mixed $value * @param mixed $mean Mean Value * @param mixed $cumulative * * @return array|float|string The result, or a string containing an error */ public static function POISSON($value, $mean, $cumulative) { return Statistical\Distributions\Poisson::distribution($value, $mean, $cumulative); } /** * QUARTILE. * * Returns the quartile of a data set. * * Excel Function: * QUARTILE(value1[,value2[, ...]],entry) * * @deprecated 1.18.0 * Use the QUARTILE() method in the Statistical\Percentiles class instead * @see Statistical\Percentiles::QUARTILE() * * @param mixed $args Data values * * @return float|string The result, or a string containing an error */ public static function QUARTILE(...$args) { return Statistical\Percentiles::QUARTILE(...$args); } /** * RANK. * * Returns the rank of a number in a list of numbers. * * @deprecated 1.18.0 * Use the RANK() method in the Statistical\Percentiles class instead * @see Statistical\Percentiles::RANK() * * @param mixed $value the number whose rank you want to find * @param mixed $valueSet An array of, or a reference to, a list of numbers * @param mixed $order Order to sort the values in the value set * * @return float|string The result, or a string containing an error */ public static function RANK($value, $valueSet, $order = 0) { return Statistical\Percentiles::RANK($value, $valueSet, $order); } /** * RSQ. * * Returns the square of the Pearson product moment correlation coefficient through data points in known_y's and known_x's. * * @deprecated 1.18.0 * Use the RSQ() method in the Statistical\Trends class instead * @see Statistical\Trends::RSQ() * * @param mixed[] $yValues Data Series Y * @param mixed[] $xValues Data Series X * * @return float|string The result, or a string containing an error */ public static function RSQ($yValues, $xValues) { return Trends::RSQ($yValues, $xValues); } /** * SKEW. * * Returns the skewness of a distribution. Skewness characterizes the degree of asymmetry * of a distribution around its mean. Positive skewness indicates a distribution with an * asymmetric tail extending toward more positive values. Negative skewness indicates a * distribution with an asymmetric tail extending toward more negative values. * * @deprecated 1.18.0 * Use the skew() method in the Statistical\Deviations class instead * @see Statistical\Deviations::skew() * * @param array ...$args Data Series * * @return float|string The result, or a string containing an error */ public static function SKEW(...$args) { return Statistical\Deviations::skew(...$args); } /** * SLOPE. * * Returns the slope of the linear regression line through data points in known_y's and known_x's. * * @deprecated 1.18.0 * Use the SLOPE() method in the Statistical\Trends class instead * @see Statistical\Trends::SLOPE() * * @param mixed[] $yValues Data Series Y * @param mixed[] $xValues Data Series X * * @return float|string The result, or a string containing an error */ public static function SLOPE($yValues, $xValues) { return Trends::SLOPE($yValues, $xValues); } /** * SMALL. * * Returns the nth smallest value in a data set. You can use this function to * select a value based on its relative standing. * * Excel Function: * SMALL(value1[,value2[, ...]],entry) * * @deprecated 1.18.0 * Use the small() method in the Statistical\Size class instead * @see Statistical\Size::small() * * @param mixed $args Data values * * @return float|string The result, or a string containing an error */ public static function SMALL(...$args) { return Statistical\Size::small(...$args); } /** * STANDARDIZE. * * Returns a normalized value from a distribution characterized by mean and standard_dev. * * @deprecated 1.18.0 * Use the execute() method in the Statistical\Standardize class instead * @see Statistical\Standardize::execute() * * @param float $value Value to normalize * @param float $mean Mean Value * @param float $stdDev Standard Deviation * * @return array|float|string Standardized value, or a string containing an error */ public static function STANDARDIZE($value, $mean, $stdDev) { return Statistical\Standardize::execute($value, $mean, $stdDev); } /** * STDEV. * * Estimates standard deviation based on a sample. The standard deviation is a measure of how * widely values are dispersed from the average value (the mean). * * Excel Function: * STDEV(value1[,value2[, ...]]) * * @deprecated 1.17.0 * Use the STDEV() method in the Statistical\StandardDeviations class instead * @see Statistical\StandardDeviations::STDEV() * * @param mixed ...$args Data values * * @return float|string The result, or a string containing an error */ public static function STDEV(...$args) { return StandardDeviations::STDEV(...$args); } /** * STDEVA. * * Estimates standard deviation based on a sample, including numbers, text, and logical values * * Excel Function: * STDEVA(value1[,value2[, ...]]) * * @deprecated 1.17.0 * Use the STDEVA() method in the Statistical\StandardDeviations class instead * @see Statistical\StandardDeviations::STDEVA() * * @param mixed ...$args Data values * * @return float|string */ public static function STDEVA(...$args) { return StandardDeviations::STDEVA(...$args); } /** * STDEVP. * * Calculates standard deviation based on the entire population * * Excel Function: * STDEVP(value1[,value2[, ...]]) * * @deprecated 1.17.0 * Use the STDEVP() method in the Statistical\StandardDeviations class instead * @see Statistical\StandardDeviations::STDEVP() * * @param mixed ...$args Data values * * @return float|string */ public static function STDEVP(...$args) { return StandardDeviations::STDEVP(...$args); } /** * STDEVPA. * * Calculates standard deviation based on the entire population, including numbers, text, and logical values * * Excel Function: * STDEVPA(value1[,value2[, ...]]) * * @deprecated 1.17.0 * Use the STDEVPA() method in the Statistical\StandardDeviations class instead * @see Statistical\StandardDeviations::STDEVPA() * * @param mixed ...$args Data values * * @return float|string */ public static function STDEVPA(...$args) { return StandardDeviations::STDEVPA(...$args); } /** * STEYX. * * @deprecated 1.18.0 * Use the STEYX() method in the Statistical\Trends class instead * @see Statistical\Trends::STEYX() * * Returns the standard error of the predicted y-value for each x in the regression. * * @param mixed[] $yValues Data Series Y * @param mixed[] $xValues Data Series X * * @return float|string */ public static function STEYX($yValues, $xValues) { return Trends::STEYX($yValues, $xValues); } /** * TDIST. * * Returns the probability of Student's T distribution. * * @deprecated 1.18.0 * Use the distribution() method in the Statistical\Distributions\StudentT class instead * @see Statistical\Distributions\StudentT::distribution() * * @param float $value Value for the function * @param float $degrees degrees of freedom * @param float $tails number of tails (1 or 2) * * @return array|float|string The result, or a string containing an error */ public static function TDIST($value, $degrees, $tails) { return Statistical\Distributions\StudentT::distribution($value, $degrees, $tails); } /** * TINV. * * Returns the one-tailed probability of the Student-T distribution. * * @deprecated 1.18.0 * Use the inverse() method in the Statistical\Distributions\StudentT class instead * @see Statistical\Distributions\StudentT::inverse() * * @param float $probability Probability for the function * @param float $degrees degrees of freedom * * @return array|float|string The result, or a string containing an error */ public static function TINV($probability, $degrees) { return Statistical\Distributions\StudentT::inverse($probability, $degrees); } /** * TREND. * * Returns values along a linear Trend * * @deprecated 1.18.0 * Use the TREND() method in the Statistical\Trends class instead * @see Statistical\Trends::TREND() * * @param mixed[] $yValues Data Series Y * @param mixed[] $xValues Data Series X * @param mixed[] $newValues Values of X for which we want to find Y * @param bool $const a logical value specifying whether to force the intersect to equal 0 * * @return float[] */ public static function TREND($yValues, $xValues = [], $newValues = [], $const = true) { return Trends::TREND($yValues, $xValues, $newValues, $const); } /** * TRIMMEAN. * * Returns the mean of the interior of a data set. TRIMMEAN calculates the mean * taken by excluding a percentage of data points from the top and bottom tails * of a data set. * * Excel Function: * TRIMEAN(value1[,value2[, ...]], $discard) * * @deprecated 1.18.0 * Use the trim() method in the Statistical\Averages\Mean class instead * @see Statistical\Averages\Mean::trim() * * @param mixed $args Data values * * @return float|string */ public static function TRIMMEAN(...$args) { return Statistical\Averages\Mean::trim(...$args); } /** * VARFunc. * * Estimates variance based on a sample. * * Excel Function: * VAR(value1[,value2[, ...]]) * * @deprecated 1.17.0 * Use the VAR() method in the Statistical\Variances class instead * @see Statistical\Variances::VAR() * * @param mixed ...$args Data values * * @return float|string (string if result is an error) */ public static function VARFunc(...$args) { return Variances::VAR(...$args); } /** * VARA. * * Estimates variance based on a sample, including numbers, text, and logical values * * Excel Function: * VARA(value1[,value2[, ...]]) * * @deprecated 1.17.0 * Use the VARA() method in the Statistical\Variances class instead * @see Statistical\Variances::VARA() * * @param mixed ...$args Data values * * @return float|string (string if result is an error) */ public static function VARA(...$args) { return Variances::VARA(...$args); } /** * VARP. * * Calculates variance based on the entire population * * Excel Function: * VARP(value1[,value2[, ...]]) * * @deprecated 1.17.0 * Use the VARP() method in the Statistical\Variances class instead * @see Statistical\Variances::VARP() * * @param mixed ...$args Data values * * @return float|string (string if result is an error) */ public static function VARP(...$args) { return Variances::VARP(...$args); } /** * VARPA. * * Calculates variance based on the entire population, including numbers, text, and logical values * * Excel Function: * VARPA(value1[,value2[, ...]]) * * @deprecated 1.17.0 * Use the VARPA() method in the Statistical\Variances class instead * @see Statistical\Variances::VARPA() * * @param mixed ...$args Data values * * @return float|string (string if result is an error) */ public static function VARPA(...$args) { return Variances::VARPA(...$args); } /** * WEIBULL. * * Returns the Weibull distribution. Use this distribution in reliability * analysis, such as calculating a device's mean time to failure. * * @deprecated 1.18.0 * Use the distribution() method in the Statistical\Distributions\Weibull class instead * @see Statistical\Distributions\Weibull::distribution() * * @param float $value * @param float $alpha Alpha Parameter * @param float $beta Beta Parameter * @param bool $cumulative * * @return array|float|string (string if result is an error) */ public static function WEIBULL($value, $alpha, $beta, $cumulative) { return Statistical\Distributions\Weibull::distribution($value, $alpha, $beta, $cumulative); } /** * ZTEST. * * Returns the one-tailed P-value of a z-test. * * For a given hypothesized population mean, x, Z.TEST returns the probability that the sample mean would be * greater than the average of observations in the data set (array) — that is, the observed sample mean. * * @deprecated 1.18.0 * Use the zTest() method in the Statistical\Distributions\StandardNormal class instead * @see Statistical\Distributions\StandardNormal::zTest() * * @param mixed $dataSet * @param float $m0 Alpha Parameter * @param float $sigma Beta Parameter * * @return array|float|string (string if result is an error) */ public static function ZTEST($dataSet, $m0, $sigma = null) { return Statistical\Distributions\StandardNormal::zTest($dataSet, $m0, $sigma); } } phpspreadsheet/src/PhpSpreadsheet/Calculation/Engine/FormattedNumber.php 0000644 00000013565 15060132323 0022550 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Calculation\Engine; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Shared\StringHelper; class FormattedNumber { /** Constants */ /** Regular Expressions */ private const STRING_REGEXP_FRACTION = '~^\s*(-?)((\d*)\s+)?(\d+\/\d+)\s*$~'; private const STRING_REGEXP_PERCENT = '~^(?:(?: *(?<PrefixedSign>[-+])? *\% *(?<PrefixedSign2>[-+])? *(?<PrefixedValue>[0-9]+\.?[0-9*]*(?:E[-+]?[0-9]*)?) *)|(?: *(?<PostfixedSign>[-+])? *(?<PostfixedValue>[0-9]+\.?[0-9]*(?:E[-+]?[0-9]*)?) *\% *))$~i'; // preg_quoted string for major currency symbols, with a %s for locale currency private const CURRENCY_CONVERSION_LIST = '\$€£¥%s'; private const STRING_CONVERSION_LIST = [ [self::class, 'convertToNumberIfNumeric'], [self::class, 'convertToNumberIfFraction'], [self::class, 'convertToNumberIfPercent'], [self::class, 'convertToNumberIfCurrency'], ]; /** * Identify whether a string contains a formatted numeric value, * and convert it to a numeric if it is. * * @param string $operand string value to test */ public static function convertToNumberIfFormatted(string &$operand): bool { foreach (self::STRING_CONVERSION_LIST as $conversionMethod) { if ($conversionMethod($operand) === true) { return true; } } return false; } /** * Identify whether a string contains a numeric value, * and convert it to a numeric if it is. * * @param string $operand string value to test */ public static function convertToNumberIfNumeric(string &$operand): bool { $thousandsSeparator = preg_quote(StringHelper::getThousandsSeparator(), '/'); $value = preg_replace(['/(\d)' . $thousandsSeparator . '(\d)/u', '/([+-])\s+(\d)/u'], ['$1$2', '$1$2'], trim($operand)); $decimalSeparator = preg_quote(StringHelper::getDecimalSeparator(), '/'); $value = preg_replace(['/(\d)' . $decimalSeparator . '(\d)/u', '/([+-])\s+(\d)/u'], ['$1.$2', '$1$2'], $value ?? ''); if (is_numeric($value)) { $operand = (float) $value; return true; } return false; } /** * Identify whether a string contains a fractional numeric value, * and convert it to a numeric if it is. * * @param string $operand string value to test */ public static function convertToNumberIfFraction(string &$operand): bool { if (preg_match(self::STRING_REGEXP_FRACTION, $operand, $match)) { $sign = ($match[1] === '-') ? '-' : '+'; $wholePart = ($match[3] === '') ? '' : ($sign . $match[3]); $fractionFormula = '=' . $wholePart . $sign . $match[4]; $operand = Calculation::getInstance()->_calculateFormulaValue($fractionFormula); return true; } return false; } /** * Identify whether a string contains a percentage, and if so, * convert it to a numeric. * * @param string $operand string value to test */ public static function convertToNumberIfPercent(string &$operand): bool { $thousandsSeparator = preg_quote(StringHelper::getThousandsSeparator(), '/'); $value = preg_replace('/(\d)' . $thousandsSeparator . '(\d)/u', '$1$2', trim($operand)); $decimalSeparator = preg_quote(StringHelper::getDecimalSeparator(), '/'); $value = preg_replace(['/(\d)' . $decimalSeparator . '(\d)/u', '/([+-])\s+(\d)/u'], ['$1.$2', '$1$2'], $value ?? ''); $match = []; if ($value !== null && preg_match(self::STRING_REGEXP_PERCENT, $value, $match, PREG_UNMATCHED_AS_NULL)) { //Calculate the percentage $sign = ($match['PrefixedSign'] ?? $match['PrefixedSign2'] ?? $match['PostfixedSign']) ?? ''; $operand = (float) ($sign . ($match['PostfixedValue'] ?? $match['PrefixedValue'])) / 100; return true; } return false; } /** * Identify whether a string contains a currency value, and if so, * convert it to a numeric. * * @param string $operand string value to test */ public static function convertToNumberIfCurrency(string &$operand): bool { $currencyRegexp = self::currencyMatcherRegexp(); $thousandsSeparator = preg_quote(StringHelper::getThousandsSeparator(), '/'); $value = preg_replace('/(\d)' . $thousandsSeparator . '(\d)/u', '$1$2', $operand); $match = []; if ($value !== null && preg_match($currencyRegexp, $value, $match, PREG_UNMATCHED_AS_NULL)) { //Determine the sign $sign = ($match['PrefixedSign'] ?? $match['PrefixedSign2'] ?? $match['PostfixedSign']) ?? ''; $decimalSeparator = StringHelper::getDecimalSeparator(); //Cast to a float $intermediate = (string) ($match['PostfixedValue'] ?? $match['PrefixedValue']); $intermediate = str_replace($decimalSeparator, '.', $intermediate); if (is_numeric($intermediate)) { $operand = (float) ($sign . str_replace($decimalSeparator, '.', $intermediate)); return true; } } return false; } public static function currencyMatcherRegexp(): string { $currencyCodes = sprintf(self::CURRENCY_CONVERSION_LIST, preg_quote(StringHelper::getCurrencyCode(), '/')); $decimalSeparator = preg_quote(StringHelper::getDecimalSeparator(), '/'); return '~^(?:(?: *(?<PrefixedSign>[-+])? *(?<PrefixedCurrency>[' . $currencyCodes . ']) *(?<PrefixedSign2>[-+])? *(?<PrefixedValue>[0-9]+[' . $decimalSeparator . ']?[0-9*]*(?:E[-+]?[0-9]*)?) *)|(?: *(?<PostfixedSign>[-+])? *(?<PostfixedValue>[0-9]+' . $decimalSeparator . '?[0-9]*(?:E[-+]?[0-9]*)?) *(?<PostfixedCurrency>[' . $currencyCodes . ']) *))$~ui'; } } phpspreadsheet/src/PhpSpreadsheet/Calculation/Engine/Logger.php 0000644 00000006537 15060132323 0020672 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Calculation\Engine; class Logger { /** * Flag to determine whether a debug log should be generated by the calculation engine * If true, then a debug log will be generated * If false, then a debug log will not be generated. * * @var bool */ private $writeDebugLog = false; /** * Flag to determine whether a debug log should be echoed by the calculation engine * If true, then a debug log will be echoed * If false, then a debug log will not be echoed * A debug log can only be echoed if it is generated. * * @var bool */ private $echoDebugLog = false; /** * The debug log generated by the calculation engine. * * @var string[] */ private $debugLog = []; /** * The calculation engine cell reference stack. * * @var CyclicReferenceStack */ private $cellStack; /** * Instantiate a Calculation engine logger. */ public function __construct(CyclicReferenceStack $stack) { $this->cellStack = $stack; } /** * Enable/Disable Calculation engine logging. * * @param bool $writeDebugLog */ public function setWriteDebugLog($writeDebugLog): void { $this->writeDebugLog = $writeDebugLog; } /** * Return whether calculation engine logging is enabled or disabled. * * @return bool */ public function getWriteDebugLog() { return $this->writeDebugLog; } /** * Enable/Disable echoing of debug log information. * * @param bool $echoDebugLog */ public function setEchoDebugLog($echoDebugLog): void { $this->echoDebugLog = $echoDebugLog; } /** * Return whether echoing of debug log information is enabled or disabled. * * @return bool */ public function getEchoDebugLog() { return $this->echoDebugLog; } /** * Write an entry to the calculation engine debug log. * * @param mixed $args */ public function writeDebugLog(string $message, ...$args): void { // Only write the debug log if logging is enabled if ($this->writeDebugLog) { $message = sprintf($message, ...$args); $cellReference = implode(' -> ', $this->cellStack->showStack()); if ($this->echoDebugLog) { echo $cellReference, ($this->cellStack->count() > 0 ? ' => ' : ''), $message, PHP_EOL; } $this->debugLog[] = $cellReference . ($this->cellStack->count() > 0 ? ' => ' : '') . $message; } } /** * Write a series of entries to the calculation engine debug log. * * @param string[] $args */ public function mergeDebugLog(array $args): void { if ($this->writeDebugLog) { foreach ($args as $entry) { $this->writeDebugLog($entry); } } } /** * Clear the calculation engine debug log. */ public function clearLog(): void { $this->debugLog = []; } /** * Return the calculation engine debug log. * * @return string[] */ public function getLog() { return $this->debugLog; } } phpspreadsheet/src/PhpSpreadsheet/Calculation/Engine/BranchPruner.php 0000644 00000014252 15060132323 0022035 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Calculation\Engine; use PhpOffice\PhpSpreadsheet\Calculation\Exception; class BranchPruner { /** * @var bool */ protected $branchPruningEnabled = true; /** * Used to generate unique store keys. * * @var int */ private $branchStoreKeyCounter = 0; /** * currently pending storeKey (last item of the storeKeysStack. * * @var ?string */ protected $pendingStoreKey; /** * @var string[] */ protected $storeKeysStack = []; /** * @var bool[] */ protected $conditionMap = []; /** * @var bool[] */ protected $thenMap = []; /** * @var bool[] */ protected $elseMap = []; /** * @var int[] */ protected $braceDepthMap = []; /** * @var null|string */ protected $currentCondition; /** * @var null|string */ protected $currentOnlyIf; /** * @var null|string */ protected $currentOnlyIfNot; /** * @var null|string */ protected $previousStoreKey; public function __construct(bool $branchPruningEnabled) { $this->branchPruningEnabled = $branchPruningEnabled; } public function clearBranchStore(): void { $this->branchStoreKeyCounter = 0; } public function initialiseForLoop(): void { $this->currentCondition = null; $this->currentOnlyIf = null; $this->currentOnlyIfNot = null; $this->previousStoreKey = null; $this->pendingStoreKey = empty($this->storeKeysStack) ? null : end($this->storeKeysStack); if ($this->branchPruningEnabled) { $this->initialiseCondition(); $this->initialiseThen(); $this->initialiseElse(); } } private function initialiseCondition(): void { if (isset($this->conditionMap[$this->pendingStoreKey]) && $this->conditionMap[$this->pendingStoreKey]) { $this->currentCondition = $this->pendingStoreKey; $stackDepth = count($this->storeKeysStack); if ($stackDepth > 1) { // nested if $this->previousStoreKey = $this->storeKeysStack[$stackDepth - 2]; } } } private function initialiseThen(): void { if (isset($this->thenMap[$this->pendingStoreKey]) && $this->thenMap[$this->pendingStoreKey]) { $this->currentOnlyIf = $this->pendingStoreKey; } elseif ( isset($this->previousStoreKey, $this->thenMap[$this->previousStoreKey]) && $this->thenMap[$this->previousStoreKey] ) { $this->currentOnlyIf = $this->previousStoreKey; } } private function initialiseElse(): void { if (isset($this->elseMap[$this->pendingStoreKey]) && $this->elseMap[$this->pendingStoreKey]) { $this->currentOnlyIfNot = $this->pendingStoreKey; } elseif ( isset($this->previousStoreKey, $this->elseMap[$this->previousStoreKey]) && $this->elseMap[$this->previousStoreKey] ) { $this->currentOnlyIfNot = $this->previousStoreKey; } } public function decrementDepth(): void { if (!empty($this->pendingStoreKey)) { --$this->braceDepthMap[$this->pendingStoreKey]; } } public function incrementDepth(): void { if (!empty($this->pendingStoreKey)) { ++$this->braceDepthMap[$this->pendingStoreKey]; } } public function functionCall(string $functionName): void { if ($this->branchPruningEnabled && ($functionName === 'IF(')) { // we handle a new if $this->pendingStoreKey = $this->getUnusedBranchStoreKey(); $this->storeKeysStack[] = $this->pendingStoreKey; $this->conditionMap[$this->pendingStoreKey] = true; $this->braceDepthMap[$this->pendingStoreKey] = 0; } elseif (!empty($this->pendingStoreKey) && array_key_exists($this->pendingStoreKey, $this->braceDepthMap)) { // this is not an if but we go deeper ++$this->braceDepthMap[$this->pendingStoreKey]; } } public function argumentSeparator(): void { if (!empty($this->pendingStoreKey) && $this->braceDepthMap[$this->pendingStoreKey] === 0) { // We must go to the IF next argument if ($this->conditionMap[$this->pendingStoreKey]) { $this->conditionMap[$this->pendingStoreKey] = false; $this->thenMap[$this->pendingStoreKey] = true; } elseif ($this->thenMap[$this->pendingStoreKey]) { $this->thenMap[$this->pendingStoreKey] = false; $this->elseMap[$this->pendingStoreKey] = true; } elseif ($this->elseMap[$this->pendingStoreKey]) { throw new Exception('Reaching fourth argument of an IF'); } } } /** * @param mixed $value */ public function closingBrace($value): void { if (!empty($this->pendingStoreKey) && $this->braceDepthMap[$this->pendingStoreKey] === -1) { // we are closing an IF( if ($value !== 'IF(') { throw new Exception('Parser bug we should be in an "IF("'); } if ($this->conditionMap[$this->pendingStoreKey]) { throw new Exception('We should not be expecting a condition'); } $this->thenMap[$this->pendingStoreKey] = false; $this->elseMap[$this->pendingStoreKey] = false; --$this->braceDepthMap[$this->pendingStoreKey]; array_pop($this->storeKeysStack); $this->pendingStoreKey = null; } } public function currentCondition(): ?string { return $this->currentCondition; } public function currentOnlyIf(): ?string { return $this->currentOnlyIf; } public function currentOnlyIfNot(): ?string { return $this->currentOnlyIfNot; } private function getUnusedBranchStoreKey(): string { $storeKeyValue = 'storeKey-' . $this->branchStoreKeyCounter; ++$this->branchStoreKeyCounter; return $storeKeyValue; } } phpspreadsheet/src/PhpSpreadsheet/Calculation/Engine/CyclicReferenceStack.php 0000644 00000002350 15060132323 0023453 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Calculation\Engine; class CyclicReferenceStack { /** * The call stack for calculated cells. * * @var mixed[] */ private $stack = []; /** * Return the number of entries on the stack. * * @return int */ public function count() { return count($this->stack); } /** * Push a new entry onto the stack. * * @param mixed $value */ public function push($value): void { $this->stack[$value] = $value; } /** * Pop the last entry from the stack. * * @return mixed */ public function pop() { return array_pop($this->stack); } /** * Test to see if a specified entry exists on the stack. * * @param mixed $value The value to test * * @return bool */ public function onStack($value) { return isset($this->stack[$value]); } /** * Clear the stack. */ public function clear(): void { $this->stack = []; } /** * Return an array of all entries on the stack. * * @return mixed[] */ public function showStack() { return $this->stack; } } phpspreadsheet/src/PhpSpreadsheet/Calculation/Engine/ArrayArgumentProcessor.php 0000644 00000014605 15060132323 0024127 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Calculation\Engine; use PhpOffice\PhpSpreadsheet\Calculation\Functions; class ArrayArgumentProcessor { /** * @var ArrayArgumentHelper */ private static $arrayArgumentHelper; /** * @param mixed ...$arguments */ public static function processArguments( ArrayArgumentHelper $arrayArgumentHelper, callable $method, ...$arguments ): array { self::$arrayArgumentHelper = $arrayArgumentHelper; if (self::$arrayArgumentHelper->hasArrayArgument() === false) { return [$method(...$arguments)]; } if (self::$arrayArgumentHelper->arrayArguments() === 1) { $nthArgument = self::$arrayArgumentHelper->getFirstArrayArgumentNumber(); return self::evaluateNthArgumentAsArray($method, $nthArgument, ...$arguments); } $singleRowVectorIndex = self::$arrayArgumentHelper->getSingleRowVector(); $singleColumnVectorIndex = self::$arrayArgumentHelper->getSingleColumnVector(); if ($singleRowVectorIndex !== null && $singleColumnVectorIndex !== null) { // Basic logic for a single row vector and a single column vector return self::evaluateVectorPair($method, $singleRowVectorIndex, $singleColumnVectorIndex, ...$arguments); } $matrixPair = self::$arrayArgumentHelper->getMatrixPair(); if ($matrixPair !== []) { if ( (self::$arrayArgumentHelper->isVector($matrixPair[0]) === true && self::$arrayArgumentHelper->isVector($matrixPair[1]) === false) || (self::$arrayArgumentHelper->isVector($matrixPair[0]) === false && self::$arrayArgumentHelper->isVector($matrixPair[1]) === true) ) { // Logic for a matrix and a vector (row or column) return self::evaluateVectorMatrixPair($method, $matrixPair, ...$arguments); } // Logic for matrix/matrix, column vector/column vector or row vector/row vector return self::evaluateMatrixPair($method, $matrixPair, ...$arguments); } // Still need to work out the logic for more than two array arguments, // For the moment, we're throwing an Exception when we initialise the ArrayArgumentHelper return ['#VALUE!']; } /** * @param mixed ...$arguments */ private static function evaluateVectorMatrixPair(callable $method, array $matrixIndexes, ...$arguments): array { $matrix2 = array_pop($matrixIndexes); /** @var array $matrixValues2 */ $matrixValues2 = $arguments[$matrix2]; $matrix1 = array_pop($matrixIndexes); /** @var array $matrixValues1 */ $matrixValues1 = $arguments[$matrix1]; $rows = min(array_map([self::$arrayArgumentHelper, 'rowCount'], [$matrix1, $matrix2])); $columns = min(array_map([self::$arrayArgumentHelper, 'columnCount'], [$matrix1, $matrix2])); if ($rows === 1) { $rows = max(array_map([self::$arrayArgumentHelper, 'rowCount'], [$matrix1, $matrix2])); } if ($columns === 1) { $columns = max(array_map([self::$arrayArgumentHelper, 'columnCount'], [$matrix1, $matrix2])); } $result = []; for ($rowIndex = 0; $rowIndex < $rows; ++$rowIndex) { for ($columnIndex = 0; $columnIndex < $columns; ++$columnIndex) { $rowIndex1 = self::$arrayArgumentHelper->isRowVector($matrix1) ? 0 : $rowIndex; $columnIndex1 = self::$arrayArgumentHelper->isColumnVector($matrix1) ? 0 : $columnIndex; $value1 = $matrixValues1[$rowIndex1][$columnIndex1]; $rowIndex2 = self::$arrayArgumentHelper->isRowVector($matrix2) ? 0 : $rowIndex; $columnIndex2 = self::$arrayArgumentHelper->isColumnVector($matrix2) ? 0 : $columnIndex; $value2 = $matrixValues2[$rowIndex2][$columnIndex2]; $arguments[$matrix1] = $value1; $arguments[$matrix2] = $value2; $result[$rowIndex][$columnIndex] = $method(...$arguments); } } return $result; } /** * @param mixed ...$arguments */ private static function evaluateMatrixPair(callable $method, array $matrixIndexes, ...$arguments): array { $matrix2 = array_pop($matrixIndexes); /** @var array $matrixValues2 */ $matrixValues2 = $arguments[$matrix2]; $matrix1 = array_pop($matrixIndexes); /** @var array $matrixValues1 */ $matrixValues1 = $arguments[$matrix1]; $result = []; foreach ($matrixValues1 as $rowIndex => $row) { foreach ($row as $columnIndex => $value1) { if (isset($matrixValues2[$rowIndex][$columnIndex]) === false) { continue; } $value2 = $matrixValues2[$rowIndex][$columnIndex]; $arguments[$matrix1] = $value1; $arguments[$matrix2] = $value2; $result[$rowIndex][$columnIndex] = $method(...$arguments); } } return $result; } /** * @param mixed ...$arguments */ private static function evaluateVectorPair(callable $method, int $rowIndex, int $columnIndex, ...$arguments): array { $rowVector = Functions::flattenArray($arguments[$rowIndex]); $columnVector = Functions::flattenArray($arguments[$columnIndex]); $result = []; foreach ($columnVector as $column) { $rowResults = []; foreach ($rowVector as $row) { $arguments[$rowIndex] = $row; $arguments[$columnIndex] = $column; $rowResults[] = $method(...$arguments); } $result[] = $rowResults; } return $result; } /** * Note, offset is from 1 (for the first argument) rather than from 0. * * @param mixed ...$arguments */ private static function evaluateNthArgumentAsArray(callable $method, int $nthArgument, ...$arguments): array { $values = array_slice($arguments, $nthArgument - 1, 1); /** @var array $values */ $values = array_pop($values); $result = []; foreach ($values as $value) { $arguments[$nthArgument - 1] = $value; $result[] = $method(...$arguments); } return $result; } } phpspreadsheet/src/PhpSpreadsheet/Calculation/Engine/Operands/Operand.php 0000644 00000000336 15060132323 0022605 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Calculation\Engine\Operands; interface Operand { public static function fromParser(string $formula, int $index, array $matches): self; public function value(): string; } phpspreadsheet/src/PhpSpreadsheet/Calculation/Engine/Operands/StructuredReference.php 0000644 00000027602 15060132323 0025205 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Calculation\Engine\Operands; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Exception; use PhpOffice\PhpSpreadsheet\Cell\Cell; use PhpOffice\PhpSpreadsheet\Cell\Coordinate; use PhpOffice\PhpSpreadsheet\Worksheet\Table; final class StructuredReference implements Operand { public const NAME = 'Structured Reference'; private const OPEN_BRACE = '['; private const CLOSE_BRACE = ']'; private const ITEM_SPECIFIER_ALL = '#All'; private const ITEM_SPECIFIER_HEADERS = '#Headers'; private const ITEM_SPECIFIER_DATA = '#Data'; private const ITEM_SPECIFIER_TOTALS = '#Totals'; private const ITEM_SPECIFIER_THIS_ROW = '#This Row'; private const ITEM_SPECIFIER_ROWS_SET = [ self::ITEM_SPECIFIER_ALL, self::ITEM_SPECIFIER_HEADERS, self::ITEM_SPECIFIER_DATA, self::ITEM_SPECIFIER_TOTALS, ]; private const TABLE_REFERENCE = '/([\p{L}_\\\\][\p{L}\p{N}\._]+)?(\[(?:[^\]\[]+|(?R))*+\])/miu'; private string $value; private string $tableName; private Table $table; private string $reference; private ?int $headersRow; private int $firstDataRow; private int $lastDataRow; private ?int $totalsRow; private array $columns; public function __construct(string $structuredReference) { $this->value = $structuredReference; } public static function fromParser(string $formula, int $index, array $matches): self { $val = $matches[0]; $srCount = substr_count($val, self::OPEN_BRACE) - substr_count($val, self::CLOSE_BRACE); while ($srCount > 0) { $srIndex = strlen($val); $srStringRemainder = substr($formula, $index + $srIndex); $closingPos = strpos($srStringRemainder, self::CLOSE_BRACE); if ($closingPos === false) { throw new Exception("Formula Error: No closing ']' to match opening '['"); } $srStringRemainder = substr($srStringRemainder, 0, $closingPos + 1); --$srCount; if (strpos($srStringRemainder, self::OPEN_BRACE) !== false) { ++$srCount; } $val .= $srStringRemainder; } return new self($val); } /** * @throws Exception * @throws \PhpOffice\PhpSpreadsheet\Exception */ public function parse(Cell $cell): string { $this->getTableStructure($cell); $cellRange = ($this->isRowReference()) ? $this->getRowReference($cell) : $this->getColumnReference(); return $cellRange; } private function isRowReference(): bool { return strpos($this->value, '[@') !== false || strpos($this->value, '[' . self::ITEM_SPECIFIER_THIS_ROW . ']') !== false; } /** * @throws Exception * @throws \PhpOffice\PhpSpreadsheet\Exception */ private function getTableStructure(Cell $cell): void { preg_match(self::TABLE_REFERENCE, $this->value, $matches); $this->tableName = $matches[1]; $this->table = ($this->tableName === '') ? $this->getTableForCell($cell) : $this->getTableByName($cell); $this->reference = $matches[2]; $tableRange = Coordinate::getRangeBoundaries($this->table->getRange()); $this->headersRow = ($this->table->getShowHeaderRow()) ? (int) $tableRange[0][1] : null; $this->firstDataRow = ($this->table->getShowHeaderRow()) ? (int) $tableRange[0][1] + 1 : $tableRange[0][1]; $this->totalsRow = ($this->table->getShowTotalsRow()) ? (int) $tableRange[1][1] : null; $this->lastDataRow = ($this->table->getShowTotalsRow()) ? (int) $tableRange[1][1] - 1 : $tableRange[1][1]; $this->columns = $this->getColumns($cell, $tableRange); } /** * @throws Exception * @throws \PhpOffice\PhpSpreadsheet\Exception */ private function getTableForCell(Cell $cell): Table { $tables = $cell->getWorksheet()->getTableCollection(); foreach ($tables as $table) { /** @var Table $table */ $range = $table->getRange(); if ($cell->isInRange($range) === true) { $this->tableName = $table->getName(); return $table; } } throw new Exception('Table for Structured Reference cannot be identified'); } /** * @throws Exception * @throws \PhpOffice\PhpSpreadsheet\Exception */ private function getTableByName(Cell $cell): Table { $table = $cell->getWorksheet()->getTableByName($this->tableName); if ($table === null) { throw new Exception("Table {$this->tableName} for Structured Reference cannot be located"); } return $table; } private function getColumns(Cell $cell, array $tableRange): array { $worksheet = $cell->getWorksheet(); $cellReference = $cell->getCoordinate(); $columns = []; $lastColumn = ++$tableRange[1][0]; for ($column = $tableRange[0][0]; $column !== $lastColumn; ++$column) { $columns[$column] = $worksheet ->getCell($column . ($this->headersRow ?? ($this->firstDataRow - 1))) ->getCalculatedValue(); } $worksheet->getCell($cellReference); return $columns; } private function getRowReference(Cell $cell): string { $reference = str_replace("\u{a0}", ' ', $this->reference); /** @var string $reference */ $reference = str_replace('[' . self::ITEM_SPECIFIER_THIS_ROW . '],', '', $reference); foreach ($this->columns as $columnId => $columnName) { $columnName = str_replace("\u{a0}", ' ', $columnName); $reference = $this->adjustRowReference($columnName, $reference, $cell, $columnId); } /** @var string $reference */ return $this->validateParsedReference(trim($reference, '[]@, ')); } private function adjustRowReference(string $columnName, string $reference, Cell $cell, string $columnId): string { if ($columnName !== '') { $cellReference = $columnId . $cell->getRow(); $pattern1 = '/\[' . preg_quote($columnName, '/') . '\]/miu'; $pattern2 = '/@' . preg_quote($columnName, '/') . '/miu'; if (preg_match($pattern1, $reference) === 1) { $reference = preg_replace($pattern1, $cellReference, $reference); } elseif (preg_match($pattern2, $reference) === 1) { $reference = preg_replace($pattern2, $cellReference, $reference); } /** @var string $reference */ } return $reference; } /** * @throws Exception * @throws \PhpOffice\PhpSpreadsheet\Exception */ private function getColumnReference(): string { $reference = str_replace("\u{a0}", ' ', $this->reference); $startRow = ($this->totalsRow === null) ? $this->lastDataRow : $this->totalsRow; $endRow = ($this->headersRow === null) ? $this->firstDataRow : $this->headersRow; [$startRow, $endRow] = $this->getRowsForColumnReference($reference, $startRow, $endRow); $reference = $this->getColumnsForColumnReference($reference, $startRow, $endRow); $reference = trim($reference, '[]@, '); if (substr_count($reference, ':') > 1) { $cells = explode(':', $reference); $firstCell = array_shift($cells); $lastCell = array_pop($cells); $reference = "{$firstCell}:{$lastCell}"; } return $this->validateParsedReference($reference); } /** * @throws Exception * @throws \PhpOffice\PhpSpreadsheet\Exception */ private function validateParsedReference(string $reference): string { if (preg_match('/^' . Calculation::CALCULATION_REGEXP_CELLREF . ':' . Calculation::CALCULATION_REGEXP_CELLREF . '$/miu', $reference) !== 1) { if (preg_match('/^' . Calculation::CALCULATION_REGEXP_CELLREF . '$/miu', $reference) !== 1) { throw new Exception( "Invalid Structured Reference {$this->reference} {$reference}", Exception::CALCULATION_ENGINE_PUSH_TO_STACK ); } } return $reference; } private function fullData(int $startRow, int $endRow): string { $columns = array_keys($this->columns); $firstColumn = array_shift($columns); $lastColumn = (empty($columns)) ? $firstColumn : array_pop($columns); return "{$firstColumn}{$startRow}:{$lastColumn}{$endRow}"; } private function getMinimumRow(string $reference): int { switch ($reference) { case self::ITEM_SPECIFIER_ALL: case self::ITEM_SPECIFIER_HEADERS: return $this->headersRow ?? $this->firstDataRow; case self::ITEM_SPECIFIER_DATA: return $this->firstDataRow; case self::ITEM_SPECIFIER_TOTALS: return $this->totalsRow ?? $this->lastDataRow; } return $this->headersRow ?? $this->firstDataRow; } private function getMaximumRow(string $reference): int { switch ($reference) { case self::ITEM_SPECIFIER_HEADERS: return $this->headersRow ?? $this->firstDataRow; case self::ITEM_SPECIFIER_DATA: return $this->lastDataRow; case self::ITEM_SPECIFIER_ALL: case self::ITEM_SPECIFIER_TOTALS: return $this->totalsRow ?? $this->lastDataRow; } return $this->totalsRow ?? $this->lastDataRow; } public function value(): string { return $this->value; } /** * @return array<int, int> */ private function getRowsForColumnReference(string &$reference, int $startRow, int $endRow): array { $rowsSelected = false; foreach (self::ITEM_SPECIFIER_ROWS_SET as $rowReference) { $pattern = '/\[' . $rowReference . '\]/mui'; /** @var string $reference */ if (preg_match($pattern, $reference) === 1) { if (($rowReference === self::ITEM_SPECIFIER_HEADERS) && ($this->table->getShowHeaderRow() === false)) { throw new Exception( 'Table Headers are Hidden, and should not be Referenced', Exception::CALCULATION_ENGINE_PUSH_TO_STACK ); } $rowsSelected = true; $startRow = min($startRow, $this->getMinimumRow($rowReference)); $endRow = max($endRow, $this->getMaximumRow($rowReference)); $reference = preg_replace($pattern, '', $reference); } } if ($rowsSelected === false) { // If there isn't any Special Item Identifier specified, then the selection defaults to data rows only. $startRow = $this->firstDataRow; $endRow = $this->lastDataRow; } return [$startRow, $endRow]; } private function getColumnsForColumnReference(string $reference, int $startRow, int $endRow): string { $columnsSelected = false; foreach ($this->columns as $columnId => $columnName) { $columnName = str_replace("\u{a0}", ' ', $columnName); $cellFrom = "{$columnId}{$startRow}"; $cellTo = "{$columnId}{$endRow}"; $cellReference = ($cellFrom === $cellTo) ? $cellFrom : "{$cellFrom}:{$cellTo}"; $pattern = '/\[' . preg_quote($columnName, '/') . '\]/mui'; if (preg_match($pattern, $reference) === 1) { $columnsSelected = true; $reference = preg_replace($pattern, $cellReference, $reference); } /** @var string $reference */ } if ($columnsSelected === false) { return $this->fullData($startRow, $endRow); } return $reference; } } phpspreadsheet/src/PhpSpreadsheet/Calculation/Engine/ArrayArgumentHelper.php 0000644 00000012325 15060132323 0023364 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Calculation\Engine; use PhpOffice\PhpSpreadsheet\Calculation\Exception; class ArrayArgumentHelper { /** * @var int */ protected $indexStart = 0; /** * @var array */ protected $arguments; /** * @var int */ protected $argumentCount; /** * @var array */ protected $rows; /** * @var array */ protected $columns; public function initialise(array $arguments): void { $keys = array_keys($arguments); $this->indexStart = (int) array_shift($keys); $this->rows = $this->rows($arguments); $this->columns = $this->columns($arguments); $this->argumentCount = count($arguments); $this->arguments = $this->flattenSingleCellArrays($arguments, $this->rows, $this->columns); $this->rows = $this->rows($arguments); $this->columns = $this->columns($arguments); if ($this->arrayArguments() > 2) { throw new Exception('Formulae with more than two array arguments are not supported'); } } public function arguments(): array { return $this->arguments; } public function hasArrayArgument(): bool { return $this->arrayArguments() > 0; } public function getFirstArrayArgumentNumber(): int { $rowArrays = $this->filterArray($this->rows); $columnArrays = $this->filterArray($this->columns); for ($index = $this->indexStart; $index < $this->argumentCount; ++$index) { if (isset($rowArrays[$index]) || isset($columnArrays[$index])) { return ++$index; } } return 0; } public function getSingleRowVector(): ?int { $rowVectors = $this->getRowVectors(); return count($rowVectors) === 1 ? array_pop($rowVectors) : null; } private function getRowVectors(): array { $rowVectors = []; for ($index = $this->indexStart; $index < ($this->indexStart + $this->argumentCount); ++$index) { if ($this->rows[$index] === 1 && $this->columns[$index] > 1) { $rowVectors[] = $index; } } return $rowVectors; } public function getSingleColumnVector(): ?int { $columnVectors = $this->getColumnVectors(); return count($columnVectors) === 1 ? array_pop($columnVectors) : null; } private function getColumnVectors(): array { $columnVectors = []; for ($index = $this->indexStart; $index < ($this->indexStart + $this->argumentCount); ++$index) { if ($this->rows[$index] > 1 && $this->columns[$index] === 1) { $columnVectors[] = $index; } } return $columnVectors; } public function getMatrixPair(): array { for ($i = $this->indexStart; $i < ($this->indexStart + $this->argumentCount - 1); ++$i) { for ($j = $i + 1; $j < $this->argumentCount; ++$j) { if (isset($this->rows[$i], $this->rows[$j])) { return [$i, $j]; } } } return []; } public function isVector(int $argument): bool { return $this->rows[$argument] === 1 || $this->columns[$argument] === 1; } public function isRowVector(int $argument): bool { return $this->rows[$argument] === 1; } public function isColumnVector(int $argument): bool { return $this->columns[$argument] === 1; } public function rowCount(int $argument): int { return $this->rows[$argument]; } public function columnCount(int $argument): int { return $this->columns[$argument]; } private function rows(array $arguments): array { return array_map( function ($argument) { return is_countable($argument) ? count($argument) : 1; }, $arguments ); } private function columns(array $arguments): array { return array_map( function ($argument) { return is_array($argument) && is_array($argument[array_keys($argument)[0]]) ? count($argument[array_keys($argument)[0]]) : 1; }, $arguments ); } public function arrayArguments(): int { $count = 0; foreach (array_keys($this->arguments) as $argument) { if ($this->rows[$argument] > 1 || $this->columns[$argument] > 1) { ++$count; } } return $count; } private function flattenSingleCellArrays(array $arguments, array $rows, array $columns): array { foreach ($arguments as $index => $argument) { if ($rows[$index] === 1 && $columns[$index] === 1) { while (is_array($argument)) { $argument = array_pop($argument); } $arguments[$index] = $argument; } } return $arguments; } private function filterArray(array $array): array { return array_filter( $array, function ($value) { return $value > 1; } ); } } phpspreadsheet/src/PhpSpreadsheet/Calculation/TextData/Replace.php 0000644 00000011463 15060132323 0021331 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Calculation\TextData; use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled; use PhpOffice\PhpSpreadsheet\Calculation\Exception as CalcExp; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; use PhpOffice\PhpSpreadsheet\Cell\DataType; use PhpOffice\PhpSpreadsheet\Shared\StringHelper; class Replace { use ArrayEnabled; /** * REPLACE. * * @param mixed $oldText The text string value to modify * Or can be an array of values * @param mixed $start Integer offset for start character of the replacement * Or can be an array of values * @param mixed $chars Integer number of characters to replace from the start offset * Or can be an array of values * @param mixed $newText String to replace in the defined position * Or can be an array of values * * @return array|string * If an array of values is passed for either of the arguments, then the returned result * will also be an array with matching dimensions */ public static function replace($oldText, $start, $chars, $newText) { if (is_array($oldText) || is_array($start) || is_array($chars) || is_array($newText)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $oldText, $start, $chars, $newText); } try { $start = Helpers::extractInt($start, 1, 0, true); $chars = Helpers::extractInt($chars, 0, 0, true); $oldText = Helpers::extractString($oldText, true); $newText = Helpers::extractString($newText, true); $left = StringHelper::substring($oldText, 0, $start - 1); $right = StringHelper::substring($oldText, $start + $chars - 1, null); } catch (CalcExp $e) { return $e->getMessage(); } $returnValue = $left . $newText . $right; if (StringHelper::countCharacters($returnValue) > DataType::MAX_STRING_LENGTH) { $returnValue = ExcelError::VALUE(); } return $returnValue; } /** * SUBSTITUTE. * * @param mixed $text The text string value to modify * Or can be an array of values * @param mixed $fromText The string value that we want to replace in $text * Or can be an array of values * @param mixed $toText The string value that we want to replace with in $text * Or can be an array of values * @param mixed $instance Integer instance Number for the occurrence of frmText to change * Or can be an array of values * * @return array|string * If an array of values is passed for either of the arguments, then the returned result * will also be an array with matching dimensions */ public static function substitute($text = '', $fromText = '', $toText = '', $instance = null) { if (is_array($text) || is_array($fromText) || is_array($toText) || is_array($instance)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $text, $fromText, $toText, $instance); } try { $text = Helpers::extractString($text, true); $fromText = Helpers::extractString($fromText, true); $toText = Helpers::extractString($toText, true); if ($instance === null) { $returnValue = str_replace($fromText, $toText, $text); } else { if (is_bool($instance)) { if ($instance === false || Functions::getCompatibilityMode() !== Functions::COMPATIBILITY_OPENOFFICE) { return ExcelError::Value(); } $instance = 1; } $instance = Helpers::extractInt($instance, 1, 0, true); $returnValue = self::executeSubstitution($text, $fromText, $toText, $instance); } } catch (CalcExp $e) { return $e->getMessage(); } if (StringHelper::countCharacters($returnValue) > DataType::MAX_STRING_LENGTH) { $returnValue = ExcelError::VALUE(); } return $returnValue; } private static function executeSubstitution(string $text, string $fromText, string $toText, int $instance): string { $pos = -1; while ($instance > 0) { $pos = mb_strpos($text, $fromText, $pos + 1, 'UTF-8'); if ($pos === false) { return $text; } --$instance; } return Functions::scalar(self::REPLACE($text, ++$pos, StringHelper::countCharacters($fromText), $toText)); } } phpspreadsheet/src/PhpSpreadsheet/Calculation/TextData/Text.php 0000644 00000021216 15060132323 0020677 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Calculation\TextData; use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Calculation\Information\ErrorValue; class Text { use ArrayEnabled; /** * LEN. * * @param mixed $value String Value * Or can be an array of values * * @return array|int * If an array of values is passed for the argument, then the returned result * will also be an array with matching dimensions */ public static function length($value = '') { if (is_array($value)) { return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $value); } $value = Helpers::extractString($value); return mb_strlen($value, 'UTF-8'); } /** * Compares two text strings and returns TRUE if they are exactly the same, FALSE otherwise. * EXACT is case-sensitive but ignores formatting differences. * Use EXACT to test text being entered into a document. * * @param mixed $value1 String Value * Or can be an array of values * @param mixed $value2 String Value * Or can be an array of values * * @return array|bool * If an array of values is passed for either of the arguments, then the returned result * will also be an array with matching dimensions */ public static function exact($value1, $value2) { if (is_array($value1) || is_array($value2)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $value1, $value2); } $value1 = Helpers::extractString($value1); $value2 = Helpers::extractString($value2); return $value2 === $value1; } /** * T. * * @param mixed $testValue Value to check * Or can be an array of values * * @return array|string * If an array of values is passed for the argument, then the returned result * will also be an array with matching dimensions */ public static function test($testValue = '') { if (is_array($testValue)) { return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $testValue); } if (is_string($testValue)) { return $testValue; } return ''; } /** * TEXTSPLIT. * * @param mixed $text the text that you're searching * @param null|array|string $columnDelimiter The text that marks the point where to spill the text across columns. * Multiple delimiters can be passed as an array of string values * @param null|array|string $rowDelimiter The text that marks the point where to spill the text down rows. * Multiple delimiters can be passed as an array of string values * @param bool $ignoreEmpty Specify FALSE to create an empty cell when two delimiters are consecutive. * true = create empty cells * false = skip empty cells * Defaults to TRUE, which creates an empty cell * @param bool $matchMode Determines whether the match is case-sensitive or not. * true = case-sensitive * false = case-insensitive * By default, a case-sensitive match is done. * @param mixed $padding The value with which to pad the result. * The default is #N/A. * * @return array the array built from the text, split by the row and column delimiters */ public static function split($text, $columnDelimiter = null, $rowDelimiter = null, bool $ignoreEmpty = false, bool $matchMode = true, $padding = '#N/A') { $text = Functions::flattenSingleValue($text); $flags = self::matchFlags($matchMode); if ($rowDelimiter !== null) { $delimiter = self::buildDelimiter($rowDelimiter); $rows = ($delimiter === '()') ? [$text] : preg_split("/{$delimiter}/{$flags}", $text); } else { $rows = [$text]; } /** @var array $rows */ if ($ignoreEmpty === true) { $rows = array_values(array_filter( $rows, function ($row) { return $row !== ''; } )); } if ($columnDelimiter !== null) { $delimiter = self::buildDelimiter($columnDelimiter); array_walk( $rows, function (&$row) use ($delimiter, $flags, $ignoreEmpty): void { $row = ($delimiter === '()') ? [$row] : preg_split("/{$delimiter}/{$flags}", $row); /** @var array $row */ if ($ignoreEmpty === true) { $row = array_values(array_filter( $row, function ($value) { return $value !== ''; } )); } } ); if ($ignoreEmpty === true) { $rows = array_values(array_filter( $rows, function ($row) { return $row !== [] && $row !== ['']; } )); } } return self::applyPadding($rows, $padding); } /** * @param mixed $padding */ private static function applyPadding(array $rows, $padding): array { $columnCount = array_reduce( $rows, function (int $counter, array $row): int { return max($counter, count($row)); }, 0 ); return array_map( function (array $row) use ($columnCount, $padding): array { return (count($row) < $columnCount) ? array_merge($row, array_fill(0, $columnCount - count($row), $padding)) : $row; }, $rows ); } /** * @param null|array|string $delimiter the text that marks the point before which you want to split * Multiple delimiters can be passed as an array of string values */ private static function buildDelimiter($delimiter): string { $valueSet = Functions::flattenArray($delimiter); if (is_array($delimiter) && count($valueSet) > 1) { $quotedDelimiters = array_map( function ($delimiter) { return preg_quote($delimiter ?? '', '/'); }, $valueSet ); $delimiters = implode('|', $quotedDelimiters); return '(' . $delimiters . ')'; } return '(' . preg_quote(/** @scrutinizer ignore-type */ Functions::flattenSingleValue($delimiter), '/') . ')'; } private static function matchFlags(bool $matchMode): string { return ($matchMode === true) ? 'miu' : 'mu'; } public static function fromArray(array $array, int $format = 0): string { $result = []; foreach ($array as $row) { $cells = []; foreach ($row as $cellValue) { $value = ($format === 1) ? self::formatValueMode1($cellValue) : self::formatValueMode0($cellValue); $cells[] = $value; } $result[] = implode(($format === 1) ? ',' : ', ', $cells); } $result = implode(($format === 1) ? ';' : ', ', $result); return ($format === 1) ? '{' . $result . '}' : $result; } /** * @param mixed $cellValue */ private static function formatValueMode0($cellValue): string { if (is_bool($cellValue)) { return Calculation::getLocaleBoolean($cellValue ? 'TRUE' : 'FALSE'); } return (string) $cellValue; } /** * @param mixed $cellValue */ private static function formatValueMode1($cellValue): string { if (is_string($cellValue) && ErrorValue::isError($cellValue) === false) { return Calculation::FORMULA_STRING_QUOTE . $cellValue . Calculation::FORMULA_STRING_QUOTE; } elseif (is_bool($cellValue)) { return Calculation::getLocaleBoolean($cellValue ? 'TRUE' : 'FALSE'); } return (string) $cellValue; } } phpspreadsheet/src/PhpSpreadsheet/Calculation/TextData/Search.php 0000644 00000007055 15060132323 0021165 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Calculation\TextData; use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled; use PhpOffice\PhpSpreadsheet\Calculation\Exception as CalcExp; use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; use PhpOffice\PhpSpreadsheet\Shared\StringHelper; class Search { use ArrayEnabled; /** * FIND (case sensitive search). * * @param mixed $needle The string to look for * Or can be an array of values * @param mixed $haystack The string in which to look * Or can be an array of values * @param mixed $offset Integer offset within $haystack to start searching from * Or can be an array of values * * @return array|int|string The offset where the first occurrence of needle was found in the haystack * If an array of values is passed for the $value or $chars arguments, then the returned result * will also be an array with matching dimensions */ public static function sensitive($needle, $haystack, $offset = 1) { if (is_array($needle) || is_array($haystack) || is_array($offset)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $needle, $haystack, $offset); } try { $needle = Helpers::extractString($needle); $haystack = Helpers::extractString($haystack); $offset = Helpers::extractInt($offset, 1, 0, true); } catch (CalcExp $e) { return $e->getMessage(); } if (StringHelper::countCharacters($haystack) >= $offset) { if (StringHelper::countCharacters($needle) === 0) { return $offset; } $pos = mb_strpos($haystack, $needle, --$offset, 'UTF-8'); if ($pos !== false) { return ++$pos; } } return ExcelError::VALUE(); } /** * SEARCH (case insensitive search). * * @param mixed $needle The string to look for * Or can be an array of values * @param mixed $haystack The string in which to look * Or can be an array of values * @param mixed $offset Integer offset within $haystack to start searching from * Or can be an array of values * * @return array|int|string The offset where the first occurrence of needle was found in the haystack * If an array of values is passed for the $value or $chars arguments, then the returned result * will also be an array with matching dimensions */ public static function insensitive($needle, $haystack, $offset = 1) { if (is_array($needle) || is_array($haystack) || is_array($offset)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $needle, $haystack, $offset); } try { $needle = Helpers::extractString($needle); $haystack = Helpers::extractString($haystack); $offset = Helpers::extractInt($offset, 1, 0, true); } catch (CalcExp $e) { return $e->getMessage(); } if (StringHelper::countCharacters($haystack) >= $offset) { if (StringHelper::countCharacters($needle) === 0) { return $offset; } $pos = mb_stripos($haystack, $needle, --$offset, 'UTF-8'); if ($pos !== false) { return ++$pos; } } return ExcelError::VALUE(); } } phpspreadsheet/src/PhpSpreadsheet/Calculation/TextData/Trim.php 0000644 00000003036 15060132323 0020666 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Calculation\TextData; use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled; class Trim { use ArrayEnabled; /** * CLEAN. * * @param mixed $stringValue String Value to check * Or can be an array of values * * @return array|string * If an array of values is passed as the argument, then the returned result will also be an array * with the same dimensions */ public static function nonPrintable($stringValue = '') { if (is_array($stringValue)) { return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $stringValue); } $stringValue = Helpers::extractString($stringValue); return (string) preg_replace('/[\\x00-\\x1f]/', '', "$stringValue"); } /** * TRIM. * * @param mixed $stringValue String Value to check * Or can be an array of values * * @return array|string * If an array of values is passed as the argument, then the returned result will also be an array * with the same dimensions */ public static function spaces($stringValue = '') { if (is_array($stringValue)) { return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $stringValue); } $stringValue = Helpers::extractString($stringValue); return trim(preg_replace('/ +/', ' ', trim("$stringValue", ' ')) ?? '', ' '); } } phpspreadsheet/src/PhpSpreadsheet/Calculation/TextData/Extract.php 0000644 00000027566 15060132323 0021403 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Calculation\TextData; use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled; use PhpOffice\PhpSpreadsheet\Calculation\Exception as CalcExp; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; use PhpOffice\PhpSpreadsheet\Shared\StringHelper; class Extract { use ArrayEnabled; /** * LEFT. * * @param mixed $value String value from which to extract characters * Or can be an array of values * @param mixed $chars The number of characters to extract (as an integer) * Or can be an array of values * * @return array|string The joined string * If an array of values is passed for the $value or $chars arguments, then the returned result * will also be an array with matching dimensions */ public static function left($value, $chars = 1) { if (is_array($value) || is_array($chars)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $value, $chars); } try { $value = Helpers::extractString($value); $chars = Helpers::extractInt($chars, 0, 1); } catch (CalcExp $e) { return $e->getMessage(); } return mb_substr($value, 0, $chars, 'UTF-8'); } /** * MID. * * @param mixed $value String value from which to extract characters * Or can be an array of values * @param mixed $start Integer offset of the first character that we want to extract * Or can be an array of values * @param mixed $chars The number of characters to extract (as an integer) * Or can be an array of values * * @return array|string The joined string * If an array of values is passed for the $value, $start or $chars arguments, then the returned result * will also be an array with matching dimensions */ public static function mid($value, $start, $chars) { if (is_array($value) || is_array($start) || is_array($chars)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $value, $start, $chars); } try { $value = Helpers::extractString($value); $start = Helpers::extractInt($start, 1); $chars = Helpers::extractInt($chars, 0); } catch (CalcExp $e) { return $e->getMessage(); } return mb_substr($value, --$start, $chars, 'UTF-8'); } /** * RIGHT. * * @param mixed $value String value from which to extract characters * Or can be an array of values * @param mixed $chars The number of characters to extract (as an integer) * Or can be an array of values * * @return array|string The joined string * If an array of values is passed for the $value or $chars arguments, then the returned result * will also be an array with matching dimensions */ public static function right($value, $chars = 1) { if (is_array($value) || is_array($chars)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $value, $chars); } try { $value = Helpers::extractString($value); $chars = Helpers::extractInt($chars, 0, 1); } catch (CalcExp $e) { return $e->getMessage(); } return mb_substr($value, mb_strlen($value, 'UTF-8') - $chars, $chars, 'UTF-8'); } /** * TEXTBEFORE. * * @param mixed $text the text that you're searching * Or can be an array of values * @param null|array|string $delimiter the text that marks the point before which you want to extract * Multiple delimiters can be passed as an array of string values * @param mixed $instance The instance of the delimiter after which you want to extract the text. * By default, this is the first instance (1). * A negative value means start searching from the end of the text string. * Or can be an array of values * @param mixed $matchMode Determines whether the match is case-sensitive or not. * 0 - Case-sensitive * 1 - Case-insensitive * Or can be an array of values * @param mixed $matchEnd Treats the end of text as a delimiter. * 0 - Don't match the delimiter against the end of the text. * 1 - Match the delimiter against the end of the text. * Or can be an array of values * @param mixed $ifNotFound value to return if no match is found * The default is a #N/A Error * Or can be an array of values * * @return mixed|mixed[] the string extracted from text before the delimiter; or the $ifNotFound value * If an array of values is passed for any of the arguments, then the returned result * will also be an array with matching dimensions */ public static function before($text, $delimiter, $instance = 1, $matchMode = 0, $matchEnd = 0, $ifNotFound = '#N/A') { if (is_array($text) || is_array($instance) || is_array($matchMode) || is_array($matchEnd) || is_array($ifNotFound)) { return self::evaluateArrayArgumentsIgnore([self::class, __FUNCTION__], 1, $text, $delimiter, $instance, $matchMode, $matchEnd, $ifNotFound); } $text = Helpers::extractString($text ?? ''); $instance = (int) $instance; $matchMode = (int) $matchMode; $matchEnd = (int) $matchEnd; $split = self::validateTextBeforeAfter($text, $delimiter, $instance, $matchMode, $matchEnd, $ifNotFound); if (is_string($split)) { return $split; } if (Helpers::extractString(Functions::flattenSingleValue($delimiter ?? '')) === '') { return ($instance > 0) ? '' : $text; } // Adjustment for a match as the first element of the split $flags = self::matchFlags($matchMode); $delimiter = self::buildDelimiter($delimiter); $adjust = preg_match('/^' . $delimiter . "\$/{$flags}", $split[0]); $oddReverseAdjustment = count($split) % 2; $split = ($instance < 0) ? array_slice($split, 0, max(count($split) - (abs($instance) * 2 - 1) - $adjust - $oddReverseAdjustment, 0)) : array_slice($split, 0, $instance * 2 - 1 - $adjust); return implode('', $split); } /** * TEXTAFTER. * * @param mixed $text the text that you're searching * @param null|array|string $delimiter the text that marks the point before which you want to extract * Multiple delimiters can be passed as an array of string values * @param mixed $instance The instance of the delimiter after which you want to extract the text. * By default, this is the first instance (1). * A negative value means start searching from the end of the text string. * Or can be an array of values * @param mixed $matchMode Determines whether the match is case-sensitive or not. * 0 - Case-sensitive * 1 - Case-insensitive * Or can be an array of values * @param mixed $matchEnd Treats the end of text as a delimiter. * 0 - Don't match the delimiter against the end of the text. * 1 - Match the delimiter against the end of the text. * Or can be an array of values * @param mixed $ifNotFound value to return if no match is found * The default is a #N/A Error * Or can be an array of values * * @return mixed|mixed[] the string extracted from text before the delimiter; or the $ifNotFound value * If an array of values is passed for any of the arguments, then the returned result * will also be an array with matching dimensions */ public static function after($text, $delimiter, $instance = 1, $matchMode = 0, $matchEnd = 0, $ifNotFound = '#N/A') { if (is_array($text) || is_array($instance) || is_array($matchMode) || is_array($matchEnd) || is_array($ifNotFound)) { return self::evaluateArrayArgumentsIgnore([self::class, __FUNCTION__], 1, $text, $delimiter, $instance, $matchMode, $matchEnd, $ifNotFound); } $text = Helpers::extractString($text ?? ''); $instance = (int) $instance; $matchMode = (int) $matchMode; $matchEnd = (int) $matchEnd; $split = self::validateTextBeforeAfter($text, $delimiter, $instance, $matchMode, $matchEnd, $ifNotFound); if (is_string($split)) { return $split; } if (Helpers::extractString(Functions::flattenSingleValue($delimiter ?? '')) === '') { return ($instance < 0) ? '' : $text; } // Adjustment for a match as the first element of the split $flags = self::matchFlags($matchMode); $delimiter = self::buildDelimiter($delimiter); $adjust = preg_match('/^' . $delimiter . "\$/{$flags}", $split[0]); $oddReverseAdjustment = count($split) % 2; $split = ($instance < 0) ? array_slice($split, count($split) - ((int) abs($instance + 1) * 2) - $adjust - $oddReverseAdjustment) : array_slice($split, $instance * 2 - $adjust); return implode('', $split); } /** * @param null|array|string $delimiter * @param int $matchMode * @param int $matchEnd * @param mixed $ifNotFound * * @return array|string */ private static function validateTextBeforeAfter(string $text, $delimiter, int $instance, $matchMode, $matchEnd, $ifNotFound) { $flags = self::matchFlags($matchMode); $delimiter = self::buildDelimiter($delimiter); if (preg_match('/' . $delimiter . "/{$flags}", $text) === 0 && $matchEnd === 0) { return $ifNotFound; } $split = preg_split('/' . $delimiter . "/{$flags}", $text, 0, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE); if ($split === false) { return ExcelError::NA(); } if ($instance === 0 || abs($instance) > StringHelper::countCharacters($text)) { return ExcelError::VALUE(); } if ($matchEnd === 0 && (abs($instance) > floor(count($split) / 2))) { return ExcelError::NA(); } elseif ($matchEnd !== 0 && (abs($instance) - 1 > ceil(count($split) / 2))) { return ExcelError::NA(); } return $split; } /** * @param null|array|string $delimiter the text that marks the point before which you want to extract * Multiple delimiters can be passed as an array of string values */ private static function buildDelimiter($delimiter): string { if (is_array($delimiter)) { $delimiter = Functions::flattenArray($delimiter); $quotedDelimiters = array_map( function ($delimiter) { return preg_quote($delimiter ?? '', '/'); }, $delimiter ); $delimiters = implode('|', $quotedDelimiters); return '(' . $delimiters . ')'; } return '(' . preg_quote($delimiter ?? '', '/') . ')'; } private static function matchFlags(int $matchMode): string { return ($matchMode === 0) ? 'mu' : 'miu'; } } phpspreadsheet/src/PhpSpreadsheet/Calculation/TextData/Concatenate.php 0000644 00000011041 15060132323 0022172 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Calculation\TextData; use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Calculation\Information\ErrorValue; use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; use PhpOffice\PhpSpreadsheet\Cell\DataType; use PhpOffice\PhpSpreadsheet\Shared\StringHelper; class Concatenate { use ArrayEnabled; /** * CONCATENATE. * * @param array $args */ public static function CONCATENATE(...$args): string { $returnValue = ''; // Loop through arguments $aArgs = Functions::flattenArray($args); foreach ($aArgs as $arg) { $value = Helpers::extractString($arg); if (ErrorValue::isError($value)) { $returnValue = $value; break; } $returnValue .= Helpers::extractString($arg); if (StringHelper::countCharacters($returnValue) > DataType::MAX_STRING_LENGTH) { $returnValue = ExcelError::CALC(); break; } } return $returnValue; } /** * TEXTJOIN. * * @param mixed $delimiter The delimter to use between the joined arguments * Or can be an array of values * @param mixed $ignoreEmpty true/false Flag indicating whether empty arguments should be skipped * Or can be an array of values * @param mixed $args The values to join * * @return array|string The joined string * If an array of values is passed for the $delimiter or $ignoreEmpty arguments, then the returned result * will also be an array with matching dimensions */ public static function TEXTJOIN($delimiter = '', $ignoreEmpty = true, ...$args) { if (is_array($delimiter) || is_array($ignoreEmpty)) { return self::evaluateArrayArgumentsSubset( [self::class, __FUNCTION__], 2, $delimiter, $ignoreEmpty, ...$args ); } $delimiter ??= ''; $ignoreEmpty ??= true; $aArgs = Functions::flattenArray($args); $returnValue = self::evaluateTextJoinArray($ignoreEmpty, $aArgs); $returnValue ??= implode($delimiter, $aArgs); if (StringHelper::countCharacters($returnValue) > DataType::MAX_STRING_LENGTH) { $returnValue = ExcelError::CALC(); } return $returnValue; } private static function evaluateTextJoinArray(bool $ignoreEmpty, array &$aArgs): ?string { foreach ($aArgs as $key => &$arg) { $value = Helpers::extractString($arg); if (ErrorValue::isError($value)) { return $value; } if ($ignoreEmpty === true && ((is_string($arg) && trim($arg) === '') || $arg === null)) { unset($aArgs[$key]); } elseif (is_bool($arg)) { $arg = Helpers::convertBooleanValue($arg); } } return null; } /** * REPT. * * Returns the result of builtin function round after validating args. * * @param mixed $stringValue The value to repeat * Or can be an array of values * @param mixed $repeatCount The number of times the string value should be repeated * Or can be an array of values * * @return array|string The repeated string * If an array of values is passed for the $stringValue or $repeatCount arguments, then the returned result * will also be an array with matching dimensions */ public static function builtinREPT($stringValue, $repeatCount) { if (is_array($stringValue) || is_array($repeatCount)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $stringValue, $repeatCount); } $stringValue = Helpers::extractString($stringValue); if (!is_numeric($repeatCount) || $repeatCount < 0) { $returnValue = ExcelError::VALUE(); } elseif (ErrorValue::isError($stringValue)) { $returnValue = $stringValue; } else { $returnValue = str_repeat($stringValue, (int) $repeatCount); if (StringHelper::countCharacters($returnValue) > DataType::MAX_STRING_LENGTH) { $returnValue = ExcelError::VALUE(); // note VALUE not CALC } } return $returnValue; } } phpspreadsheet/src/PhpSpreadsheet/Calculation/TextData/CaseConvert.php 0000644 00000004740 15060132323 0022172 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Calculation\TextData; use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled; use PhpOffice\PhpSpreadsheet\Shared\StringHelper; class CaseConvert { use ArrayEnabled; /** * LOWERCASE. * * Converts a string value to upper case. * * @param mixed $mixedCaseValue The string value to convert to lower case * Or can be an array of values * * @return array|string * If an array of values is passed as the argument, then the returned result will also be an array * with the same dimensions */ public static function lower($mixedCaseValue) { if (is_array($mixedCaseValue)) { return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $mixedCaseValue); } $mixedCaseValue = Helpers::extractString($mixedCaseValue); return StringHelper::strToLower($mixedCaseValue); } /** * UPPERCASE. * * Converts a string value to upper case. * * @param mixed $mixedCaseValue The string value to convert to upper case * Or can be an array of values * * @return array|string * If an array of values is passed as the argument, then the returned result will also be an array * with the same dimensions */ public static function upper($mixedCaseValue) { if (is_array($mixedCaseValue)) { return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $mixedCaseValue); } $mixedCaseValue = Helpers::extractString($mixedCaseValue); return StringHelper::strToUpper($mixedCaseValue); } /** * PROPERCASE. * * Converts a string value to proper or title case. * * @param mixed $mixedCaseValue The string value to convert to title case * Or can be an array of values * * @return array|string * If an array of values is passed as the argument, then the returned result will also be an array * with the same dimensions */ public static function proper($mixedCaseValue) { if (is_array($mixedCaseValue)) { return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $mixedCaseValue); } $mixedCaseValue = Helpers::extractString($mixedCaseValue); return StringHelper::strToTitle($mixedCaseValue); } } phpspreadsheet/src/PhpSpreadsheet/Calculation/TextData/Helpers.php 0000644 00000005031 15060132323 0021352 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Calculation\TextData; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Exception as CalcExp; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Calculation\Information\ErrorValue; use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; class Helpers { public static function convertBooleanValue(bool $value): string { if (Functions::getCompatibilityMode() == Functions::COMPATIBILITY_OPENOFFICE) { return $value ? '1' : '0'; } return ($value) ? Calculation::getTRUE() : Calculation::getFALSE(); } /** * @param mixed $value String value from which to extract characters */ public static function extractString($value, bool $throwIfError = false): string { if (is_bool($value)) { return self::convertBooleanValue($value); } if ($throwIfError && is_string($value) && ErrorValue::isError($value)) { throw new CalcExp($value); } return (string) $value; } /** * @param mixed $value */ public static function extractInt($value, int $minValue, int $gnumericNull = 0, bool $ooBoolOk = false): int { if ($value === null) { // usually 0, but sometimes 1 for Gnumeric $value = (Functions::getCompatibilityMode() === Functions::COMPATIBILITY_GNUMERIC) ? $gnumericNull : 0; } if (is_bool($value) && ($ooBoolOk || Functions::getCompatibilityMode() !== Functions::COMPATIBILITY_OPENOFFICE)) { $value = (int) $value; } if (!is_numeric($value)) { throw new CalcExp(ExcelError::VALUE()); } $value = (int) $value; if ($value < $minValue) { throw new CalcExp(ExcelError::VALUE()); } return (int) $value; } /** * @param mixed $value */ public static function extractFloat($value): float { if ($value === null) { $value = 0.0; } if (is_bool($value)) { $value = (float) $value; } if (!is_numeric($value)) { throw new CalcExp(ExcelError::VALUE()); } return (float) $value; } /** * @param mixed $value */ public static function validateInt($value): int { if ($value === null) { $value = 0; } elseif (is_bool($value)) { $value = (int) $value; } return (int) $value; } } phpspreadsheet/src/PhpSpreadsheet/Calculation/TextData/CharacterConvert.php 0000644 00000005051 15060132323 0023207 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Calculation\TextData; use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; class CharacterConvert { use ArrayEnabled; /** * CHAR. * * @param mixed $character Integer Value to convert to its character representation * Or can be an array of values * * @return array|string The character string * If an array of values is passed as the argument, then the returned result will also be an array * with the same dimensions */ public static function character($character) { if (is_array($character)) { return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $character); } $character = Helpers::validateInt($character); $min = Functions::getCompatibilityMode() === Functions::COMPATIBILITY_OPENOFFICE ? 0 : 1; if ($character < $min || $character > 255) { return ExcelError::VALUE(); } $result = iconv('UCS-4LE', 'UTF-8', pack('V', $character)); return ($result === false) ? '' : $result; } /** * CODE. * * @param mixed $characters String character to convert to its ASCII value * Or can be an array of values * * @return array|int|string A string if arguments are invalid * If an array of values is passed as the argument, then the returned result will also be an array * with the same dimensions */ public static function code($characters) { if (is_array($characters)) { return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $characters); } $characters = Helpers::extractString($characters); if ($characters === '') { return ExcelError::VALUE(); } $character = $characters; if (mb_strlen($characters, 'UTF-8') > 1) { $character = mb_substr($characters, 0, 1, 'UTF-8'); } return self::unicodeToOrd($character); } private static function unicodeToOrd(string $character): int { $retVal = 0; $iconv = iconv('UTF-8', 'UCS-4LE', $character); if ($iconv !== false) { $result = unpack('V', $iconv); if (is_array($result) && isset($result[1])) { $retVal = $result[1]; } } return $retVal; } } phpspreadsheet/src/PhpSpreadsheet/Calculation/TextData/Format.php 0000644 00000026770 15060132323 0021215 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Calculation\TextData; use DateTimeInterface; use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel; use PhpOffice\PhpSpreadsheet\Calculation\Exception as CalcExp; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; use PhpOffice\PhpSpreadsheet\Calculation\MathTrig; use PhpOffice\PhpSpreadsheet\RichText\RichText; use PhpOffice\PhpSpreadsheet\Shared\Date; use PhpOffice\PhpSpreadsheet\Shared\StringHelper; use PhpOffice\PhpSpreadsheet\Style\NumberFormat; class Format { use ArrayEnabled; /** * DOLLAR. * * This function converts a number to text using currency format, with the decimals rounded to the specified place. * The format used is $#,##0.00_);($#,##0.00).. * * @param mixed $value The value to format * Or can be an array of values * @param mixed $decimals The number of digits to display to the right of the decimal point (as an integer). * If decimals is negative, number is rounded to the left of the decimal point. * If you omit decimals, it is assumed to be 2 * Or can be an array of values * * @return array|string * If an array of values is passed for either of the arguments, then the returned result * will also be an array with matching dimensions */ public static function DOLLAR($value = 0, $decimals = 2) { if (is_array($value) || is_array($decimals)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $value, $decimals); } try { $value = Helpers::extractFloat($value); $decimals = Helpers::extractInt($decimals, -100, 0, true); } catch (CalcExp $e) { return $e->getMessage(); } $mask = '$#,##0'; if ($decimals > 0) { $mask .= '.' . str_repeat('0', $decimals); } else { $round = 10 ** abs($decimals); if ($value < 0) { $round = 0 - $round; } $value = MathTrig\Round::multiple($value, $round); } $mask = "{$mask};-{$mask}"; return NumberFormat::toFormattedString($value, $mask); } /** * FIXED. * * @param mixed $value The value to format * Or can be an array of values * @param mixed $decimals Integer value for the number of decimal places that should be formatted * Or can be an array of values * @param mixed $noCommas Boolean value indicating whether the value should have thousands separators or not * Or can be an array of values * * @return array|string * If an array of values is passed for either of the arguments, then the returned result * will also be an array with matching dimensions */ public static function FIXEDFORMAT($value, $decimals = 2, $noCommas = false) { if (is_array($value) || is_array($decimals) || is_array($noCommas)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $value, $decimals, $noCommas); } try { $value = Helpers::extractFloat($value); $decimals = Helpers::extractInt($decimals, -100, 0, true); } catch (CalcExp $e) { return $e->getMessage(); } $valueResult = round($value, $decimals); if ($decimals < 0) { $decimals = 0; } if ($noCommas === false) { $valueResult = number_format( $valueResult, $decimals, StringHelper::getDecimalSeparator(), StringHelper::getThousandsSeparator() ); } return (string) $valueResult; } /** * TEXT. * * @param mixed $value The value to format * Or can be an array of values * @param mixed $format A string with the Format mask that should be used * Or can be an array of values * * @return array|string * If an array of values is passed for either of the arguments, then the returned result * will also be an array with matching dimensions */ public static function TEXTFORMAT($value, $format) { if (is_array($value) || is_array($format)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $value, $format); } $value = Helpers::extractString($value); $format = Helpers::extractString($format); if (!is_numeric($value) && Date::isDateTimeFormatCode($format)) { $value = DateTimeExcel\DateValue::fromString($value) + DateTimeExcel\TimeValue::fromString($value); } return (string) NumberFormat::toFormattedString($value, $format); } /** * @param mixed $value Value to check * * @return mixed */ private static function convertValue($value, bool $spacesMeanZero = false) { $value = $value ?? 0; if (is_bool($value)) { if (Functions::getCompatibilityMode() === Functions::COMPATIBILITY_OPENOFFICE) { $value = (int) $value; } else { throw new CalcExp(ExcelError::VALUE()); } } if (is_string($value)) { $value = trim($value); if ($spacesMeanZero && $value === '') { $value = 0; } } return $value; } /** * VALUE. * * @param mixed $value Value to check * Or can be an array of values * * @return array|DateTimeInterface|float|int|string A string if arguments are invalid * If an array of values is passed for the argument, then the returned result * will also be an array with matching dimensions */ public static function VALUE($value = '') { if (is_array($value)) { return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $value); } try { $value = self::convertValue($value); } catch (CalcExp $e) { return $e->getMessage(); } if (!is_numeric($value)) { $numberValue = str_replace( StringHelper::getThousandsSeparator(), '', trim($value, " \t\n\r\0\x0B" . StringHelper::getCurrencyCode()) ); if ($numberValue === '') { return ExcelError::VALUE(); } if (is_numeric($numberValue)) { return (float) $numberValue; } $dateSetting = Functions::getReturnDateType(); Functions::setReturnDateType(Functions::RETURNDATE_EXCEL); if (strpos($value, ':') !== false) { $timeValue = Functions::scalar(DateTimeExcel\TimeValue::fromString($value)); if ($timeValue !== ExcelError::VALUE()) { Functions::setReturnDateType($dateSetting); return $timeValue; } } $dateValue = Functions::scalar(DateTimeExcel\DateValue::fromString($value)); if ($dateValue !== ExcelError::VALUE()) { Functions::setReturnDateType($dateSetting); return $dateValue; } Functions::setReturnDateType($dateSetting); return ExcelError::VALUE(); } return (float) $value; } /** * TEXT. * * @param mixed $value The value to format * Or can be an array of values * @param mixed $format * * @return array|string * If an array of values is passed for either of the arguments, then the returned result * will also be an array with matching dimensions */ public static function valueToText($value, $format = false) { if (is_array($value) || is_array($format)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $value, $format); } $format = (bool) $format; if (is_object($value) && $value instanceof RichText) { $value = $value->getPlainText(); } if (is_string($value)) { $value = ($format === true) ? Calculation::wrapResult($value) : $value; $value = str_replace("\n", '', $value); } elseif (is_bool($value)) { $value = Calculation::getLocaleBoolean($value ? 'TRUE' : 'FALSE'); } return (string) $value; } /** * @param mixed $decimalSeparator */ private static function getDecimalSeparator($decimalSeparator): string { return empty($decimalSeparator) ? StringHelper::getDecimalSeparator() : (string) $decimalSeparator; } /** * @param mixed $groupSeparator */ private static function getGroupSeparator($groupSeparator): string { return empty($groupSeparator) ? StringHelper::getThousandsSeparator() : (string) $groupSeparator; } /** * NUMBERVALUE. * * @param mixed $value The value to format * Or can be an array of values * @param mixed $decimalSeparator A string with the decimal separator to use, defaults to locale defined value * Or can be an array of values * @param mixed $groupSeparator A string with the group/thousands separator to use, defaults to locale defined value * Or can be an array of values * * @return array|float|string */ public static function NUMBERVALUE($value = '', $decimalSeparator = null, $groupSeparator = null) { if (is_array($value) || is_array($decimalSeparator) || is_array($groupSeparator)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $value, $decimalSeparator, $groupSeparator); } try { $value = self::convertValue($value, true); $decimalSeparator = self::getDecimalSeparator($decimalSeparator); $groupSeparator = self::getGroupSeparator($groupSeparator); } catch (CalcExp $e) { return $e->getMessage(); } if (!is_numeric($value)) { $decimalPositions = preg_match_all('/' . preg_quote($decimalSeparator, '/') . '/', $value, $matches, PREG_OFFSET_CAPTURE); if ($decimalPositions > 1) { return ExcelError::VALUE(); } $decimalOffset = array_pop($matches[0])[1] ?? null; if ($decimalOffset === null || strpos($value, $groupSeparator, $decimalOffset) !== false) { return ExcelError::VALUE(); } $value = str_replace([$groupSeparator, $decimalSeparator], ['', '.'], $value); // Handle the special case of trailing % signs $percentageString = rtrim($value, '%'); if (!is_numeric($percentageString)) { return ExcelError::VALUE(); } $percentageAdjustment = strlen($value) - strlen($percentageString); if ($percentageAdjustment) { $value = (float) $percentageString; $value /= 10 ** ($percentageAdjustment * 2); } } return is_array($value) ? ExcelError::VALUE() : (float) $value; } } phpspreadsheet/src/PhpSpreadsheet/Calculation/Category.php 0000644 00000001321 15060132323 0020005 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Calculation; abstract class Category { // Function categories const CATEGORY_CUBE = 'Cube'; const CATEGORY_DATABASE = 'Database'; const CATEGORY_DATE_AND_TIME = 'Date and Time'; const CATEGORY_ENGINEERING = 'Engineering'; const CATEGORY_FINANCIAL = 'Financial'; const CATEGORY_INFORMATION = 'Information'; const CATEGORY_LOGICAL = 'Logical'; const CATEGORY_LOOKUP_AND_REFERENCE = 'Lookup and Reference'; const CATEGORY_MATH_AND_TRIG = 'Math and Trig'; const CATEGORY_STATISTICAL = 'Statistical'; const CATEGORY_TEXT_AND_DATA = 'Text and Data'; const CATEGORY_WEB = 'Web'; const CATEGORY_UNCATEGORISED = 'Uncategorised'; } phpspreadsheet/src/PhpSpreadsheet/Calculation/ExceptionHandler.php 0000644 00000000670 15060132323 0021472 0 ustar 00 <?php namespace PhpOffice\PhpSpreadsheet\Calculation; class ExceptionHandler { /** * Register errorhandler. */ public function __construct() { /** @var callable */ $callable = [Exception::class, 'errorHandlerCallback']; set_error_handler($callable, E_ALL); } /** * Unregister errorhandler. */ public function __destruct() { restore_error_handler(); } } phpspreadsheet/src/PhpSpreadsheet/Calculation/locale/bg/functions 0000644 00000147436 15060132323 0021323 0 ustar 00 ## ## PhpSpreadsheet ## ## ## Data in this file derived from information provided by web-junior (http://www.web-junior.net/) ## ## ## ## Add-in and Automation functions Функции надстроек и автоматизации ## GETPIVOTDATA = ПОЛУЧИТЬ.ДАННЫЕ.СВОДНОЙ.ТАБЛИЦЫ ## Возвращает данные, хранящиеся в отчете сводной таблицы. ## ## Cube functions Функции Куб ## CUBEKPIMEMBER = КУБЭЛЕМЕНТКИП ## Возвращает свойство ключевого индикатора производительности «(КИП)» и отображает имя «КИП» в ячейке. «КИП» представляет собой количественную величину, такую как ежемесячная валовая прибыль или ежеквартальная текучесть кадров, используемой для контроля эффективности работы организации. CUBEMEMBER = КУБЭЛЕМЕНТ ## Возвращает элемент или кортеж из куба. Используется для проверки существования элемента или кортежа в кубе. CUBEMEMBERPROPERTY = КУБСВОЙСТВОЭЛЕМЕНТА ## Возвращает значение свойства элемента из куба. Используется для проверки существования имени элемента в кубе и возвращает указанное свойство для этого элемента. CUBERANKEDMEMBER = КУБПОРЭЛЕМЕНТ ## Возвращает n-ый или ранжированный элемент в множество. Используется для возвращения одного или нескольких элементов в множество, например, лучшего продавца или 10 лучших студентов. CUBESET = КУБМНОЖ ## Определяет вычислительное множество элементов или кортежей, отправляя на сервер выражение, которое создает множество, а затем возвращает его в Microsoft Office Excel. CUBESETCOUNT = КУБЧИСЛОЭЛМНОЖ ## Возвращает число элементов множества. CUBEVALUE = КУБЗНАЧЕНИЕ ## Возвращает обобщенное значение из куба. ## ## Database functions Функции для работы с базами данных ## DAVERAGE = ДСРЗНАЧ ## Возвращает среднее значение выбранных записей базы данных. DCOUNT = БСЧЁТ ## Подсчитывает количество числовых ячеек в базе данных. DCOUNTA = БСЧЁТА ## Подсчитывает количество непустых ячеек в базе данных. DGET = БИЗВЛЕЧЬ ## Извлекает из базы данных одну запись, удовлетворяющую заданному условию. DMAX = ДМАКС ## Возвращает максимальное значение среди выделенных записей базы данных. DMIN = ДМИН ## Возвращает минимальное значение среди выделенных записей базы данных. DPRODUCT = БДПРОИЗВЕД ## Перемножает значения определенного поля в записях базы данных, удовлетворяющих условию. DSTDEV = ДСТАНДОТКЛ ## Оценивает стандартное отклонение по выборке для выделенных записей базы данных. DSTDEVP = ДСТАНДОТКЛП ## Вычисляет стандартное отклонение по генеральной совокупности для выделенных записей базы данных DSUM = БДСУММ ## Суммирует числа в поле для записей базы данных, удовлетворяющих условию. DVAR = БДДИСП ## Оценивает дисперсию по выборке из выделенных записей базы данных DVARP = БДДИСПП ## Вычисляет дисперсию по генеральной совокупности для выделенных записей базы данных ## ## Date and time functions Функции даты и времени ## DATE = ДАТА ## Возвращает заданную дату в числовом формате. DATEVALUE = ДАТАЗНАЧ ## Преобразует дату из текстового формата в числовой формат. DAY = ДЕНЬ ## Преобразует дату в числовом формате в день месяца. DAYS360 = ДНЕЙ360 ## Вычисляет количество дней между двумя датами на основе 360-дневного года. EDATE = ДАТАМЕС ## Возвращает дату в числовом формате, отстоящую на заданное число месяцев вперед или назад от начальной даты. EOMONTH = КОНМЕСЯЦА ## Возвращает дату в числовом формате для последнего дня месяца, отстоящего вперед или назад на заданное число месяцев. HOUR = ЧАС ## Преобразует дату в числовом формате в часы. MINUTE = МИНУТЫ ## Преобразует дату в числовом формате в минуты. MONTH = МЕСЯЦ ## Преобразует дату в числовом формате в месяцы. NETWORKDAYS = ЧИСТРАБДНИ ## Возвращает количество рабочих дней между двумя датами. NOW = ТДАТА ## Возвращает текущую дату и время в числовом формате. SECOND = СЕКУНДЫ ## Преобразует дату в числовом формате в секунды. TIME = ВРЕМЯ ## Возвращает заданное время в числовом формате. TIMEVALUE = ВРЕМЗНАЧ ## Преобразует время из текстового формата в числовой формат. TODAY = СЕГОДНЯ ## Возвращает текущую дату в числовом формате. WEEKDAY = ДЕНЬНЕД ## Преобразует дату в числовом формате в день недели. WEEKNUM = НОМНЕДЕЛИ ## Преобразует числовое представление в число, которое указывает, на какую неделю года приходится указанная дата. WORKDAY = РАБДЕНЬ ## Возвращает дату в числовом формате, отстоящую вперед или назад на заданное количество рабочих дней. YEAR = ГОД ## Преобразует дату в числовом формате в год. YEARFRAC = ДОЛЯГОДА ## Возвращает долю года, которую составляет количество дней между начальной и конечной датами. ## ## Engineering functions Инженерные функции ## BESSELI = БЕССЕЛЬ.I ## Возвращает модифицированную функцию Бесселя In(x). BESSELJ = БЕССЕЛЬ.J ## Возвращает функцию Бесселя Jn(x). BESSELK = БЕССЕЛЬ.K ## Возвращает модифицированную функцию Бесселя Kn(x). BESSELY = БЕССЕЛЬ.Y ## Возвращает функцию Бесселя Yn(x). BIN2DEC = ДВ.В.ДЕС ## Преобразует двоичное число в десятичное. BIN2HEX = ДВ.В.ШЕСТН ## Преобразует двоичное число в шестнадцатеричное. BIN2OCT = ДВ.В.ВОСЬМ ## Преобразует двоичное число в восьмеричное. COMPLEX = КОМПЛЕКСН ## Преобразует коэффициенты при вещественной и мнимой частях комплексного числа в комплексное число. CONVERT = ПРЕОБР ## Преобразует число из одной системы единиц измерения в другую. DEC2BIN = ДЕС.В.ДВ ## Преобразует десятичное число в двоичное. DEC2HEX = ДЕС.В.ШЕСТН ## Преобразует десятичное число в шестнадцатеричное. DEC2OCT = ДЕС.В.ВОСЬМ ## Преобразует десятичное число в восьмеричное. DELTA = ДЕЛЬТА ## Проверяет равенство двух значений. ERF = ФОШ ## Возвращает функцию ошибки. ERFC = ДФОШ ## Возвращает дополнительную функцию ошибки. GESTEP = ПОРОГ ## Проверяет, не превышает ли данное число порогового значения. HEX2BIN = ШЕСТН.В.ДВ ## Преобразует шестнадцатеричное число в двоичное. HEX2DEC = ШЕСТН.В.ДЕС ## Преобразует шестнадцатеричное число в десятичное. HEX2OCT = ШЕСТН.В.ВОСЬМ ## Преобразует шестнадцатеричное число в восьмеричное. IMABS = МНИМ.ABS ## Возвращает абсолютную величину (модуль) комплексного числа. IMAGINARY = МНИМ.ЧАСТЬ ## Возвращает коэффициент при мнимой части комплексного числа. IMARGUMENT = МНИМ.АРГУМЕНТ ## Возвращает значение аргумента комплексного числа (тета) — угол, выраженный в радианах. IMCONJUGATE = МНИМ.СОПРЯЖ ## Возвращает комплексно-сопряженное комплексное число. IMCOS = МНИМ.COS ## Возвращает косинус комплексного числа. IMDIV = МНИМ.ДЕЛ ## Возвращает частное от деления двух комплексных чисел. IMEXP = МНИМ.EXP ## Возвращает экспоненту комплексного числа. IMLN = МНИМ.LN ## Возвращает натуральный логарифм комплексного числа. IMLOG10 = МНИМ.LOG10 ## Возвращает обычный (десятичный) логарифм комплексного числа. IMLOG2 = МНИМ.LOG2 ## Возвращает двоичный логарифм комплексного числа. IMPOWER = МНИМ.СТЕПЕНЬ ## Возвращает комплексное число, возведенное в целую степень. IMPRODUCT = МНИМ.ПРОИЗВЕД ## Возвращает произведение от 2 до 29 комплексных чисел. IMREAL = МНИМ.ВЕЩ ## Возвращает коэффициент при вещественной части комплексного числа. IMSIN = МНИМ.SIN ## Возвращает синус комплексного числа. IMSQRT = МНИМ.КОРЕНЬ ## Возвращает значение квадратного корня из комплексного числа. IMSUB = МНИМ.РАЗН ## Возвращает разность двух комплексных чисел. IMSUM = МНИМ.СУММ ## Возвращает сумму комплексных чисел. OCT2BIN = ВОСЬМ.В.ДВ ## Преобразует восьмеричное число в двоичное. OCT2DEC = ВОСЬМ.В.ДЕС ## Преобразует восьмеричное число в десятичное. OCT2HEX = ВОСЬМ.В.ШЕСТН ## Преобразует восьмеричное число в шестнадцатеричное. ## ## Financial functions Финансовые функции ## ACCRINT = НАКОПДОХОД ## Возвращает накопленный процент по ценным бумагам с периодической выплатой процентов. ACCRINTM = НАКОПДОХОДПОГАШ ## Возвращает накопленный процент по ценным бумагам, проценты по которым выплачиваются в срок погашения. AMORDEGRC = АМОРУМ ## Возвращает величину амортизации для каждого периода, используя коэффициент амортизации. AMORLINC = АМОРУВ ## Возвращает величину амортизации для каждого периода. COUPDAYBS = ДНЕЙКУПОНДО ## Возвращает количество дней от начала действия купона до даты соглашения. COUPDAYS = ДНЕЙКУПОН ## Возвращает число дней в периоде купона, содержащем дату соглашения. COUPDAYSNC = ДНЕЙКУПОНПОСЛЕ ## Возвращает число дней от даты соглашения до срока следующего купона. COUPNCD = ДАТАКУПОНПОСЛЕ ## Возвращает следующую дату купона после даты соглашения. COUPNUM = ЧИСЛКУПОН ## Возвращает количество купонов, которые могут быть оплачены между датой соглашения и сроком вступления в силу. COUPPCD = ДАТАКУПОНДО ## Возвращает предыдущую дату купона перед датой соглашения. CUMIPMT = ОБЩПЛАТ ## Возвращает общую выплату, произведенную между двумя периодическими выплатами. CUMPRINC = ОБЩДОХОД ## Возвращает общую выплату по займу между двумя периодами. DB = ФУО ## Возвращает величину амортизации актива для заданного периода, рассчитанную методом фиксированного уменьшения остатка. DDB = ДДОБ ## Возвращает величину амортизации актива за данный период, используя метод двойного уменьшения остатка или иной явно указанный метод. DISC = СКИДКА ## Возвращает норму скидки для ценных бумаг. DOLLARDE = РУБЛЬ.ДЕС ## Преобразует цену в рублях, выраженную в виде дроби, в цену в рублях, выраженную десятичным числом. DOLLARFR = РУБЛЬ.ДРОБЬ ## Преобразует цену в рублях, выраженную десятичным числом, в цену в рублях, выраженную в виде дроби. DURATION = ДЛИТ ## Возвращает ежегодную продолжительность действия ценных бумаг с периодическими выплатами по процентам. EFFECT = ЭФФЕКТ ## Возвращает действующие ежегодные процентные ставки. FV = БС ## Возвращает будущую стоимость инвестиции. FVSCHEDULE = БЗРАСПИС ## Возвращает будущую стоимость первоначальной основной суммы после начисления ряда сложных процентов. INTRATE = ИНОРМА ## Возвращает процентную ставку для полностью инвестированных ценных бумаг. IPMT = ПРПЛТ ## Возвращает величину выплаты прибыли на вложения за данный период. IRR = ВСД ## Возвращает внутреннюю ставку доходности для ряда потоков денежных средств. ISPMT = ПРОЦПЛАТ ## Вычисляет выплаты за указанный период инвестиции. MDURATION = МДЛИТ ## Возвращает модифицированную длительность Маколея для ценных бумаг с предполагаемой номинальной стоимостью 100 рублей. MIRR = МВСД ## Возвращает внутреннюю ставку доходности, при которой положительные и отрицательные денежные потоки имеют разные значения ставки. NOMINAL = НОМИНАЛ ## Возвращает номинальную годовую процентную ставку. NPER = КПЕР ## Возвращает общее количество периодов выплаты для данного вклада. NPV = ЧПС ## Возвращает чистую приведенную стоимость инвестиции, основанной на серии периодических денежных потоков и ставке дисконтирования. ODDFPRICE = ЦЕНАПЕРВНЕРЕГ ## Возвращает цену за 100 рублей нарицательной стоимости ценных бумаг с нерегулярным первым периодом. ODDFYIELD = ДОХОДПЕРВНЕРЕГ ## Возвращает доход по ценным бумагам с нерегулярным первым периодом. ODDLPRICE = ЦЕНАПОСЛНЕРЕГ ## Возвращает цену за 100 рублей нарицательной стоимости ценных бумаг с нерегулярным последним периодом. ODDLYIELD = ДОХОДПОСЛНЕРЕГ ## Возвращает доход по ценным бумагам с нерегулярным последним периодом. PMT = ПЛТ ## Возвращает величину выплаты за один период аннуитета. PPMT = ОСПЛТ ## Возвращает величину выплат в погашение основной суммы по инвестиции за заданный период. PRICE = ЦЕНА ## Возвращает цену за 100 рублей нарицательной стоимости ценных бумаг, по которым производится периодическая выплата процентов. PRICEDISC = ЦЕНАСКИДКА ## Возвращает цену за 100 рублей номинальной стоимости ценных бумаг, на которые сделана скидка. PRICEMAT = ЦЕНАПОГАШ ## Возвращает цену за 100 рублей номинальной стоимости ценных бумаг, проценты по которым выплачиваются в срок погашения. PV = ПС ## Возвращает приведенную (к текущему моменту) стоимость инвестиции. RATE = СТАВКА ## Возвращает процентную ставку по аннуитету за один период. RECEIVED = ПОЛУЧЕНО ## Возвращает сумму, полученную к сроку погашения полностью обеспеченных ценных бумаг. SLN = АПЛ ## Возвращает величину линейной амортизации актива за один период. SYD = АСЧ ## Возвращает величину амортизации актива за данный период, рассчитанную методом суммы годовых чисел. TBILLEQ = РАВНОКЧЕК ## Возвращает эквивалентный облигации доход по казначейскому чеку. TBILLPRICE = ЦЕНАКЧЕК ## Возвращает цену за 100 рублей нарицательной стоимости для казначейского чека. TBILLYIELD = ДОХОДКЧЕК ## Возвращает доход по казначейскому чеку. VDB = ПУО ## Возвращает величину амортизации актива для указанного или частичного периода при использовании метода сокращающегося баланса. XIRR = ЧИСТВНДОХ ## Возвращает внутреннюю ставку доходности для графика денежных потоков, которые не обязательно носят периодический характер. XNPV = ЧИСТНЗ ## Возвращает чистую приведенную стоимость для денежных потоков, которые не обязательно являются периодическими. YIELD = ДОХОД ## Возвращает доход от ценных бумаг, по которым производятся периодические выплаты процентов. YIELDDISC = ДОХОДСКИДКА ## Возвращает годовой доход по ценным бумагам, на которые сделана скидка (пример — казначейские чеки). YIELDMAT = ДОХОДПОГАШ ## Возвращает годовой доход от ценных бумаг, проценты по которым выплачиваются в срок погашения. ## ## Information functions Информационные функции ## CELL = ЯЧЕЙКА ## Возвращает информацию о формате, расположении или содержимом ячейки. ERROR.TYPE = ТИП.ОШИБКИ ## Возвращает числовой код, соответствующий типу ошибки. INFO = ИНФОРМ ## Возвращает информацию о текущей операционной среде. ISBLANK = ЕПУСТО ## Возвращает значение ИСТИНА, если аргумент является ссылкой на пустую ячейку. ISERR = ЕОШ ## Возвращает значение ИСТИНА, если аргумент ссылается на любое значение ошибки, кроме #Н/Д. ISERROR = ЕОШИБКА ## Возвращает значение ИСТИНА, если аргумент ссылается на любое значение ошибки. ISEVEN = ЕЧЁТН ## Возвращает значение ИСТИНА, если значение аргумента является четным числом. ISLOGICAL = ЕЛОГИЧ ## Возвращает значение ИСТИНА, если аргумент ссылается на логическое значение. ISNA = ЕНД ## Возвращает значение ИСТИНА, если аргумент ссылается на значение ошибки #Н/Д. ISNONTEXT = ЕНЕТЕКСТ ## Возвращает значение ИСТИНА, если значение аргумента не является текстом. ISNUMBER = ЕЧИСЛО ## Возвращает значение ИСТИНА, если аргумент ссылается на число. ISODD = ЕНЕЧЁТ ## Возвращает значение ИСТИНА, если значение аргумента является нечетным числом. ISREF = ЕССЫЛКА ## Возвращает значение ИСТИНА, если значение аргумента является ссылкой. ISTEXT = ЕТЕКСТ ## Возвращает значение ИСТИНА, если значение аргумента является текстом. N = Ч ## Возвращает значение, преобразованное в число. NA = НД ## Возвращает значение ошибки #Н/Д. TYPE = ТИП ## Возвращает число, обозначающее тип данных значения. ## ## Logical functions Логические функции ## AND = И ## Renvoie VRAI si tous ses arguments sont VRAI. FALSE = ЛОЖЬ ## Возвращает логическое значение ЛОЖЬ. IF = ЕСЛИ ## Выполняет проверку условия. IFERROR = ЕСЛИОШИБКА ## Возвращает введённое значение, если вычисление по формуле вызывает ошибку; в противном случае функция возвращает результат вычисления. NOT = НЕ ## Меняет логическое значение своего аргумента на противоположное. OR = ИЛИ ## Возвращает значение ИСТИНА, если хотя бы один аргумент имеет значение ИСТИНА. TRUE = ИСТИНА ## Возвращает логическое значение ИСТИНА. ## ## Lookup and reference functions Функции ссылки и поиска ## ADDRESS = АДРЕС ## Возвращает ссылку на отдельную ячейку листа в виде текста. AREAS = ОБЛАСТИ ## Возвращает количество областей в ссылке. CHOOSE = ВЫБОР ## Выбирает значение из списка значений по индексу. COLUMN = СТОЛБЕЦ ## Возвращает номер столбца, на который указывает ссылка. COLUMNS = ЧИСЛСТОЛБ ## Возвращает количество столбцов в ссылке. HLOOKUP = ГПР ## Ищет в первой строке массива и возвращает значение отмеченной ячейки HYPERLINK = ГИПЕРССЫЛКА ## Создает ссылку, открывающую документ, который находится на сервере сети, в интрасети или в Интернете. INDEX = ИНДЕКС ## Использует индекс для выбора значения из ссылки или массива. INDIRECT = ДВССЫЛ ## Возвращает ссылку, заданную текстовым значением. LOOKUP = ПРОСМОТР ## Ищет значения в векторе или массиве. MATCH = ПОИСКПОЗ ## Ищет значения в ссылке или массиве. OFFSET = СМЕЩ ## Возвращает смещение ссылки относительно заданной ссылки. ROW = СТРОКА ## Возвращает номер строки, определяемой ссылкой. ROWS = ЧСТРОК ## Возвращает количество строк в ссылке. RTD = ДРВ ## Извлекает данные реального времени из программ, поддерживающих автоматизацию COM (Программирование объектов. Стандартное средство для работы с объектами некоторого приложения из другого приложения или средства разработки. Программирование объектов (ранее называемое программированием OLE) является функцией модели COM (Component Object Model, модель компонентных объектов).). TRANSPOSE = ТРАНСП ## Возвращает транспонированный массив. VLOOKUP = ВПР ## Ищет значение в первом столбце массива и возвращает значение из ячейки в найденной строке и указанном столбце. ## ## Math and trigonometry functions Математические и тригонометрические функции ## ABS = ABS ## Возвращает модуль (абсолютную величину) числа. ACOS = ACOS ## Возвращает арккосинус числа. ACOSH = ACOSH ## Возвращает гиперболический арккосинус числа. ASIN = ASIN ## Возвращает арксинус числа. ASINH = ASINH ## Возвращает гиперболический арксинус числа. ATAN = ATAN ## Возвращает арктангенс числа. ATAN2 = ATAN2 ## Возвращает арктангенс для заданных координат x и y. ATANH = ATANH ## Возвращает гиперболический арктангенс числа. CEILING = ОКРВВЕРХ ## Округляет число до ближайшего целого или до ближайшего кратного указанному значению. COMBIN = ЧИСЛКОМБ ## Возвращает количество комбинаций для заданного числа объектов. COS = COS ## Возвращает косинус числа. COSH = COSH ## Возвращает гиперболический косинус числа. DEGREES = ГРАДУСЫ ## Преобразует радианы в градусы. EVEN = ЧЁТН ## Округляет число до ближайшего четного целого. EXP = EXP ## Возвращает число e, возведенное в указанную степень. FACT = ФАКТР ## Возвращает факториал числа. FACTDOUBLE = ДВФАКТР ## Возвращает двойной факториал числа. FLOOR = ОКРВНИЗ ## Округляет число до ближайшего меньшего по модулю значения. GCD = НОД ## Возвращает наибольший общий делитель. INT = ЦЕЛОЕ ## Округляет число до ближайшего меньшего целого. LCM = НОК ## Возвращает наименьшее общее кратное. LN = LN ## Возвращает натуральный логарифм числа. LOG = LOG ## Возвращает логарифм числа по заданному основанию. LOG10 = LOG10 ## Возвращает десятичный логарифм числа. MDETERM = МОПРЕД ## Возвращает определитель матрицы массива. MINVERSE = МОБР ## Возвращает обратную матрицу массива. MMULT = МУМНОЖ ## Возвращает произведение матриц двух массивов. MOD = ОСТАТ ## Возвращает остаток от деления. MROUND = ОКРУГЛТ ## Возвращает число, округленное с требуемой точностью. MULTINOMIAL = МУЛЬТИНОМ ## Возвращает мультиномиальный коэффициент множества чисел. ODD = НЕЧЁТ ## Округляет число до ближайшего нечетного целого. PI = ПИ ## Возвращает число пи. POWER = СТЕПЕНЬ ## Возвращает результат возведения числа в степень. PRODUCT = ПРОИЗВЕД ## Возвращает произведение аргументов. QUOTIENT = ЧАСТНОЕ ## Возвращает целую часть частного при делении. RADIANS = РАДИАНЫ ## Преобразует градусы в радианы. RAND = СЛЧИС ## Возвращает случайное число в интервале от 0 до 1. RANDBETWEEN = СЛУЧМЕЖДУ ## Возвращает случайное число в интервале между двумя заданными числами. ROMAN = РИМСКОЕ ## Преобразует арабские цифры в римские в виде текста. ROUND = ОКРУГЛ ## Округляет число до указанного количества десятичных разрядов. ROUNDDOWN = ОКРУГЛВНИЗ ## Округляет число до ближайшего меньшего по модулю значения. ROUNDUP = ОКРУГЛВВЕРХ ## Округляет число до ближайшего большего по модулю значения. SERIESSUM = РЯД.СУММ ## Возвращает сумму степенного ряда, вычисленную по формуле. SIGN = ЗНАК ## Возвращает знак числа. SIN = SIN ## Возвращает синус заданного угла. SINH = SINH ## Возвращает гиперболический синус числа. SQRT = КОРЕНЬ ## Возвращает положительное значение квадратного корня. SQRTPI = КОРЕНЬПИ ## Возвращает квадратный корень из значения выражения (число * ПИ). SUBTOTAL = ПРОМЕЖУТОЧНЫЕ.ИТОГИ ## Возвращает промежуточный итог в списке или базе данных. SUM = СУММ ## Суммирует аргументы. SUMIF = СУММЕСЛИ ## Суммирует ячейки, удовлетворяющие заданному условию. SUMIFS = СУММЕСЛИМН ## Суммирует диапазон ячеек, удовлетворяющих нескольким условиям. SUMPRODUCT = СУММПРОИЗВ ## Возвращает сумму произведений соответствующих элементов массивов. SUMSQ = СУММКВ ## Возвращает сумму квадратов аргументов. SUMX2MY2 = СУММРАЗНКВ ## Возвращает сумму разностей квадратов соответствующих значений в двух массивах. SUMX2PY2 = СУММСУММКВ ## Возвращает сумму сумм квадратов соответствующих элементов двух массивов. SUMXMY2 = СУММКВРАЗН ## Возвращает сумму квадратов разностей соответствующих значений в двух массивах. TAN = TAN ## Возвращает тангенс числа. TANH = TANH ## Возвращает гиперболический тангенс числа. TRUNC = ОТБР ## Отбрасывает дробную часть числа. ## ## Statistical functions Статистические функции ## AVEDEV = СРОТКЛ ## Возвращает среднее арифметическое абсолютных значений отклонений точек данных от среднего. AVERAGE = СРЗНАЧ ## Возвращает среднее арифметическое аргументов. AVERAGEA = СРЗНАЧА ## Возвращает среднее арифметическое аргументов, включая числа, текст и логические значения. AVERAGEIF = СРЗНАЧЕСЛИ ## Возвращает среднее значение (среднее арифметическое) всех ячеек в диапазоне, которые удовлетворяют данному условию. AVERAGEIFS = СРЗНАЧЕСЛИМН ## Возвращает среднее значение (среднее арифметическое) всех ячеек, которые удовлетворяют нескольким условиям. BETADIST = БЕТАРАСП ## Возвращает интегральную функцию бета-распределения. BETAINV = БЕТАОБР ## Возвращает обратную интегральную функцию указанного бета-распределения. BINOMDIST = БИНОМРАСП ## Возвращает отдельное значение биномиального распределения. CHIDIST = ХИ2РАСП ## Возвращает одностороннюю вероятность распределения хи-квадрат. CHIINV = ХИ2ОБР ## Возвращает обратное значение односторонней вероятности распределения хи-квадрат. CHITEST = ХИ2ТЕСТ ## Возвращает тест на независимость. CONFIDENCE = ДОВЕРИТ ## Возвращает доверительный интервал для среднего значения по генеральной совокупности. CORREL = КОРРЕЛ ## Возвращает коэффициент корреляции между двумя множествами данных. COUNT = СЧЁТ ## Подсчитывает количество чисел в списке аргументов. COUNTA = СЧЁТЗ ## Подсчитывает количество значений в списке аргументов. COUNTBLANK = СЧИТАТЬПУСТОТЫ ## Подсчитывает количество пустых ячеек в диапазоне COUNTIF = СЧЁТЕСЛИ ## Подсчитывает количество ячеек в диапазоне, удовлетворяющих заданному условию COUNTIFS = СЧЁТЕСЛИМН ## Подсчитывает количество ячеек внутри диапазона, удовлетворяющих нескольким условиям. COVAR = КОВАР ## Возвращает ковариацию, среднее произведений парных отклонений CRITBINOM = КРИТБИНОМ ## Возвращает наименьшее значение, для которого интегральное биномиальное распределение меньше или равно заданному критерию. DEVSQ = КВАДРОТКЛ ## Возвращает сумму квадратов отклонений. EXPONDIST = ЭКСПРАСП ## Возвращает экспоненциальное распределение. FDIST = FРАСП ## Возвращает F-распределение вероятности. FINV = FРАСПОБР ## Возвращает обратное значение для F-распределения вероятности. FISHER = ФИШЕР ## Возвращает преобразование Фишера. FISHERINV = ФИШЕРОБР ## Возвращает обратное преобразование Фишера. FORECAST = ПРЕДСКАЗ ## Возвращает значение линейного тренда. FREQUENCY = ЧАСТОТА ## Возвращает распределение частот в виде вертикального массива. FTEST = ФТЕСТ ## Возвращает результат F-теста. GAMMADIST = ГАММАРАСП ## Возвращает гамма-распределение. GAMMAINV = ГАММАОБР ## Возвращает обратное гамма-распределение. GAMMALN = ГАММАНЛОГ ## Возвращает натуральный логарифм гамма функции, Γ(x). GEOMEAN = СРГЕОМ ## Возвращает среднее геометрическое. GROWTH = РОСТ ## Возвращает значения в соответствии с экспоненциальным трендом. HARMEAN = СРГАРМ ## Возвращает среднее гармоническое. HYPGEOMDIST = ГИПЕРГЕОМЕТ ## Возвращает гипергеометрическое распределение. INTERCEPT = ОТРЕЗОК ## Возвращает отрезок, отсекаемый на оси линией линейной регрессии. KURT = ЭКСЦЕСС ## Возвращает эксцесс множества данных. LARGE = НАИБОЛЬШИЙ ## Возвращает k-ое наибольшее значение в множестве данных. LINEST = ЛИНЕЙН ## Возвращает параметры линейного тренда. LOGEST = ЛГРФПРИБЛ ## Возвращает параметры экспоненциального тренда. LOGINV = ЛОГНОРМОБР ## Возвращает обратное логарифмическое нормальное распределение. LOGNORMDIST = ЛОГНОРМРАСП ## Возвращает интегральное логарифмическое нормальное распределение. MAX = МАКС ## Возвращает наибольшее значение в списке аргументов. MAXA = МАКСА ## Возвращает наибольшее значение в списке аргументов, включая числа, текст и логические значения. MEDIAN = МЕДИАНА ## Возвращает медиану заданных чисел. MIN = МИН ## Возвращает наименьшее значение в списке аргументов. MINA = МИНА ## Возвращает наименьшее значение в списке аргументов, включая числа, текст и логические значения. MODE = МОДА ## Возвращает значение моды множества данных. NEGBINOMDIST = ОТРБИНОМРАСП ## Возвращает отрицательное биномиальное распределение. NORMDIST = НОРМРАСП ## Возвращает нормальную функцию распределения. NORMINV = НОРМОБР ## Возвращает обратное нормальное распределение. NORMSDIST = НОРМСТРАСП ## Возвращает стандартное нормальное интегральное распределение. NORMSINV = НОРМСТОБР ## Возвращает обратное значение стандартного нормального распределения. PEARSON = ПИРСОН ## Возвращает коэффициент корреляции Пирсона. PERCENTILE = ПЕРСЕНТИЛЬ ## Возвращает k-ую персентиль для значений диапазона. PERCENTRANK = ПРОЦЕНТРАНГ ## Возвращает процентную норму значения в множестве данных. PERMUT = ПЕРЕСТ ## Возвращает количество перестановок для заданного числа объектов. POISSON = ПУАССОН ## Возвращает распределение Пуассона. PROB = ВЕРОЯТНОСТЬ ## Возвращает вероятность того, что значение из диапазона находится внутри заданных пределов. QUARTILE = КВАРТИЛЬ ## Возвращает квартиль множества данных. RANK = РАНГ ## Возвращает ранг числа в списке чисел. RSQ = КВПИРСОН ## Возвращает квадрат коэффициента корреляции Пирсона. SKEW = СКОС ## Возвращает асимметрию распределения. SLOPE = НАКЛОН ## Возвращает наклон линии линейной регрессии. SMALL = НАИМЕНЬШИЙ ## Возвращает k-ое наименьшее значение в множестве данных. STANDARDIZE = НОРМАЛИЗАЦИЯ ## Возвращает нормализованное значение. STDEV = СТАНДОТКЛОН ## Оценивает стандартное отклонение по выборке. STDEVA = СТАНДОТКЛОНА ## Оценивает стандартное отклонение по выборке, включая числа, текст и логические значения. STDEVP = СТАНДОТКЛОНП ## Вычисляет стандартное отклонение по генеральной совокупности. STDEVPA = СТАНДОТКЛОНПА ## Вычисляет стандартное отклонение по генеральной совокупности, включая числа, текст и логические значения. STEYX = СТОШYX ## Возвращает стандартную ошибку предсказанных значений y для каждого значения x в регрессии. TDIST = СТЬЮДРАСП ## Возвращает t-распределение Стьюдента. TINV = СТЬЮДРАСПОБР ## Возвращает обратное t-распределение Стьюдента. TREND = ТЕНДЕНЦИЯ ## Возвращает значения в соответствии с линейным трендом. TRIMMEAN = УРЕЗСРЕДНЕЕ ## Возвращает среднее внутренности множества данных. TTEST = ТТЕСТ ## Возвращает вероятность, соответствующую критерию Стьюдента. VAR = ДИСП ## Оценивает дисперсию по выборке. VARA = ДИСПА ## Оценивает дисперсию по выборке, включая числа, текст и логические значения. VARP = ДИСПР ## Вычисляет дисперсию для генеральной совокупности. VARPA = ДИСПРА ## Вычисляет дисперсию для генеральной совокупности, включая числа, текст и логические значения. WEIBULL = ВЕЙБУЛЛ ## Возвращает распределение Вейбулла. ZTEST = ZТЕСТ ## Возвращает двустороннее P-значение z-теста. ## ## Text functions Текстовые функции ## ASC = ASC ## Для языков с двухбайтовыми наборами знаков (например, катакана) преобразует полноширинные (двухбайтовые) знаки в полуширинные (однобайтовые). BAHTTEXT = БАТТЕКСТ ## Преобразует число в текст, используя денежный формат ß (БАТ). CHAR = СИМВОЛ ## Возвращает знак с заданным кодом. CLEAN = ПЕЧСИМВ ## Удаляет все непечатаемые знаки из текста. CODE = КОДСИМВ ## Возвращает числовой код первого знака в текстовой строке. CONCATENATE = СЦЕПИТЬ ## Объединяет несколько текстовых элементов в один. DOLLAR = РУБЛЬ ## Преобразует число в текст, используя денежный формат. EXACT = СОВПАД ## Проверяет идентичность двух текстовых значений. FIND = НАЙТИ ## Ищет вхождения одного текстового значения в другом (с учетом регистра). FINDB = НАЙТИБ ## Ищет вхождения одного текстового значения в другом (с учетом регистра). FIXED = ФИКСИРОВАННЫЙ ## Форматирует число и преобразует его в текст с заданным числом десятичных знаков. JIS = JIS ## Для языков с двухбайтовыми наборами знаков (например, катакана) преобразует полуширинные (однобайтовые) знаки в текстовой строке в полноширинные (двухбайтовые). LEFT = ЛЕВСИМВ ## Возвращает крайние слева знаки текстового значения. LEFTB = ЛЕВБ ## Возвращает крайние слева знаки текстового значения. LEN = ДЛСТР ## Возвращает количество знаков в текстовой строке. LENB = ДЛИНБ ## Возвращает количество знаков в текстовой строке. LOWER = СТРОЧН ## Преобразует все буквы текста в строчные. MID = ПСТР ## Возвращает заданное число знаков из строки текста, начиная с указанной позиции. MIDB = ПСТРБ ## Возвращает заданное число знаков из строки текста, начиная с указанной позиции. PHONETIC = PHONETIC ## Извлекает фонетические (фуригана) знаки из текстовой строки. PROPER = ПРОПНАЧ ## Преобразует первую букву в каждом слове текста в прописную. REPLACE = ЗАМЕНИТЬ ## Заменяет знаки в тексте. REPLACEB = ЗАМЕНИТЬБ ## Заменяет знаки в тексте. REPT = ПОВТОР ## Повторяет текст заданное число раз. RIGHT = ПРАВСИМВ ## Возвращает крайние справа знаки текстовой строки. RIGHTB = ПРАВБ ## Возвращает крайние справа знаки текстовой строки. SEARCH = ПОИСК ## Ищет вхождения одного текстового значения в другом (без учета регистра). SEARCHB = ПОИСКБ ## Ищет вхождения одного текстового значения в другом (без учета регистра). SUBSTITUTE = ПОДСТАВИТЬ ## Заменяет в текстовой строке старый текст новым. T = Т ## Преобразует аргументы в текст. TEXT = ТЕКСТ ## Форматирует число и преобразует его в текст. TRIM = СЖПРОБЕЛЫ ## Удаляет из текста пробелы. UPPER = ПРОПИСН ## Преобразует все буквы текста в прописные. VALUE = ЗНАЧЕН ## Преобразует текстовый аргумент в число. phpspreadsheet/src/PhpSpreadsheet/Calculation/locale/bg/config 0000644 00000000430 15060132323 0020536 0 ustar 00 ## ## PhpSpreadsheet ## ## ## ArgumentSeparator = ; ## ## (For future use) ## currencySymbol = лв ## ## Excel Error Codes (For future use) ## NULL = #ПРАЗНО! DIV0 = #ДЕЛ/0! VALUE = #СТОЙНОСТ! REF = #РЕФ! NAME = #ИМЕ? NUM = #ЧИСЛО! NA = #Н/Д phpspreadsheet/src/PhpSpreadsheet/Calculation/locale/fi/functions 0000644 00000026262 15060132323 0021322 0 ustar 00 ############################################################ ## ## PhpSpreadsheet - function name translations ## ## Suomi (Finnish) ## ############################################################ ## ## Kuutiofunktiot (Cube Functions) ## CUBEKPIMEMBER = KUUTIOKPIJÄSEN CUBEMEMBER = KUUTIONJÄSEN CUBEMEMBERPROPERTY = KUUTIONJÄSENENOMINAISUUS CUBERANKEDMEMBER = KUUTIONLUOKITELTUJÄSEN CUBESET = KUUTIOJOUKKO CUBESETCOUNT = KUUTIOJOUKKOJENMÄÄRÄ CUBEVALUE = KUUTIONARVO ## ## Tietokantafunktiot (Database Functions) ## DAVERAGE = TKESKIARVO DCOUNT = TLASKE DCOUNTA = TLASKEA DGET = TNOUDA DMAX = TMAKS DMIN = TMIN DPRODUCT = TTULO DSTDEV = TKESKIHAJONTA DSTDEVP = TKESKIHAJONTAP DSUM = TSUMMA DVAR = TVARIANSSI DVARP = TVARIANSSIP ## ## Päivämäärä- ja aikafunktiot (Date & Time Functions) ## DATE = PÄIVÄYS DATEDIF = PVMERO DATESTRING = PVMMERKKIJONO DATEVALUE = PÄIVÄYSARVO DAY = PÄIVÄ DAYS = PÄIVÄT DAYS360 = PÄIVÄT360 EDATE = PÄIVÄ.KUUKAUSI EOMONTH = KUUKAUSI.LOPPU HOUR = TUNNIT ISOWEEKNUM = VIIKKO.ISO.NRO MINUTE = MINUUTIT MONTH = KUUKAUSI NETWORKDAYS = TYÖPÄIVÄT NETWORKDAYS.INTL = TYÖPÄIVÄT.KANSVÄL NOW = NYT SECOND = SEKUNNIT THAIDAYOFWEEK = THAI.VIIKONPÄIVÄ THAIMONTHOFYEAR = THAI.KUUKAUSI THAIYEAR = THAI.VUOSI TIME = AIKA TIMEVALUE = AIKA_ARVO TODAY = TÄMÄ.PÄIVÄ WEEKDAY = VIIKONPÄIVÄ WEEKNUM = VIIKKO.NRO WORKDAY = TYÖPÄIVÄ WORKDAY.INTL = TYÖPÄIVÄ.KANSVÄL YEAR = VUOSI YEARFRAC = VUOSI.OSA ## ## Tekniset funktiot (Engineering Functions) ## BESSELI = BESSELI BESSELJ = BESSELJ BESSELK = BESSELK BESSELY = BESSELY BIN2DEC = BINDES BIN2HEX = BINHEKSA BIN2OCT = BINOKT BITAND = BITTI.JA BITLSHIFT = BITTI.SIIRTO.V BITOR = BITTI.TAI BITRSHIFT = BITTI.SIIRTO.O BITXOR = BITTI.EHDOTON.TAI COMPLEX = KOMPLEKSI CONVERT = MUUNNA DEC2BIN = DESBIN DEC2HEX = DESHEKSA DEC2OCT = DESOKT DELTA = SAMA.ARVO ERF = VIRHEFUNKTIO ERF.PRECISE = VIRHEFUNKTIO.TARKKA ERFC = VIRHEFUNKTIO.KOMPLEMENTTI ERFC.PRECISE = VIRHEFUNKTIO.KOMPLEMENTTI.TARKKA GESTEP = RAJA HEX2BIN = HEKSABIN HEX2DEC = HEKSADES HEX2OCT = HEKSAOKT IMABS = KOMPLEKSI.ABS IMAGINARY = KOMPLEKSI.IMAG IMARGUMENT = KOMPLEKSI.ARG IMCONJUGATE = KOMPLEKSI.KONJ IMCOS = KOMPLEKSI.COS IMCOSH = IMCOSH IMCOT = KOMPLEKSI.COT IMCSC = KOMPLEKSI.KOSEK IMCSCH = KOMPLEKSI.KOSEKH IMDIV = KOMPLEKSI.OSAM IMEXP = KOMPLEKSI.EKSP IMLN = KOMPLEKSI.LN IMLOG10 = KOMPLEKSI.LOG10 IMLOG2 = KOMPLEKSI.LOG2 IMPOWER = KOMPLEKSI.POT IMPRODUCT = KOMPLEKSI.TULO IMREAL = KOMPLEKSI.REAALI IMSEC = KOMPLEKSI.SEK IMSECH = KOMPLEKSI.SEKH IMSIN = KOMPLEKSI.SIN IMSINH = KOMPLEKSI.SINH IMSQRT = KOMPLEKSI.NELIÖJ IMSUB = KOMPLEKSI.EROTUS IMSUM = KOMPLEKSI.SUM IMTAN = KOMPLEKSI.TAN OCT2BIN = OKTBIN OCT2DEC = OKTDES OCT2HEX = OKTHEKSA ## ## Rahoitusfunktiot (Financial Functions) ## ACCRINT = KERTYNYT.KORKO ACCRINTM = KERTYNYT.KORKO.LOPUSSA AMORDEGRC = AMORDEGRC AMORLINC = AMORLINC COUPDAYBS = KORKOPÄIVÄT.ALUSTA COUPDAYS = KORKOPÄIVÄT COUPDAYSNC = KORKOPÄIVÄT.SEURAAVA COUPNCD = KORKOPÄIVÄ.SEURAAVA COUPNUM = KORKOPÄIVÄ.JAKSOT COUPPCD = KORKOPÄIVÄ.EDELLINEN CUMIPMT = MAKSETTU.KORKO CUMPRINC = MAKSETTU.LYHENNYS DB = DB DDB = DDB DISC = DISKONTTOKORKO DOLLARDE = VALUUTTA.DES DOLLARFR = VALUUTTA.MURTO DURATION = KESTO EFFECT = KORKO.EFEKT FV = TULEVA.ARVO FVSCHEDULE = TULEVA.ARVO.ERIKORKO INTRATE = KORKO.ARVOPAPERI IPMT = IPMT IRR = SISÄINEN.KORKO ISPMT = ISPMT MDURATION = KESTO.MUUNN MIRR = MSISÄINEN NOMINAL = KORKO.VUOSI NPER = NJAKSO NPV = NNA ODDFPRICE = PARITON.ENS.NIMELLISARVO ODDFYIELD = PARITON.ENS.TUOTTO ODDLPRICE = PARITON.VIIM.NIMELLISARVO ODDLYIELD = PARITON.VIIM.TUOTTO PDURATION = KESTO.JAKSO PMT = MAKSU PPMT = PPMT PRICE = HINTA PRICEDISC = HINTA.DISK PRICEMAT = HINTA.LUNASTUS PV = NA RATE = KORKO RECEIVED = SAATU.HINTA RRI = TOT.ROI SLN = STP SYD = VUOSIPOISTO TBILLEQ = OBLIG.TUOTTOPROS TBILLPRICE = OBLIG.HINTA TBILLYIELD = OBLIG.TUOTTO VDB = VDB XIRR = SISÄINEN.KORKO.JAKSOTON XNPV = NNA.JAKSOTON YIELD = TUOTTO YIELDDISC = TUOTTO.DISK YIELDMAT = TUOTTO.ERÄP ## ## Tietofunktiot (Information Functions) ## CELL = SOLU ERROR.TYPE = VIRHEEN.LAJI INFO = KUVAUS ISBLANK = ONTYHJÄ ISERR = ONVIRH ISERROR = ONVIRHE ISEVEN = ONPARILLINEN ISFORMULA = ONKAAVA ISLOGICAL = ONTOTUUS ISNA = ONPUUTTUU ISNONTEXT = ONEI_TEKSTI ISNUMBER = ONLUKU ISODD = ONPARITON ISREF = ONVIITT ISTEXT = ONTEKSTI N = N NA = PUUTTUU SHEET = TAULUKKO SHEETS = TAULUKOT TYPE = TYYPPI ## ## Loogiset funktiot (Logical Functions) ## AND = JA FALSE = EPÄTOSI IF = JOS IFERROR = JOSVIRHE IFNA = JOSPUUTTUU IFS = JOSS NOT = EI OR = TAI SWITCH = MUUTA TRUE = TOSI XOR = EHDOTON.TAI ## ## Haku- ja viitefunktiot (Lookup & Reference Functions) ## ADDRESS = OSOITE AREAS = ALUEET CHOOSE = VALITSE.INDEKSI COLUMN = SARAKE COLUMNS = SARAKKEET FORMULATEXT = KAAVA.TEKSTI GETPIVOTDATA = NOUDA.PIVOT.TIEDOT HLOOKUP = VHAKU HYPERLINK = HYPERLINKKI INDEX = INDEKSI INDIRECT = EPÄSUORA LOOKUP = HAKU MATCH = VASTINE OFFSET = SIIRTYMÄ ROW = RIVI ROWS = RIVIT RTD = RTD TRANSPOSE = TRANSPONOI VLOOKUP = PHAKU *RC = RS ## ## Matemaattiset ja trigonometriset funktiot (Math & Trig Functions) ## ABS = ITSEISARVO ACOS = ACOS ACOSH = ACOSH ACOT = ACOT ACOTH = ACOTH AGGREGATE = KOOSTE ARABIC = ARABIA ASIN = ASIN ASINH = ASINH ATAN = ATAN ATAN2 = ATAN2 ATANH = ATANH BASE = PERUS CEILING.MATH = PYÖRISTÄ.KERR.YLÖS.MATEMAATTINEN CEILING.PRECISE = PYÖRISTÄ.KERR.YLÖS.TARKKA COMBIN = KOMBINAATIO COMBINA = KOMBINAATIOA COS = COS COSH = COSH COT = COT COTH = COTH CSC = KOSEK CSCH = KOSEKH DECIMAL = DESIMAALI DEGREES = ASTEET ECMA.CEILING = ECMA.PYÖRISTÄ.KERR.YLÖS EVEN = PARILLINEN EXP = EKSPONENTTI FACT = KERTOMA FACTDOUBLE = KERTOMA.OSA FLOOR.MATH = PYÖRISTÄ.KERR.ALAS.MATEMAATTINEN FLOOR.PRECISE = PYÖRISTÄ.KERR.ALAS.TARKKA GCD = SUURIN.YHT.TEKIJÄ INT = KOKONAISLUKU ISO.CEILING = ISO.PYÖRISTÄ.KERR.YLÖS LCM = PIENIN.YHT.JAETTAVA LN = LUONNLOG LOG = LOG LOG10 = LOG10 MDETERM = MDETERM MINVERSE = MKÄÄNTEINEN MMULT = MKERRO MOD = JAKOJ MROUND = PYÖRISTÄ.KERR MULTINOMIAL = MULTINOMI MUNIT = YKSIKKÖM ODD = PARITON PI = PII POWER = POTENSSI PRODUCT = TULO QUOTIENT = OSAMÄÄRÄ RADIANS = RADIAANIT RAND = SATUNNAISLUKU RANDBETWEEN = SATUNNAISLUKU.VÄLILTÄ ROMAN = ROMAN ROUND = PYÖRISTÄ ROUNDBAHTDOWN = PYÖRISTÄ.BAHT.ALAS ROUNDBAHTUP = PYÖRISTÄ.BAHT.YLÖS ROUNDDOWN = PYÖRISTÄ.DES.ALAS ROUNDUP = PYÖRISTÄ.DES.YLÖS SEC = SEK SECH = SEKH SERIESSUM = SARJA.SUMMA SIGN = ETUMERKKI SIN = SIN SINH = SINH SQRT = NELIÖJUURI SQRTPI = NELIÖJUURI.PII SUBTOTAL = VÄLISUMMA SUM = SUMMA SUMIF = SUMMA.JOS SUMIFS = SUMMA.JOS.JOUKKO SUMPRODUCT = TULOJEN.SUMMA SUMSQ = NELIÖSUMMA SUMX2MY2 = NELIÖSUMMIEN.EROTUS SUMX2PY2 = NELIÖSUMMIEN.SUMMA SUMXMY2 = EROTUSTEN.NELIÖSUMMA TAN = TAN TANH = TANH TRUNC = KATKAISE ## ## Tilastolliset funktiot (Statistical Functions) ## AVEDEV = KESKIPOIKKEAMA AVERAGE = KESKIARVO AVERAGEA = KESKIARVOA AVERAGEIF = KESKIARVO.JOS AVERAGEIFS = KESKIARVO.JOS.JOUKKO BETA.DIST = BEETA.JAKAUMA BETA.INV = BEETA.KÄÄNT BINOM.DIST = BINOMI.JAKAUMA BINOM.DIST.RANGE = BINOMI.JAKAUMA.ALUE BINOM.INV = BINOMIJAKAUMA.KÄÄNT CHISQ.DIST = CHINELIÖ.JAKAUMA CHISQ.DIST.RT = CHINELIÖ.JAKAUMA.OH CHISQ.INV = CHINELIÖ.KÄÄNT CHISQ.INV.RT = CHINELIÖ.KÄÄNT.OH CHISQ.TEST = CHINELIÖ.TESTI CONFIDENCE.NORM = LUOTTAMUSVÄLI.NORM CONFIDENCE.T = LUOTTAMUSVÄLI.T CORREL = KORRELAATIO COUNT = LASKE COUNTA = LASKE.A COUNTBLANK = LASKE.TYHJÄT COUNTIF = LASKE.JOS COUNTIFS = LASKE.JOS.JOUKKO COVARIANCE.P = KOVARIANSSI.P COVARIANCE.S = KOVARIANSSI.S DEVSQ = OIKAISTU.NELIÖSUMMA EXPON.DIST = EKSPONENTIAALI.JAKAUMA F.DIST = F.JAKAUMA F.DIST.RT = F.JAKAUMA.OH F.INV = F.KÄÄNT F.INV.RT = F.KÄÄNT.OH F.TEST = F.TESTI FISHER = FISHER FISHERINV = FISHER.KÄÄNT FORECAST.ETS = ENNUSTE.ETS FORECAST.ETS.CONFINT = ENNUSTE.ETS.CONFINT FORECAST.ETS.SEASONALITY = ENNUSTE.ETS.KAUSIVAIHTELU FORECAST.ETS.STAT = ENNUSTE.ETS.STAT FORECAST.LINEAR = ENNUSTE.LINEAARINEN FREQUENCY = TAAJUUS GAMMA = GAMMA GAMMA.DIST = GAMMA.JAKAUMA GAMMA.INV = GAMMA.JAKAUMA.KÄÄNT GAMMALN = GAMMALN GAMMALN.PRECISE = GAMMALN.TARKKA GAUSS = GAUSS GEOMEAN = KESKIARVO.GEOM GROWTH = KASVU HARMEAN = KESKIARVO.HARM HYPGEOM.DIST = HYPERGEOM_JAKAUMA INTERCEPT = LEIKKAUSPISTE KURT = KURT LARGE = SUURI LINEST = LINREGR LOGEST = LOGREGR LOGNORM.DIST = LOGNORM_JAKAUMA LOGNORM.INV = LOGNORM.KÄÄNT MAX = MAKS MAXA = MAKSA MAXIFS = MAKS.JOS MEDIAN = MEDIAANI MIN = MIN MINA = MINA MINIFS = MIN.JOS MODE.MULT = MOODI.USEA MODE.SNGL = MOODI.YKSI NEGBINOM.DIST = BINOMI.JAKAUMA.NEG NORM.DIST = NORMAALI.JAKAUMA NORM.INV = NORMAALI.JAKAUMA.KÄÄNT NORM.S.DIST = NORM_JAKAUMA.NORMIT NORM.S.INV = NORM_JAKAUMA.KÄÄNT PEARSON = PEARSON PERCENTILE.EXC = PROSENTTIPISTE.ULK PERCENTILE.INC = PROSENTTIPISTE.SIS PERCENTRANK.EXC = PROSENTTIJÄRJESTYS.ULK PERCENTRANK.INC = PROSENTTIJÄRJESTYS.SIS PERMUT = PERMUTAATIO PERMUTATIONA = PERMUTAATIOA PHI = FII POISSON.DIST = POISSON.JAKAUMA PROB = TODENNÄKÖISYYS QUARTILE.EXC = NELJÄNNES.ULK QUARTILE.INC = NELJÄNNES.SIS RANK.AVG = ARVON.MUKAAN.KESKIARVO RANK.EQ = ARVON.MUKAAN.TASAN RSQ = PEARSON.NELIÖ SKEW = JAKAUMAN.VINOUS SKEW.P = JAKAUMAN.VINOUS.POP SLOPE = KULMAKERROIN SMALL = PIENI STANDARDIZE = NORMITA STDEV.P = KESKIHAJONTA.P STDEV.S = KESKIHAJONTA.S STDEVA = KESKIHAJONTAA STDEVPA = KESKIHAJONTAPA STEYX = KESKIVIRHE T.DIST = T.JAKAUMA T.DIST.2T = T.JAKAUMA.2S T.DIST.RT = T.JAKAUMA.OH T.INV = T.KÄÄNT T.INV.2T = T.KÄÄNT.2S T.TEST = T.TESTI TREND = SUUNTAUS TRIMMEAN = KESKIARVO.TASATTU VAR.P = VAR.P VAR.S = VAR.S VARA = VARA VARPA = VARPA WEIBULL.DIST = WEIBULL.JAKAUMA Z.TEST = Z.TESTI ## ## Tekstifunktiot (Text Functions) ## BAHTTEXT = BAHTTEKSTI CHAR = MERKKI CLEAN = SIIVOA CODE = KOODI CONCAT = YHDISTÄ DOLLAR = VALUUTTA EXACT = VERTAA FIND = ETSI FIXED = KIINTEÄ ISTHAIDIGIT = ON.THAI.NUMERO LEFT = VASEN LEN = PITUUS LOWER = PIENET MID = POIMI.TEKSTI NUMBERSTRING = NROMERKKIJONO NUMBERVALUE = NROARVO PHONETIC = FONEETTINEN PROPER = ERISNIMI REPLACE = KORVAA REPT = TOISTA RIGHT = OIKEA SEARCH = KÄY.LÄPI SUBSTITUTE = VAIHDA T = T TEXT = TEKSTI TEXTJOIN = TEKSTI.YHDISTÄ THAIDIGIT = THAI.NUMERO THAINUMSOUND = THAI.LUKU.ÄÄNI THAINUMSTRING = THAI.LUKU.MERKKIJONO THAISTRINGLENGTH = THAI.MERKKIJONON.PITUUS TRIM = POISTA.VÄLIT UNICHAR = UNICODEMERKKI UNICODE = UNICODE UPPER = ISOT VALUE = ARVO ## ## Verkkofunktiot (Web Functions) ## ENCODEURL = URLKOODAUS FILTERXML = SUODATA.XML WEBSERVICE = VERKKOPALVELU ## ## Yhteensopivuusfunktiot (Compatibility Functions) ## BETADIST = BEETAJAKAUMA BETAINV = BEETAJAKAUMA.KÄÄNT BINOMDIST = BINOMIJAKAUMA CEILING = PYÖRISTÄ.KERR.YLÖS CHIDIST = CHIJAKAUMA CHIINV = CHIJAKAUMA.KÄÄNT CHITEST = CHITESTI CONCATENATE = KETJUTA CONFIDENCE = LUOTTAMUSVÄLI COVAR = KOVARIANSSI CRITBINOM = BINOMIJAKAUMA.KRIT EXPONDIST = EKSPONENTIAALIJAKAUMA FDIST = FJAKAUMA FINV = FJAKAUMA.KÄÄNT FLOOR = PYÖRISTÄ.KERR.ALAS FORECAST = ENNUSTE FTEST = FTESTI GAMMADIST = GAMMAJAKAUMA GAMMAINV = GAMMAJAKAUMA.KÄÄNT HYPGEOMDIST = HYPERGEOM.JAKAUMA LOGINV = LOGNORM.JAKAUMA.KÄÄNT LOGNORMDIST = LOGNORM.JAKAUMA MODE = MOODI NEGBINOMDIST = BINOMIJAKAUMA.NEG NORMDIST = NORM.JAKAUMA NORMINV = NORM.JAKAUMA.KÄÄNT NORMSDIST = NORM.JAKAUMA.NORMIT NORMSINV = NORM.JAKAUMA.NORMIT.KÄÄNT PERCENTILE = PROSENTTIPISTE PERCENTRANK = PROSENTTIJÄRJESTYS POISSON = POISSON QUARTILE = NELJÄNNES RANK = ARVON.MUKAAN STDEV = KESKIHAJONTA STDEVP = KESKIHAJONTAP TDIST = TJAKAUMA TINV = TJAKAUMA.KÄÄNT TTEST = TTESTI VAR = VAR VARP = VARP WEIBULL = WEIBULL ZTEST = ZTESTI phpspreadsheet/src/PhpSpreadsheet/Calculation/locale/fi/config 0000644 00000000521 15060132323 0020545 0 ustar 00 ############################################################ ## ## PhpSpreadsheet - locale settings ## ## Suomi (Finnish) ## ############################################################ ArgumentSeparator = ; ## ## Error Codes ## NULL = #TYHJÄ! DIV0 = #JAKO/0! VALUE = #ARVO! REF = #VIITTAUS! NAME = #NIMI? NUM = #LUKU! NA = #PUUTTUU! phpspreadsheet/src/PhpSpreadsheet/Calculation/locale/de/functions 0000644 00000023633 15060132323 0021313 0 ustar 00 ############################################################ ## ## PhpSpreadsheet - function name translations ## ## Deutsch (German) ## ############################################################ ## ## Cubefunktionen (Cube Functions) ## CUBEKPIMEMBER = CUBEKPIELEMENT CUBEMEMBER = CUBEELEMENT CUBEMEMBERPROPERTY = CUBEELEMENTEIGENSCHAFT CUBERANKEDMEMBER = CUBERANGELEMENT CUBESET = CUBEMENGE CUBESETCOUNT = CUBEMENGENANZAHL CUBEVALUE = CUBEWERT ## ## Datenbankfunktionen (Database Functions) ## DAVERAGE = DBMITTELWERT DCOUNT = DBANZAHL DCOUNTA = DBANZAHL2 DGET = DBAUSZUG DMAX = DBMAX DMIN = DBMIN DPRODUCT = DBPRODUKT DSTDEV = DBSTDABW DSTDEVP = DBSTDABWN DSUM = DBSUMME DVAR = DBVARIANZ DVARP = DBVARIANZEN ## ## Datums- und Uhrzeitfunktionen (Date & Time Functions) ## DATE = DATUM DATEVALUE = DATWERT DAY = TAG DAYS = TAGE DAYS360 = TAGE360 EDATE = EDATUM EOMONTH = MONATSENDE HOUR = STUNDE ISOWEEKNUM = ISOKALENDERWOCHE MINUTE = MINUTE MONTH = MONAT NETWORKDAYS = NETTOARBEITSTAGE NETWORKDAYS.INTL = NETTOARBEITSTAGE.INTL NOW = JETZT SECOND = SEKUNDE THAIDAYOFWEEK = THAIWOCHENTAG THAIMONTHOFYEAR = THAIMONATDESJAHRES THAIYEAR = THAIJAHR TIME = ZEIT TIMEVALUE = ZEITWERT TODAY = HEUTE WEEKDAY = WOCHENTAG WEEKNUM = KALENDERWOCHE WORKDAY = ARBEITSTAG WORKDAY.INTL = ARBEITSTAG.INTL YEAR = JAHR YEARFRAC = BRTEILJAHRE ## ## Technische Funktionen (Engineering Functions) ## BESSELI = BESSELI BESSELJ = BESSELJ BESSELK = BESSELK BESSELY = BESSELY BIN2DEC = BININDEZ BIN2HEX = BININHEX BIN2OCT = BININOKT BITAND = BITUND BITLSHIFT = BITLVERSCHIEB BITOR = BITODER BITRSHIFT = BITRVERSCHIEB BITXOR = BITXODER COMPLEX = KOMPLEXE CONVERT = UMWANDELN DEC2BIN = DEZINBIN DEC2HEX = DEZINHEX DEC2OCT = DEZINOKT DELTA = DELTA ERF = GAUSSFEHLER ERF.PRECISE = GAUSSF.GENAU ERFC = GAUSSFKOMPL ERFC.PRECISE = GAUSSFKOMPL.GENAU GESTEP = GGANZZAHL HEX2BIN = HEXINBIN HEX2DEC = HEXINDEZ HEX2OCT = HEXINOKT IMABS = IMABS IMAGINARY = IMAGINÄRTEIL IMARGUMENT = IMARGUMENT IMCONJUGATE = IMKONJUGIERTE IMCOS = IMCOS IMCOSH = IMCOSHYP IMCOT = IMCOT IMCSC = IMCOSEC IMCSCH = IMCOSECHYP IMDIV = IMDIV IMEXP = IMEXP IMLN = IMLN IMLOG10 = IMLOG10 IMLOG2 = IMLOG2 IMPOWER = IMAPOTENZ IMPRODUCT = IMPRODUKT IMREAL = IMREALTEIL IMSEC = IMSEC IMSECH = IMSECHYP IMSIN = IMSIN IMSINH = IMSINHYP IMSQRT = IMWURZEL IMSUB = IMSUB IMSUM = IMSUMME IMTAN = IMTAN OCT2BIN = OKTINBIN OCT2DEC = OKTINDEZ OCT2HEX = OKTINHEX ## ## Finanzmathematische Funktionen (Financial Functions) ## ACCRINT = AUFGELZINS ACCRINTM = AUFGELZINSF AMORDEGRC = AMORDEGRK AMORLINC = AMORLINEARK COUPDAYBS = ZINSTERMTAGVA COUPDAYS = ZINSTERMTAGE COUPDAYSNC = ZINSTERMTAGNZ COUPNCD = ZINSTERMNZ COUPNUM = ZINSTERMZAHL COUPPCD = ZINSTERMVZ CUMIPMT = KUMZINSZ CUMPRINC = KUMKAPITAL DB = GDA2 DDB = GDA DISC = DISAGIO DOLLARDE = NOTIERUNGDEZ DOLLARFR = NOTIERUNGBRU DURATION = DURATION EFFECT = EFFEKTIV FV = ZW FVSCHEDULE = ZW2 INTRATE = ZINSSATZ IPMT = ZINSZ IRR = IKV ISPMT = ISPMT MDURATION = MDURATION MIRR = QIKV NOMINAL = NOMINAL NPER = ZZR NPV = NBW ODDFPRICE = UNREGER.KURS ODDFYIELD = UNREGER.REND ODDLPRICE = UNREGLE.KURS ODDLYIELD = UNREGLE.REND PDURATION = PDURATION PMT = RMZ PPMT = KAPZ PRICE = KURS PRICEDISC = KURSDISAGIO PRICEMAT = KURSFÄLLIG PV = BW RATE = ZINS RECEIVED = AUSZAHLUNG RRI = ZSATZINVEST SLN = LIA SYD = DIA TBILLEQ = TBILLÄQUIV TBILLPRICE = TBILLKURS TBILLYIELD = TBILLRENDITE VDB = VDB XIRR = XINTZINSFUSS XNPV = XKAPITALWERT YIELD = RENDITE YIELDDISC = RENDITEDIS YIELDMAT = RENDITEFÄLL ## ## Informationsfunktionen (Information Functions) ## CELL = ZELLE ERROR.TYPE = FEHLER.TYP INFO = INFO ISBLANK = ISTLEER ISERR = ISTFEHL ISERROR = ISTFEHLER ISEVEN = ISTGERADE ISFORMULA = ISTFORMEL ISLOGICAL = ISTLOG ISNA = ISTNV ISNONTEXT = ISTKTEXT ISNUMBER = ISTZAHL ISODD = ISTUNGERADE ISREF = ISTBEZUG ISTEXT = ISTTEXT N = N NA = NV SHEET = BLATT SHEETS = BLÄTTER TYPE = TYP ## ## Logische Funktionen (Logical Functions) ## AND = UND FALSE = FALSCH IF = WENN IFERROR = WENNFEHLER IFNA = WENNNV IFS = WENNS NOT = NICHT OR = ODER SWITCH = ERSTERWERT TRUE = WAHR XOR = XODER ## ## Nachschlage- und Verweisfunktionen (Lookup & Reference Functions) ## ADDRESS = ADRESSE AREAS = BEREICHE CHOOSE = WAHL COLUMN = SPALTE COLUMNS = SPALTEN FORMULATEXT = FORMELTEXT GETPIVOTDATA = PIVOTDATENZUORDNEN HLOOKUP = WVERWEIS HYPERLINK = HYPERLINK INDEX = INDEX INDIRECT = INDIREKT LOOKUP = VERWEIS MATCH = VERGLEICH OFFSET = BEREICH.VERSCHIEBEN ROW = ZEILE ROWS = ZEILEN RTD = RTD TRANSPOSE = MTRANS VLOOKUP = SVERWEIS *RC = ZS ## ## Mathematische und trigonometrische Funktionen (Math & Trig Functions) ## ABS = ABS ACOS = ARCCOS ACOSH = ARCCOSHYP ACOT = ARCCOT ACOTH = ARCCOTHYP AGGREGATE = AGGREGAT ARABIC = ARABISCH ASIN = ARCSIN ASINH = ARCSINHYP ATAN = ARCTAN ATAN2 = ARCTAN2 ATANH = ARCTANHYP BASE = BASIS CEILING.MATH = OBERGRENZE.MATHEMATIK CEILING.PRECISE = OBERGRENZE.GENAU COMBIN = KOMBINATIONEN COMBINA = KOMBINATIONEN2 COS = COS COSH = COSHYP COT = COT COTH = COTHYP CSC = COSEC CSCH = COSECHYP DECIMAL = DEZIMAL DEGREES = GRAD ECMA.CEILING = ECMA.OBERGRENZE EVEN = GERADE EXP = EXP FACT = FAKULTÄT FACTDOUBLE = ZWEIFAKULTÄT FLOOR.MATH = UNTERGRENZE.MATHEMATIK FLOOR.PRECISE = UNTERGRENZE.GENAU GCD = GGT INT = GANZZAHL ISO.CEILING = ISO.OBERGRENZE LCM = KGV LN = LN LOG = LOG LOG10 = LOG10 MDETERM = MDET MINVERSE = MINV MMULT = MMULT MOD = REST MROUND = VRUNDEN MULTINOMIAL = POLYNOMIAL MUNIT = MEINHEIT ODD = UNGERADE PI = PI POWER = POTENZ PRODUCT = PRODUKT QUOTIENT = QUOTIENT RADIANS = BOGENMASS RAND = ZUFALLSZAHL RANDBETWEEN = ZUFALLSBEREICH ROMAN = RÖMISCH ROUND = RUNDEN ROUNDBAHTDOWN = RUNDBAHTNED ROUNDBAHTUP = BAHTAUFRUNDEN ROUNDDOWN = ABRUNDEN ROUNDUP = AUFRUNDEN SEC = SEC SECH = SECHYP SERIESSUM = POTENZREIHE SIGN = VORZEICHEN SIN = SIN SINH = SINHYP SQRT = WURZEL SQRTPI = WURZELPI SUBTOTAL = TEILERGEBNIS SUM = SUMME SUMIF = SUMMEWENN SUMIFS = SUMMEWENNS SUMPRODUCT = SUMMENPRODUKT SUMSQ = QUADRATESUMME SUMX2MY2 = SUMMEX2MY2 SUMX2PY2 = SUMMEX2PY2 SUMXMY2 = SUMMEXMY2 TAN = TAN TANH = TANHYP TRUNC = KÜRZEN ## ## Statistische Funktionen (Statistical Functions) ## AVEDEV = MITTELABW AVERAGE = MITTELWERT AVERAGEA = MITTELWERTA AVERAGEIF = MITTELWERTWENN AVERAGEIFS = MITTELWERTWENNS BETA.DIST = BETA.VERT BETA.INV = BETA.INV BINOM.DIST = BINOM.VERT BINOM.DIST.RANGE = BINOM.VERT.BEREICH BINOM.INV = BINOM.INV CHISQ.DIST = CHIQU.VERT CHISQ.DIST.RT = CHIQU.VERT.RE CHISQ.INV = CHIQU.INV CHISQ.INV.RT = CHIQU.INV.RE CHISQ.TEST = CHIQU.TEST CONFIDENCE.NORM = KONFIDENZ.NORM CONFIDENCE.T = KONFIDENZ.T CORREL = KORREL COUNT = ANZAHL COUNTA = ANZAHL2 COUNTBLANK = ANZAHLLEEREZELLEN COUNTIF = ZÄHLENWENN COUNTIFS = ZÄHLENWENNS COVARIANCE.P = KOVARIANZ.P COVARIANCE.S = KOVARIANZ.S DEVSQ = SUMQUADABW EXPON.DIST = EXPON.VERT F.DIST = F.VERT F.DIST.RT = F.VERT.RE F.INV = F.INV F.INV.RT = F.INV.RE F.TEST = F.TEST FISHER = FISHER FISHERINV = FISHERINV FORECAST.ETS = PROGNOSE.ETS FORECAST.ETS.CONFINT = PROGNOSE.ETS.KONFINT FORECAST.ETS.SEASONALITY = PROGNOSE.ETS.SAISONALITÄT FORECAST.ETS.STAT = PROGNOSE.ETS.STAT FORECAST.LINEAR = PROGNOSE.LINEAR FREQUENCY = HÄUFIGKEIT GAMMA = GAMMA GAMMA.DIST = GAMMA.VERT GAMMA.INV = GAMMA.INV GAMMALN = GAMMALN GAMMALN.PRECISE = GAMMALN.GENAU GAUSS = GAUSS GEOMEAN = GEOMITTEL GROWTH = VARIATION HARMEAN = HARMITTEL HYPGEOM.DIST = HYPGEOM.VERT INTERCEPT = ACHSENABSCHNITT KURT = KURT LARGE = KGRÖSSTE LINEST = RGP LOGEST = RKP LOGNORM.DIST = LOGNORM.VERT LOGNORM.INV = LOGNORM.INV MAX = MAX MAXA = MAXA MAXIFS = MAXWENNS MEDIAN = MEDIAN MIN = MIN MINA = MINA MINIFS = MINWENNS MODE.MULT = MODUS.VIELF MODE.SNGL = MODUS.EINF NEGBINOM.DIST = NEGBINOM.VERT NORM.DIST = NORM.VERT NORM.INV = NORM.INV NORM.S.DIST = NORM.S.VERT NORM.S.INV = NORM.S.INV PEARSON = PEARSON PERCENTILE.EXC = QUANTIL.EXKL PERCENTILE.INC = QUANTIL.INKL PERCENTRANK.EXC = QUANTILSRANG.EXKL PERCENTRANK.INC = QUANTILSRANG.INKL PERMUT = VARIATIONEN PERMUTATIONA = VARIATIONEN2 PHI = PHI POISSON.DIST = POISSON.VERT PROB = WAHRSCHBEREICH QUARTILE.EXC = QUARTILE.EXKL QUARTILE.INC = QUARTILE.INKL RANK.AVG = RANG.MITTELW RANK.EQ = RANG.GLEICH RSQ = BESTIMMTHEITSMASS SKEW = SCHIEFE SKEW.P = SCHIEFE.P SLOPE = STEIGUNG SMALL = KKLEINSTE STANDARDIZE = STANDARDISIERUNG STDEV.P = STABW.N STDEV.S = STABW.S STDEVA = STABWA STDEVPA = STABWNA STEYX = STFEHLERYX T.DIST = T.VERT T.DIST.2T = T.VERT.2S T.DIST.RT = T.VERT.RE T.INV = T.INV T.INV.2T = T.INV.2S T.TEST = T.TEST TREND = TREND TRIMMEAN = GESTUTZTMITTEL VAR.P = VAR.P VAR.S = VAR.S VARA = VARIANZA VARPA = VARIANZENA WEIBULL.DIST = WEIBULL.VERT Z.TEST = G.TEST ## ## Textfunktionen (Text Functions) ## BAHTTEXT = BAHTTEXT CHAR = ZEICHEN CLEAN = SÄUBERN CODE = CODE CONCAT = TEXTKETTE DOLLAR = DM EXACT = IDENTISCH FIND = FINDEN FIXED = FEST ISTHAIDIGIT = ISTTHAIZAHLENWORT LEFT = LINKS LEN = LÄNGE LOWER = KLEIN MID = TEIL NUMBERVALUE = ZAHLENWERT PROPER = GROSS2 REPLACE = ERSETZEN REPT = WIEDERHOLEN RIGHT = RECHTS SEARCH = SUCHEN SUBSTITUTE = WECHSELN T = T TEXT = TEXT TEXTJOIN = TEXTVERKETTEN THAIDIGIT = THAIZAHLENWORT THAINUMSOUND = THAIZAHLSOUND THAINUMSTRING = THAILANDSKNUMSTRENG THAISTRINGLENGTH = THAIZEICHENFOLGENLÄNGE TRIM = GLÄTTEN UNICHAR = UNIZEICHEN UNICODE = UNICODE UPPER = GROSS VALUE = WERT ## ## Webfunktionen (Web Functions) ## ENCODEURL = URLCODIEREN FILTERXML = XMLFILTERN WEBSERVICE = WEBDIENST ## ## Kompatibilitätsfunktionen (Compatibility Functions) ## BETADIST = BETAVERT BETAINV = BETAINV BINOMDIST = BINOMVERT CEILING = OBERGRENZE CHIDIST = CHIVERT CHIINV = CHIINV CHITEST = CHITEST CONCATENATE = VERKETTEN CONFIDENCE = KONFIDENZ COVAR = KOVAR CRITBINOM = KRITBINOM EXPONDIST = EXPONVERT FDIST = FVERT FINV = FINV FLOOR = UNTERGRENZE FORECAST = SCHÄTZER FTEST = FTEST GAMMADIST = GAMMAVERT GAMMAINV = GAMMAINV HYPGEOMDIST = HYPGEOMVERT LOGINV = LOGINV LOGNORMDIST = LOGNORMVERT MODE = MODALWERT NEGBINOMDIST = NEGBINOMVERT NORMDIST = NORMVERT NORMINV = NORMINV NORMSDIST = STANDNORMVERT NORMSINV = STANDNORMINV PERCENTILE = QUANTIL PERCENTRANK = QUANTILSRANG POISSON = POISSON QUARTILE = QUARTILE RANK = RANG STDEV = STABW STDEVP = STABWN TDIST = TVERT TINV = TINV TTEST = TTEST VAR = VARIANZ VARP = VARIANZEN WEIBULL = WEIBULL ZTEST = GTEST phpspreadsheet/src/PhpSpreadsheet/Calculation/locale/de/config 0000644 00000000452 15060132323 0020542 0 ustar 00 ############################################################ ## ## PhpSpreadsheet - locale settings ## ## Deutsch (German) ## ############################################################ ArgumentSeparator = ; ## ## Error Codes ## NULL DIV0 VALUE = #WERT! REF = #BEZUG! NAME NUM = #ZAHL! NA = #NV phpspreadsheet/src/PhpSpreadsheet/Calculation/locale/sv/functions 0000644 00000023241 15060132323 0021346 0 ustar 00 ############################################################ ## ## PhpSpreadsheet - function name translations ## ## Svenska (Swedish) ## ############################################################ ## ## Kubfunktioner (Cube Functions) ## CUBEKPIMEMBER = KUBKPIMEDLEM CUBEMEMBER = KUBMEDLEM CUBEMEMBERPROPERTY = KUBMEDLEMSEGENSKAP CUBERANKEDMEMBER = KUBRANGORDNADMEDLEM CUBESET = KUBUPPSÄTTNING CUBESETCOUNT = KUBUPPSÄTTNINGANTAL CUBEVALUE = KUBVÄRDE ## ## Databasfunktioner (Database Functions) ## DAVERAGE = DMEDEL DCOUNT = DANTAL DCOUNTA = DANTALV DGET = DHÄMTA DMAX = DMAX DMIN = DMIN DPRODUCT = DPRODUKT DSTDEV = DSTDAV DSTDEVP = DSTDAVP DSUM = DSUMMA DVAR = DVARIANS DVARP = DVARIANSP ## ## Tid- och datumfunktioner (Date & Time Functions) ## DATE = DATUM DATEVALUE = DATUMVÄRDE DAY = DAG DAYS = DAGAR DAYS360 = DAGAR360 EDATE = EDATUM EOMONTH = SLUTMÅNAD HOUR = TIMME ISOWEEKNUM = ISOVECKONR MINUTE = MINUT MONTH = MÅNAD NETWORKDAYS = NETTOARBETSDAGAR NETWORKDAYS.INTL = NETTOARBETSDAGAR.INT NOW = NU SECOND = SEKUND THAIDAYOFWEEK = THAIVECKODAG THAIMONTHOFYEAR = THAIMÅNAD THAIYEAR = THAIÅR TIME = KLOCKSLAG TIMEVALUE = TIDVÄRDE TODAY = IDAG WEEKDAY = VECKODAG WEEKNUM = VECKONR WORKDAY = ARBETSDAGAR WORKDAY.INTL = ARBETSDAGAR.INT YEAR = ÅR YEARFRAC = ÅRDEL ## ## Tekniska funktioner (Engineering Functions) ## BESSELI = BESSELI BESSELJ = BESSELJ BESSELK = BESSELK BESSELY = BESSELY BIN2DEC = BIN.TILL.DEC BIN2HEX = BIN.TILL.HEX BIN2OCT = BIN.TILL.OKT BITAND = BITOCH BITLSHIFT = BITVSKIFT BITOR = BITELLER BITRSHIFT = BITHSKIFT BITXOR = BITXELLER COMPLEX = KOMPLEX CONVERT = KONVERTERA DEC2BIN = DEC.TILL.BIN DEC2HEX = DEC.TILL.HEX DEC2OCT = DEC.TILL.OKT DELTA = DELTA ERF = FELF ERF.PRECISE = FELF.EXAKT ERFC = FELFK ERFC.PRECISE = FELFK.EXAKT GESTEP = SLSTEG HEX2BIN = HEX.TILL.BIN HEX2DEC = HEX.TILL.DEC HEX2OCT = HEX.TILL.OKT IMABS = IMABS IMAGINARY = IMAGINÄR IMARGUMENT = IMARGUMENT IMCONJUGATE = IMKONJUGAT IMCOS = IMCOS IMCOSH = IMCOSH IMCOT = IMCOT IMCSC = IMCSC IMCSCH = IMCSCH IMDIV = IMDIV IMEXP = IMEUPPHÖJT IMLN = IMLN IMLOG10 = IMLOG10 IMLOG2 = IMLOG2 IMPOWER = IMUPPHÖJT IMPRODUCT = IMPRODUKT IMREAL = IMREAL IMSEC = IMSEK IMSECH = IMSEKH IMSIN = IMSIN IMSINH = IMSINH IMSQRT = IMROT IMSUB = IMDIFF IMSUM = IMSUM IMTAN = IMTAN OCT2BIN = OKT.TILL.BIN OCT2DEC = OKT.TILL.DEC OCT2HEX = OKT.TILL.HEX ## ## Finansiella funktioner (Financial Functions) ## ACCRINT = UPPLRÄNTA ACCRINTM = UPPLOBLRÄNTA AMORDEGRC = AMORDEGRC AMORLINC = AMORLINC COUPDAYBS = KUPDAGBB COUPDAYS = KUPDAGB COUPDAYSNC = KUPDAGNK COUPNCD = KUPNKD COUPNUM = KUPANT COUPPCD = KUPFKD CUMIPMT = KUMRÄNTA CUMPRINC = KUMPRIS DB = DB DDB = DEGAVSKR DISC = DISK DOLLARDE = DECTAL DOLLARFR = BRÅK DURATION = LÖPTID EFFECT = EFFRÄNTA FV = SLUTVÄRDE FVSCHEDULE = FÖRRÄNTNING INTRATE = ÅRSRÄNTA IPMT = RBETALNING IRR = IR ISPMT = RALÅN MDURATION = MLÖPTID MIRR = MODIR NOMINAL = NOMRÄNTA NPER = PERIODER NPV = NETNUVÄRDE ODDFPRICE = UDDAFPRIS ODDFYIELD = UDDAFAVKASTNING ODDLPRICE = UDDASPRIS ODDLYIELD = UDDASAVKASTNING PDURATION = PLÖPTID PMT = BETALNING PPMT = AMORT PRICE = PRIS PRICEDISC = PRISDISK PRICEMAT = PRISFÖRF PV = NUVÄRDE RATE = RÄNTA RECEIVED = BELOPP RRI = AVKPÅINVEST SLN = LINAVSKR SYD = ÅRSAVSKR TBILLEQ = SSVXEKV TBILLPRICE = SSVXPRIS TBILLYIELD = SSVXRÄNTA VDB = VDEGRAVSKR XIRR = XIRR XNPV = XNUVÄRDE YIELD = NOMAVK YIELDDISC = NOMAVKDISK YIELDMAT = NOMAVKFÖRF ## ## Informationsfunktioner (Information Functions) ## CELL = CELL ERROR.TYPE = FEL.TYP INFO = INFO ISBLANK = ÄRTOM ISERR = ÄRF ISERROR = ÄRFEL ISEVEN = ÄRJÄMN ISFORMULA = ÄRFORMEL ISLOGICAL = ÄRLOGISK ISNA = ÄRSAKNAD ISNONTEXT = ÄREJTEXT ISNUMBER = ÄRTAL ISODD = ÄRUDDA ISREF = ÄRREF ISTEXT = ÄRTEXT N = N NA = SAKNAS SHEET = BLAD SHEETS = ANTALBLAD TYPE = VÄRDETYP ## ## Logiska funktioner (Logical Functions) ## AND = OCH FALSE = FALSKT IF = OM IFERROR = OMFEL IFNA = OMSAKNAS IFS = IFS NOT = ICKE OR = ELLER SWITCH = VÄXLA TRUE = SANT XOR = XELLER ## ## Sök- och referensfunktioner (Lookup & Reference Functions) ## ADDRESS = ADRESS AREAS = OMRÅDEN CHOOSE = VÄLJ COLUMN = KOLUMN COLUMNS = KOLUMNER FORMULATEXT = FORMELTEXT GETPIVOTDATA = HÄMTA.PIVOTDATA HLOOKUP = LETAKOLUMN HYPERLINK = HYPERLÄNK INDEX = INDEX INDIRECT = INDIREKT LOOKUP = LETAUPP MATCH = PASSA OFFSET = FÖRSKJUTNING ROW = RAD ROWS = RADER RTD = RTD TRANSPOSE = TRANSPONERA VLOOKUP = LETARAD *RC = RK ## ## Matematiska och trigonometriska funktioner (Math & Trig Functions) ## ABS = ABS ACOS = ARCCOS ACOSH = ARCCOSH ACOT = ARCCOT ACOTH = ARCCOTH AGGREGATE = MÄNGD ARABIC = ARABISKA ASIN = ARCSIN ASINH = ARCSINH ATAN = ARCTAN ATAN2 = ARCTAN2 ATANH = ARCTANH BASE = BAS CEILING.MATH = RUNDA.UPP.MATEMATISKT CEILING.PRECISE = RUNDA.UPP.EXAKT COMBIN = KOMBIN COMBINA = KOMBINA COS = COS COSH = COSH COT = COT COTH = COTH CSC = CSC CSCH = CSCH DECIMAL = DECIMAL DEGREES = GRADER ECMA.CEILING = ECMA.RUNDA.UPP EVEN = JÄMN EXP = EXP FACT = FAKULTET FACTDOUBLE = DUBBELFAKULTET FLOOR.MATH = RUNDA.NER.MATEMATISKT FLOOR.PRECISE = RUNDA.NER.EXAKT GCD = SGD INT = HELTAL ISO.CEILING = ISO.RUNDA.UPP LCM = MGM LN = LN LOG = LOG LOG10 = LOG10 MDETERM = MDETERM MINVERSE = MINVERT MMULT = MMULT MOD = REST MROUND = MAVRUNDA MULTINOMIAL = MULTINOMIAL MUNIT = MENHET ODD = UDDA PI = PI POWER = UPPHÖJT.TILL PRODUCT = PRODUKT QUOTIENT = KVOT RADIANS = RADIANER RAND = SLUMP RANDBETWEEN = SLUMP.MELLAN ROMAN = ROMERSK ROUND = AVRUNDA ROUNDBAHTDOWN = AVRUNDABAHTNEDÅT ROUNDBAHTUP = AVRUNDABAHTUPPÅT ROUNDDOWN = AVRUNDA.NEDÅT ROUNDUP = AVRUNDA.UPPÅT SEC = SEK SECH = SEKH SERIESSUM = SERIESUMMA SIGN = TECKEN SIN = SIN SINH = SINH SQRT = ROT SQRTPI = ROTPI SUBTOTAL = DELSUMMA SUM = SUMMA SUMIF = SUMMA.OM SUMIFS = SUMMA.OMF SUMPRODUCT = PRODUKTSUMMA SUMSQ = KVADRATSUMMA SUMX2MY2 = SUMMAX2MY2 SUMX2PY2 = SUMMAX2PY2 SUMXMY2 = SUMMAXMY2 TAN = TAN TANH = TANH TRUNC = AVKORTA ## ## Statistiska funktioner (Statistical Functions) ## AVEDEV = MEDELAVV AVERAGE = MEDEL AVERAGEA = AVERAGEA AVERAGEIF = MEDEL.OM AVERAGEIFS = MEDEL.OMF BETA.DIST = BETA.FÖRD BETA.INV = BETA.INV BINOM.DIST = BINOM.FÖRD BINOM.DIST.RANGE = BINOM.FÖRD.INTERVALL BINOM.INV = BINOM.INV CHISQ.DIST = CHI2.FÖRD CHISQ.DIST.RT = CHI2.FÖRD.RT CHISQ.INV = CHI2.INV CHISQ.INV.RT = CHI2.INV.RT CHISQ.TEST = CHI2.TEST CONFIDENCE.NORM = KONFIDENS.NORM CONFIDENCE.T = KONFIDENS.T CORREL = KORREL COUNT = ANTAL COUNTA = ANTALV COUNTBLANK = ANTAL.TOMMA COUNTIF = ANTAL.OM COUNTIFS = ANTAL.OMF COVARIANCE.P = KOVARIANS.P COVARIANCE.S = KOVARIANS.S DEVSQ = KVADAVV EXPON.DIST = EXPON.FÖRD F.DIST = F.FÖRD F.DIST.RT = F.FÖRD.RT F.INV = F.INV F.INV.RT = F.INV.RT F.TEST = F.TEST FISHER = FISHER FISHERINV = FISHERINV FORECAST.ETS = PROGNOS.ETS FORECAST.ETS.CONFINT = PROGNOS.ETS.KONFINT FORECAST.ETS.SEASONALITY = PROGNOS.ETS.SÄSONGSBEROENDE FORECAST.ETS.STAT = PROGNOS.ETS.STAT FORECAST.LINEAR = PROGNOS.LINJÄR FREQUENCY = FREKVENS GAMMA = GAMMA GAMMA.DIST = GAMMA.FÖRD GAMMA.INV = GAMMA.INV GAMMALN = GAMMALN GAMMALN.PRECISE = GAMMALN.EXAKT GAUSS = GAUSS GEOMEAN = GEOMEDEL GROWTH = EXPTREND HARMEAN = HARMMEDEL HYPGEOM.DIST = HYPGEOM.FÖRD INTERCEPT = SKÄRNINGSPUNKT KURT = TOPPIGHET LARGE = STÖRSTA LINEST = REGR LOGEST = EXPREGR LOGNORM.DIST = LOGNORM.FÖRD LOGNORM.INV = LOGNORM.INV MAX = MAX MAXA = MAXA MAXIFS = MAXIFS MEDIAN = MEDIAN MIN = MIN MINA = MINA MINIFS = MINIFS MODE.MULT = TYPVÄRDE.FLERA MODE.SNGL = TYPVÄRDE.ETT NEGBINOM.DIST = NEGBINOM.FÖRD NORM.DIST = NORM.FÖRD NORM.INV = NORM.INV NORM.S.DIST = NORM.S.FÖRD NORM.S.INV = NORM.S.INV PEARSON = PEARSON PERCENTILE.EXC = PERCENTIL.EXK PERCENTILE.INC = PERCENTIL.INK PERCENTRANK.EXC = PROCENTRANG.EXK PERCENTRANK.INC = PROCENTRANG.INK PERMUT = PERMUT PERMUTATIONA = PERMUTATIONA PHI = PHI POISSON.DIST = POISSON.FÖRD PROB = SANNOLIKHET QUARTILE.EXC = KVARTIL.EXK QUARTILE.INC = KVARTIL.INK RANK.AVG = RANG.MED RANK.EQ = RANG.EKV RSQ = RKV SKEW = SNEDHET SKEW.P = SNEDHET.P SLOPE = LUTNING SMALL = MINSTA STANDARDIZE = STANDARDISERA STDEV.P = STDAV.P STDEV.S = STDAV.S STDEVA = STDEVA STDEVPA = STDEVPA STEYX = STDFELYX T.DIST = T.FÖRD T.DIST.2T = T.FÖRD.2T T.DIST.RT = T.FÖRD.RT T.INV = T.INV T.INV.2T = T.INV.2T T.TEST = T.TEST TREND = TREND TRIMMEAN = TRIMMEDEL VAR.P = VARIANS.P VAR.S = VARIANS.S VARA = VARA VARPA = VARPA WEIBULL.DIST = WEIBULL.FÖRD Z.TEST = Z.TEST ## ## Textfunktioner (Text Functions) ## BAHTTEXT = BAHTTEXT CHAR = TECKENKOD CLEAN = STÄDA CODE = KOD CONCAT = SAMMAN DOLLAR = VALUTA EXACT = EXAKT FIND = HITTA FIXED = FASTTAL LEFT = VÄNSTER LEN = LÄNGD LOWER = GEMENER MID = EXTEXT NUMBERVALUE = TALVÄRDE PROPER = INITIAL REPLACE = ERSÄTT REPT = REP RIGHT = HÖGER SEARCH = SÖK SUBSTITUTE = BYT.UT T = T TEXT = TEXT TEXTJOIN = TEXTJOIN THAIDIGIT = THAISIFFRA THAINUMSOUND = THAITALLJUD THAINUMSTRING = THAITALSTRÄNG THAISTRINGLENGTH = THAISTRÄNGLÄNGD TRIM = RENSA UNICHAR = UNITECKENKOD UNICODE = UNICODE UPPER = VERSALER VALUE = TEXTNUM ## ## Webbfunktioner (Web Functions) ## ENCODEURL = KODAWEBBADRESS FILTERXML = FILTRERAXML WEBSERVICE = WEBBTJÄNST ## ## Kompatibilitetsfunktioner (Compatibility Functions) ## BETADIST = BETAFÖRD BETAINV = BETAINV BINOMDIST = BINOMFÖRD CEILING = RUNDA.UPP CHIDIST = CHI2FÖRD CHIINV = CHI2INV CHITEST = CHI2TEST CONCATENATE = SAMMANFOGA CONFIDENCE = KONFIDENS COVAR = KOVAR CRITBINOM = KRITBINOM EXPONDIST = EXPONFÖRD FDIST = FFÖRD FINV = FINV FLOOR = RUNDA.NER FORECAST = PREDIKTION FTEST = FTEST GAMMADIST = GAMMAFÖRD GAMMAINV = GAMMAINV HYPGEOMDIST = HYPGEOMFÖRD LOGINV = LOGINV LOGNORMDIST = LOGNORMFÖRD MODE = TYPVÄRDE NEGBINOMDIST = NEGBINOMFÖRD NORMDIST = NORMFÖRD NORMINV = NORMINV NORMSDIST = NORMSFÖRD NORMSINV = NORMSINV PERCENTILE = PERCENTIL PERCENTRANK = PROCENTRANG POISSON = POISSON QUARTILE = KVARTIL RANK = RANG STDEV = STDAV STDEVP = STDAVP TDIST = TFÖRD TINV = TINV TTEST = TTEST VAR = VARIANS VARP = VARIANSP WEIBULL = WEIBULL ZTEST = ZTEST phpspreadsheet/src/PhpSpreadsheet/Calculation/locale/sv/config 0000644 00000000542 15060132323 0020602 0 ustar 00 ############################################################ ## ## PhpSpreadsheet - locale settings ## ## Svenska (Swedish) ## ############################################################ ArgumentSeparator = ; ## ## Error Codes ## NULL = #SKÄRNING! DIV0 = #DIVISION/0! VALUE = #VÄRDEFEL! REF = #REFERENS! NAME = #NAMN? NUM = #OGILTIGT! NA = #SAKNAS! phpspreadsheet/src/PhpSpreadsheet/Calculation/locale/es/functions 0000644 00000024714 15060132323 0021333 0 ustar 00 ############################################################ ## ## PhpSpreadsheet - function name translations ## ## Español (Spanish) ## ############################################################ ## ## Funciones de cubo (Cube Functions) ## CUBEKPIMEMBER = MIEMBROKPICUBO CUBEMEMBER = MIEMBROCUBO CUBEMEMBERPROPERTY = PROPIEDADMIEMBROCUBO CUBERANKEDMEMBER = MIEMBRORANGOCUBO CUBESET = CONJUNTOCUBO CUBESETCOUNT = RECUENTOCONJUNTOCUBO CUBEVALUE = VALORCUBO ## ## Funciones de base de datos (Database Functions) ## DAVERAGE = BDPROMEDIO DCOUNT = BDCONTAR DCOUNTA = BDCONTARA DGET = BDEXTRAER DMAX = BDMAX DMIN = BDMIN DPRODUCT = BDPRODUCTO DSTDEV = BDDESVEST DSTDEVP = BDDESVESTP DSUM = BDSUMA DVAR = BDVAR DVARP = BDVARP ## ## Funciones de fecha y hora (Date & Time Functions) ## DATE = FECHA DATEDIF = SIFECHA DATESTRING = CADENA.FECHA DATEVALUE = FECHANUMERO DAY = DIA DAYS = DIAS DAYS360 = DIAS360 EDATE = FECHA.MES EOMONTH = FIN.MES HOUR = HORA ISOWEEKNUM = ISO.NUM.DE.SEMANA MINUTE = MINUTO MONTH = MES NETWORKDAYS = DIAS.LAB NETWORKDAYS.INTL = DIAS.LAB.INTL NOW = AHORA SECOND = SEGUNDO THAIDAYOFWEEK = DIASEMTAI THAIMONTHOFYEAR = MESAÑOTAI THAIYEAR = AÑOTAI TIME = NSHORA TIMEVALUE = HORANUMERO TODAY = HOY WEEKDAY = DIASEM WEEKNUM = NUM.DE.SEMANA WORKDAY = DIA.LAB WORKDAY.INTL = DIA.LAB.INTL YEAR = AÑO YEARFRAC = FRAC.AÑO ## ## Funciones de ingeniería (Engineering Functions) ## BESSELI = BESSELI BESSELJ = BESSELJ BESSELK = BESSELK BESSELY = BESSELY BIN2DEC = BIN.A.DEC BIN2HEX = BIN.A.HEX BIN2OCT = BIN.A.OCT BITAND = BIT.Y BITLSHIFT = BIT.DESPLIZQDA BITOR = BIT.O BITRSHIFT = BIT.DESPLDCHA BITXOR = BIT.XO COMPLEX = COMPLEJO CONVERT = CONVERTIR DEC2BIN = DEC.A.BIN DEC2HEX = DEC.A.HEX DEC2OCT = DEC.A.OCT DELTA = DELTA ERF = FUN.ERROR ERF.PRECISE = FUN.ERROR.EXACTO ERFC = FUN.ERROR.COMPL ERFC.PRECISE = FUN.ERROR.COMPL.EXACTO GESTEP = MAYOR.O.IGUAL HEX2BIN = HEX.A.BIN HEX2DEC = HEX.A.DEC HEX2OCT = HEX.A.OCT IMABS = IM.ABS IMAGINARY = IMAGINARIO IMARGUMENT = IM.ANGULO IMCONJUGATE = IM.CONJUGADA IMCOS = IM.COS IMCOSH = IM.COSH IMCOT = IM.COT IMCSC = IM.CSC IMCSCH = IM.CSCH IMDIV = IM.DIV IMEXP = IM.EXP IMLN = IM.LN IMLOG10 = IM.LOG10 IMLOG2 = IM.LOG2 IMPOWER = IM.POT IMPRODUCT = IM.PRODUCT IMREAL = IM.REAL IMSEC = IM.SEC IMSECH = IM.SECH IMSIN = IM.SENO IMSINH = IM.SENOH IMSQRT = IM.RAIZ2 IMSUB = IM.SUSTR IMSUM = IM.SUM IMTAN = IM.TAN OCT2BIN = OCT.A.BIN OCT2DEC = OCT.A.DEC OCT2HEX = OCT.A.HEX ## ## Funciones financieras (Financial Functions) ## ACCRINT = INT.ACUM ACCRINTM = INT.ACUM.V AMORDEGRC = AMORTIZ.PROGRE AMORLINC = AMORTIZ.LIN COUPDAYBS = CUPON.DIAS.L1 COUPDAYS = CUPON.DIAS COUPDAYSNC = CUPON.DIAS.L2 COUPNCD = CUPON.FECHA.L2 COUPNUM = CUPON.NUM COUPPCD = CUPON.FECHA.L1 CUMIPMT = PAGO.INT.ENTRE CUMPRINC = PAGO.PRINC.ENTRE DB = DB DDB = DDB DISC = TASA.DESC DOLLARDE = MONEDA.DEC DOLLARFR = MONEDA.FRAC DURATION = DURACION EFFECT = INT.EFECTIVO FV = VF FVSCHEDULE = VF.PLAN INTRATE = TASA.INT IPMT = PAGOINT IRR = TIR ISPMT = INT.PAGO.DIR MDURATION = DURACION.MODIF MIRR = TIRM NOMINAL = TASA.NOMINAL NPER = NPER NPV = VNA ODDFPRICE = PRECIO.PER.IRREGULAR.1 ODDFYIELD = RENDTO.PER.IRREGULAR.1 ODDLPRICE = PRECIO.PER.IRREGULAR.2 ODDLYIELD = RENDTO.PER.IRREGULAR.2 PDURATION = P.DURACION PMT = PAGO PPMT = PAGOPRIN PRICE = PRECIO PRICEDISC = PRECIO.DESCUENTO PRICEMAT = PRECIO.VENCIMIENTO PV = VA RATE = TASA RECEIVED = CANTIDAD.RECIBIDA RRI = RRI SLN = SLN SYD = SYD TBILLEQ = LETRA.DE.TEST.EQV.A.BONO TBILLPRICE = LETRA.DE.TES.PRECIO TBILLYIELD = LETRA.DE.TES.RENDTO VDB = DVS XIRR = TIR.NO.PER XNPV = VNA.NO.PER YIELD = RENDTO YIELDDISC = RENDTO.DESC YIELDMAT = RENDTO.VENCTO ## ## Funciones de información (Information Functions) ## CELL = CELDA ERROR.TYPE = TIPO.DE.ERROR INFO = INFO ISBLANK = ESBLANCO ISERR = ESERR ISERROR = ESERROR ISEVEN = ES.PAR ISFORMULA = ESFORMULA ISLOGICAL = ESLOGICO ISNA = ESNOD ISNONTEXT = ESNOTEXTO ISNUMBER = ESNUMERO ISODD = ES.IMPAR ISREF = ESREF ISTEXT = ESTEXTO N = N NA = NOD SHEET = HOJA SHEETS = HOJAS TYPE = TIPO ## ## Funciones lógicas (Logical Functions) ## AND = Y FALSE = FALSO IF = SI IFERROR = SI.ERROR IFNA = SI.ND IFS = SI.CONJUNTO NOT = NO OR = O SWITCH = CAMBIAR TRUE = VERDADERO XOR = XO ## ## Funciones de búsqueda y referencia (Lookup & Reference Functions) ## ADDRESS = DIRECCION AREAS = AREAS CHOOSE = ELEGIR COLUMN = COLUMNA COLUMNS = COLUMNAS FORMULATEXT = FORMULATEXTO GETPIVOTDATA = IMPORTARDATOSDINAMICOS HLOOKUP = BUSCARH HYPERLINK = HIPERVINCULO INDEX = INDICE INDIRECT = INDIRECTO LOOKUP = BUSCAR MATCH = COINCIDIR OFFSET = DESREF ROW = FILA ROWS = FILAS RTD = RDTR TRANSPOSE = TRANSPONER VLOOKUP = BUSCARV *RC = FC ## ## Funciones matemáticas y trigonométricas (Math & Trig Functions) ## ABS = ABS ACOS = ACOS ACOSH = ACOSH ACOT = ACOT ACOTH = ACOTH AGGREGATE = AGREGAR ARABIC = NUMERO.ARABE ASIN = ASENO ASINH = ASENOH ATAN = ATAN ATAN2 = ATAN2 ATANH = ATANH BASE = BASE CEILING.MATH = MULTIPLO.SUPERIOR.MAT CEILING.PRECISE = MULTIPLO.SUPERIOR.EXACTO COMBIN = COMBINAT COMBINA = COMBINA COS = COS COSH = COSH COT = COT COTH = COTH CSC = CSC CSCH = CSCH DECIMAL = CONV.DECIMAL DEGREES = GRADOS ECMA.CEILING = MULTIPLO.SUPERIOR.ECMA EVEN = REDONDEA.PAR EXP = EXP FACT = FACT FACTDOUBLE = FACT.DOBLE FLOOR.MATH = MULTIPLO.INFERIOR.MAT FLOOR.PRECISE = MULTIPLO.INFERIOR.EXACTO GCD = M.C.D INT = ENTERO ISO.CEILING = MULTIPLO.SUPERIOR.ISO LCM = M.C.M LN = LN LOG = LOG LOG10 = LOG10 MDETERM = MDETERM MINVERSE = MINVERSA MMULT = MMULT MOD = RESIDUO MROUND = REDOND.MULT MULTINOMIAL = MULTINOMIAL MUNIT = M.UNIDAD ODD = REDONDEA.IMPAR PI = PI POWER = POTENCIA PRODUCT = PRODUCTO QUOTIENT = COCIENTE RADIANS = RADIANES RAND = ALEATORIO RANDBETWEEN = ALEATORIO.ENTRE ROMAN = NUMERO.ROMANO ROUND = REDONDEAR ROUNDBAHTDOWN = REDONDEAR.BAHT.MAS ROUNDBAHTUP = REDONDEAR.BAHT.MENOS ROUNDDOWN = REDONDEAR.MENOS ROUNDUP = REDONDEAR.MAS SEC = SEC SECH = SECH SERIESSUM = SUMA.SERIES SIGN = SIGNO SIN = SENO SINH = SENOH SQRT = RAIZ SQRTPI = RAIZ2PI SUBTOTAL = SUBTOTALES SUM = SUMA SUMIF = SUMAR.SI SUMIFS = SUMAR.SI.CONJUNTO SUMPRODUCT = SUMAPRODUCTO SUMSQ = SUMA.CUADRADOS SUMX2MY2 = SUMAX2MENOSY2 SUMX2PY2 = SUMAX2MASY2 SUMXMY2 = SUMAXMENOSY2 TAN = TAN TANH = TANH TRUNC = TRUNCAR ## ## Funciones estadísticas (Statistical Functions) ## AVEDEV = DESVPROM AVERAGE = PROMEDIO AVERAGEA = PROMEDIOA AVERAGEIF = PROMEDIO.SI AVERAGEIFS = PROMEDIO.SI.CONJUNTO BETA.DIST = DISTR.BETA.N BETA.INV = INV.BETA.N BINOM.DIST = DISTR.BINOM.N BINOM.DIST.RANGE = DISTR.BINOM.SERIE BINOM.INV = INV.BINOM CHISQ.DIST = DISTR.CHICUAD CHISQ.DIST.RT = DISTR.CHICUAD.CD CHISQ.INV = INV.CHICUAD CHISQ.INV.RT = INV.CHICUAD.CD CHISQ.TEST = PRUEBA.CHICUAD CONFIDENCE.NORM = INTERVALO.CONFIANZA.NORM CONFIDENCE.T = INTERVALO.CONFIANZA.T CORREL = COEF.DE.CORREL COUNT = CONTAR COUNTA = CONTARA COUNTBLANK = CONTAR.BLANCO COUNTIF = CONTAR.SI COUNTIFS = CONTAR.SI.CONJUNTO COVARIANCE.P = COVARIANCE.P COVARIANCE.S = COVARIANZA.M DEVSQ = DESVIA2 EXPON.DIST = DISTR.EXP.N F.DIST = DISTR.F.N F.DIST.RT = DISTR.F.CD F.INV = INV.F F.INV.RT = INV.F.CD F.TEST = PRUEBA.F.N FISHER = FISHER FISHERINV = PRUEBA.FISHER.INV FORECAST.ETS = PRONOSTICO.ETS FORECAST.ETS.CONFINT = PRONOSTICO.ETS.CONFINT FORECAST.ETS.SEASONALITY = PRONOSTICO.ETS.ESTACIONALIDAD FORECAST.ETS.STAT = PRONOSTICO.ETS.STAT FORECAST.LINEAR = PRONOSTICO.LINEAL FREQUENCY = FRECUENCIA GAMMA = GAMMA GAMMA.DIST = DISTR.GAMMA.N GAMMA.INV = INV.GAMMA GAMMALN = GAMMA.LN GAMMALN.PRECISE = GAMMA.LN.EXACTO GAUSS = GAUSS GEOMEAN = MEDIA.GEOM GROWTH = CRECIMIENTO HARMEAN = MEDIA.ARMO HYPGEOM.DIST = DISTR.HIPERGEOM.N INTERCEPT = INTERSECCION.EJE KURT = CURTOSIS LARGE = K.ESIMO.MAYOR LINEST = ESTIMACION.LINEAL LOGEST = ESTIMACION.LOGARITMICA LOGNORM.DIST = DISTR.LOGNORM LOGNORM.INV = INV.LOGNORM MAX = MAX MAXA = MAXA MAXIFS = MAX.SI.CONJUNTO MEDIAN = MEDIANA MIN = MIN MINA = MINA MINIFS = MIN.SI.CONJUNTO MODE.MULT = MODA.VARIOS MODE.SNGL = MODA.UNO NEGBINOM.DIST = NEGBINOM.DIST NORM.DIST = DISTR.NORM.N NORM.INV = INV.NORM NORM.S.DIST = DISTR.NORM.ESTAND.N NORM.S.INV = INV.NORM.ESTAND PEARSON = PEARSON PERCENTILE.EXC = PERCENTIL.EXC PERCENTILE.INC = PERCENTIL.INC PERCENTRANK.EXC = RANGO.PERCENTIL.EXC PERCENTRANK.INC = RANGO.PERCENTIL.INC PERMUT = PERMUTACIONES PERMUTATIONA = PERMUTACIONES.A PHI = FI POISSON.DIST = POISSON.DIST PROB = PROBABILIDAD QUARTILE.EXC = CUARTIL.EXC QUARTILE.INC = CUARTIL.INC RANK.AVG = JERARQUIA.MEDIA RANK.EQ = JERARQUIA.EQV RSQ = COEFICIENTE.R2 SKEW = COEFICIENTE.ASIMETRIA SKEW.P = COEFICIENTE.ASIMETRIA.P SLOPE = PENDIENTE SMALL = K.ESIMO.MENOR STANDARDIZE = NORMALIZACION STDEV.P = DESVEST.P STDEV.S = DESVEST.M STDEVA = DESVESTA STDEVPA = DESVESTPA STEYX = ERROR.TIPICO.XY T.DIST = DISTR.T.N T.DIST.2T = DISTR.T.2C T.DIST.RT = DISTR.T.CD T.INV = INV.T T.INV.2T = INV.T.2C T.TEST = PRUEBA.T.N TREND = TENDENCIA TRIMMEAN = MEDIA.ACOTADA VAR.P = VAR.P VAR.S = VAR.S VARA = VARA VARPA = VARPA WEIBULL.DIST = DISTR.WEIBULL Z.TEST = PRUEBA.Z.N ## ## Funciones de texto (Text Functions) ## BAHTTEXT = TEXTOBAHT CHAR = CARACTER CLEAN = LIMPIAR CODE = CODIGO CONCAT = CONCAT DOLLAR = MONEDA EXACT = IGUAL FIND = ENCONTRAR FIXED = DECIMAL ISTHAIDIGIT = ESDIGITOTAI LEFT = IZQUIERDA LEN = LARGO LOWER = MINUSC MID = EXTRAE NUMBERSTRING = CADENA.NUMERO NUMBERVALUE = VALOR.NUMERO PHONETIC = FONETICO PROPER = NOMPROPIO REPLACE = REEMPLAZAR REPT = REPETIR RIGHT = DERECHA SEARCH = HALLAR SUBSTITUTE = SUSTITUIR T = T TEXT = TEXTO TEXTJOIN = UNIRCADENAS THAIDIGIT = DIGITOTAI THAINUMSOUND = SONNUMTAI THAINUMSTRING = CADENANUMTAI THAISTRINGLENGTH = LONGCADENATAI TRIM = ESPACIOS UNICHAR = UNICAR UNICODE = UNICODE UPPER = MAYUSC VALUE = VALOR ## ## Funciones web (Web Functions) ## ENCODEURL = URLCODIF FILTERXML = XMLFILTRO WEBSERVICE = SERVICIOWEB ## ## Funciones de compatibilidad (Compatibility Functions) ## BETADIST = DISTR.BETA BETAINV = DISTR.BETA.INV BINOMDIST = DISTR.BINOM CEILING = MULTIPLO.SUPERIOR CHIDIST = DISTR.CHI CHIINV = PRUEBA.CHI.INV CHITEST = PRUEBA.CHI CONCATENATE = CONCATENAR CONFIDENCE = INTERVALO.CONFIANZA COVAR = COVAR CRITBINOM = BINOM.CRIT EXPONDIST = DISTR.EXP FDIST = DISTR.F FINV = DISTR.F.INV FLOOR = MULTIPLO.INFERIOR FORECAST = PRONOSTICO FTEST = PRUEBA.F GAMMADIST = DISTR.GAMMA GAMMAINV = DISTR.GAMMA.INV HYPGEOMDIST = DISTR.HIPERGEOM LOGINV = DISTR.LOG.INV LOGNORMDIST = DISTR.LOG.NORM MODE = MODA NEGBINOMDIST = NEGBINOMDIST NORMDIST = DISTR.NORM NORMINV = DISTR.NORM.INV NORMSDIST = DISTR.NORM.ESTAND NORMSINV = DISTR.NORM.ESTAND.INV PERCENTILE = PERCENTIL PERCENTRANK = RANGO.PERCENTIL POISSON = POISSON QUARTILE = CUARTIL RANK = JERARQUIA STDEV = DESVEST STDEVP = DESVESTP TDIST = DISTR.T TINV = DISTR.T.INV TTEST = PRUEBA.T VAR = VAR VARP = VARP WEIBULL = DIST.WEIBULL ZTEST = PRUEBA.Z phpspreadsheet/src/PhpSpreadsheet/Calculation/locale/es/config 0000644 00000000516 15060132323 0020562 0 ustar 00 ############################################################ ## ## PhpSpreadsheet - locale settings ## ## Español (Spanish) ## ############################################################ ArgumentSeparator = ; ## ## Error Codes ## NULL = #¡NULO! DIV0 = #¡DIV/0! VALUE = #¡VALOR! REF = #¡REF! NAME = #¿NOMBRE? NUM = #¡NUM! NA phpspreadsheet/src/PhpSpreadsheet/Calculation/locale/nl/functions 0000644 00000024377 15060132323 0021342 0 ustar 00 ############################################################ ## ## PhpSpreadsheet - function name translations ## ## Nederlands (Dutch) ## ############################################################ ## ## Kubusfuncties (Cube Functions) ## CUBEKPIMEMBER = KUBUSKPILID CUBEMEMBER = KUBUSLID CUBEMEMBERPROPERTY = KUBUSLIDEIGENSCHAP CUBERANKEDMEMBER = KUBUSGERANGSCHIKTLID CUBESET = KUBUSSET CUBESETCOUNT = KUBUSSETAANTAL CUBEVALUE = KUBUSWAARDE ## ## Databasefuncties (Database Functions) ## DAVERAGE = DBGEMIDDELDE DCOUNT = DBAANTAL DCOUNTA = DBAANTALC DGET = DBLEZEN DMAX = DBMAX DMIN = DBMIN DPRODUCT = DBPRODUCT DSTDEV = DBSTDEV DSTDEVP = DBSTDEVP DSUM = DBSOM DVAR = DBVAR DVARP = DBVARP ## ## Datum- en tijdfuncties (Date & Time Functions) ## DATE = DATUM DATESTRING = DATUMNOTATIE DATEVALUE = DATUMWAARDE DAY = DAG DAYS = DAGEN DAYS360 = DAGEN360 EDATE = ZELFDE.DAG EOMONTH = LAATSTE.DAG HOUR = UUR ISOWEEKNUM = ISO.WEEKNUMMER MINUTE = MINUUT MONTH = MAAND NETWORKDAYS = NETTO.WERKDAGEN NETWORKDAYS.INTL = NETWERKDAGEN.INTL NOW = NU SECOND = SECONDE THAIDAYOFWEEK = THAIS.WEEKDAG THAIMONTHOFYEAR = THAIS.MAAND.VAN.JAAR THAIYEAR = THAIS.JAAR TIME = TIJD TIMEVALUE = TIJDWAARDE TODAY = VANDAAG WEEKDAY = WEEKDAG WEEKNUM = WEEKNUMMER WORKDAY = WERKDAG WORKDAY.INTL = WERKDAG.INTL YEAR = JAAR YEARFRAC = JAAR.DEEL ## ## Technische functies (Engineering Functions) ## BESSELI = BESSEL.I BESSELJ = BESSEL.J BESSELK = BESSEL.K BESSELY = BESSEL.Y BIN2DEC = BIN.N.DEC BIN2HEX = BIN.N.HEX BIN2OCT = BIN.N.OCT BITAND = BIT.EN BITLSHIFT = BIT.VERSCHUIF.LINKS BITOR = BIT.OF BITRSHIFT = BIT.VERSCHUIF.RECHTS BITXOR = BIT.EX.OF COMPLEX = COMPLEX CONVERT = CONVERTEREN DEC2BIN = DEC.N.BIN DEC2HEX = DEC.N.HEX DEC2OCT = DEC.N.OCT DELTA = DELTA ERF = FOUTFUNCTIE ERF.PRECISE = FOUTFUNCTIE.NAUWKEURIG ERFC = FOUT.COMPLEMENT ERFC.PRECISE = FOUT.COMPLEMENT.NAUWKEURIG GESTEP = GROTER.DAN HEX2BIN = HEX.N.BIN HEX2DEC = HEX.N.DEC HEX2OCT = HEX.N.OCT IMABS = C.ABS IMAGINARY = C.IM.DEEL IMARGUMENT = C.ARGUMENT IMCONJUGATE = C.TOEGEVOEGD IMCOS = C.COS IMCOSH = C.COSH IMCOT = C.COT IMCSC = C.COSEC IMCSCH = C.COSECH IMDIV = C.QUOTIENT IMEXP = C.EXP IMLN = C.LN IMLOG10 = C.LOG10 IMLOG2 = C.LOG2 IMPOWER = C.MACHT IMPRODUCT = C.PRODUCT IMREAL = C.REEEL.DEEL IMSEC = C.SEC IMSECH = C.SECH IMSIN = C.SIN IMSINH = C.SINH IMSQRT = C.WORTEL IMSUB = C.VERSCHIL IMSUM = C.SOM IMTAN = C.TAN OCT2BIN = OCT.N.BIN OCT2DEC = OCT.N.DEC OCT2HEX = OCT.N.HEX ## ## Financiële functies (Financial Functions) ## ACCRINT = SAMENG.RENTE ACCRINTM = SAMENG.RENTE.V AMORDEGRC = AMORDEGRC AMORLINC = AMORLINC COUPDAYBS = COUP.DAGEN.BB COUPDAYS = COUP.DAGEN COUPDAYSNC = COUP.DAGEN.VV COUPNCD = COUP.DATUM.NB COUPNUM = COUP.AANTAL COUPPCD = COUP.DATUM.VB CUMIPMT = CUM.RENTE CUMPRINC = CUM.HOOFDSOM DB = DB DDB = DDB DISC = DISCONTO DOLLARDE = EURO.DE DOLLARFR = EURO.BR DURATION = DUUR EFFECT = EFFECT.RENTE FV = TW FVSCHEDULE = TOEK.WAARDE2 INTRATE = RENTEPERCENTAGE IPMT = IBET IRR = IR ISPMT = ISBET MDURATION = AANG.DUUR MIRR = GIR NOMINAL = NOMINALE.RENTE NPER = NPER NPV = NHW ODDFPRICE = AFW.ET.PRIJS ODDFYIELD = AFW.ET.REND ODDLPRICE = AFW.LT.PRIJS ODDLYIELD = AFW.LT.REND PDURATION = PDUUR PMT = BET PPMT = PBET PRICE = PRIJS.NOM PRICEDISC = PRIJS.DISCONTO PRICEMAT = PRIJS.VERVALDAG PV = HW RATE = RENTE RECEIVED = OPBRENGST RRI = RRI SLN = LIN.AFSCHR SYD = SYD TBILLEQ = SCHATK.OBL TBILLPRICE = SCHATK.PRIJS TBILLYIELD = SCHATK.REND VDB = VDB XIRR = IR.SCHEMA XNPV = NHW2 YIELD = RENDEMENT YIELDDISC = REND.DISCONTO YIELDMAT = REND.VERVAL ## ## Informatiefuncties (Information Functions) ## CELL = CEL ERROR.TYPE = TYPE.FOUT INFO = INFO ISBLANK = ISLEEG ISERR = ISFOUT2 ISERROR = ISFOUT ISEVEN = IS.EVEN ISFORMULA = ISFORMULE ISLOGICAL = ISLOGISCH ISNA = ISNB ISNONTEXT = ISGEENTEKST ISNUMBER = ISGETAL ISODD = IS.ONEVEN ISREF = ISVERWIJZING ISTEXT = ISTEKST N = N NA = NB SHEET = BLAD SHEETS = BLADEN TYPE = TYPE ## ## Logische functies (Logical Functions) ## AND = EN FALSE = ONWAAR IF = ALS IFERROR = ALS.FOUT IFNA = ALS.NB IFS = ALS.VOORWAARDEN NOT = NIET OR = OF SWITCH = SCHAKELEN TRUE = WAAR XOR = EX.OF ## ## Zoek- en verwijzingsfuncties (Lookup & Reference Functions) ## ADDRESS = ADRES AREAS = BEREIKEN CHOOSE = KIEZEN COLUMN = KOLOM COLUMNS = KOLOMMEN FORMULATEXT = FORMULETEKST GETPIVOTDATA = DRAAITABEL.OPHALEN HLOOKUP = HORIZ.ZOEKEN HYPERLINK = HYPERLINK INDEX = INDEX INDIRECT = INDIRECT LOOKUP = ZOEKEN MATCH = VERGELIJKEN OFFSET = VERSCHUIVING ROW = RIJ ROWS = RIJEN RTD = RTG TRANSPOSE = TRANSPONEREN VLOOKUP = VERT.ZOEKEN *RC = RK ## ## Wiskundige en trigonometrische functies (Math & Trig Functions) ## ABS = ABS ACOS = BOOGCOS ACOSH = BOOGCOSH ACOT = BOOGCOT ACOTH = BOOGCOTH AGGREGATE = AGGREGAAT ARABIC = ARABISCH ASIN = BOOGSIN ASINH = BOOGSINH ATAN = BOOGTAN ATAN2 = BOOGTAN2 ATANH = BOOGTANH BASE = BASIS CEILING.MATH = AFRONDEN.BOVEN.WISK CEILING.PRECISE = AFRONDEN.BOVEN.NAUWKEURIG COMBIN = COMBINATIES COMBINA = COMBIN.A COS = COS COSH = COSH COT = COT COTH = COTH CSC = COSEC CSCH = COSECH DECIMAL = DECIMAAL DEGREES = GRADEN ECMA.CEILING = ECMA.AFRONDEN.BOVEN EVEN = EVEN EXP = EXP FACT = FACULTEIT FACTDOUBLE = DUBBELE.FACULTEIT FLOOR.MATH = AFRONDEN.BENEDEN.WISK FLOOR.PRECISE = AFRONDEN.BENEDEN.NAUWKEURIG GCD = GGD INT = INTEGER ISO.CEILING = ISO.AFRONDEN.BOVEN LCM = KGV LN = LN LOG = LOG LOG10 = LOG10 MDETERM = DETERMINANTMAT MINVERSE = INVERSEMAT MMULT = PRODUCTMAT MOD = REST MROUND = AFRONDEN.N.VEELVOUD MULTINOMIAL = MULTINOMIAAL MUNIT = EENHEIDMAT ODD = ONEVEN PI = PI POWER = MACHT PRODUCT = PRODUCT QUOTIENT = QUOTIENT RADIANS = RADIALEN RAND = ASELECT RANDBETWEEN = ASELECTTUSSEN ROMAN = ROMEINS ROUND = AFRONDEN ROUNDBAHTDOWN = BAHT.AFR.NAAR.BENEDEN ROUNDBAHTUP = BAHT.AFR.NAAR.BOVEN ROUNDDOWN = AFRONDEN.NAAR.BENEDEN ROUNDUP = AFRONDEN.NAAR.BOVEN SEC = SEC SECH = SECH SERIESSUM = SOM.MACHTREEKS SIGN = POS.NEG SIN = SIN SINH = SINH SQRT = WORTEL SQRTPI = WORTEL.PI SUBTOTAL = SUBTOTAAL SUM = SOM SUMIF = SOM.ALS SUMIFS = SOMMEN.ALS SUMPRODUCT = SOMPRODUCT SUMSQ = KWADRATENSOM SUMX2MY2 = SOM.X2MINY2 SUMX2PY2 = SOM.X2PLUSY2 SUMXMY2 = SOM.XMINY.2 TAN = TAN TANH = TANH TRUNC = GEHEEL ## ## Statistische functies (Statistical Functions) ## AVEDEV = GEM.DEVIATIE AVERAGE = GEMIDDELDE AVERAGEA = GEMIDDELDEA AVERAGEIF = GEMIDDELDE.ALS AVERAGEIFS = GEMIDDELDEN.ALS BETA.DIST = BETA.VERD BETA.INV = BETA.INV BINOM.DIST = BINOM.VERD BINOM.DIST.RANGE = BINOM.VERD.BEREIK BINOM.INV = BINOMIALE.INV CHISQ.DIST = CHIKW.VERD CHISQ.DIST.RT = CHIKW.VERD.RECHTS CHISQ.INV = CHIKW.INV CHISQ.INV.RT = CHIKW.INV.RECHTS CHISQ.TEST = CHIKW.TEST CONFIDENCE.NORM = VERTROUWELIJKHEID.NORM CONFIDENCE.T = VERTROUWELIJKHEID.T CORREL = CORRELATIE COUNT = AANTAL COUNTA = AANTALARG COUNTBLANK = AANTAL.LEGE.CELLEN COUNTIF = AANTAL.ALS COUNTIFS = AANTALLEN.ALS COVARIANCE.P = COVARIANTIE.P COVARIANCE.S = COVARIANTIE.S DEVSQ = DEV.KWAD EXPON.DIST = EXPON.VERD.N F.DIST = F.VERD F.DIST.RT = F.VERD.RECHTS F.INV = F.INV F.INV.RT = F.INV.RECHTS F.TEST = F.TEST FISHER = FISHER FISHERINV = FISHER.INV FORECAST.ETS = VOORSPELLEN.ETS FORECAST.ETS.CONFINT = VOORSPELLEN.ETS.CONFINT FORECAST.ETS.SEASONALITY = VOORSPELLEN.ETS.SEASONALITY FORECAST.ETS.STAT = FORECAST.ETS.STAT FORECAST.LINEAR = VOORSPELLEN.LINEAR FREQUENCY = INTERVAL GAMMA = GAMMA GAMMA.DIST = GAMMA.VERD.N GAMMA.INV = GAMMA.INV.N GAMMALN = GAMMA.LN GAMMALN.PRECISE = GAMMA.LN.NAUWKEURIG GAUSS = GAUSS GEOMEAN = MEETK.GEM GROWTH = GROEI HARMEAN = HARM.GEM HYPGEOM.DIST = HYPGEOM.VERD INTERCEPT = SNIJPUNT KURT = KURTOSIS LARGE = GROOTSTE LINEST = LIJNSCH LOGEST = LOGSCH LOGNORM.DIST = LOGNORM.VERD LOGNORM.INV = LOGNORM.INV MAX = MAX MAXA = MAXA MAXIFS = MAX.ALS.VOORWAARDEN MEDIAN = MEDIAAN MIN = MIN MINA = MINA MINIFS = MIN.ALS.VOORWAARDEN MODE.MULT = MODUS.MEERV MODE.SNGL = MODUS.ENKELV NEGBINOM.DIST = NEGBINOM.VERD NORM.DIST = NORM.VERD.N NORM.INV = NORM.INV.N NORM.S.DIST = NORM.S.VERD NORM.S.INV = NORM.S.INV PEARSON = PEARSON PERCENTILE.EXC = PERCENTIEL.EXC PERCENTILE.INC = PERCENTIEL.INC PERCENTRANK.EXC = PROCENTRANG.EXC PERCENTRANK.INC = PROCENTRANG.INC PERMUT = PERMUTATIES PERMUTATIONA = PERMUTATIE.A PHI = PHI POISSON.DIST = POISSON.VERD PROB = KANS QUARTILE.EXC = KWARTIEL.EXC QUARTILE.INC = KWARTIEL.INC RANK.AVG = RANG.GEMIDDELDE RANK.EQ = RANG.GELIJK RSQ = R.KWADRAAT SKEW = SCHEEFHEID SKEW.P = SCHEEFHEID.P SLOPE = RICHTING SMALL = KLEINSTE STANDARDIZE = NORMALISEREN STDEV.P = STDEV.P STDEV.S = STDEV.S STDEVA = STDEVA STDEVPA = STDEVPA STEYX = STAND.FOUT.YX T.DIST = T.DIST T.DIST.2T = T.VERD.2T T.DIST.RT = T.VERD.RECHTS T.INV = T.INV T.INV.2T = T.INV.2T T.TEST = T.TEST TREND = TREND TRIMMEAN = GETRIMD.GEM VAR.P = VAR.P VAR.S = VAR.S VARA = VARA VARPA = VARPA WEIBULL.DIST = WEIBULL.VERD Z.TEST = Z.TEST ## ## Tekstfuncties (Text Functions) ## BAHTTEXT = BAHT.TEKST CHAR = TEKEN CLEAN = WISSEN.CONTROL CODE = CODE CONCAT = TEKST.SAMENV DOLLAR = EURO EXACT = GELIJK FIND = VIND.ALLES FIXED = VAST ISTHAIDIGIT = IS.THAIS.CIJFER LEFT = LINKS LEN = LENGTE LOWER = KLEINE.LETTERS MID = DEEL NUMBERSTRING = GETALNOTATIE NUMBERVALUE = NUMERIEKE.WAARDE PHONETIC = FONETISCH PROPER = BEGINLETTERS REPLACE = VERVANGEN REPT = HERHALING RIGHT = RECHTS SEARCH = VIND.SPEC SUBSTITUTE = SUBSTITUEREN T = T TEXT = TEKST TEXTJOIN = TEKST.COMBINEREN THAIDIGIT = THAIS.CIJFER THAINUMSOUND = THAIS.GETAL.GELUID THAINUMSTRING = THAIS.GETAL.REEKS THAISTRINGLENGTH = THAIS.REEKS.LENGTE TRIM = SPATIES.WISSEN UNICHAR = UNITEKEN UNICODE = UNICODE UPPER = HOOFDLETTERS VALUE = WAARDE ## ## Webfuncties (Web Functions) ## ENCODEURL = URL.CODEREN FILTERXML = XML.FILTEREN WEBSERVICE = WEBSERVICE ## ## Compatibiliteitsfuncties (Compatibility Functions) ## BETADIST = BETAVERD BETAINV = BETAINV BINOMDIST = BINOMIALE.VERD CEILING = AFRONDEN.BOVEN CHIDIST = CHI.KWADRAAT CHIINV = CHI.KWADRAAT.INV CHITEST = CHI.TOETS CONCATENATE = TEKST.SAMENVOEGEN CONFIDENCE = BETROUWBAARHEID COVAR = COVARIANTIE CRITBINOM = CRIT.BINOM EXPONDIST = EXPON.VERD FDIST = F.VERDELING FINV = F.INVERSE FLOOR = AFRONDEN.BENEDEN FORECAST = VOORSPELLEN FTEST = F.TOETS GAMMADIST = GAMMA.VERD GAMMAINV = GAMMA.INV HYPGEOMDIST = HYPERGEO.VERD LOGINV = LOG.NORM.INV LOGNORMDIST = LOG.NORM.VERD MODE = MODUS NEGBINOMDIST = NEG.BINOM.VERD NORMDIST = NORM.VERD NORMINV = NORM.INV NORMSDIST = STAND.NORM.VERD NORMSINV = STAND.NORM.INV PERCENTILE = PERCENTIEL PERCENTRANK = PERCENT.RANG POISSON = POISSON QUARTILE = KWARTIEL RANK = RANG STDEV = STDEV STDEVP = STDEVP TDIST = T.VERD TINV = TINV TTEST = T.TOETS VAR = VAR VARP = VARP WEIBULL = WEIBULL ZTEST = Z.TOETS phpspreadsheet/src/PhpSpreadsheet/Calculation/locale/nl/config 0000644 00000000514 15060132323 0020562 0 ustar 00 ############################################################ ## ## PhpSpreadsheet - locale settings ## ## Nederlands (Dutch) ## ############################################################ ArgumentSeparator = ; ## ## Error Codes ## NULL = #LEEG! DIV0 = #DEEL/0! VALUE = #WAARDE! REF = #VERW! NAME = #NAAM? NUM = #GETAL! NA = #N/B phpspreadsheet/src/PhpSpreadsheet/Calculation/locale/da/functions 0000644 00000024441 15060132323 0021305 0 ustar 00 ############################################################ ## ## PhpSpreadsheet - function name translations ## ## Dansk (Danish) ## ############################################################ ## ## Kubefunktioner (Cube Functions) ## CUBEKPIMEMBER = KUBE.KPI.MEDLEM CUBEMEMBER = KUBEMEDLEM CUBEMEMBERPROPERTY = KUBEMEDLEM.EGENSKAB CUBERANKEDMEMBER = KUBERANGERET.MEDLEM CUBESET = KUBESÆT CUBESETCOUNT = KUBESÆT.ANTAL CUBEVALUE = KUBEVÆRDI ## ## Databasefunktioner (Database Functions) ## DAVERAGE = DMIDDEL DCOUNT = DTÆL DCOUNTA = DTÆLV DGET = DHENT DMAX = DMAKS DMIN = DMIN DPRODUCT = DPRODUKT DSTDEV = DSTDAFV DSTDEVP = DSTDAFVP DSUM = DSUM DVAR = DVARIANS DVARP = DVARIANSP ## ## Dato- og klokkeslætfunktioner (Date & Time Functions) ## DATE = DATO DATEDIF = DATO.FORSKEL DATESTRING = DATOSTRENG DATEVALUE = DATOVÆRDI DAY = DAG DAYS = DAGE DAYS360 = DAGE360 EDATE = EDATO EOMONTH = SLUT.PÅ.MÅNED HOUR = TIME ISOWEEKNUM = ISOUGE.NR MINUTE = MINUT MONTH = MÅNED NETWORKDAYS = ANTAL.ARBEJDSDAGE NETWORKDAYS.INTL = ANTAL.ARBEJDSDAGE.INTL NOW = NU SECOND = SEKUND THAIDAYOFWEEK = THAILANDSKUGEDAG THAIMONTHOFYEAR = THAILANDSKMÅNED THAIYEAR = THAILANDSKÅR TIME = TID TIMEVALUE = TIDSVÆRDI TODAY = IDAG WEEKDAY = UGEDAG WEEKNUM = UGE.NR WORKDAY = ARBEJDSDAG WORKDAY.INTL = ARBEJDSDAG.INTL YEAR = ÅR YEARFRAC = ÅR.BRØK ## ## Tekniske funktioner (Engineering Functions) ## BESSELI = BESSELI BESSELJ = BESSELJ BESSELK = BESSELK BESSELY = BESSELY BIN2DEC = BIN.TIL.DEC BIN2HEX = BIN.TIL.HEX BIN2OCT = BIN.TIL.OKT BITAND = BITOG BITLSHIFT = BITLSKIFT BITOR = BITELLER BITRSHIFT = BITRSKIFT BITXOR = BITXELLER COMPLEX = KOMPLEKS CONVERT = KONVERTER DEC2BIN = DEC.TIL.BIN DEC2HEX = DEC.TIL.HEX DEC2OCT = DEC.TIL.OKT DELTA = DELTA ERF = FEJLFUNK ERF.PRECISE = ERF.PRECISE ERFC = FEJLFUNK.KOMP ERFC.PRECISE = ERFC.PRECISE GESTEP = GETRIN HEX2BIN = HEX.TIL.BIN HEX2DEC = HEX.TIL.DEC HEX2OCT = HEX.TIL.OKT IMABS = IMAGABS IMAGINARY = IMAGINÆR IMARGUMENT = IMAGARGUMENT IMCONJUGATE = IMAGKONJUGERE IMCOS = IMAGCOS IMCOSH = IMAGCOSH IMCOT = IMAGCOT IMCSC = IMAGCSC IMCSCH = IMAGCSCH IMDIV = IMAGDIV IMEXP = IMAGEKSP IMLN = IMAGLN IMLOG10 = IMAGLOG10 IMLOG2 = IMAGLOG2 IMPOWER = IMAGPOTENS IMPRODUCT = IMAGPRODUKT IMREAL = IMAGREELT IMSEC = IMAGSEC IMSECH = IMAGSECH IMSIN = IMAGSIN IMSINH = IMAGSINH IMSQRT = IMAGKVROD IMSUB = IMAGSUB IMSUM = IMAGSUM IMTAN = IMAGTAN OCT2BIN = OKT.TIL.BIN OCT2DEC = OKT.TIL.DEC OCT2HEX = OKT.TIL.HEX ## ## Finansielle funktioner (Financial Functions) ## ACCRINT = PÅLØBRENTE ACCRINTM = PÅLØBRENTE.UDLØB AMORDEGRC = AMORDEGRC AMORLINC = AMORLINC COUPDAYBS = KUPONDAGE.SA COUPDAYS = KUPONDAGE.A COUPDAYSNC = KUPONDAGE.ANK COUPNCD = KUPONDAG.NÆSTE COUPNUM = KUPONBETALINGER COUPPCD = KUPONDAG.FORRIGE CUMIPMT = AKKUM.RENTE CUMPRINC = AKKUM.HOVEDSTOL DB = DB DDB = DSA DISC = DISKONTO DOLLARDE = KR.DECIMAL DOLLARFR = KR.BRØK DURATION = VARIGHED EFFECT = EFFEKTIV.RENTE FV = FV FVSCHEDULE = FVTABEL INTRATE = RENTEFOD IPMT = R.YDELSE IRR = IA ISPMT = ISPMT MDURATION = MVARIGHED MIRR = MIA NOMINAL = NOMINEL NPER = NPER NPV = NUTIDSVÆRDI ODDFPRICE = ULIGE.KURS.PÅLYDENDE ODDFYIELD = ULIGE.FØRSTE.AFKAST ODDLPRICE = ULIGE.SIDSTE.KURS ODDLYIELD = ULIGE.SIDSTE.AFKAST PDURATION = PVARIGHED PMT = YDELSE PPMT = H.YDELSE PRICE = KURS PRICEDISC = KURS.DISKONTO PRICEMAT = KURS.UDLØB PV = NV RATE = RENTE RECEIVED = MODTAGET.VED.UDLØB RRI = RRI SLN = LA SYD = ÅRSAFSKRIVNING TBILLEQ = STATSOBLIGATION TBILLPRICE = STATSOBLIGATION.KURS TBILLYIELD = STATSOBLIGATION.AFKAST VDB = VSA XIRR = INTERN.RENTE XNPV = NETTO.NUTIDSVÆRDI YIELD = AFKAST YIELDDISC = AFKAST.DISKONTO YIELDMAT = AFKAST.UDLØBSDATO ## ## Informationsfunktioner (Information Functions) ## CELL = CELLE ERROR.TYPE = FEJLTYPE INFO = INFO ISBLANK = ER.TOM ISERR = ER.FJL ISERROR = ER.FEJL ISEVEN = ER.LIGE ISFORMULA = ER.FORMEL ISLOGICAL = ER.LOGISK ISNA = ER.IKKE.TILGÆNGELIG ISNONTEXT = ER.IKKE.TEKST ISNUMBER = ER.TAL ISODD = ER.ULIGE ISREF = ER.REFERENCE ISTEXT = ER.TEKST N = TAL NA = IKKE.TILGÆNGELIG SHEET = ARK SHEETS = ARK.FLERE TYPE = VÆRDITYPE ## ## Logiske funktioner (Logical Functions) ## AND = OG FALSE = FALSK IF = HVIS IFERROR = HVIS.FEJL IFNA = HVISIT IFS = HVISER NOT = IKKE OR = ELLER SWITCH = SKIFT TRUE = SAND XOR = XELLER ## ## Opslags- og referencefunktioner (Lookup & Reference Functions) ## ADDRESS = ADRESSE AREAS = OMRÅDER CHOOSE = VÆLG COLUMN = KOLONNE COLUMNS = KOLONNER FORMULATEXT = FORMELTEKST GETPIVOTDATA = GETPIVOTDATA HLOOKUP = VOPSLAG HYPERLINK = HYPERLINK INDEX = INDEKS INDIRECT = INDIREKTE LOOKUP = SLÅ.OP MATCH = SAMMENLIGN OFFSET = FORSKYDNING ROW = RÆKKE ROWS = RÆKKER RTD = RTD TRANSPOSE = TRANSPONER VLOOKUP = LOPSLAG *RC = RK ## ## Matematiske og trigonometriske funktioner (Math & Trig Functions) ## ABS = ABS ACOS = ARCCOS ACOSH = ARCCOSH ACOT = ARCCOT ACOTH = ARCCOTH AGGREGATE = SAMLING ARABIC = ARABISK ASIN = ARCSIN ASINH = ARCSINH ATAN = ARCTAN ATAN2 = ARCTAN2 ATANH = ARCTANH BASE = BASIS CEILING.MATH = LOFT.MAT CEILING.PRECISE = LOFT.PRECISE COMBIN = KOMBIN COMBINA = KOMBINA COS = COS COSH = COSH COT = COT COTH = COTH CSC = CSC CSCH = CSCH DECIMAL = DECIMAL DEGREES = GRADER ECMA.CEILING = ECMA.LOFT EVEN = LIGE EXP = EKSP FACT = FAKULTET FACTDOUBLE = DOBBELT.FAKULTET FLOOR.MATH = AFRUND.BUND.MAT FLOOR.PRECISE = AFRUND.GULV.PRECISE GCD = STØRSTE.FÆLLES.DIVISOR INT = HELTAL ISO.CEILING = ISO.LOFT LCM = MINDSTE.FÆLLES.MULTIPLUM LN = LN LOG = LOG LOG10 = LOG10 MDETERM = MDETERM MINVERSE = MINVERT MMULT = MPRODUKT MOD = REST MROUND = MAFRUND MULTINOMIAL = MULTINOMIAL MUNIT = MENHED ODD = ULIGE PI = PI POWER = POTENS PRODUCT = PRODUKT QUOTIENT = KVOTIENT RADIANS = RADIANER RAND = SLUMP RANDBETWEEN = SLUMPMELLEM ROMAN = ROMERTAL ROUND = AFRUND ROUNDBAHTDOWN = RUNDBAHTNED ROUNDBAHTUP = RUNDBAHTOP ROUNDDOWN = RUND.NED ROUNDUP = RUND.OP SEC = SEC SECH = SECH SERIESSUM = SERIESUM SIGN = FORTEGN SIN = SIN SINH = SINH SQRT = KVROD SQRTPI = KVRODPI SUBTOTAL = SUBTOTAL SUM = SUM SUMIF = SUM.HVIS SUMIFS = SUM.HVISER SUMPRODUCT = SUMPRODUKT SUMSQ = SUMKV SUMX2MY2 = SUMX2MY2 SUMX2PY2 = SUMX2PY2 SUMXMY2 = SUMXMY2 TAN = TAN TANH = TANH TRUNC = AFKORT ## ## Statistiske funktioner (Statistical Functions) ## AVEDEV = MAD AVERAGE = MIDDEL AVERAGEA = MIDDELV AVERAGEIF = MIDDEL.HVIS AVERAGEIFS = MIDDEL.HVISER BETA.DIST = BETA.FORDELING BETA.INV = BETA.INV BINOM.DIST = BINOMIAL.FORDELING BINOM.DIST.RANGE = BINOMIAL.DIST.INTERVAL BINOM.INV = BINOMIAL.INV CHISQ.DIST = CHI2.FORDELING CHISQ.DIST.RT = CHI2.FORD.RT CHISQ.INV = CHI2.INV CHISQ.INV.RT = CHI2.INV.RT CHISQ.TEST = CHI2.TEST CONFIDENCE.NORM = KONFIDENS.NORM CONFIDENCE.T = KONFIDENST CORREL = KORRELATION COUNT = TÆL COUNTA = TÆLV COUNTBLANK = ANTAL.BLANKE COUNTIF = TÆL.HVIS COUNTIFS = TÆL.HVISER COVARIANCE.P = KOVARIANS.P COVARIANCE.S = KOVARIANS.S DEVSQ = SAK EXPON.DIST = EKSP.FORDELING F.DIST = F.FORDELING F.DIST.RT = F.FORDELING.RT F.INV = F.INV F.INV.RT = F.INV.RT F.TEST = F.TEST FISHER = FISHER FISHERINV = FISHERINV FORECAST.ETS = PROGNOSE.ETS FORECAST.ETS.CONFINT = PROGNOSE.ETS.CONFINT FORECAST.ETS.SEASONALITY = PROGNOSE.ETS.SÆSONUDSVING FORECAST.ETS.STAT = PROGNOSE.ETS.STAT FORECAST.LINEAR = PROGNOSE.LINEÆR FREQUENCY = FREKVENS GAMMA = GAMMA GAMMA.DIST = GAMMA.FORDELING GAMMA.INV = GAMMA.INV GAMMALN = GAMMALN GAMMALN.PRECISE = GAMMALN.PRECISE GAUSS = GAUSS GEOMEAN = GEOMIDDELVÆRDI GROWTH = FORØGELSE HARMEAN = HARMIDDELVÆRDI HYPGEOM.DIST = HYPGEO.FORDELING INTERCEPT = SKÆRING KURT = TOPSTEJL LARGE = STØRSTE LINEST = LINREGR LOGEST = LOGREGR LOGNORM.DIST = LOGNORM.FORDELING LOGNORM.INV = LOGNORM.INV MAX = MAKS MAXA = MAKSV MAXIFS = MAKSHVISER MEDIAN = MEDIAN MIN = MIN MINA = MINV MINIFS = MINHVISER MODE.MULT = HYPPIGST.FLERE MODE.SNGL = HYPPIGST.ENKELT NEGBINOM.DIST = NEGBINOM.FORDELING NORM.DIST = NORMAL.FORDELING NORM.INV = NORM.INV NORM.S.DIST = STANDARD.NORM.FORDELING NORM.S.INV = STANDARD.NORM.INV PEARSON = PEARSON PERCENTILE.EXC = FRAKTIL.UDELAD PERCENTILE.INC = FRAKTIL.MEDTAG PERCENTRANK.EXC = PROCENTPLADS.UDELAD PERCENTRANK.INC = PROCENTPLADS.MEDTAG PERMUT = PERMUT PERMUTATIONA = PERMUTATIONA PHI = PHI POISSON.DIST = POISSON.FORDELING PROB = SANDSYNLIGHED QUARTILE.EXC = KVARTIL.UDELAD QUARTILE.INC = KVARTIL.MEDTAG RANK.AVG = PLADS.GNSN RANK.EQ = PLADS.LIGE RSQ = FORKLARINGSGRAD SKEW = SKÆVHED SKEW.P = SKÆVHED.P SLOPE = STIGNING SMALL = MINDSTE STANDARDIZE = STANDARDISER STDEV.P = STDAFV.P STDEV.S = STDAFV.S STDEVA = STDAFVV STDEVPA = STDAFVPV STEYX = STFYX T.DIST = T.FORDELING T.DIST.2T = T.FORDELING.2T T.DIST.RT = T.FORDELING.RT T.INV = T.INV T.INV.2T = T.INV.2T T.TEST = T.TEST TREND = TENDENS TRIMMEAN = TRIMMIDDELVÆRDI VAR.P = VARIANS.P VAR.S = VARIANS.S VARA = VARIANSV VARPA = VARIANSPV WEIBULL.DIST = WEIBULL.FORDELING Z.TEST = Z.TEST ## ## Tekstfunktioner (Text Functions) ## BAHTTEXT = BAHTTEKST CHAR = TEGN CLEAN = RENS CODE = KODE CONCAT = CONCAT DOLLAR = KR EXACT = EKSAKT FIND = FIND FIXED = FAST ISTHAIDIGIT = ERTHAILANDSKCIFFER LEFT = VENSTRE LEN = LÆNGDE LOWER = SMÅ.BOGSTAVER MID = MIDT NUMBERSTRING = TALSTRENG NUMBERVALUE = TALVÆRDI PHONETIC = FONETISK PROPER = STORT.FORBOGSTAV REPLACE = ERSTAT REPT = GENTAG RIGHT = HØJRE SEARCH = SØG SUBSTITUTE = UDSKIFT T = T TEXT = TEKST TEXTJOIN = TEKST.KOMBINER THAIDIGIT = THAILANDSKCIFFER THAINUMSOUND = THAILANDSKNUMLYD THAINUMSTRING = THAILANDSKNUMSTRENG THAISTRINGLENGTH = THAILANDSKSTRENGLÆNGDE TRIM = FJERN.OVERFLØDIGE.BLANKE UNICHAR = UNICHAR UNICODE = UNICODE UPPER = STORE.BOGSTAVER VALUE = VÆRDI ## ## Webfunktioner (Web Functions) ## ENCODEURL = KODNINGSURL FILTERXML = FILTRERXML WEBSERVICE = WEBTJENESTE ## ## Kompatibilitetsfunktioner (Compatibility Functions) ## BETADIST = BETAFORDELING BETAINV = BETAINV BINOMDIST = BINOMIALFORDELING CEILING = AFRUND.LOFT CHIDIST = CHIFORDELING CHIINV = CHIINV CHITEST = CHITEST CONCATENATE = SAMMENKÆDNING CONFIDENCE = KONFIDENSINTERVAL COVAR = KOVARIANS CRITBINOM = KRITBINOM EXPONDIST = EKSPFORDELING FDIST = FFORDELING FINV = FINV FLOOR = AFRUND.GULV FORECAST = PROGNOSE FTEST = FTEST GAMMADIST = GAMMAFORDELING GAMMAINV = GAMMAINV HYPGEOMDIST = HYPGEOFORDELING LOGINV = LOGINV LOGNORMDIST = LOGNORMFORDELING MODE = HYPPIGST NEGBINOMDIST = NEGBINOMFORDELING NORMDIST = NORMFORDELING NORMINV = NORMINV NORMSDIST = STANDARDNORMFORDELING NORMSINV = STANDARDNORMINV PERCENTILE = FRAKTIL PERCENTRANK = PROCENTPLADS POISSON = POISSON QUARTILE = KVARTIL RANK = PLADS STDEV = STDAFV STDEVP = STDAFVP TDIST = TFORDELING TINV = TINV TTEST = TTEST VAR = VARIANS VARP = VARIANSP WEIBULL = WEIBULL ZTEST = ZTEST phpspreadsheet/src/PhpSpreadsheet/Calculation/locale/da/config 0000644 00000000467 15060132323 0020544 0 ustar 00 ############################################################ ## ## PhpSpreadsheet - locale settings ## ## Dansk (Danish) ## ############################################################ ArgumentSeparator = ; ## ## Error Codes ## NULL = #NUL! DIV0 VALUE = #VÆRDI! REF = #REFERENCE! NAME = #NAVN? NUM NA = #I/T phpspreadsheet/src/PhpSpreadsheet/Calculation/locale/en/uk/config 0000644 00000000107 15060132323 0021170 0 ustar 00 ## ## PhpSpreadsheet ## ## ## (For future use) ## currencySymbol = £ phpspreadsheet/src/PhpSpreadsheet/Calculation/locale/fr/functions 0000644 00000024740 15060132323 0021332 0 ustar 00 ############################################################ ## ## PhpSpreadsheet - function name translations ## ## Français (French) ## ############################################################ ## ## Fonctions Cube (Cube Functions) ## CUBEKPIMEMBER = MEMBREKPICUBE CUBEMEMBER = MEMBRECUBE CUBEMEMBERPROPERTY = PROPRIETEMEMBRECUBE CUBERANKEDMEMBER = RANGMEMBRECUBE CUBESET = JEUCUBE CUBESETCOUNT = NBJEUCUBE CUBEVALUE = VALEURCUBE ## ## Fonctions de base de données (Database Functions) ## DAVERAGE = BDMOYENNE DCOUNT = BDNB DCOUNTA = BDNBVAL DGET = BDLIRE DMAX = BDMAX DMIN = BDMIN DPRODUCT = BDPRODUIT DSTDEV = BDECARTYPE DSTDEVP = BDECARTYPEP DSUM = BDSOMME DVAR = BDVAR DVARP = BDVARP ## ## Fonctions de date et d’heure (Date & Time Functions) ## DATE = DATE DATEVALUE = DATEVAL DAY = JOUR DAYS = JOURS DAYS360 = JOURS360 EDATE = MOIS.DECALER EOMONTH = FIN.MOIS HOUR = HEURE ISOWEEKNUM = NO.SEMAINE.ISO MINUTE = MINUTE MONTH = MOIS NETWORKDAYS = NB.JOURS.OUVRES NETWORKDAYS.INTL = NB.JOURS.OUVRES.INTL NOW = MAINTENANT SECOND = SECONDE TIME = TEMPS TIMEVALUE = TEMPSVAL TODAY = AUJOURDHUI WEEKDAY = JOURSEM WEEKNUM = NO.SEMAINE WORKDAY = SERIE.JOUR.OUVRE WORKDAY.INTL = SERIE.JOUR.OUVRE.INTL YEAR = ANNEE YEARFRAC = FRACTION.ANNEE ## ## Fonctions d’ingénierie (Engineering Functions) ## BESSELI = BESSELI BESSELJ = BESSELJ BESSELK = BESSELK BESSELY = BESSELY BIN2DEC = BINDEC BIN2HEX = BINHEX BIN2OCT = BINOCT BITAND = BITET BITLSHIFT = BITDECALG BITOR = BITOU BITRSHIFT = BITDECALD BITXOR = BITOUEXCLUSIF COMPLEX = COMPLEXE CONVERT = CONVERT DEC2BIN = DECBIN DEC2HEX = DECHEX DEC2OCT = DECOCT DELTA = DELTA ERF = ERF ERF.PRECISE = ERF.PRECIS ERFC = ERFC ERFC.PRECISE = ERFC.PRECIS GESTEP = SUP.SEUIL HEX2BIN = HEXBIN HEX2DEC = HEXDEC HEX2OCT = HEXOCT IMABS = COMPLEXE.MODULE IMAGINARY = COMPLEXE.IMAGINAIRE IMARGUMENT = COMPLEXE.ARGUMENT IMCONJUGATE = COMPLEXE.CONJUGUE IMCOS = COMPLEXE.COS IMCOSH = COMPLEXE.COSH IMCOT = COMPLEXE.COT IMCSC = COMPLEXE.CSC IMCSCH = COMPLEXE.CSCH IMDIV = COMPLEXE.DIV IMEXP = COMPLEXE.EXP IMLN = COMPLEXE.LN IMLOG10 = COMPLEXE.LOG10 IMLOG2 = COMPLEXE.LOG2 IMPOWER = COMPLEXE.PUISSANCE IMPRODUCT = COMPLEXE.PRODUIT IMREAL = COMPLEXE.REEL IMSEC = COMPLEXE.SEC IMSECH = COMPLEXE.SECH IMSIN = COMPLEXE.SIN IMSINH = COMPLEXE.SINH IMSQRT = COMPLEXE.RACINE IMSUB = COMPLEXE.DIFFERENCE IMSUM = COMPLEXE.SOMME IMTAN = COMPLEXE.TAN OCT2BIN = OCTBIN OCT2DEC = OCTDEC OCT2HEX = OCTHEX ## ## Fonctions financières (Financial Functions) ## ACCRINT = INTERET.ACC ACCRINTM = INTERET.ACC.MAT AMORDEGRC = AMORDEGRC AMORLINC = AMORLINC COUPDAYBS = NB.JOURS.COUPON.PREC COUPDAYS = NB.JOURS.COUPONS COUPDAYSNC = NB.JOURS.COUPON.SUIV COUPNCD = DATE.COUPON.SUIV COUPNUM = NB.COUPONS COUPPCD = DATE.COUPON.PREC CUMIPMT = CUMUL.INTER CUMPRINC = CUMUL.PRINCPER DB = DB DDB = DDB DISC = TAUX.ESCOMPTE DOLLARDE = PRIX.DEC DOLLARFR = PRIX.FRAC DURATION = DUREE EFFECT = TAUX.EFFECTIF FV = VC FVSCHEDULE = VC.PAIEMENTS INTRATE = TAUX.INTERET IPMT = INTPER IRR = TRI ISPMT = ISPMT MDURATION = DUREE.MODIFIEE MIRR = TRIM NOMINAL = TAUX.NOMINAL NPER = NPM NPV = VAN ODDFPRICE = PRIX.PCOUPON.IRREG ODDFYIELD = REND.PCOUPON.IRREG ODDLPRICE = PRIX.DCOUPON.IRREG ODDLYIELD = REND.DCOUPON.IRREG PDURATION = PDUREE PMT = VPM PPMT = PRINCPER PRICE = PRIX.TITRE PRICEDISC = VALEUR.ENCAISSEMENT PRICEMAT = PRIX.TITRE.ECHEANCE PV = VA RATE = TAUX RECEIVED = VALEUR.NOMINALE RRI = TAUX.INT.EQUIV SLN = AMORLIN SYD = SYD TBILLEQ = TAUX.ESCOMPTE.R TBILLPRICE = PRIX.BON.TRESOR TBILLYIELD = RENDEMENT.BON.TRESOR VDB = VDB XIRR = TRI.PAIEMENTS XNPV = VAN.PAIEMENTS YIELD = RENDEMENT.TITRE YIELDDISC = RENDEMENT.SIMPLE YIELDMAT = RENDEMENT.TITRE.ECHEANCE ## ## Fonctions d’information (Information Functions) ## CELL = CELLULE ERROR.TYPE = TYPE.ERREUR INFO = INFORMATIONS ISBLANK = ESTVIDE ISERR = ESTERR ISERROR = ESTERREUR ISEVEN = EST.PAIR ISFORMULA = ESTFORMULE ISLOGICAL = ESTLOGIQUE ISNA = ESTNA ISNONTEXT = ESTNONTEXTE ISNUMBER = ESTNUM ISODD = EST.IMPAIR ISREF = ESTREF ISTEXT = ESTTEXTE N = N NA = NA SHEET = FEUILLE SHEETS = FEUILLES TYPE = TYPE ## ## Fonctions logiques (Logical Functions) ## AND = ET FALSE = FAUX IF = SI IFERROR = SIERREUR IFNA = SI.NON.DISP IFS = SI.CONDITIONS NOT = NON OR = OU SWITCH = SI.MULTIPLE TRUE = VRAI XOR = OUX ## ## Fonctions de recherche et de référence (Lookup & Reference Functions) ## ADDRESS = ADRESSE AREAS = ZONES CHOOSE = CHOISIR COLUMN = COLONNE COLUMNS = COLONNES FORMULATEXT = FORMULETEXTE GETPIVOTDATA = LIREDONNEESTABCROISDYNAMIQUE HLOOKUP = RECHERCHEH HYPERLINK = LIEN_HYPERTEXTE INDEX = INDEX INDIRECT = INDIRECT LOOKUP = RECHERCHE MATCH = EQUIV OFFSET = DECALER ROW = LIGNE ROWS = LIGNES RTD = RTD TRANSPOSE = TRANSPOSE VLOOKUP = RECHERCHEV *RC = LC ## ## Fonctions mathématiques et trigonométriques (Math & Trig Functions) ## ABS = ABS ACOS = ACOS ACOSH = ACOSH ACOT = ACOT ACOTH = ACOTH AGGREGATE = AGREGAT ARABIC = CHIFFRE.ARABE ASIN = ASIN ASINH = ASINH ATAN = ATAN ATAN2 = ATAN2 ATANH = ATANH BASE = BASE CEILING.MATH = PLAFOND.MATH CEILING.PRECISE = PLAFOND.PRECIS COMBIN = COMBIN COMBINA = COMBINA COS = COS COSH = COSH COT = COT COTH = COTH CSC = CSC CSCH = CSCH DECIMAL = DECIMAL DEGREES = DEGRES ECMA.CEILING = ECMA.PLAFOND EVEN = PAIR EXP = EXP FACT = FACT FACTDOUBLE = FACTDOUBLE FLOOR.MATH = PLANCHER.MATH FLOOR.PRECISE = PLANCHER.PRECIS GCD = PGCD INT = ENT ISO.CEILING = ISO.PLAFOND LCM = PPCM LN = LN LOG = LOG LOG10 = LOG10 MDETERM = DETERMAT MINVERSE = INVERSEMAT MMULT = PRODUITMAT MOD = MOD MROUND = ARRONDI.AU.MULTIPLE MULTINOMIAL = MULTINOMIALE MUNIT = MATRICE.UNITAIRE ODD = IMPAIR PI = PI POWER = PUISSANCE PRODUCT = PRODUIT QUOTIENT = QUOTIENT RADIANS = RADIANS RAND = ALEA RANDBETWEEN = ALEA.ENTRE.BORNES ROMAN = ROMAIN ROUND = ARRONDI ROUNDDOWN = ARRONDI.INF ROUNDUP = ARRONDI.SUP SEC = SEC SECH = SECH SERIESSUM = SOMME.SERIES SIGN = SIGNE SIN = SIN SINH = SINH SQRT = RACINE SQRTPI = RACINE.PI SUBTOTAL = SOUS.TOTAL SUM = SOMME SUMIF = SOMME.SI SUMIFS = SOMME.SI.ENS SUMPRODUCT = SOMMEPROD SUMSQ = SOMME.CARRES SUMX2MY2 = SOMME.X2MY2 SUMX2PY2 = SOMME.X2PY2 SUMXMY2 = SOMME.XMY2 TAN = TAN TANH = TANH TRUNC = TRONQUE ## ## Fonctions statistiques (Statistical Functions) ## AVEDEV = ECART.MOYEN AVERAGE = MOYENNE AVERAGEA = AVERAGEA AVERAGEIF = MOYENNE.SI AVERAGEIFS = MOYENNE.SI.ENS BETA.DIST = LOI.BETA.N BETA.INV = BETA.INVERSE.N BINOM.DIST = LOI.BINOMIALE.N BINOM.DIST.RANGE = LOI.BINOMIALE.SERIE BINOM.INV = LOI.BINOMIALE.INVERSE CHISQ.DIST = LOI.KHIDEUX.N CHISQ.DIST.RT = LOI.KHIDEUX.DROITE CHISQ.INV = LOI.KHIDEUX.INVERSE CHISQ.INV.RT = LOI.KHIDEUX.INVERSE.DROITE CHISQ.TEST = CHISQ.TEST CONFIDENCE.NORM = INTERVALLE.CONFIANCE.NORMAL CONFIDENCE.T = INTERVALLE.CONFIANCE.STUDENT CORREL = COEFFICIENT.CORRELATION COUNT = NB COUNTA = NBVAL COUNTBLANK = NB.VIDE COUNTIF = NB.SI COUNTIFS = NB.SI.ENS COVARIANCE.P = COVARIANCE.PEARSON COVARIANCE.S = COVARIANCE.STANDARD DEVSQ = SOMME.CARRES.ECARTS EXPON.DIST = LOI.EXPONENTIELLE.N F.DIST = LOI.F.N F.DIST.RT = LOI.F.DROITE F.INV = INVERSE.LOI.F.N F.INV.RT = INVERSE.LOI.F.DROITE F.TEST = F.TEST FISHER = FISHER FISHERINV = FISHER.INVERSE FORECAST.ETS = PREVISION.ETS FORECAST.ETS.CONFINT = PREVISION.ETS.CONFINT FORECAST.ETS.SEASONALITY = PREVISION.ETS.CARACTERESAISONNIER FORECAST.ETS.STAT = PREVISION.ETS.STAT FORECAST.LINEAR = PREVISION.LINEAIRE FREQUENCY = FREQUENCE GAMMA = GAMMA GAMMA.DIST = LOI.GAMMA.N GAMMA.INV = LOI.GAMMA.INVERSE.N GAMMALN = LNGAMMA GAMMALN.PRECISE = LNGAMMA.PRECIS GAUSS = GAUSS GEOMEAN = MOYENNE.GEOMETRIQUE GROWTH = CROISSANCE HARMEAN = MOYENNE.HARMONIQUE HYPGEOM.DIST = LOI.HYPERGEOMETRIQUE.N INTERCEPT = ORDONNEE.ORIGINE KURT = KURTOSIS LARGE = GRANDE.VALEUR LINEST = DROITEREG LOGEST = LOGREG LOGNORM.DIST = LOI.LOGNORMALE.N LOGNORM.INV = LOI.LOGNORMALE.INVERSE.N MAX = MAX MAXA = MAXA MAXIFS = MAX.SI MEDIAN = MEDIANE MIN = MIN MINA = MINA MINIFS = MIN.SI MODE.MULT = MODE.MULTIPLE MODE.SNGL = MODE.SIMPLE NEGBINOM.DIST = LOI.BINOMIALE.NEG.N NORM.DIST = LOI.NORMALE.N NORM.INV = LOI.NORMALE.INVERSE.N NORM.S.DIST = LOI.NORMALE.STANDARD.N NORM.S.INV = LOI.NORMALE.STANDARD.INVERSE.N PEARSON = PEARSON PERCENTILE.EXC = CENTILE.EXCLURE PERCENTILE.INC = CENTILE.INCLURE PERCENTRANK.EXC = RANG.POURCENTAGE.EXCLURE PERCENTRANK.INC = RANG.POURCENTAGE.INCLURE PERMUT = PERMUTATION PERMUTATIONA = PERMUTATIONA PHI = PHI POISSON.DIST = LOI.POISSON.N PROB = PROBABILITE QUARTILE.EXC = QUARTILE.EXCLURE QUARTILE.INC = QUARTILE.INCLURE RANK.AVG = MOYENNE.RANG RANK.EQ = EQUATION.RANG RSQ = COEFFICIENT.DETERMINATION SKEW = COEFFICIENT.ASYMETRIE SKEW.P = COEFFICIENT.ASYMETRIE.P SLOPE = PENTE SMALL = PETITE.VALEUR STANDARDIZE = CENTREE.REDUITE STDEV.P = ECARTYPE.PEARSON STDEV.S = ECARTYPE.STANDARD STDEVA = STDEVA STDEVPA = STDEVPA STEYX = ERREUR.TYPE.XY T.DIST = LOI.STUDENT.N T.DIST.2T = LOI.STUDENT.BILATERALE T.DIST.RT = LOI.STUDENT.DROITE T.INV = LOI.STUDENT.INVERSE.N T.INV.2T = LOI.STUDENT.INVERSE.BILATERALE T.TEST = T.TEST TREND = TENDANCE TRIMMEAN = MOYENNE.REDUITE VAR.P = VAR.P.N VAR.S = VAR.S VARA = VARA VARPA = VARPA WEIBULL.DIST = LOI.WEIBULL.N Z.TEST = Z.TEST ## ## Fonctions de texte (Text Functions) ## BAHTTEXT = BAHTTEXT CHAR = CAR CLEAN = EPURAGE CODE = CODE CONCAT = CONCAT DOLLAR = DEVISE EXACT = EXACT FIND = TROUVE FIXED = CTXT LEFT = GAUCHE LEN = NBCAR LOWER = MINUSCULE MID = STXT NUMBERVALUE = VALEURNOMBRE PHONETIC = PHONETIQUE PROPER = NOMPROPRE REPLACE = REMPLACER REPT = REPT RIGHT = DROITE SEARCH = CHERCHE SUBSTITUTE = SUBSTITUE T = T TEXT = TEXTE TEXTJOIN = JOINDRE.TEXTE TRIM = SUPPRESPACE UNICHAR = UNICAR UNICODE = UNICODE UPPER = MAJUSCULE VALUE = CNUM ## ## Fonctions web (Web Functions) ## ENCODEURL = URLENCODAGE FILTERXML = FILTRE.XML WEBSERVICE = SERVICEWEB ## ## Fonctions de compatibilité (Compatibility Functions) ## BETADIST = LOI.BETA BETAINV = BETA.INVERSE BINOMDIST = LOI.BINOMIALE CEILING = PLAFOND CHIDIST = LOI.KHIDEUX CHIINV = KHIDEUX.INVERSE CHITEST = TEST.KHIDEUX CONCATENATE = CONCATENER CONFIDENCE = INTERVALLE.CONFIANCE COVAR = COVARIANCE CRITBINOM = CRITERE.LOI.BINOMIALE EXPONDIST = LOI.EXPONENTIELLE FDIST = LOI.F FINV = INVERSE.LOI.F FLOOR = PLANCHER FORECAST = PREVISION FTEST = TEST.F GAMMADIST = LOI.GAMMA GAMMAINV = LOI.GAMMA.INVERSE HYPGEOMDIST = LOI.HYPERGEOMETRIQUE LOGINV = LOI.LOGNORMALE.INVERSE LOGNORMDIST = LOI.LOGNORMALE MODE = MODE NEGBINOMDIST = LOI.BINOMIALE.NEG NORMDIST = LOI.NORMALE NORMINV = LOI.NORMALE.INVERSE NORMSDIST = LOI.NORMALE.STANDARD NORMSINV = LOI.NORMALE.STANDARD.INVERSE PERCENTILE = CENTILE PERCENTRANK = RANG.POURCENTAGE POISSON = LOI.POISSON QUARTILE = QUARTILE RANK = RANG STDEV = ECARTYPE STDEVP = ECARTYPEP TDIST = LOI.STUDENT TINV = LOI.STUDENT.INVERSE TTEST = TEST.STUDENT VAR = VAR VARP = VAR.P WEIBULL = LOI.WEIBULL ZTEST = TEST.Z phpspreadsheet/src/PhpSpreadsheet/Calculation/locale/fr/config 0000644 00000000460 15060132323 0020560 0 ustar 00 ############################################################ ## ## PhpSpreadsheet - locale settings ## ## Français (French) ## ############################################################ ArgumentSeparator = ; ## ## Error Codes ## NULL = #NUL! DIV0 VALUE = #VALEUR! REF NAME = #NOM? NUM = #NOMBRE! NA phpspreadsheet/src/PhpSpreadsheet/Calculation/locale/hu/functions 0000644 00000025073 15060132323 0021337 0 ustar 00 ############################################################ ## ## PhpSpreadsheet - function name translations ## ## Magyar (Hungarian) ## ############################################################ ## ## Kockafüggvények (Cube Functions) ## CUBEKPIMEMBER = KOCKA.FŐTELJMUT CUBEMEMBER = KOCKA.TAG CUBEMEMBERPROPERTY = KOCKA.TAG.TUL CUBERANKEDMEMBER = KOCKA.HALM.ELEM CUBESET = KOCKA.HALM CUBESETCOUNT = KOCKA.HALM.DB CUBEVALUE = KOCKA.ÉRTÉK ## ## Adatbázis-kezelő függvények (Database Functions) ## DAVERAGE = AB.ÁTLAG DCOUNT = AB.DARAB DCOUNTA = AB.DARAB2 DGET = AB.MEZŐ DMAX = AB.MAX DMIN = AB.MIN DPRODUCT = AB.SZORZAT DSTDEV = AB.SZÓRÁS DSTDEVP = AB.SZÓRÁS2 DSUM = AB.SZUM DVAR = AB.VAR DVARP = AB.VAR2 ## ## Dátumfüggvények (Date & Time Functions) ## DATE = DÁTUM DATEDIF = DÁTUMTÓLIG DATESTRING = DÁTUMSZÖVEG DATEVALUE = DÁTUMÉRTÉK DAY = NAP DAYS = NAPOK DAYS360 = NAP360 EDATE = KALK.DÁTUM EOMONTH = HÓNAP.UTOLSÓ.NAP HOUR = ÓRA ISOWEEKNUM = ISO.HÉT.SZÁMA MINUTE = PERCEK MONTH = HÓNAP NETWORKDAYS = ÖSSZ.MUNKANAP NETWORKDAYS.INTL = ÖSSZ.MUNKANAP.INTL NOW = MOST SECOND = MPERC THAIDAYOFWEEK = THAIHÉTNAPJA THAIMONTHOFYEAR = THAIHÓNAP THAIYEAR = THAIÉV TIME = IDŐ TIMEVALUE = IDŐÉRTÉK TODAY = MA WEEKDAY = HÉT.NAPJA WEEKNUM = HÉT.SZÁMA WORKDAY = KALK.MUNKANAP WORKDAY.INTL = KALK.MUNKANAP.INTL YEAR = ÉV YEARFRAC = TÖRTÉV ## ## Mérnöki függvények (Engineering Functions) ## BESSELI = BESSELI BESSELJ = BESSELJ BESSELK = BESSELK BESSELY = BESSELY BIN2DEC = BIN.DEC BIN2HEX = BIN.HEX BIN2OCT = BIN.OKT BITAND = BIT.ÉS BITLSHIFT = BIT.BAL.ELTOL BITOR = BIT.VAGY BITRSHIFT = BIT.JOBB.ELTOL BITXOR = BIT.XVAGY COMPLEX = KOMPLEX CONVERT = KONVERTÁLÁS DEC2BIN = DEC.BIN DEC2HEX = DEC.HEX DEC2OCT = DEC.OKT DELTA = DELTA ERF = HIBAF ERF.PRECISE = HIBAF.PONTOS ERFC = HIBAF.KOMPLEMENTER ERFC.PRECISE = HIBAFKOMPLEMENTER.PONTOS GESTEP = KÜSZÖBNÉL.NAGYOBB HEX2BIN = HEX.BIN HEX2DEC = HEX.DEC HEX2OCT = HEX.OKT IMABS = KÉPZ.ABSZ IMAGINARY = KÉPZETES IMARGUMENT = KÉPZ.ARGUMENT IMCONJUGATE = KÉPZ.KONJUGÁLT IMCOS = KÉPZ.COS IMCOSH = KÉPZ.COSH IMCOT = KÉPZ.COT IMCSC = KÉPZ.CSC IMCSCH = KÉPZ.CSCH IMDIV = KÉPZ.HÁNYAD IMEXP = KÉPZ.EXP IMLN = KÉPZ.LN IMLOG10 = KÉPZ.LOG10 IMLOG2 = KÉPZ.LOG2 IMPOWER = KÉPZ.HATV IMPRODUCT = KÉPZ.SZORZAT IMREAL = KÉPZ.VALÓS IMSEC = KÉPZ.SEC IMSECH = KÉPZ.SECH IMSIN = KÉPZ.SIN IMSINH = KÉPZ.SINH IMSQRT = KÉPZ.GYÖK IMSUB = KÉPZ.KÜL IMSUM = KÉPZ.ÖSSZEG IMTAN = KÉPZ.TAN OCT2BIN = OKT.BIN OCT2DEC = OKT.DEC OCT2HEX = OKT.HEX ## ## Pénzügyi függvények (Financial Functions) ## ACCRINT = IDŐSZAKI.KAMAT ACCRINTM = LEJÁRATI.KAMAT AMORDEGRC = ÉRTÉKCSÖKK.TÉNYEZŐVEL AMORLINC = ÉRTÉKCSÖKK COUPDAYBS = SZELVÉNYIDŐ.KEZDETTŐL COUPDAYS = SZELVÉNYIDŐ COUPDAYSNC = SZELVÉNYIDŐ.KIFIZETÉSTŐL COUPNCD = ELSŐ.SZELVÉNYDÁTUM COUPNUM = SZELVÉNYSZÁM COUPPCD = UTOLSÓ.SZELVÉNYDÁTUM CUMIPMT = ÖSSZES.KAMAT CUMPRINC = ÖSSZES.TŐKERÉSZ DB = KCS2 DDB = KCSA DISC = LESZÁM DOLLARDE = FORINT.DEC DOLLARFR = FORINT.TÖRT DURATION = KAMATÉRZ EFFECT = TÉNYLEGES FV = JBÉ FVSCHEDULE = KJÉ INTRATE = KAMATRÁTA IPMT = RRÉSZLET IRR = BMR ISPMT = LRÉSZLETKAMAT MDURATION = MKAMATÉRZ MIRR = MEGTÉRÜLÉS NOMINAL = NÉVLEGES NPER = PER.SZÁM NPV = NMÉ ODDFPRICE = ELTÉRŐ.EÁR ODDFYIELD = ELTÉRŐ.EHOZAM ODDLPRICE = ELTÉRŐ.UÁR ODDLYIELD = ELTÉRŐ.UHOZAM PDURATION = KAMATÉRZ.PER PMT = RÉSZLET PPMT = PRÉSZLET PRICE = ÁR PRICEDISC = ÁR.LESZÁM PRICEMAT = ÁR.LEJÁRAT PV = MÉ RATE = RÁTA RECEIVED = KAPOTT RRI = MR SLN = LCSA SYD = ÉSZÖ TBILLEQ = KJEGY.EGYENÉRT TBILLPRICE = KJEGY.ÁR TBILLYIELD = KJEGY.HOZAM VDB = ÉCSRI XIRR = XBMR XNPV = XNJÉ YIELD = HOZAM YIELDDISC = HOZAM.LESZÁM YIELDMAT = HOZAM.LEJÁRAT ## ## Információs függvények (Information Functions) ## CELL = CELLA ERROR.TYPE = HIBA.TÍPUS INFO = INFÓ ISBLANK = ÜRES ISERR = HIBA.E ISERROR = HIBÁS ISEVEN = PÁROSE ISFORMULA = KÉPLET ISLOGICAL = LOGIKAI ISNA = NINCS ISNONTEXT = NEM.SZÖVEG ISNUMBER = SZÁM ISODD = PÁRATLANE ISREF = HIVATKOZÁS ISTEXT = SZÖVEG.E N = S NA = HIÁNYZIK SHEET = LAP SHEETS = LAPOK TYPE = TÍPUS ## ## Logikai függvények (Logical Functions) ## AND = ÉS FALSE = HAMIS IF = HA IFERROR = HAHIBA IFNA = HAHIÁNYZIK IFS = HAELSŐIGAZ NOT = NEM OR = VAGY SWITCH = ÁTVÁLT TRUE = IGAZ XOR = XVAGY ## ## Keresési és hivatkozási függvények (Lookup & Reference Functions) ## ADDRESS = CÍM AREAS = TERÜLET CHOOSE = VÁLASZT COLUMN = OSZLOP COLUMNS = OSZLOPOK FORMULATEXT = KÉPLETSZÖVEG GETPIVOTDATA = KIMUTATÁSADATOT.VESZ HLOOKUP = VKERES HYPERLINK = HIPERHIVATKOZÁS INDEX = INDEX INDIRECT = INDIREKT LOOKUP = KERES MATCH = HOL.VAN OFFSET = ELTOLÁS ROW = SOR ROWS = SOROK RTD = VIA TRANSPOSE = TRANSZPONÁLÁS VLOOKUP = FKERES *RC = SO ## ## Matematikai és trigonometrikus függvények (Math & Trig Functions) ## ABS = ABS ACOS = ARCCOS ACOSH = ACOSH ACOT = ARCCOT ACOTH = ARCCOTH AGGREGATE = ÖSSZESÍT ARABIC = ARAB ASIN = ARCSIN ASINH = ASINH ATAN = ARCTAN ATAN2 = ARCTAN2 ATANH = ATANH BASE = ALAP CEILING.MATH = PLAFON.MAT CEILING.PRECISE = PLAFON.PONTOS COMBIN = KOMBINÁCIÓK COMBINA = KOMBINÁCIÓK.ISM COS = COS COSH = COSH COT = COT COTH = COTH CSC = CSC CSCH = CSCH DECIMAL = TIZEDES DEGREES = FOK ECMA.CEILING = ECMA.PLAFON EVEN = PÁROS EXP = KITEVŐ FACT = FAKT FACTDOUBLE = FAKTDUPLA FLOOR.MATH = PADLÓ.MAT FLOOR.PRECISE = PADLÓ.PONTOS GCD = LKO INT = INT ISO.CEILING = ISO.PLAFON LCM = LKT LN = LN LOG = LOG LOG10 = LOG10 MDETERM = MDETERM MINVERSE = INVERZ.MÁTRIX MMULT = MSZORZAT MOD = MARADÉK MROUND = TÖBBSZ.KEREKÍT MULTINOMIAL = SZORHÁNYFAKT MUNIT = MMÁTRIX ODD = PÁRATLAN PI = PI POWER = HATVÁNY PRODUCT = SZORZAT QUOTIENT = KVÓCIENS RADIANS = RADIÁN RAND = VÉL RANDBETWEEN = VÉLETLEN.KÖZÖTT ROMAN = RÓMAI ROUND = KEREKÍTÉS ROUNDBAHTDOWN = BAHTKEREK.LE ROUNDBAHTUP = BAHTKEREK.FEL ROUNDDOWN = KEREK.LE ROUNDUP = KEREK.FEL SEC = SEC SECH = SECH SERIESSUM = SORÖSSZEG SIGN = ELŐJEL SIN = SIN SINH = SINH SQRT = GYÖK SQRTPI = GYÖKPI SUBTOTAL = RÉSZÖSSZEG SUM = SZUM SUMIF = SZUMHA SUMIFS = SZUMHATÖBB SUMPRODUCT = SZORZATÖSSZEG SUMSQ = NÉGYZETÖSSZEG SUMX2MY2 = SZUMX2BŐLY2 SUMX2PY2 = SZUMX2MEGY2 SUMXMY2 = SZUMXBŐLY2 TAN = TAN TANH = TANH TRUNC = CSONK ## ## Statisztikai függvények (Statistical Functions) ## AVEDEV = ÁTL.ELTÉRÉS AVERAGE = ÁTLAG AVERAGEA = ÁTLAGA AVERAGEIF = ÁTLAGHA AVERAGEIFS = ÁTLAGHATÖBB BETA.DIST = BÉTA.ELOSZL BETA.INV = BÉTA.INVERZ BINOM.DIST = BINOM.ELOSZL BINOM.DIST.RANGE = BINOM.ELOSZL.TART BINOM.INV = BINOM.INVERZ CHISQ.DIST = KHINÉGYZET.ELOSZLÁS CHISQ.DIST.RT = KHINÉGYZET.ELOSZLÁS.JOBB CHISQ.INV = KHINÉGYZET.INVERZ CHISQ.INV.RT = KHINÉGYZET.INVERZ.JOBB CHISQ.TEST = KHINÉGYZET.PRÓBA CONFIDENCE.NORM = MEGBÍZHATÓSÁG.NORM CONFIDENCE.T = MEGBÍZHATÓSÁG.T CORREL = KORREL COUNT = DARAB COUNTA = DARAB2 COUNTBLANK = DARABÜRES COUNTIF = DARABTELI COUNTIFS = DARABHATÖBB COVARIANCE.P = KOVARIANCIA.S COVARIANCE.S = KOVARIANCIA.M DEVSQ = SQ EXPON.DIST = EXP.ELOSZL F.DIST = F.ELOSZL F.DIST.RT = F.ELOSZLÁS.JOBB F.INV = F.INVERZ F.INV.RT = F.INVERZ.JOBB F.TEST = F.PRÓB FISHER = FISHER FISHERINV = INVERZ.FISHER FORECAST.ETS = ELŐREJELZÉS.ESIM FORECAST.ETS.CONFINT = ELŐREJELZÉS.ESIM.KONFINT FORECAST.ETS.SEASONALITY = ELŐREJELZÉS.ESIM.SZEZONALITÁS FORECAST.ETS.STAT = ELŐREJELZÉS.ESIM.STAT FORECAST.LINEAR = ELŐREJELZÉS.LINEÁRIS FREQUENCY = GYAKORISÁG GAMMA = GAMMA GAMMA.DIST = GAMMA.ELOSZL GAMMA.INV = GAMMA.INVERZ GAMMALN = GAMMALN GAMMALN.PRECISE = GAMMALN.PONTOS GAUSS = GAUSS GEOMEAN = MÉRTANI.KÖZÉP GROWTH = NÖV HARMEAN = HARM.KÖZÉP HYPGEOM.DIST = HIPGEOM.ELOSZLÁS INTERCEPT = METSZ KURT = CSÚCSOSSÁG LARGE = NAGY LINEST = LIN.ILL LOGEST = LOG.ILL LOGNORM.DIST = LOGNORM.ELOSZLÁS LOGNORM.INV = LOGNORM.INVERZ MAX = MAX MAXA = MAXA MAXIFS = MAXHA MEDIAN = MEDIÁN MIN = MIN MINA = MIN2 MINIFS = MINHA MODE.MULT = MÓDUSZ.TÖBB MODE.SNGL = MÓDUSZ.EGY NEGBINOM.DIST = NEGBINOM.ELOSZLÁS NORM.DIST = NORM.ELOSZLÁS NORM.INV = NORM.INVERZ NORM.S.DIST = NORM.S.ELOSZLÁS NORM.S.INV = NORM.S.INVERZ PEARSON = PEARSON PERCENTILE.EXC = PERCENTILIS.KIZÁR PERCENTILE.INC = PERCENTILIS.TARTALMAZ PERCENTRANK.EXC = SZÁZALÉKRANG.KIZÁR PERCENTRANK.INC = SZÁZALÉKRANG.TARTALMAZ PERMUT = VARIÁCIÓK PERMUTATIONA = VARIÁCIÓK.ISM PHI = FI POISSON.DIST = POISSON.ELOSZLÁS PROB = VALÓSZÍNŰSÉG QUARTILE.EXC = KVARTILIS.KIZÁR QUARTILE.INC = KVARTILIS.TARTALMAZ RANK.AVG = RANG.ÁTL RANK.EQ = RANG.EGY RSQ = RNÉGYZET SKEW = FERDESÉG SKEW.P = FERDESÉG.P SLOPE = MEREDEKSÉG SMALL = KICSI STANDARDIZE = NORMALIZÁLÁS STDEV.P = SZÓR.S STDEV.S = SZÓR.M STDEVA = SZÓRÁSA STDEVPA = SZÓRÁSPA STEYX = STHIBAYX T.DIST = T.ELOSZL T.DIST.2T = T.ELOSZLÁS.2SZ T.DIST.RT = T.ELOSZLÁS.JOBB T.INV = T.INVERZ T.INV.2T = T.INVERZ.2SZ T.TEST = T.PRÓB TREND = TREND TRIMMEAN = RÉSZÁTLAG VAR.P = VAR.S VAR.S = VAR.M VARA = VARA VARPA = VARPA WEIBULL.DIST = WEIBULL.ELOSZLÁS Z.TEST = Z.PRÓB ## ## Szövegműveletekhez használható függvények (Text Functions) ## BAHTTEXT = BAHTSZÖVEG CHAR = KARAKTER CLEAN = TISZTÍT CODE = KÓD CONCAT = FŰZ DOLLAR = FORINT EXACT = AZONOS FIND = SZÖVEG.TALÁL FIXED = FIX ISTHAIDIGIT = ON.THAI.NUMERO LEFT = BAL LEN = HOSSZ LOWER = KISBETŰ MID = KÖZÉP NUMBERSTRING = SZÁM.BETŰVEL NUMBERVALUE = SZÁMÉRTÉK PHONETIC = FONETIKUS PROPER = TNÉV REPLACE = CSERE REPT = SOKSZOR RIGHT = JOBB SEARCH = SZÖVEG.KERES SUBSTITUTE = HELYETTE T = T TEXT = SZÖVEG TEXTJOIN = SZÖVEGÖSSZEFŰZÉS THAIDIGIT = THAISZÁM THAINUMSOUND = THAISZÁMHANG THAINUMSTRING = THAISZÁMKAR THAISTRINGLENGTH = THAIKARHOSSZ TRIM = KIMETSZ UNICHAR = UNIKARAKTER UNICODE = UNICODE UPPER = NAGYBETŰS VALUE = ÉRTÉK ## ## Webes függvények (Web Functions) ## ENCODEURL = URL.KÓDOL FILTERXML = XMLSZŰRÉS WEBSERVICE = WEBSZOLGÁLTATÁS ## ## Kompatibilitási függvények (Compatibility Functions) ## BETADIST = BÉTA.ELOSZLÁS BETAINV = INVERZ.BÉTA BINOMDIST = BINOM.ELOSZLÁS CEILING = PLAFON CHIDIST = KHI.ELOSZLÁS CHIINV = INVERZ.KHI CHITEST = KHI.PRÓBA CONCATENATE = ÖSSZEFŰZ CONFIDENCE = MEGBÍZHATÓSÁG COVAR = KOVAR CRITBINOM = KRITBINOM EXPONDIST = EXP.ELOSZLÁS FDIST = F.ELOSZLÁS FINV = INVERZ.F FLOOR = PADLÓ FORECAST = ELŐREJELZÉS FTEST = F.PRÓBA GAMMADIST = GAMMA.ELOSZLÁS GAMMAINV = INVERZ.GAMMA HYPGEOMDIST = HIPERGEOM.ELOSZLÁS LOGINV = INVERZ.LOG.ELOSZLÁS LOGNORMDIST = LOG.ELOSZLÁS MODE = MÓDUSZ NEGBINOMDIST = NEGBINOM.ELOSZL NORMDIST = NORM.ELOSZL NORMINV = INVERZ.NORM NORMSDIST = STNORMELOSZL NORMSINV = INVERZ.STNORM PERCENTILE = PERCENTILIS PERCENTRANK = SZÁZALÉKRANG POISSON = POISSON QUARTILE = KVARTILIS RANK = SORSZÁM STDEV = SZÓRÁS STDEVP = SZÓRÁSP TDIST = T.ELOSZLÁS TINV = INVERZ.T TTEST = T.PRÓBA VAR = VAR VARP = VARP WEIBULL = WEIBULL ZTEST = Z.PRÓBA phpspreadsheet/src/PhpSpreadsheet/Calculation/locale/hu/config 0000644 00000000531 15060132323 0020564 0 ustar 00 ############################################################ ## ## PhpSpreadsheet - locale settings ## ## Magyar (Hungarian) ## ############################################################ ArgumentSeparator = ; ## ## Error Codes ## NULL = #NULLA! DIV0 = #ZÉRÓOSZTÓ! VALUE = #ÉRTÉK! REF = #HIV! NAME = #NÉV? NUM = #SZÁM! NA = #HIÁNYZIK phpspreadsheet/src/PhpSpreadsheet/Calculation/locale/tr/functions 0000644 00000024411 15060132323 0021343 0 ustar 00 ############################################################ ## ## PhpSpreadsheet - function name translations ## ## Türkçe (Turkish) ## ############################################################ ## ## Küp işlevleri (Cube Functions) ## CUBEKPIMEMBER = KÜPKPIÜYESİ CUBEMEMBER = KÜPÜYESİ CUBEMEMBERPROPERTY = KÜPÜYEÖZELLİĞİ CUBERANKEDMEMBER = DERECELİKÜPÜYESİ CUBESET = KÜPKÜMESİ CUBESETCOUNT = KÜPKÜMESAYISI CUBEVALUE = KÜPDEĞERİ ## ## Veritabanı işlevleri (Database Functions) ## DAVERAGE = VSEÇORT DCOUNT = VSEÇSAY DCOUNTA = VSEÇSAYDOLU DGET = VAL DMAX = VSEÇMAK DMIN = VSEÇMİN DPRODUCT = VSEÇÇARP DSTDEV = VSEÇSTDSAPMA DSTDEVP = VSEÇSTDSAPMAS DSUM = VSEÇTOPLA DVAR = VSEÇVAR DVARP = VSEÇVARS ## ## Tarih ve saat işlevleri (Date & Time Functions) ## DATE = TARİH DATEDIF = ETARİHLİ DATESTRING = TARİHDİZİ DATEVALUE = TARİHSAYISI DAY = GÜN DAYS = GÜNSAY DAYS360 = GÜN360 EDATE = SERİTARİH EOMONTH = SERİAY HOUR = SAAT ISOWEEKNUM = ISOHAFTASAY MINUTE = DAKİKA MONTH = AY NETWORKDAYS = TAMİŞGÜNÜ NETWORKDAYS.INTL = TAMİŞGÜNÜ.ULUSL NOW = ŞİMDİ SECOND = SANİYE THAIDAYOFWEEK = TAYHAFTANINGÜNÜ THAIMONTHOFYEAR = TAYYILINAYI THAIYEAR = TAYYILI TIME = ZAMAN TIMEVALUE = ZAMANSAYISI TODAY = BUGÜN WEEKDAY = HAFTANINGÜNÜ WEEKNUM = HAFTASAY WORKDAY = İŞGÜNÜ WORKDAY.INTL = İŞGÜNÜ.ULUSL YEAR = YIL YEARFRAC = YILORAN ## ## Mühendislik işlevleri (Engineering Functions) ## BESSELI = BESSELI BESSELJ = BESSELJ BESSELK = BESSELK BESSELY = BESSELY BIN2DEC = BIN2DEC BIN2HEX = BIN2HEX BIN2OCT = BIN2OCT BITAND = BİTVE BITLSHIFT = BİTSOLAKAYDIR BITOR = BİTVEYA BITRSHIFT = BİTSAĞAKAYDIR BITXOR = BİTÖZELVEYA COMPLEX = KARMAŞIK CONVERT = ÇEVİR DEC2BIN = DEC2BIN DEC2HEX = DEC2HEX DEC2OCT = DEC2OCT DELTA = DELTA ERF = HATAİŞLEV ERF.PRECISE = HATAİŞLEV.DUYARLI ERFC = TÜMHATAİŞLEV ERFC.PRECISE = TÜMHATAİŞLEV.DUYARLI GESTEP = BESINIR HEX2BIN = HEX2BIN HEX2DEC = HEX2DEC HEX2OCT = HEX2OCT IMABS = SANMUTLAK IMAGINARY = SANAL IMARGUMENT = SANBAĞ_DEĞİŞKEN IMCONJUGATE = SANEŞLENEK IMCOS = SANCOS IMCOSH = SANCOSH IMCOT = SANCOT IMCSC = SANCSC IMCSCH = SANCSCH IMDIV = SANBÖL IMEXP = SANÜS IMLN = SANLN IMLOG10 = SANLOG10 IMLOG2 = SANLOG2 IMPOWER = SANKUVVET IMPRODUCT = SANÇARP IMREAL = SANGERÇEK IMSEC = SANSEC IMSECH = SANSECH IMSIN = SANSIN IMSINH = SANSINH IMSQRT = SANKAREKÖK IMSUB = SANTOPLA IMSUM = SANÇIKAR IMTAN = SANTAN OCT2BIN = OCT2BIN OCT2DEC = OCT2DEC OCT2HEX = OCT2HEX ## ## Finansal işlevler (Financial Functions) ## ACCRINT = GERÇEKFAİZ ACCRINTM = GERÇEKFAİZV AMORDEGRC = AMORDEGRC AMORLINC = AMORLINC COUPDAYBS = KUPONGÜNBD COUPDAYS = KUPONGÜN COUPDAYSNC = KUPONGÜNDSK COUPNCD = KUPONGÜNSKT COUPNUM = KUPONSAYI COUPPCD = KUPONGÜNÖKT CUMIPMT = TOPÖDENENFAİZ CUMPRINC = TOPANAPARA DB = AZALANBAKİYE DDB = ÇİFTAZALANBAKİYE DISC = İNDİRİM DOLLARDE = LİRAON DOLLARFR = LİRAKES DURATION = SÜRE EFFECT = ETKİN FV = GD FVSCHEDULE = GDPROGRAM INTRATE = FAİZORANI IPMT = FAİZTUTARI IRR = İÇ_VERİM_ORANI ISPMT = ISPMT MDURATION = MSÜRE MIRR = D_İÇ_VERİM_ORANI NOMINAL = NOMİNAL NPER = TAKSİT_SAYISI NPV = NBD ODDFPRICE = TEKYDEĞER ODDFYIELD = TEKYÖDEME ODDLPRICE = TEKSDEĞER ODDLYIELD = TEKSÖDEME PDURATION = PSÜRE PMT = DEVRESEL_ÖDEME PPMT = ANA_PARA_ÖDEMESİ PRICE = DEĞER PRICEDISC = DEĞERİND PRICEMAT = DEĞERVADE PV = BD RATE = FAİZ_ORANI RECEIVED = GETİRİ RRI = GERÇEKLEŞENYATIRIMGETİRİSİ SLN = DA SYD = YAT TBILLEQ = HTAHEŞ TBILLPRICE = HTAHDEĞER TBILLYIELD = HTAHÖDEME VDB = DAB XIRR = AİÇVERİMORANI XNPV = ANBD YIELD = ÖDEME YIELDDISC = ÖDEMEİND YIELDMAT = ÖDEMEVADE ## ## Bilgi işlevleri (Information Functions) ## CELL = HÜCRE ERROR.TYPE = HATA.TİPİ INFO = BİLGİ ISBLANK = EBOŞSA ISERR = EHATA ISERROR = EHATALIYSA ISEVEN = ÇİFTMİ ISFORMULA = EFORMÜLSE ISLOGICAL = EMANTIKSALSA ISNA = EYOKSA ISNONTEXT = EMETİNDEĞİLSE ISNUMBER = ESAYIYSA ISODD = TEKMİ ISREF = EREFSE ISTEXT = EMETİNSE N = S NA = YOKSAY SHEET = SAYFA SHEETS = SAYFALAR TYPE = TÜR ## ## Mantıksal işlevler (Logical Functions) ## AND = VE FALSE = YANLIŞ IF = EĞER IFERROR = EĞERHATA IFNA = EĞERYOKSA IFS = ÇOKEĞER NOT = DEĞİL OR = YADA SWITCH = İLKEŞLEŞEN TRUE = DOĞRU XOR = ÖZELVEYA ## ## Arama ve başvuru işlevleri (Lookup & Reference Functions) ## ADDRESS = ADRES AREAS = ALANSAY CHOOSE = ELEMAN COLUMN = SÜTUN COLUMNS = SÜTUNSAY FORMULATEXT = FORMÜLMETNİ GETPIVOTDATA = ÖZETVERİAL HLOOKUP = YATAYARA HYPERLINK = KÖPRÜ INDEX = İNDİS INDIRECT = DOLAYLI LOOKUP = ARA MATCH = KAÇINCI OFFSET = KAYDIR ROW = SATIR ROWS = SATIRSAY RTD = GZV TRANSPOSE = DEVRİK_DÖNÜŞÜM VLOOKUP = DÜŞEYARA ## ## Matematik ve trigonometri işlevleri (Math & Trig Functions) ## ABS = MUTLAK ACOS = ACOS ACOSH = ACOSH ACOT = ACOT ACOTH = ACOTH AGGREGATE = TOPLAMA ARABIC = ARAP ASIN = ASİN ASINH = ASİNH ATAN = ATAN ATAN2 = ATAN2 ATANH = ATANH BASE = TABAN CEILING.MATH = TAVANAYUVARLA.MATEMATİK CEILING.PRECISE = TAVANAYUVARLA.DUYARLI COMBIN = KOMBİNASYON COMBINA = KOMBİNASYONA COS = COS COSH = COSH COT = COT COTH = COTH CSC = CSC CSCH = CSCH DECIMAL = ONDALIK DEGREES = DERECE ECMA.CEILING = ECMA.TAVAN EVEN = ÇİFT EXP = ÜS FACT = ÇARPINIM FACTDOUBLE = ÇİFTFAKTÖR FLOOR.MATH = TABANAYUVARLA.MATEMATİK FLOOR.PRECISE = TABANAYUVARLA.DUYARLI GCD = OBEB INT = TAMSAYI ISO.CEILING = ISO.TAVAN LCM = OKEK LN = LN LOG = LOG LOG10 = LOG10 MDETERM = DETERMİNANT MINVERSE = DİZEY_TERS MMULT = DÇARP MOD = MOD MROUND = KYUVARLA MULTINOMIAL = ÇOKTERİMLİ MUNIT = BİRİMMATRİS ODD = TEK PI = Pİ POWER = KUVVET PRODUCT = ÇARPIM QUOTIENT = BÖLÜM RADIANS = RADYAN RAND = S_SAYI_ÜRET RANDBETWEEN = RASTGELEARADA ROMAN = ROMEN ROUND = YUVARLA ROUNDBAHTDOWN = BAHTAŞAĞIYUVARLA ROUNDBAHTUP = BAHTYUKARIYUVARLA ROUNDDOWN = AŞAĞIYUVARLA ROUNDUP = YUKARIYUVARLA SEC = SEC SECH = SECH SERIESSUM = SERİTOPLA SIGN = İŞARET SIN = SİN SINH = SİNH SQRT = KAREKÖK SQRTPI = KAREKÖKPİ SUBTOTAL = ALTTOPLAM SUM = TOPLA SUMIF = ETOPLA SUMIFS = ÇOKETOPLA SUMPRODUCT = TOPLA.ÇARPIM SUMSQ = TOPKARE SUMX2MY2 = TOPX2EY2 SUMX2PY2 = TOPX2AY2 SUMXMY2 = TOPXEY2 TAN = TAN TANH = TANH TRUNC = NSAT ## ## İstatistik işlevleri (Statistical Functions) ## AVEDEV = ORTSAP AVERAGE = ORTALAMA AVERAGEA = ORTALAMAA AVERAGEIF = EĞERORTALAMA AVERAGEIFS = ÇOKEĞERORTALAMA BETA.DIST = BETA.DAĞ BETA.INV = BETA.TERS BINOM.DIST = BİNOM.DAĞ BINOM.DIST.RANGE = BİNOM.DAĞ.ARALIK BINOM.INV = BİNOM.TERS CHISQ.DIST = KİKARE.DAĞ CHISQ.DIST.RT = KİKARE.DAĞ.SAĞK CHISQ.INV = KİKARE.TERS CHISQ.INV.RT = KİKARE.TERS.SAĞK CHISQ.TEST = KİKARE.TEST CONFIDENCE.NORM = GÜVENİLİRLİK.NORM CONFIDENCE.T = GÜVENİLİRLİK.T CORREL = KORELASYON COUNT = BAĞ_DEĞ_SAY COUNTA = BAĞ_DEĞ_DOLU_SAY COUNTBLANK = BOŞLUKSAY COUNTIF = EĞERSAY COUNTIFS = ÇOKEĞERSAY COVARIANCE.P = KOVARYANS.P COVARIANCE.S = KOVARYANS.S DEVSQ = SAPKARE EXPON.DIST = ÜSTEL.DAĞ F.DIST = F.DAĞ F.DIST.RT = F.DAĞ.SAĞK F.INV = F.TERS F.INV.RT = F.TERS.SAĞK F.TEST = F.TEST FISHER = FISHER FISHERINV = FISHERTERS FORECAST.ETS = TAHMİN.ETS FORECAST.ETS.CONFINT = TAHMİN.ETS.GVNARAL FORECAST.ETS.SEASONALITY = TAHMİN.ETS.MEVSİMSELLİK FORECAST.ETS.STAT = TAHMİN.ETS.İSTAT FORECAST.LINEAR = TAHMİN.DOĞRUSAL FREQUENCY = SIKLIK GAMMA = GAMA GAMMA.DIST = GAMA.DAĞ GAMMA.INV = GAMA.TERS GAMMALN = GAMALN GAMMALN.PRECISE = GAMALN.DUYARLI GAUSS = GAUSS GEOMEAN = GEOORT GROWTH = BÜYÜME HARMEAN = HARORT HYPGEOM.DIST = HİPERGEOM.DAĞ INTERCEPT = KESMENOKTASI KURT = BASIKLIK LARGE = BÜYÜK LINEST = DOT LOGEST = LOT LOGNORM.DIST = LOGNORM.DAĞ LOGNORM.INV = LOGNORM.TERS MAX = MAK MAXA = MAKA MAXIFS = ÇOKEĞERMAK MEDIAN = ORTANCA MIN = MİN MINA = MİNA MINIFS = ÇOKEĞERMİN MODE.MULT = ENÇOK_OLAN.ÇOK MODE.SNGL = ENÇOK_OLAN.TEK NEGBINOM.DIST = NEGBİNOM.DAĞ NORM.DIST = NORM.DAĞ NORM.INV = NORM.TERS NORM.S.DIST = NORM.S.DAĞ NORM.S.INV = NORM.S.TERS PEARSON = PEARSON PERCENTILE.EXC = YÜZDEBİRLİK.HRC PERCENTILE.INC = YÜZDEBİRLİK.DHL PERCENTRANK.EXC = YÜZDERANK.HRC PERCENTRANK.INC = YÜZDERANK.DHL PERMUT = PERMÜTASYON PERMUTATIONA = PERMÜTASYONA PHI = PHI POISSON.DIST = POISSON.DAĞ PROB = OLASILIK QUARTILE.EXC = DÖRTTEBİRLİK.HRC QUARTILE.INC = DÖRTTEBİRLİK.DHL RANK.AVG = RANK.ORT RANK.EQ = RANK.EŞİT RSQ = RKARE SKEW = ÇARPIKLIK SKEW.P = ÇARPIKLIK.P SLOPE = EĞİM SMALL = KÜÇÜK STANDARDIZE = STANDARTLAŞTIRMA STDEV.P = STDSAPMA.P STDEV.S = STDSAPMA.S STDEVA = STDSAPMAA STDEVPA = STDSAPMASA STEYX = STHYX T.DIST = T.DAĞ T.DIST.2T = T.DAĞ.2K T.DIST.RT = T.DAĞ.SAĞK T.INV = T.TERS T.INV.2T = T.TERS.2K T.TEST = T.TEST TREND = EĞİLİM TRIMMEAN = KIRPORTALAMA VAR.P = VAR.P VAR.S = VAR.S VARA = VARA VARPA = VARSA WEIBULL.DIST = WEIBULL.DAĞ Z.TEST = Z.TEST ## ## Metin işlevleri (Text Functions) ## BAHTTEXT = BAHTMETİN CHAR = DAMGA CLEAN = TEMİZ CODE = KOD CONCAT = ARALIKBİRLEŞTİR DOLLAR = LİRA EXACT = ÖZDEŞ FIND = BUL FIXED = SAYIDÜZENLE ISTHAIDIGIT = TAYRAKAMIYSA LEFT = SOLDAN LEN = UZUNLUK LOWER = KÜÇÜKHARF MID = PARÇAAL NUMBERSTRING = SAYIDİZİ NUMBERVALUE = SAYIDEĞERİ PHONETIC = SES PROPER = YAZIM.DÜZENİ REPLACE = DEĞİŞTİR REPT = YİNELE RIGHT = SAĞDAN SEARCH = MBUL SUBSTITUTE = YERİNEKOY T = M TEXT = METNEÇEVİR TEXTJOIN = METİNBİRLEŞTİR THAIDIGIT = TAYRAKAM THAINUMSOUND = TAYSAYISES THAINUMSTRING = TAYSAYIDİZE THAISTRINGLENGTH = TAYDİZEUZUNLUĞU TRIM = KIRP UNICHAR = UNICODEKARAKTERİ UNICODE = UNICODE UPPER = BÜYÜKHARF VALUE = SAYIYAÇEVİR ## ## Metin işlevleri (Web Functions) ## ENCODEURL = URLKODLA FILTERXML = XMLFİLTRELE WEBSERVICE = WEBHİZMETİ ## ## Uyumluluk işlevleri (Compatibility Functions) ## BETADIST = BETADAĞ BETAINV = BETATERS BINOMDIST = BİNOMDAĞ CEILING = TAVANAYUVARLA CHIDIST = KİKAREDAĞ CHIINV = KİKARETERS CHITEST = KİKARETEST CONCATENATE = BİRLEŞTİR CONFIDENCE = GÜVENİRLİK COVAR = KOVARYANS CRITBINOM = KRİTİKBİNOM EXPONDIST = ÜSTELDAĞ FDIST = FDAĞ FINV = FTERS FLOOR = TABANAYUVARLA FORECAST = TAHMİN FTEST = FTEST GAMMADIST = GAMADAĞ GAMMAINV = GAMATERS HYPGEOMDIST = HİPERGEOMDAĞ LOGINV = LOGTERS LOGNORMDIST = LOGNORMDAĞ MODE = ENÇOK_OLAN NEGBINOMDIST = NEGBİNOMDAĞ NORMDIST = NORMDAĞ NORMINV = NORMTERS NORMSDIST = NORMSDAĞ NORMSINV = NORMSTERS PERCENTILE = YÜZDEBİRLİK PERCENTRANK = YÜZDERANK POISSON = POISSON QUARTILE = DÖRTTEBİRLİK RANK = RANK STDEV = STDSAPMA STDEVP = STDSAPMAS TDIST = TDAĞ TINV = TTERS TTEST = TTEST VAR = VAR VARP = VARS WEIBULL = WEIBULL ZTEST = ZTEST phpspreadsheet/src/PhpSpreadsheet/Calculation/locale/tr/config 0000644 00000000512 15060132323 0020574 0 ustar 00 ############################################################ ## ## PhpSpreadsheet - locale settings ## ## Türkçe (Turkish) ## ############################################################ ArgumentSeparator = ; ## ## Error Codes ## NULL = #BOŞ! DIV0 = #SAYI/0! VALUE = #DEĞER! REF = #BAŞV! NAME = #AD? NUM = #SAYI! NA = #YOK phpspreadsheet/src/PhpSpreadsheet/Calculation/locale/ru/functions 0000644 00000033315 15060132323 0021347 0 ustar 00 ############################################################ ## ## PhpSpreadsheet - function name translations ## ## русский язык (Russian) ## ############################################################ ## ## Функции кубов (Cube Functions) ## CUBEKPIMEMBER = КУБЭЛЕМЕНТКИП CUBEMEMBER = КУБЭЛЕМЕНТ CUBEMEMBERPROPERTY = КУБСВОЙСТВОЭЛЕМЕНТА CUBERANKEDMEMBER = КУБПОРЭЛЕМЕНТ CUBESET = КУБМНОЖ CUBESETCOUNT = КУБЧИСЛОЭЛМНОЖ CUBEVALUE = КУБЗНАЧЕНИЕ ## ## Функции для работы с базами данных (Database Functions) ## DAVERAGE = ДСРЗНАЧ DCOUNT = БСЧЁТ DCOUNTA = БСЧЁТА DGET = БИЗВЛЕЧЬ DMAX = ДМАКС DMIN = ДМИН DPRODUCT = БДПРОИЗВЕД DSTDEV = ДСТАНДОТКЛ DSTDEVP = ДСТАНДОТКЛП DSUM = БДСУММ DVAR = БДДИСП DVARP = БДДИСПП ## ## Функции даты и времени (Date & Time Functions) ## DATE = ДАТА DATEDIF = РАЗНДАТ DATESTRING = СТРОКАДАННЫХ DATEVALUE = ДАТАЗНАЧ DAY = ДЕНЬ DAYS = ДНИ DAYS360 = ДНЕЙ360 EDATE = ДАТАМЕС EOMONTH = КОНМЕСЯЦА HOUR = ЧАС ISOWEEKNUM = НОМНЕДЕЛИ.ISO MINUTE = МИНУТЫ MONTH = МЕСЯЦ NETWORKDAYS = ЧИСТРАБДНИ NETWORKDAYS.INTL = ЧИСТРАБДНИ.МЕЖД NOW = ТДАТА SECOND = СЕКУНДЫ THAIDAYOFWEEK = ТАЙДЕНЬНЕД THAIMONTHOFYEAR = ТАЙМЕСЯЦ THAIYEAR = ТАЙГОД TIME = ВРЕМЯ TIMEVALUE = ВРЕМЗНАЧ TODAY = СЕГОДНЯ WEEKDAY = ДЕНЬНЕД WEEKNUM = НОМНЕДЕЛИ WORKDAY = РАБДЕНЬ WORKDAY.INTL = РАБДЕНЬ.МЕЖД YEAR = ГОД YEARFRAC = ДОЛЯГОДА ## ## Инженерные функции (Engineering Functions) ## BESSELI = БЕССЕЛЬ.I BESSELJ = БЕССЕЛЬ.J BESSELK = БЕССЕЛЬ.K BESSELY = БЕССЕЛЬ.Y BIN2DEC = ДВ.В.ДЕС BIN2HEX = ДВ.В.ШЕСТН BIN2OCT = ДВ.В.ВОСЬМ BITAND = БИТ.И BITLSHIFT = БИТ.СДВИГЛ BITOR = БИТ.ИЛИ BITRSHIFT = БИТ.СДВИГП BITXOR = БИТ.ИСКЛИЛИ COMPLEX = КОМПЛЕКСН CONVERT = ПРЕОБР DEC2BIN = ДЕС.В.ДВ DEC2HEX = ДЕС.В.ШЕСТН DEC2OCT = ДЕС.В.ВОСЬМ DELTA = ДЕЛЬТА ERF = ФОШ ERF.PRECISE = ФОШ.ТОЧН ERFC = ДФОШ ERFC.PRECISE = ДФОШ.ТОЧН GESTEP = ПОРОГ HEX2BIN = ШЕСТН.В.ДВ HEX2DEC = ШЕСТН.В.ДЕС HEX2OCT = ШЕСТН.В.ВОСЬМ IMABS = МНИМ.ABS IMAGINARY = МНИМ.ЧАСТЬ IMARGUMENT = МНИМ.АРГУМЕНТ IMCONJUGATE = МНИМ.СОПРЯЖ IMCOS = МНИМ.COS IMCOSH = МНИМ.COSH IMCOT = МНИМ.COT IMCSC = МНИМ.CSC IMCSCH = МНИМ.CSCH IMDIV = МНИМ.ДЕЛ IMEXP = МНИМ.EXP IMLN = МНИМ.LN IMLOG10 = МНИМ.LOG10 IMLOG2 = МНИМ.LOG2 IMPOWER = МНИМ.СТЕПЕНЬ IMPRODUCT = МНИМ.ПРОИЗВЕД IMREAL = МНИМ.ВЕЩ IMSEC = МНИМ.SEC IMSECH = МНИМ.SECH IMSIN = МНИМ.SIN IMSINH = МНИМ.SINH IMSQRT = МНИМ.КОРЕНЬ IMSUB = МНИМ.РАЗН IMSUM = МНИМ.СУММ IMTAN = МНИМ.TAN OCT2BIN = ВОСЬМ.В.ДВ OCT2DEC = ВОСЬМ.В.ДЕС OCT2HEX = ВОСЬМ.В.ШЕСТН ## ## Финансовые функции (Financial Functions) ## ACCRINT = НАКОПДОХОД ACCRINTM = НАКОПДОХОДПОГАШ AMORDEGRC = АМОРУМ AMORLINC = АМОРУВ COUPDAYBS = ДНЕЙКУПОНДО COUPDAYS = ДНЕЙКУПОН COUPDAYSNC = ДНЕЙКУПОНПОСЛЕ COUPNCD = ДАТАКУПОНПОСЛЕ COUPNUM = ЧИСЛКУПОН COUPPCD = ДАТАКУПОНДО CUMIPMT = ОБЩПЛАТ CUMPRINC = ОБЩДОХОД DB = ФУО DDB = ДДОБ DISC = СКИДКА DOLLARDE = РУБЛЬ.ДЕС DOLLARFR = РУБЛЬ.ДРОБЬ DURATION = ДЛИТ EFFECT = ЭФФЕКТ FV = БС FVSCHEDULE = БЗРАСПИС INTRATE = ИНОРМА IPMT = ПРПЛТ IRR = ВСД ISPMT = ПРОЦПЛАТ MDURATION = МДЛИТ MIRR = МВСД NOMINAL = НОМИНАЛ NPER = КПЕР NPV = ЧПС ODDFPRICE = ЦЕНАПЕРВНЕРЕГ ODDFYIELD = ДОХОДПЕРВНЕРЕГ ODDLPRICE = ЦЕНАПОСЛНЕРЕГ ODDLYIELD = ДОХОДПОСЛНЕРЕГ PDURATION = ПДЛИТ PMT = ПЛТ PPMT = ОСПЛТ PRICE = ЦЕНА PRICEDISC = ЦЕНАСКИДКА PRICEMAT = ЦЕНАПОГАШ PV = ПС RATE = СТАВКА RECEIVED = ПОЛУЧЕНО RRI = ЭКВ.СТАВКА SLN = АПЛ SYD = АСЧ TBILLEQ = РАВНОКЧЕК TBILLPRICE = ЦЕНАКЧЕК TBILLYIELD = ДОХОДКЧЕК USDOLLAR = ДОЛЛСША VDB = ПУО XIRR = ЧИСТВНДОХ XNPV = ЧИСТНЗ YIELD = ДОХОД YIELDDISC = ДОХОДСКИДКА YIELDMAT = ДОХОДПОГАШ ## ## Информационные функции (Information Functions) ## CELL = ЯЧЕЙКА ERROR.TYPE = ТИП.ОШИБКИ INFO = ИНФОРМ ISBLANK = ЕПУСТО ISERR = ЕОШ ISERROR = ЕОШИБКА ISEVEN = ЕЧЁТН ISFORMULA = ЕФОРМУЛА ISLOGICAL = ЕЛОГИЧ ISNA = ЕНД ISNONTEXT = ЕНЕТЕКСТ ISNUMBER = ЕЧИСЛО ISODD = ЕНЕЧЁТ ISREF = ЕССЫЛКА ISTEXT = ЕТЕКСТ N = Ч NA = НД SHEET = ЛИСТ SHEETS = ЛИСТЫ TYPE = ТИП ## ## Логические функции (Logical Functions) ## AND = И FALSE = ЛОЖЬ IF = ЕСЛИ IFERROR = ЕСЛИОШИБКА IFNA = ЕСНД IFS = УСЛОВИЯ NOT = НЕ OR = ИЛИ SWITCH = ПЕРЕКЛЮЧ TRUE = ИСТИНА XOR = ИСКЛИЛИ ## ## Функции ссылки и поиска (Lookup & Reference Functions) ## ADDRESS = АДРЕС AREAS = ОБЛАСТИ CHOOSE = ВЫБОР COLUMN = СТОЛБЕЦ COLUMNS = ЧИСЛСТОЛБ FILTER = ФИЛЬТР FORMULATEXT = Ф.ТЕКСТ GETPIVOTDATA = ПОЛУЧИТЬ.ДАННЫЕ.СВОДНОЙ.ТАБЛИЦЫ HLOOKUP = ГПР HYPERLINK = ГИПЕРССЫЛКА INDEX = ИНДЕКС INDIRECT = ДВССЫЛ LOOKUP = ПРОСМОТР MATCH = ПОИСКПОЗ OFFSET = СМЕЩ ROW = СТРОКА ROWS = ЧСТРОК RTD = ДРВ SORT = СОРТ SORTBY = СОРТПО TRANSPOSE = ТРАНСП UNIQUE = УНИК VLOOKUP = ВПР XLOOKUP = ПРОСМОТРX XMATCH = ПОИСКПОЗX ## ## Математические и тригонометрические функции (Math & Trig Functions) ## ABS = ABS ACOS = ACOS ACOSH = ACOSH ACOT = ACOT ACOTH = ACOTH AGGREGATE = АГРЕГАТ ARABIC = АРАБСКОЕ ASIN = ASIN ASINH = ASINH ATAN = ATAN ATAN2 = ATAN2 ATANH = ATANH BASE = ОСНОВАНИЕ CEILING.MATH = ОКРВВЕРХ.МАТ CEILING.PRECISE = ОКРВВЕРХ.ТОЧН COMBIN = ЧИСЛКОМБ COMBINA = ЧИСЛКОМБА COS = COS COSH = COSH COT = COT COTH = COTH CSC = CSC CSCH = CSCH DECIMAL = ДЕС DEGREES = ГРАДУСЫ ECMA.CEILING = ECMA.ОКРВВЕРХ EVEN = ЧЁТН EXP = EXP FACT = ФАКТР FACTDOUBLE = ДВФАКТР FLOOR.MATH = ОКРВНИЗ.МАТ FLOOR.PRECISE = ОКРВНИЗ.ТОЧН GCD = НОД INT = ЦЕЛОЕ ISO.CEILING = ISO.ОКРВВЕРХ LCM = НОК LN = LN LOG = LOG LOG10 = LOG10 MDETERM = МОПРЕД MINVERSE = МОБР MMULT = МУМНОЖ MOD = ОСТАТ MROUND = ОКРУГЛТ MULTINOMIAL = МУЛЬТИНОМ MUNIT = МЕДИН ODD = НЕЧЁТ PI = ПИ POWER = СТЕПЕНЬ PRODUCT = ПРОИЗВЕД QUOTIENT = ЧАСТНОЕ RADIANS = РАДИАНЫ RAND = СЛЧИС RANDARRAY = СЛУЧМАССИВ RANDBETWEEN = СЛУЧМЕЖДУ ROMAN = РИМСКОЕ ROUND = ОКРУГЛ ROUNDBAHTDOWN = ОКРУГЛБАТВНИЗ ROUNDBAHTUP = ОКРУГЛБАТВВЕРХ ROUNDDOWN = ОКРУГЛВНИЗ ROUNDUP = ОКРУГЛВВЕРХ SEC = SEC SECH = SECH SERIESSUM = РЯД.СУММ SEQUENCE = ПОСЛЕДОВ SIGN = ЗНАК SIN = SIN SINH = SINH SQRT = КОРЕНЬ SQRTPI = КОРЕНЬПИ SUBTOTAL = ПРОМЕЖУТОЧНЫЕ.ИТОГИ SUM = СУММ SUMIF = СУММЕСЛИ SUMIFS = СУММЕСЛИМН SUMPRODUCT = СУММПРОИЗВ SUMSQ = СУММКВ SUMX2MY2 = СУММРАЗНКВ SUMX2PY2 = СУММСУММКВ SUMXMY2 = СУММКВРАЗН TAN = TAN TANH = TANH TRUNC = ОТБР ## ## Статистические функции (Statistical Functions) ## AVEDEV = СРОТКЛ AVERAGE = СРЗНАЧ AVERAGEA = СРЗНАЧА AVERAGEIF = СРЗНАЧЕСЛИ AVERAGEIFS = СРЗНАЧЕСЛИМН BETA.DIST = БЕТА.РАСП BETA.INV = БЕТА.ОБР BINOM.DIST = БИНОМ.РАСП BINOM.DIST.RANGE = БИНОМ.РАСП.ДИАП BINOM.INV = БИНОМ.ОБР CHISQ.DIST = ХИ2.РАСП CHISQ.DIST.RT = ХИ2.РАСП.ПХ CHISQ.INV = ХИ2.ОБР CHISQ.INV.RT = ХИ2.ОБР.ПХ CHISQ.TEST = ХИ2.ТЕСТ CONFIDENCE.NORM = ДОВЕРИТ.НОРМ CONFIDENCE.T = ДОВЕРИТ.СТЬЮДЕНТ CORREL = КОРРЕЛ COUNT = СЧЁТ COUNTA = СЧЁТЗ COUNTBLANK = СЧИТАТЬПУСТОТЫ COUNTIF = СЧЁТЕСЛИ COUNTIFS = СЧЁТЕСЛИМН COVARIANCE.P = КОВАРИАЦИЯ.Г COVARIANCE.S = КОВАРИАЦИЯ.В DEVSQ = КВАДРОТКЛ EXPON.DIST = ЭКСП.РАСП F.DIST = F.РАСП F.DIST.RT = F.РАСП.ПХ F.INV = F.ОБР F.INV.RT = F.ОБР.ПХ F.TEST = F.ТЕСТ FISHER = ФИШЕР FISHERINV = ФИШЕРОБР FORECAST.ETS = ПРЕДСКАЗ.ETS FORECAST.ETS.CONFINT = ПРЕДСКАЗ.ЕTS.ДОВИНТЕРВАЛ FORECAST.ETS.SEASONALITY = ПРЕДСКАЗ.ETS.СЕЗОННОСТЬ FORECAST.ETS.STAT = ПРЕДСКАЗ.ETS.СТАТ FORECAST.LINEAR = ПРЕДСКАЗ.ЛИНЕЙН FREQUENCY = ЧАСТОТА GAMMA = ГАММА GAMMA.DIST = ГАММА.РАСП GAMMA.INV = ГАММА.ОБР GAMMALN = ГАММАНЛОГ GAMMALN.PRECISE = ГАММАНЛОГ.ТОЧН GAUSS = ГАУСС GEOMEAN = СРГЕОМ GROWTH = РОСТ HARMEAN = СРГАРМ HYPGEOM.DIST = ГИПЕРГЕОМ.РАСП INTERCEPT = ОТРЕЗОК KURT = ЭКСЦЕСС LARGE = НАИБОЛЬШИЙ LINEST = ЛИНЕЙН LOGEST = ЛГРФПРИБЛ LOGNORM.DIST = ЛОГНОРМ.РАСП LOGNORM.INV = ЛОГНОРМ.ОБР MAX = МАКС MAXA = МАКСА MAXIFS = МАКСЕСЛИ MEDIAN = МЕДИАНА MIN = МИН MINA = МИНА MINIFS = МИНЕСЛИ MODE.MULT = МОДА.НСК MODE.SNGL = МОДА.ОДН NEGBINOM.DIST = ОТРБИНОМ.РАСП NORM.DIST = НОРМ.РАСП NORM.INV = НОРМ.ОБР NORM.S.DIST = НОРМ.СТ.РАСП NORM.S.INV = НОРМ.СТ.ОБР PEARSON = PEARSON PERCENTILE.EXC = ПРОЦЕНТИЛЬ.ИСКЛ PERCENTILE.INC = ПРОЦЕНТИЛЬ.ВКЛ PERCENTRANK.EXC = ПРОЦЕНТРАНГ.ИСКЛ PERCENTRANK.INC = ПРОЦЕНТРАНГ.ВКЛ PERMUT = ПЕРЕСТ PERMUTATIONA = ПЕРЕСТА PHI = ФИ POISSON.DIST = ПУАССОН.РАСП PROB = ВЕРОЯТНОСТЬ QUARTILE.EXC = КВАРТИЛЬ.ИСКЛ QUARTILE.INC = КВАРТИЛЬ.ВКЛ RANK.AVG = РАНГ.СР RANK.EQ = РАНГ.РВ RSQ = КВПИРСОН SKEW = СКОС SKEW.P = СКОС.Г SLOPE = НАКЛОН SMALL = НАИМЕНЬШИЙ STANDARDIZE = НОРМАЛИЗАЦИЯ STDEV.P = СТАНДОТКЛОН.Г STDEV.S = СТАНДОТКЛОН.В STDEVA = СТАНДОТКЛОНА STDEVPA = СТАНДОТКЛОНПА STEYX = СТОШYX T.DIST = СТЬЮДЕНТ.РАСП T.DIST.2T = СТЬЮДЕНТ.РАСП.2Х T.DIST.RT = СТЬЮДЕНТ.РАСП.ПХ T.INV = СТЬЮДЕНТ.ОБР T.INV.2T = СТЬЮДЕНТ.ОБР.2Х T.TEST = СТЬЮДЕНТ.ТЕСТ TREND = ТЕНДЕНЦИЯ TRIMMEAN = УРЕЗСРЕДНЕЕ VAR.P = ДИСП.Г VAR.S = ДИСП.В VARA = ДИСПА VARPA = ДИСПРА WEIBULL.DIST = ВЕЙБУЛЛ.РАСП Z.TEST = Z.ТЕСТ ## ## Текстовые функции (Text Functions) ## ARRAYTOTEXT = МАССИВВТЕКСТ BAHTTEXT = БАТТЕКСТ CHAR = СИМВОЛ CLEAN = ПЕЧСИМВ CODE = КОДСИМВ CONCAT = СЦЕП DBCS = БДЦС DOLLAR = РУБЛЬ EXACT = СОВПАД FIND = НАЙТИ FINDB = НАЙТИБ FIXED = ФИКСИРОВАННЫЙ ISTHAIDIGIT = ЕТАЙЦИФРЫ LEFT = ЛЕВСИМВ LEFTB = ЛЕВБ LEN = ДЛСТР LENB = ДЛИНБ LOWER = СТРОЧН MID = ПСТР MIDB = ПСТРБ NUMBERSTRING = СТРОКАЧИСЕЛ NUMBERVALUE = ЧЗНАЧ PROPER = ПРОПНАЧ REPLACE = ЗАМЕНИТЬ REPLACEB = ЗАМЕНИТЬБ REPT = ПОВТОР RIGHT = ПРАВСИМВ RIGHTB = ПРАВБ SEARCH = ПОИСК SEARCHB = ПОИСКБ SUBSTITUTE = ПОДСТАВИТЬ T = Т TEXT = ТЕКСТ TEXTJOIN = ОБЪЕДИНИТЬ THAIDIGIT = ТАЙЦИФРА THAINUMSOUND = ТАЙЧИСЛОВЗВУК THAINUMSTRING = ТАЙЧИСЛОВСТРОКУ THAISTRINGLENGTH = ТАЙДЛИНАСТРОКИ TRIM = СЖПРОБЕЛЫ UNICHAR = ЮНИСИМВ UNICODE = UNICODE UPPER = ПРОПИСН VALUE = ЗНАЧЕН VALUETOTEXT = ЗНАЧЕНИЕВТЕКСТ ## ## Веб-функции (Web Functions) ## ENCODEURL = КОДИР.URL FILTERXML = ФИЛЬТР.XML WEBSERVICE = ВЕБСЛУЖБА ## ## Функции совместимости (Compatibility Functions) ## BETADIST = БЕТАРАСП BETAINV = БЕТАОБР BINOMDIST = БИНОМРАСП CEILING = ОКРВВЕРХ CHIDIST = ХИ2РАСП CHIINV = ХИ2ОБР CHITEST = ХИ2ТЕСТ CONCATENATE = СЦЕПИТЬ CONFIDENCE = ДОВЕРИТ COVAR = КОВАР CRITBINOM = КРИТБИНОМ EXPONDIST = ЭКСПРАСП FDIST = FРАСП FINV = FРАСПОБР FLOOR = ОКРВНИЗ FORECAST = ПРЕДСКАЗ FTEST = ФТЕСТ GAMMADIST = ГАММАРАСП GAMMAINV = ГАММАОБР HYPGEOMDIST = ГИПЕРГЕОМЕТ LOGINV = ЛОГНОРМОБР LOGNORMDIST = ЛОГНОРМРАСП MODE = МОДА NEGBINOMDIST = ОТРБИНОМРАСП NORMDIST = НОРМРАСП NORMINV = НОРМОБР NORMSDIST = НОРМСТРАСП NORMSINV = НОРМСТОБР PERCENTILE = ПЕРСЕНТИЛЬ PERCENTRANK = ПРОЦЕНТРАНГ POISSON = ПУАССОН QUARTILE = КВАРТИЛЬ RANK = РАНГ STDEV = СТАНДОТКЛОН STDEVP = СТАНДОТКЛОНП TDIST = СТЬЮДРАСП TINV = СТЬЮДРАСПОБР TTEST = ТТЕСТ VAR = ДИСП VARP = ДИСПР WEIBULL = ВЕЙБУЛЛ ZTEST = ZТЕСТ phpspreadsheet/src/PhpSpreadsheet/Calculation/locale/ru/config 0000644 00000000566 15060132323 0020606 0 ustar 00 ############################################################ ## ## PhpSpreadsheet - locale settings ## ## русский язык (Russian) ## ############################################################ ArgumentSeparator = ; ## ## Error Codes ## NULL = #ПУСТО! DIV0 = #ДЕЛ/0! VALUE = #ЗНАЧ! REF = #ССЫЛКА! NAME = #ИМЯ? NUM = #ЧИСЛО! NA = #Н/Д phpspreadsheet/src/PhpSpreadsheet/Calculation/locale/cs/functions 0000644 00000022455 15060132323 0021331 0 ustar 00 ############################################################ ## ## PhpSpreadsheet - function name translations ## ## Ceština (Czech) ## ############################################################ ## ## Funkce pro práci s datovými krychlemi (Cube Functions) ## CUBEKPIMEMBER = CUBEKPIMEMBER CUBEMEMBER = CUBEMEMBER CUBEMEMBERPROPERTY = CUBEMEMBERPROPERTY CUBERANKEDMEMBER = CUBERANKEDMEMBER CUBESET = CUBESET CUBESETCOUNT = CUBESETCOUNT CUBEVALUE = CUBEVALUE ## ## Funkce databáze (Database Functions) ## DAVERAGE = DPRŮMĚR DCOUNT = DPOČET DCOUNTA = DPOČET2 DGET = DZÍSKAT DMAX = DMAX DMIN = DMIN DPRODUCT = DSOUČIN DSTDEV = DSMODCH.VÝBĚR DSTDEVP = DSMODCH DSUM = DSUMA DVAR = DVAR.VÝBĚR DVARP = DVAR ## ## Funkce data a času (Date & Time Functions) ## DATE = DATUM DATEVALUE = DATUMHODN DAY = DEN DAYS = DAYS DAYS360 = ROK360 EDATE = EDATE EOMONTH = EOMONTH HOUR = HODINA ISOWEEKNUM = ISOWEEKNUM MINUTE = MINUTA MONTH = MĚSÍC NETWORKDAYS = NETWORKDAYS NETWORKDAYS.INTL = NETWORKDAYS.INTL NOW = NYNÍ SECOND = SEKUNDA TIME = ČAS TIMEVALUE = ČASHODN TODAY = DNES WEEKDAY = DENTÝDNE WEEKNUM = WEEKNUM WORKDAY = WORKDAY WORKDAY.INTL = WORKDAY.INTL YEAR = ROK YEARFRAC = YEARFRAC ## ## Inženýrské funkce (Engineering Functions) ## BESSELI = BESSELI BESSELJ = BESSELJ BESSELK = BESSELK BESSELY = BESSELY BIN2DEC = BIN2DEC BIN2HEX = BIN2HEX BIN2OCT = BIN2OCT BITAND = BITAND BITLSHIFT = BITLSHIFT BITOR = BITOR BITRSHIFT = BITRSHIFT BITXOR = BITXOR COMPLEX = COMPLEX CONVERT = CONVERT DEC2BIN = DEC2BIN DEC2HEX = DEC2HEX DEC2OCT = DEC2OCT DELTA = DELTA ERF = ERF ERF.PRECISE = ERF.PRECISE ERFC = ERFC ERFC.PRECISE = ERFC.PRECISE GESTEP = GESTEP HEX2BIN = HEX2BIN HEX2DEC = HEX2DEC HEX2OCT = HEX2OCT IMABS = IMABS IMAGINARY = IMAGINARY IMARGUMENT = IMARGUMENT IMCONJUGATE = IMCONJUGATE IMCOS = IMCOS IMCOSH = IMCOSH IMCOT = IMCOT IMCSC = IMCSC IMCSCH = IMCSCH IMDIV = IMDIV IMEXP = IMEXP IMLN = IMLN IMLOG10 = IMLOG10 IMLOG2 = IMLOG2 IMPOWER = IMPOWER IMPRODUCT = IMPRODUCT IMREAL = IMREAL IMSEC = IMSEC IMSECH = IMSECH IMSIN = IMSIN IMSINH = IMSINH IMSQRT = IMSQRT IMSUB = IMSUB IMSUM = IMSUM IMTAN = IMTAN OCT2BIN = OCT2BIN OCT2DEC = OCT2DEC OCT2HEX = OCT2HEX ## ## Finanční funkce (Financial Functions) ## ACCRINT = ACCRINT ACCRINTM = ACCRINTM AMORDEGRC = AMORDEGRC AMORLINC = AMORLINC COUPDAYBS = COUPDAYBS COUPDAYS = COUPDAYS COUPDAYSNC = COUPDAYSNC COUPNCD = COUPNCD COUPNUM = COUPNUM COUPPCD = COUPPCD CUMIPMT = CUMIPMT CUMPRINC = CUMPRINC DB = ODPIS.ZRYCH DDB = ODPIS.ZRYCH2 DISC = DISC DOLLARDE = DOLLARDE DOLLARFR = DOLLARFR DURATION = DURATION EFFECT = EFFECT FV = BUDHODNOTA FVSCHEDULE = FVSCHEDULE INTRATE = INTRATE IPMT = PLATBA.ÚROK IRR = MÍRA.VÝNOSNOSTI ISPMT = ISPMT MDURATION = MDURATION MIRR = MOD.MÍRA.VÝNOSNOSTI NOMINAL = NOMINAL NPER = POČET.OBDOBÍ NPV = ČISTÁ.SOUČHODNOTA ODDFPRICE = ODDFPRICE ODDFYIELD = ODDFYIELD ODDLPRICE = ODDLPRICE ODDLYIELD = ODDLYIELD PDURATION = PDURATION PMT = PLATBA PPMT = PLATBA.ZÁKLAD PRICE = PRICE PRICEDISC = PRICEDISC PRICEMAT = PRICEMAT PV = SOUČHODNOTA RATE = ÚROKOVÁ.MÍRA RECEIVED = RECEIVED RRI = RRI SLN = ODPIS.LIN SYD = ODPIS.NELIN TBILLEQ = TBILLEQ TBILLPRICE = TBILLPRICE TBILLYIELD = TBILLYIELD VDB = ODPIS.ZA.INT XIRR = XIRR XNPV = XNPV YIELD = YIELD YIELDDISC = YIELDDISC YIELDMAT = YIELDMAT ## ## Informační funkce (Information Functions) ## CELL = POLÍČKO ERROR.TYPE = CHYBA.TYP INFO = O.PROSTŘEDÍ ISBLANK = JE.PRÁZDNÉ ISERR = JE.CHYBA ISERROR = JE.CHYBHODN ISEVEN = ISEVEN ISFORMULA = ISFORMULA ISLOGICAL = JE.LOGHODN ISNA = JE.NEDEF ISNONTEXT = JE.NETEXT ISNUMBER = JE.ČISLO ISODD = ISODD ISREF = JE.ODKAZ ISTEXT = JE.TEXT N = N NA = NEDEF SHEET = SHEET SHEETS = SHEETS TYPE = TYP ## ## Logické funkce (Logical Functions) ## AND = A FALSE = NEPRAVDA IF = KDYŽ IFERROR = IFERROR IFNA = IFNA IFS = IFS NOT = NE OR = NEBO SWITCH = SWITCH TRUE = PRAVDA XOR = XOR ## ## Vyhledávací funkce a funkce pro odkazy (Lookup & Reference Functions) ## ADDRESS = ODKAZ AREAS = POČET.BLOKŮ CHOOSE = ZVOLIT COLUMN = SLOUPEC COLUMNS = SLOUPCE FORMULATEXT = FORMULATEXT GETPIVOTDATA = ZÍSKATKONTDATA HLOOKUP = VVYHLEDAT HYPERLINK = HYPERTEXTOVÝ.ODKAZ INDEX = INDEX INDIRECT = NEPŘÍMÝ.ODKAZ LOOKUP = VYHLEDAT MATCH = POZVYHLEDAT OFFSET = POSUN ROW = ŘÁDEK ROWS = ŘÁDKY RTD = RTD TRANSPOSE = TRANSPOZICE VLOOKUP = SVYHLEDAT ## ## Matematické a trigonometrické funkce (Math & Trig Functions) ## ABS = ABS ACOS = ARCCOS ACOSH = ARCCOSH ACOT = ACOT ACOTH = ACOTH AGGREGATE = AGGREGATE ARABIC = ARABIC ASIN = ARCSIN ASINH = ARCSINH ATAN = ARCTG ATAN2 = ARCTG2 ATANH = ARCTGH BASE = BASE CEILING.MATH = CEILING.MATH COMBIN = KOMBINACE COMBINA = COMBINA COS = COS COSH = COSH COT = COT COTH = COTH CSC = CSC CSCH = CSCH DECIMAL = DECIMAL DEGREES = DEGREES EVEN = ZAOKROUHLIT.NA.SUDÉ EXP = EXP FACT = FAKTORIÁL FACTDOUBLE = FACTDOUBLE FLOOR.MATH = FLOOR.MATH GCD = GCD INT = CELÁ.ČÁST LCM = LCM LN = LN LOG = LOGZ LOG10 = LOG MDETERM = DETERMINANT MINVERSE = INVERZE MMULT = SOUČIN.MATIC MOD = MOD MROUND = MROUND MULTINOMIAL = MULTINOMIAL MUNIT = MUNIT ODD = ZAOKROUHLIT.NA.LICHÉ PI = PI POWER = POWER PRODUCT = SOUČIN QUOTIENT = QUOTIENT RADIANS = RADIANS RAND = NÁHČÍSLO RANDBETWEEN = RANDBETWEEN ROMAN = ROMAN ROUND = ZAOKROUHLIT ROUNDDOWN = ROUNDDOWN ROUNDUP = ROUNDUP SEC = SEC SECH = SECH SERIESSUM = SERIESSUM SIGN = SIGN SIN = SIN SINH = SINH SQRT = ODMOCNINA SQRTPI = SQRTPI SUBTOTAL = SUBTOTAL SUM = SUMA SUMIF = SUMIF SUMIFS = SUMIFS SUMPRODUCT = SOUČIN.SKALÁRNÍ SUMSQ = SUMA.ČTVERCŮ SUMX2MY2 = SUMX2MY2 SUMX2PY2 = SUMX2PY2 SUMXMY2 = SUMXMY2 TAN = TG TANH = TGH TRUNC = USEKNOUT ## ## Statistické funkce (Statistical Functions) ## AVEDEV = PRŮMODCHYLKA AVERAGE = PRŮMĚR AVERAGEA = AVERAGEA AVERAGEIF = AVERAGEIF AVERAGEIFS = AVERAGEIFS BETA.DIST = BETA.DIST BETA.INV = BETA.INV BINOM.DIST = BINOM.DIST BINOM.DIST.RANGE = BINOM.DIST.RANGE BINOM.INV = BINOM.INV CHISQ.DIST = CHISQ.DIST CHISQ.DIST.RT = CHISQ.DIST.RT CHISQ.INV = CHISQ.INV CHISQ.INV.RT = CHISQ.INV.RT CHISQ.TEST = CHISQ.TEST CONFIDENCE.NORM = CONFIDENCE.NORM CONFIDENCE.T = CONFIDENCE.T CORREL = CORREL COUNT = POČET COUNTA = POČET2 COUNTBLANK = COUNTBLANK COUNTIF = COUNTIF COUNTIFS = COUNTIFS COVARIANCE.P = COVARIANCE.P COVARIANCE.S = COVARIANCE.S DEVSQ = DEVSQ EXPON.DIST = EXPON.DIST F.DIST = F.DIST F.DIST.RT = F.DIST.RT F.INV = F.INV F.INV.RT = F.INV.RT F.TEST = F.TEST FISHER = FISHER FISHERINV = FISHERINV FORECAST.ETS = FORECAST.ETS FORECAST.ETS.CONFINT = FORECAST.ETS.CONFINT FORECAST.ETS.SEASONALITY = FORECAST.ETS.SEASONALITY FORECAST.ETS.STAT = FORECAST.ETS.STAT FORECAST.LINEAR = FORECAST.LINEAR FREQUENCY = ČETNOSTI GAMMA = GAMMA GAMMA.DIST = GAMMA.DIST GAMMA.INV = GAMMA.INV GAMMALN = GAMMALN GAMMALN.PRECISE = GAMMALN.PRECISE GAUSS = GAUSS GEOMEAN = GEOMEAN GROWTH = LOGLINTREND HARMEAN = HARMEAN HYPGEOM.DIST = HYPGEOM.DIST INTERCEPT = INTERCEPT KURT = KURT LARGE = LARGE LINEST = LINREGRESE LOGEST = LOGLINREGRESE LOGNORM.DIST = LOGNORM.DIST LOGNORM.INV = LOGNORM.INV MAX = MAX MAXA = MAXA MAXIFS = MAXIFS MEDIAN = MEDIAN MIN = MIN MINA = MINA MINIFS = MINIFS MODE.MULT = MODE.MULT MODE.SNGL = MODE.SNGL NEGBINOM.DIST = NEGBINOM.DIST NORM.DIST = NORM.DIST NORM.INV = NORM.INV NORM.S.DIST = NORM.S.DIST NORM.S.INV = NORM.S.INV PEARSON = PEARSON PERCENTILE.EXC = PERCENTIL.EXC PERCENTILE.INC = PERCENTIL.INC PERCENTRANK.EXC = PERCENTRANK.EXC PERCENTRANK.INC = PERCENTRANK.INC PERMUT = PERMUTACE PERMUTATIONA = PERMUTATIONA PHI = PHI POISSON.DIST = POISSON.DIST PROB = PROB QUARTILE.EXC = QUARTIL.EXC QUARTILE.INC = QUARTIL.INC RANK.AVG = RANK.AVG RANK.EQ = RANK.EQ RSQ = RKQ SKEW = SKEW SKEW.P = SKEW.P SLOPE = SLOPE SMALL = SMALL STANDARDIZE = STANDARDIZE STDEV.P = SMODCH.P STDEV.S = SMODCH.VÝBĚR.S STDEVA = STDEVA STDEVPA = STDEVPA STEYX = STEYX T.DIST = T.DIST T.DIST.2T = T.DIST.2T T.DIST.RT = T.DIST.RT T.INV = T.INV T.INV.2T = T.INV.2T T.TEST = T.TEST TREND = LINTREND TRIMMEAN = TRIMMEAN VAR.P = VAR.P VAR.S = VAR.S VARA = VARA VARPA = VARPA WEIBULL.DIST = WEIBULL.DIST Z.TEST = Z.TEST ## ## Textové funkce (Text Functions) ## BAHTTEXT = BAHTTEXT CHAR = ZNAK CLEAN = VYČISTIT CODE = KÓD CONCAT = CONCAT DOLLAR = KČ EXACT = STEJNÉ FIND = NAJÍT FIXED = ZAOKROUHLIT.NA.TEXT LEFT = ZLEVA LEN = DÉLKA LOWER = MALÁ MID = ČÁST NUMBERVALUE = NUMBERVALUE PHONETIC = ZVUKOVÉ PROPER = VELKÁ2 REPLACE = NAHRADIT REPT = OPAKOVAT RIGHT = ZPRAVA SEARCH = HLEDAT SUBSTITUTE = DOSADIT T = T TEXT = HODNOTA.NA.TEXT TEXTJOIN = TEXTJOIN TRIM = PROČISTIT UNICHAR = UNICHAR UNICODE = UNICODE UPPER = VELKÁ VALUE = HODNOTA ## ## Webové funkce (Web Functions) ## ENCODEURL = ENCODEURL FILTERXML = FILTERXML WEBSERVICE = WEBSERVICE ## ## Funkce pro kompatibilitu (Compatibility Functions) ## BETADIST = BETADIST BETAINV = BETAINV BINOMDIST = BINOMDIST CEILING = ZAOKR.NAHORU CHIDIST = CHIDIST CHIINV = CHIINV CHITEST = CHITEST CONCATENATE = CONCATENATE CONFIDENCE = CONFIDENCE COVAR = COVAR CRITBINOM = CRITBINOM EXPONDIST = EXPONDIST FDIST = FDIST FINV = FINV FLOOR = ZAOKR.DOLŮ FORECAST = FORECAST FTEST = FTEST GAMMADIST = GAMMADIST GAMMAINV = GAMMAINV HYPGEOMDIST = HYPGEOMDIST LOGINV = LOGINV LOGNORMDIST = LOGNORMDIST MODE = MODE NEGBINOMDIST = NEGBINOMDIST NORMDIST = NORMDIST NORMINV = NORMINV NORMSDIST = NORMSDIST NORMSINV = NORMSINV PERCENTILE = PERCENTIL PERCENTRANK = PERCENTRANK POISSON = POISSON QUARTILE = QUARTIL RANK = RANK STDEV = SMODCH.VÝBĚR STDEVP = SMODCH TDIST = TDIST TINV = TINV TTEST = TTEST VAR = VAR.VÝBĚR VARP = VAR WEIBULL = WEIBULL ZTEST = ZTEST phpspreadsheet/src/PhpSpreadsheet/Calculation/locale/cs/config 0000644 00000000535 15060132323 0020561 0 ustar 00 ############################################################ ## ## PhpSpreadsheet - locale settings ## ## Ceština (Czech) ## ############################################################ ArgumentSeparator = ; ## ## Error Codes ## NULL DIV0 = #DĚLENÍ_NULOU! VALUE = #HODNOTA! REF = #ODKAZ! NAME = #NÁZEV? NUM = #ČÍSLO! NA = #NENÍ_K_DISPOZICI phpspreadsheet/src/PhpSpreadsheet/Calculation/locale/it/functions 0000644 00000025234 15060132323 0021336 0 ustar 00 ############################################################ ## ## PhpSpreadsheet - function name translations ## ## Italiano (Italian) ## ############################################################ ## ## Funzioni cubo (Cube Functions) ## CUBEKPIMEMBER = MEMBRO.KPI.CUBO CUBEMEMBER = MEMBRO.CUBO CUBEMEMBERPROPERTY = PROPRIETÀ.MEMBRO.CUBO CUBERANKEDMEMBER = MEMBRO.CUBO.CON.RANGO CUBESET = SET.CUBO CUBESETCOUNT = CONTA.SET.CUBO CUBEVALUE = VALORE.CUBO ## ## Funzioni di database (Database Functions) ## DAVERAGE = DB.MEDIA DCOUNT = DB.CONTA.NUMERI DCOUNTA = DB.CONTA.VALORI DGET = DB.VALORI DMAX = DB.MAX DMIN = DB.MIN DPRODUCT = DB.PRODOTTO DSTDEV = DB.DEV.ST DSTDEVP = DB.DEV.ST.POP DSUM = DB.SOMMA DVAR = DB.VAR DVARP = DB.VAR.POP ## ## Funzioni data e ora (Date & Time Functions) ## DATE = DATA DATEDIF = DATA.DIFF DATESTRING = DATA.STRINGA DATEVALUE = DATA.VALORE DAY = GIORNO DAYS = GIORNI DAYS360 = GIORNO360 EDATE = DATA.MESE EOMONTH = FINE.MESE HOUR = ORA ISOWEEKNUM = NUM.SETTIMANA.ISO MINUTE = MINUTO MONTH = MESE NETWORKDAYS = GIORNI.LAVORATIVI.TOT NETWORKDAYS.INTL = GIORNI.LAVORATIVI.TOT.INTL NOW = ADESSO SECOND = SECONDO THAIDAYOFWEEK = THAIGIORNODELLASETTIMANA THAIMONTHOFYEAR = THAIMESEDELLANNO THAIYEAR = THAIANNO TIME = ORARIO TIMEVALUE = ORARIO.VALORE TODAY = OGGI WEEKDAY = GIORNO.SETTIMANA WEEKNUM = NUM.SETTIMANA WORKDAY = GIORNO.LAVORATIVO WORKDAY.INTL = GIORNO.LAVORATIVO.INTL YEAR = ANNO YEARFRAC = FRAZIONE.ANNO ## ## Funzioni ingegneristiche (Engineering Functions) ## BESSELI = BESSEL.I BESSELJ = BESSEL.J BESSELK = BESSEL.K BESSELY = BESSEL.Y BIN2DEC = BINARIO.DECIMALE BIN2HEX = BINARIO.HEX BIN2OCT = BINARIO.OCT BITAND = BITAND BITLSHIFT = BIT.SPOSTA.SX BITOR = BITOR BITRSHIFT = BIT.SPOSTA.DX BITXOR = BITXOR COMPLEX = COMPLESSO CONVERT = CONVERTI DEC2BIN = DECIMALE.BINARIO DEC2HEX = DECIMALE.HEX DEC2OCT = DECIMALE.OCT DELTA = DELTA ERF = FUNZ.ERRORE ERF.PRECISE = FUNZ.ERRORE.PRECISA ERFC = FUNZ.ERRORE.COMP ERFC.PRECISE = FUNZ.ERRORE.COMP.PRECISA GESTEP = SOGLIA HEX2BIN = HEX.BINARIO HEX2DEC = HEX.DECIMALE HEX2OCT = HEX.OCT IMABS = COMP.MODULO IMAGINARY = COMP.IMMAGINARIO IMARGUMENT = COMP.ARGOMENTO IMCONJUGATE = COMP.CONIUGATO IMCOS = COMP.COS IMCOSH = COMP.COSH IMCOT = COMP.COT IMCSC = COMP.CSC IMCSCH = COMP.CSCH IMDIV = COMP.DIV IMEXP = COMP.EXP IMLN = COMP.LN IMLOG10 = COMP.LOG10 IMLOG2 = COMP.LOG2 IMPOWER = COMP.POTENZA IMPRODUCT = COMP.PRODOTTO IMREAL = COMP.PARTE.REALE IMSEC = COMP.SEC IMSECH = COMP.SECH IMSIN = COMP.SEN IMSINH = COMP.SENH IMSQRT = COMP.RADQ IMSUB = COMP.DIFF IMSUM = COMP.SOMMA IMTAN = COMP.TAN OCT2BIN = OCT.BINARIO OCT2DEC = OCT.DECIMALE OCT2HEX = OCT.HEX ## ## Funzioni finanziarie (Financial Functions) ## ACCRINT = INT.MATURATO.PER ACCRINTM = INT.MATURATO.SCAD AMORDEGRC = AMMORT.DEGR AMORLINC = AMMORT.PER COUPDAYBS = GIORNI.CED.INIZ.LIQ COUPDAYS = GIORNI.CED COUPDAYSNC = GIORNI.CED.NUOVA COUPNCD = DATA.CED.SUCC COUPNUM = NUM.CED COUPPCD = DATA.CED.PREC CUMIPMT = INT.CUMUL CUMPRINC = CAP.CUM DB = AMMORT.FISSO DDB = AMMORT DISC = TASSO.SCONTO DOLLARDE = VALUTA.DEC DOLLARFR = VALUTA.FRAZ DURATION = DURATA EFFECT = EFFETTIVO FV = VAL.FUT FVSCHEDULE = VAL.FUT.CAPITALE INTRATE = TASSO.INT IPMT = INTERESSI IRR = TIR.COST ISPMT = INTERESSE.RATA MDURATION = DURATA.M MIRR = TIR.VAR NOMINAL = NOMINALE NPER = NUM.RATE NPV = VAN ODDFPRICE = PREZZO.PRIMO.IRR ODDFYIELD = REND.PRIMO.IRR ODDLPRICE = PREZZO.ULTIMO.IRR ODDLYIELD = REND.ULTIMO.IRR PDURATION = DURATA.P PMT = RATA PPMT = P.RATA PRICE = PREZZO PRICEDISC = PREZZO.SCONT PRICEMAT = PREZZO.SCAD PV = VA RATE = TASSO RECEIVED = RICEV.SCAD RRI = RIT.INVEST.EFFETT SLN = AMMORT.COST SYD = AMMORT.ANNUO TBILLEQ = BOT.EQUIV TBILLPRICE = BOT.PREZZO TBILLYIELD = BOT.REND VDB = AMMORT.VAR XIRR = TIR.X XNPV = VAN.X YIELD = REND YIELDDISC = REND.TITOLI.SCONT YIELDMAT = REND.SCAD ## ## Funzioni relative alle informazioni (Information Functions) ## CELL = CELLA ERROR.TYPE = ERRORE.TIPO INFO = AMBIENTE.INFO ISBLANK = VAL.VUOTO ISERR = VAL.ERR ISERROR = VAL.ERRORE ISEVEN = VAL.PARI ISFORMULA = VAL.FORMULA ISLOGICAL = VAL.LOGICO ISNA = VAL.NON.DISP ISNONTEXT = VAL.NON.TESTO ISNUMBER = VAL.NUMERO ISODD = VAL.DISPARI ISREF = VAL.RIF ISTEXT = VAL.TESTO N = NUM NA = NON.DISP SHEET = FOGLIO SHEETS = FOGLI TYPE = TIPO ## ## Funzioni logiche (Logical Functions) ## AND = E FALSE = FALSO IF = SE IFERROR = SE.ERRORE IFNA = SE.NON.DISP. IFS = PIÙ.SE NOT = NON OR = O SWITCH = SWITCH TRUE = VERO XOR = XOR ## ## Funzioni di ricerca e di riferimento (Lookup & Reference Functions) ## ADDRESS = INDIRIZZO AREAS = AREE CHOOSE = SCEGLI COLUMN = RIF.COLONNA COLUMNS = COLONNE FORMULATEXT = TESTO.FORMULA GETPIVOTDATA = INFO.DATI.TAB.PIVOT HLOOKUP = CERCA.ORIZZ HYPERLINK = COLLEG.IPERTESTUALE INDEX = INDICE INDIRECT = INDIRETTO LOOKUP = CERCA MATCH = CONFRONTA OFFSET = SCARTO ROW = RIF.RIGA ROWS = RIGHE RTD = DATITEMPOREALE TRANSPOSE = MATR.TRASPOSTA VLOOKUP = CERCA.VERT ## ## Funzioni matematiche e trigonometriche (Math & Trig Functions) ## ABS = ASS ACOS = ARCCOS ACOSH = ARCCOSH ACOT = ARCCOT ACOTH = ARCCOTH AGGREGATE = AGGREGA ARABIC = ARABO ASIN = ARCSEN ASINH = ARCSENH ATAN = ARCTAN ATAN2 = ARCTAN.2 ATANH = ARCTANH BASE = BASE CEILING.MATH = ARROTONDA.ECCESSO.MAT CEILING.PRECISE = ARROTONDA.ECCESSO.PRECISA COMBIN = COMBINAZIONE COMBINA = COMBINAZIONE.VALORI COS = COS COSH = COSH COT = COT COTH = COTH CSC = CSC CSCH = CSCH DECIMAL = DECIMALE DEGREES = GRADI ECMA.CEILING = ECMA.ARROTONDA.ECCESSO EVEN = PARI EXP = EXP FACT = FATTORIALE FACTDOUBLE = FATT.DOPPIO FLOOR.MATH = ARROTONDA.DIFETTO.MAT FLOOR.PRECISE = ARROTONDA.DIFETTO.PRECISA GCD = MCD INT = INT ISO.CEILING = ISO.ARROTONDA.ECCESSO LCM = MCM LN = LN LOG = LOG LOG10 = LOG10 MDETERM = MATR.DETERM MINVERSE = MATR.INVERSA MMULT = MATR.PRODOTTO MOD = RESTO MROUND = ARROTONDA.MULTIPLO MULTINOMIAL = MULTINOMIALE MUNIT = MATR.UNIT ODD = DISPARI PI = PI.GRECO POWER = POTENZA PRODUCT = PRODOTTO QUOTIENT = QUOZIENTE RADIANS = RADIANTI RAND = CASUALE RANDBETWEEN = CASUALE.TRA ROMAN = ROMANO ROUND = ARROTONDA ROUNDBAHTDOWN = ARROTBAHTGIU ROUNDBAHTUP = ARROTBAHTSU ROUNDDOWN = ARROTONDA.PER.DIF ROUNDUP = ARROTONDA.PER.ECC SEC = SEC SECH = SECH SERIESSUM = SOMMA.SERIE SIGN = SEGNO SIN = SEN SINH = SENH SQRT = RADQ SQRTPI = RADQ.PI.GRECO SUBTOTAL = SUBTOTALE SUM = SOMMA SUMIF = SOMMA.SE SUMIFS = SOMMA.PIÙ.SE SUMPRODUCT = MATR.SOMMA.PRODOTTO SUMSQ = SOMMA.Q SUMX2MY2 = SOMMA.DIFF.Q SUMX2PY2 = SOMMA.SOMMA.Q SUMXMY2 = SOMMA.Q.DIFF TAN = TAN TANH = TANH TRUNC = TRONCA ## ## Funzioni statistiche (Statistical Functions) ## AVEDEV = MEDIA.DEV AVERAGE = MEDIA AVERAGEA = MEDIA.VALORI AVERAGEIF = MEDIA.SE AVERAGEIFS = MEDIA.PIÙ.SE BETA.DIST = DISTRIB.BETA.N BETA.INV = INV.BETA.N BINOM.DIST = DISTRIB.BINOM.N BINOM.DIST.RANGE = INTERVALLO.DISTRIB.BINOM.N. BINOM.INV = INV.BINOM CHISQ.DIST = DISTRIB.CHI.QUAD CHISQ.DIST.RT = DISTRIB.CHI.QUAD.DS CHISQ.INV = INV.CHI.QUAD CHISQ.INV.RT = INV.CHI.QUAD.DS CHISQ.TEST = TEST.CHI.QUAD CONFIDENCE.NORM = CONFIDENZA.NORM CONFIDENCE.T = CONFIDENZA.T CORREL = CORRELAZIONE COUNT = CONTA.NUMERI COUNTA = CONTA.VALORI COUNTBLANK = CONTA.VUOTE COUNTIF = CONTA.SE COUNTIFS = CONTA.PIÙ.SE COVARIANCE.P = COVARIANZA.P COVARIANCE.S = COVARIANZA.C DEVSQ = DEV.Q EXPON.DIST = DISTRIB.EXP.N F.DIST = DISTRIBF F.DIST.RT = DISTRIB.F.DS F.INV = INVF F.INV.RT = INV.F.DS F.TEST = TESTF FISHER = FISHER FISHERINV = INV.FISHER FORECAST.ETS = PREVISIONE.ETS FORECAST.ETS.CONFINT = PREVISIONE.ETS.INTCONF FORECAST.ETS.SEASONALITY = PREVISIONE.ETS.STAGIONALITÀ FORECAST.ETS.STAT = PREVISIONE.ETS.STAT FORECAST.LINEAR = PREVISIONE.LINEARE FREQUENCY = FREQUENZA GAMMA = GAMMA GAMMA.DIST = DISTRIB.GAMMA.N GAMMA.INV = INV.GAMMA.N GAMMALN = LN.GAMMA GAMMALN.PRECISE = LN.GAMMA.PRECISA GAUSS = GAUSS GEOMEAN = MEDIA.GEOMETRICA GROWTH = CRESCITA HARMEAN = MEDIA.ARMONICA HYPGEOM.DIST = DISTRIB.IPERGEOM.N INTERCEPT = INTERCETTA KURT = CURTOSI LARGE = GRANDE LINEST = REGR.LIN LOGEST = REGR.LOG LOGNORM.DIST = DISTRIB.LOGNORM.N LOGNORM.INV = INV.LOGNORM.N MAX = MAX MAXA = MAX.VALORI MAXIFS = MAX.PIÙ.SE MEDIAN = MEDIANA MIN = MIN MINA = MIN.VALORI MINIFS = MIN.PIÙ.SE MODE.MULT = MODA.MULT MODE.SNGL = MODA.SNGL NEGBINOM.DIST = DISTRIB.BINOM.NEG.N NORM.DIST = DISTRIB.NORM.N NORM.INV = INV.NORM.N NORM.S.DIST = DISTRIB.NORM.ST.N NORM.S.INV = INV.NORM.S PEARSON = PEARSON PERCENTILE.EXC = ESC.PERCENTILE PERCENTILE.INC = INC.PERCENTILE PERCENTRANK.EXC = ESC.PERCENT.RANGO PERCENTRANK.INC = INC.PERCENT.RANGO PERMUT = PERMUTAZIONE PERMUTATIONA = PERMUTAZIONE.VALORI PHI = PHI POISSON.DIST = DISTRIB.POISSON PROB = PROBABILITÀ QUARTILE.EXC = ESC.QUARTILE QUARTILE.INC = INC.QUARTILE RANK.AVG = RANGO.MEDIA RANK.EQ = RANGO.UG RSQ = RQ SKEW = ASIMMETRIA SKEW.P = ASIMMETRIA.P SLOPE = PENDENZA SMALL = PICCOLO STANDARDIZE = NORMALIZZA STDEV.P = DEV.ST.P STDEV.S = DEV.ST.C STDEVA = DEV.ST.VALORI STDEVPA = DEV.ST.POP.VALORI STEYX = ERR.STD.YX T.DIST = DISTRIB.T.N T.DIST.2T = DISTRIB.T.2T T.DIST.RT = DISTRIB.T.DS T.INV = INVT T.INV.2T = INV.T.2T T.TEST = TESTT TREND = TENDENZA TRIMMEAN = MEDIA.TRONCATA VAR.P = VAR.P VAR.S = VAR.C VARA = VAR.VALORI VARPA = VAR.POP.VALORI WEIBULL.DIST = DISTRIB.WEIBULL Z.TEST = TESTZ ## ## Funzioni di testo (Text Functions) ## BAHTTEXT = BAHTTESTO CHAR = CODICE.CARATT CLEAN = LIBERA CODE = CODICE CONCAT = CONCAT DOLLAR = VALUTA EXACT = IDENTICO FIND = TROVA FIXED = FISSO ISTHAIDIGIT = ÈTHAICIFRA LEFT = SINISTRA LEN = LUNGHEZZA LOWER = MINUSC MID = STRINGA.ESTRAI NUMBERSTRING = NUMERO.STRINGA NUMBERVALUE = NUMERO.VALORE PHONETIC = FURIGANA PROPER = MAIUSC.INIZ REPLACE = RIMPIAZZA REPT = RIPETI RIGHT = DESTRA SEARCH = RICERCA SUBSTITUTE = SOSTITUISCI T = T TEXT = TESTO TEXTJOIN = TESTO.UNISCI THAIDIGIT = THAICIFRA THAINUMSOUND = THAINUMSUONO THAINUMSTRING = THAISZÁMKAR THAISTRINGLENGTH = THAILUNGSTRINGA TRIM = ANNULLA.SPAZI UNICHAR = CARATT.UNI UNICODE = UNICODE UPPER = MAIUSC VALUE = VALORE ## ## Funzioni Web (Web Functions) ## ENCODEURL = CODIFICA.URL FILTERXML = FILTRO.XML WEBSERVICE = SERVIZIO.WEB ## ## Funzioni di compatibilità (Compatibility Functions) ## BETADIST = DISTRIB.BETA BETAINV = INV.BETA BINOMDIST = DISTRIB.BINOM CEILING = ARROTONDA.ECCESSO CHIDIST = DISTRIB.CHI CHIINV = INV.CHI CHITEST = TEST.CHI CONCATENATE = CONCATENA CONFIDENCE = CONFIDENZA COVAR = COVARIANZA CRITBINOM = CRIT.BINOM EXPONDIST = DISTRIB.EXP FDIST = DISTRIB.F FINV = INV.F FLOOR = ARROTONDA.DIFETTO FORECAST = PREVISIONE FTEST = TEST.F GAMMADIST = DISTRIB.GAMMA GAMMAINV = INV.GAMMA HYPGEOMDIST = DISTRIB.IPERGEOM LOGINV = INV.LOGNORM LOGNORMDIST = DISTRIB.LOGNORM MODE = MODA NEGBINOMDIST = DISTRIB.BINOM.NEG NORMDIST = DISTRIB.NORM NORMINV = INV.NORM NORMSDIST = DISTRIB.NORM.ST NORMSINV = INV.NORM.ST PERCENTILE = PERCENTILE PERCENTRANK = PERCENT.RANGO POISSON = POISSON QUARTILE = QUARTILE RANK = RANGO STDEV = DEV.ST STDEVP = DEV.ST.POP TDIST = DISTRIB.T TINV = INV.T TTEST = TEST.T VAR = VAR VARP = VAR.POP WEIBULL = WEIBULL ZTEST = TEST.Z phpspreadsheet/src/PhpSpreadsheet/Calculation/locale/it/config 0000644 00000000455 15060132323 0020571 0 ustar 00 ############################################################ ## ## PhpSpreadsheet - locale settings ## ## Italiano (Italian) ## ############################################################ ArgumentSeparator = ; ## ## Error Codes ## NULL DIV0 VALUE = #VALORE! REF = #RIF! NAME = #NOME? NUM NA = #N/D phpspreadsheet/src/PhpSpreadsheet/Calculation/locale/Translations.xlsx 0000644 00000324313 15060132323 0022370 0 ustar 00 PK ! ����� � [Content_Types].xml �(� Ėˎ�@E������gQٞ�L�LF�����i�~�����`,'� �Hـ��{n�����ޖ�"�f�!�����q�����=�"$�rUz3q O��� �p�Ù(��W)Q`f>��/K�"~�+�^�������8J����,զ��۞_7NƉ�W�fB�P���ʭ���~�4r�7��3T� �2�01�'�B^dF(q�UƑ�1,L�O���ܓǿD��� *�u���O^�hrH^U�����})w>�ޯ��"C�^��*�ډ�����o#���x�O>��z�T�2�#J�����"*B�F|LW�8��𡽭����Z�<Uт��h���}lYLa����؞�v�ػ}������?�P6���j"�� ,�ml(I�:(��1�ik��L�0�{��s]`�Br�}�> ��ëH�K��4�D2pꦗ�Ɖ�w��z��� e� ��w��pY�i� �� PK ! ��, t _rels/.rels �(� ���N�0�;�徦Bh�.i7��x��Um�(�`{{��`�FAbǶ�:?��d���x�r�,�\ t�L��R�,GwRDg�#���b������;��S\5>�T��R����RQ��B�ȣK_* 8=�Zy�-Ԩ�y~��q 9��sS�07WR,�>�����"��)�ȇ$ܤ^�B�\JC�)���D��R�� �F�Tq��*��F��,�~�� ��at��3�փ;vl�^"�������>d���Xħ���юF�]�C��sZ�:2�_6�����I�oϠF����ݕ�; �� PK ! vn�h t xl/workbook.xml�Vmo�:�>���Ӽ�����R����~A��c�&qf;�j��qBh)W�ر������?o��x�B2^E�9��A+�3V=F��Ej��!�2\�F�J�y�ϧ� O+Ο �d�r��в$�i���i�5%V����ř�)Uea��X%f�Bq _�� 'MI+ՁZ`�˜ղG+�)p%OMm^� �bS/-(2J^>V\�Uno�� ��sl�&]U2"��ku�Vg�m9�A��18 ɳ}f:�{�D�A��=V� ���� �Z�����{�\49_���u�5p]ť�T��K5˘�Y����z�!�:nXR��cdM�t�#�k�jD��2�`�Z�qQ(**��W x���o9�bOs7n� ��_a�$�+9�*7QDh.�G�������4��}-������JfYp��|�e|\8�fLt�,�Q�G��>^�{�Ε0�2�����g�!0%ە�%$�<TD��Ïx4� ��t{��N3����y~<K�a��?����F�;zh�y��#�5��������}L=�z�O�n�w�n�+����*�C�/�j87��e*�� :m������u�� �nt���x4F&�=�^�����FG�ؤ36����c�7ֶ��ng�j+h�%�0�43�l;+�t�ֹ�!B}�����ɴ��D��o� �s[��7�-�NOm�ǎ�U$ݪ+�&�0�x����]H����3��8<�Oҁ?t���Ou��)�j����jOS��A]~�:�c���o���]��%�I���ӿS��nAOTN�NT�~�^\��{5[<ܧ�*_\���N���X�8(�>�V��a� �� PK ! �� � xl/_rels/workbook.xml.rels �(� ���N�0E�H���=q� T���-����C��G��Q �J��Xε|����z�i:�[g%ϒ�3�ڕ��%�=]�s�Q�Ru�= ���g�T�Oش�X����?���0q,�T.���J�U "Oӕ�=x1�d�R�-�9��:��vU�jxt�̀�GZ�H\@�*�%�Q���8C~N��� ĉ� �^�%��a�Y�cZ�*&�1��݉,��]xZ>g�0����$nϙ6*@�m>N43y ��0������C��^�n�� �� PK ! {-ؼ' �/ xl/worksheets/sheet1.xml��]o�0��'�?D�'���DZ1Z�I����k�85�3��i�}ljMؘ&\�@��|�ǰ�=֕��DW�&E��Ú��e�Mї���9��MN+ް���}�8p�����.E;)۹�uَմsy��RpQS ���Z�h�o�+��~�մl�@��k�(ʌ��l_�F�**!�nW����x�����s��p����E|u� ��B���!��,/�#�:�&њ��};p�mʪ�/}�ȩ���m��TБ#i�< ����饧�C�ىtYɫ08�{.��Fy]���"#,x%,:�T��|_�)�y��A�It/'�2�M�Ux?yG����:��_�f���=��#X��%�/�8D�͢�ג�3�Q���I]� �|`��a��SmMd�M�G�#+�UU�V!rh&�g� ;R��R���d?��+����?���)~� �o��a�>���� �86.!�L��_�Σ��ީ綩ͺ?�����+���JΡ�W�����2v(�(����N]�C&���P�r��!��L��a�\�*�}پ��}�wi�@��X5e�N�a4��g@�=Vø�?x��j� n�%i����k����,��(��g���@��uD�q��EK0�֠04'�%��Ed��G$��S@{%��e���2L�S{Ec�e���]��(`�e������2��l1��(A���5I�M/e�V�Ĝ6��B\�'6�$F��[c}h�Ze�R�=����2��؇c���;�vsO�l�1B��|��u� �� �����n�8�_���%K��� [>��Y>�� �iS�����/�,b���b�������QZ篏�/����z~����;�����Y��s3���t������r��?<�>��o�x>=~yw�Si�]ڸ���g��χ�����j���tlN&�I�DRd��" ��٤f�R_ y^�|�&������39#)J��{SMl��ii*Z��r! ʃ(3�0,%DY��!XJ�Ʊ���MR1�]��qڈ�S�� �M�`+Z��;�����!|:�����籺���]�4?� :� ��2��H��]��H�l�.sX�$��&�2��C��e$�`i,�Ny�i"ZB O�8E��\��<�Ù�v7,%>:�B��/��'!�&�B���IקY�qwAa��!h�-���Db�����+aw�B!���y\a���3��az���ѱIQ�F��$����&K_t1�$� P C��$d�Xڝb7�I��g7����O��n&YJ�`)�!�Q�n ���\�$� ���@ ��.l��Ȃ�h !؉�k��T�/�ί�y� �Ǖˁ� w����c?��x�� ݧ���ňgO"%H��i�B��F.��)w!�]H�҅�r!�]H�i�B:��Ҵ�e$p�n�ݶ�w���7����� [��T6ܻ���N_�����I�8�:�T����3�,��� 0Ob�虣��Ƿ�)`�I9`�FK�8bV�qn�oÛ۞&�?nC�`��[+`(��������'�K2r9����@R>��hR%�9X� C�`H>