Livraison d ela gestion des opérations v0.4.0
This commit is contained in:
161
api/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/AutoFilter.php
vendored
Normal file
161
api/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/AutoFilter.php
vendored
Normal file
@@ -0,0 +1,161 @@
|
||||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Reader\Xlsx;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Reader\Xlsx;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column\Rule;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\Table;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
||||
use SimpleXMLElement;
|
||||
|
||||
class AutoFilter
|
||||
{
|
||||
private Table|Worksheet $parent;
|
||||
|
||||
private SimpleXMLElement $worksheetXml;
|
||||
|
||||
public function __construct(Table|Worksheet $parent, SimpleXMLElement $worksheetXml)
|
||||
{
|
||||
$this->parent = $parent;
|
||||
$this->worksheetXml = $worksheetXml;
|
||||
}
|
||||
|
||||
public function load(): void
|
||||
{
|
||||
// Remove all "$" in the auto filter range
|
||||
$attrs = $this->worksheetXml->autoFilter->attributes() ?? [];
|
||||
$autoFilterRange = (string) preg_replace('/\$/', '', $attrs['ref'] ?? '');
|
||||
if (str_contains($autoFilterRange, ':')) {
|
||||
$this->readAutoFilter($autoFilterRange);
|
||||
}
|
||||
}
|
||||
|
||||
private function readAutoFilter(string $autoFilterRange): void
|
||||
{
|
||||
$autoFilter = $this->parent->getAutoFilter();
|
||||
$autoFilter->setRange($autoFilterRange);
|
||||
|
||||
foreach ($this->worksheetXml->autoFilter->filterColumn as $filterColumn) {
|
||||
$attributes = $filterColumn->attributes() ?? [];
|
||||
$column = $autoFilter->getColumnByOffset((int) ($attributes['colId'] ?? 0));
|
||||
// Check for standard filters
|
||||
if ($filterColumn->filters) {
|
||||
$column->setFilterType(Column::AUTOFILTER_FILTERTYPE_FILTER);
|
||||
$filters = Xlsx::testSimpleXml($filterColumn->filters->attributes());
|
||||
if ((isset($filters['blank'])) && ((int) $filters['blank'] == 1)) {
|
||||
// Operator is undefined, but always treated as EQUAL
|
||||
$column->createRule()->setRule('', '')->setRuleType(Rule::AUTOFILTER_RULETYPE_FILTER);
|
||||
}
|
||||
// Standard filters are always an OR join, so no join rule needs to be set
|
||||
// Entries can be either filter elements
|
||||
foreach ($filterColumn->filters->filter as $filterRule) {
|
||||
// Operator is undefined, but always treated as EQUAL
|
||||
$attr2 = $filterRule->attributes() ?? ['val' => ''];
|
||||
$column->createRule()->setRule('', (string) $attr2['val'])->setRuleType(Rule::AUTOFILTER_RULETYPE_FILTER);
|
||||
}
|
||||
|
||||
// Or Date Group elements
|
||||
$this->readDateRangeAutoFilter($filterColumn->filters, $column);
|
||||
}
|
||||
|
||||
// Check for custom filters
|
||||
$this->readCustomAutoFilter($filterColumn, $column);
|
||||
// Check for dynamic filters
|
||||
$this->readDynamicAutoFilter($filterColumn, $column);
|
||||
// Check for dynamic filters
|
||||
$this->readTopTenAutoFilter($filterColumn, $column);
|
||||
}
|
||||
$autoFilter->setEvaluated(true);
|
||||
}
|
||||
|
||||
private function readDateRangeAutoFilter(SimpleXMLElement $filters, Column $column): void
|
||||
{
|
||||
foreach ($filters->dateGroupItem as $dateGroupItemx) {
|
||||
// Operator is undefined, but always treated as EQUAL
|
||||
$dateGroupItem = $dateGroupItemx->attributes();
|
||||
if ($dateGroupItem !== null) {
|
||||
$column->createRule()->setRule(
|
||||
'',
|
||||
[
|
||||
'year' => (string) $dateGroupItem['year'],
|
||||
'month' => (string) $dateGroupItem['month'],
|
||||
'day' => (string) $dateGroupItem['day'],
|
||||
'hour' => (string) $dateGroupItem['hour'],
|
||||
'minute' => (string) $dateGroupItem['minute'],
|
||||
'second' => (string) $dateGroupItem['second'],
|
||||
],
|
||||
(string) $dateGroupItem['dateTimeGrouping']
|
||||
)->setRuleType(Rule::AUTOFILTER_RULETYPE_DATEGROUP);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function readCustomAutoFilter(?SimpleXMLElement $filterColumn, Column $column): void
|
||||
{
|
||||
if (isset($filterColumn, $filterColumn->customFilters)) {
|
||||
$column->setFilterType(Column::AUTOFILTER_FILTERTYPE_CUSTOMFILTER);
|
||||
$customFilters = $filterColumn->customFilters;
|
||||
$attributes = $customFilters->attributes();
|
||||
// Custom filters can an AND or an OR join;
|
||||
// and there should only ever be one or two entries
|
||||
if ((isset($attributes['and'])) && ((string) $attributes['and'] === '1')) {
|
||||
$column->setJoin(Column::AUTOFILTER_COLUMN_JOIN_AND);
|
||||
}
|
||||
foreach ($customFilters->customFilter as $filterRule) {
|
||||
$attr2 = $filterRule->attributes() ?? ['operator' => '', 'val' => ''];
|
||||
$column->createRule()->setRule(
|
||||
(string) $attr2['operator'],
|
||||
(string) $attr2['val']
|
||||
)->setRuleType(Rule::AUTOFILTER_RULETYPE_CUSTOMFILTER);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function readDynamicAutoFilter(?SimpleXMLElement $filterColumn, Column $column): void
|
||||
{
|
||||
if (isset($filterColumn, $filterColumn->dynamicFilter)) {
|
||||
$column->setFilterType(Column::AUTOFILTER_FILTERTYPE_DYNAMICFILTER);
|
||||
// We should only ever have one dynamic filter
|
||||
foreach ($filterColumn->dynamicFilter as $filterRule) {
|
||||
// Operator is undefined, but always treated as EQUAL
|
||||
$attr2 = $filterRule->attributes() ?? [];
|
||||
$column->createRule()->setRule(
|
||||
'',
|
||||
(string) ($attr2['val'] ?? ''),
|
||||
(string) ($attr2['type'] ?? '')
|
||||
)->setRuleType(Rule::AUTOFILTER_RULETYPE_DYNAMICFILTER);
|
||||
if (isset($attr2['val'])) {
|
||||
$column->setAttribute('val', (string) $attr2['val']);
|
||||
}
|
||||
if (isset($attr2['maxVal'])) {
|
||||
$column->setAttribute('maxVal', (string) $attr2['maxVal']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function readTopTenAutoFilter(?SimpleXMLElement $filterColumn, Column $column): void
|
||||
{
|
||||
if (isset($filterColumn, $filterColumn->top10)) {
|
||||
$column->setFilterType(Column::AUTOFILTER_FILTERTYPE_TOPTENFILTER);
|
||||
// We should only ever have one top10 filter
|
||||
foreach ($filterColumn->top10 as $filterRule) {
|
||||
$attr2 = $filterRule->attributes() ?? [];
|
||||
$column->createRule()->setRule(
|
||||
(
|
||||
((isset($attr2['percent'])) && ((string) $attr2['percent'] === '1'))
|
||||
? Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT
|
||||
: Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_BY_VALUE
|
||||
),
|
||||
(string) ($attr2['val'] ?? ''),
|
||||
(
|
||||
((isset($attr2['top'])) && ((string) $attr2['top'] === '1'))
|
||||
? Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP
|
||||
: Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_BOTTOM
|
||||
)
|
||||
)->setRuleType(Rule::AUTOFILTER_RULETYPE_TOPTENFILTER);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
21
api/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/BaseParserClass.php
vendored
Normal file
21
api/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/BaseParserClass.php
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Reader\Xlsx;
|
||||
|
||||
use Stringable;
|
||||
|
||||
class BaseParserClass
|
||||
{
|
||||
protected static function boolean(mixed $value): bool
|
||||
{
|
||||
if (is_object($value)) {
|
||||
$value = ($value instanceof Stringable) ? ((string) $value) : 'true';
|
||||
}
|
||||
|
||||
if (is_numeric($value)) {
|
||||
return (bool) $value;
|
||||
}
|
||||
|
||||
return $value === 'true' || $value === 'TRUE';
|
||||
}
|
||||
}
|
||||
1572
api/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/Chart.php
vendored
Normal file
1572
api/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/Chart.php
vendored
Normal file
File diff suppressed because it is too large
Load Diff
219
api/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/ColumnAndRowAttributes.php
vendored
Normal file
219
api/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/ColumnAndRowAttributes.php
vendored
Normal file
@@ -0,0 +1,219 @@
|
||||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Reader\Xlsx;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
|
||||
use PhpOffice\PhpSpreadsheet\Reader\DefaultReadFilter;
|
||||
use PhpOffice\PhpSpreadsheet\Reader\IReadFilter;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
||||
use SimpleXMLElement;
|
||||
|
||||
class ColumnAndRowAttributes extends BaseParserClass
|
||||
{
|
||||
private Worksheet $worksheet;
|
||||
|
||||
private ?SimpleXMLElement $worksheetXml;
|
||||
|
||||
public function __construct(Worksheet $workSheet, ?SimpleXMLElement $worksheetXml = null)
|
||||
{
|
||||
$this->worksheet = $workSheet;
|
||||
$this->worksheetXml = $worksheetXml;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Worksheet column attributes by attributes array passed.
|
||||
*
|
||||
* @param string $columnAddress A, B, ... DX, ...
|
||||
* @param array $columnAttributes array of attributes (indexes are attribute name, values are value)
|
||||
* 'xfIndex', 'visible', 'collapsed', 'outlineLevel', 'width', ... ?
|
||||
*/
|
||||
private function setColumnAttributes(string $columnAddress, array $columnAttributes): void
|
||||
{
|
||||
if (isset($columnAttributes['xfIndex'])) {
|
||||
$this->worksheet->getColumnDimension($columnAddress)->setXfIndex($columnAttributes['xfIndex']);
|
||||
}
|
||||
if (isset($columnAttributes['visible'])) {
|
||||
$this->worksheet->getColumnDimension($columnAddress)->setVisible($columnAttributes['visible']);
|
||||
}
|
||||
if (isset($columnAttributes['collapsed'])) {
|
||||
$this->worksheet->getColumnDimension($columnAddress)->setCollapsed($columnAttributes['collapsed']);
|
||||
}
|
||||
if (isset($columnAttributes['outlineLevel'])) {
|
||||
$this->worksheet->getColumnDimension($columnAddress)->setOutlineLevel($columnAttributes['outlineLevel']);
|
||||
}
|
||||
if (isset($columnAttributes['width'])) {
|
||||
$this->worksheet->getColumnDimension($columnAddress)->setWidth($columnAttributes['width']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Worksheet row attributes by attributes array passed.
|
||||
*
|
||||
* @param int $rowNumber 1, 2, 3, ... 99, ...
|
||||
* @param array $rowAttributes array of attributes (indexes are attribute name, values are value)
|
||||
* 'xfIndex', 'visible', 'collapsed', 'outlineLevel', 'rowHeight', ... ?
|
||||
*/
|
||||
private function setRowAttributes(int $rowNumber, array $rowAttributes): void
|
||||
{
|
||||
if (isset($rowAttributes['xfIndex'])) {
|
||||
$this->worksheet->getRowDimension($rowNumber)->setXfIndex($rowAttributes['xfIndex']);
|
||||
}
|
||||
if (isset($rowAttributes['visible'])) {
|
||||
$this->worksheet->getRowDimension($rowNumber)->setVisible($rowAttributes['visible']);
|
||||
}
|
||||
if (isset($rowAttributes['collapsed'])) {
|
||||
$this->worksheet->getRowDimension($rowNumber)->setCollapsed($rowAttributes['collapsed']);
|
||||
}
|
||||
if (isset($rowAttributes['outlineLevel'])) {
|
||||
$this->worksheet->getRowDimension($rowNumber)->setOutlineLevel($rowAttributes['outlineLevel']);
|
||||
}
|
||||
if (isset($rowAttributes['rowHeight'])) {
|
||||
$this->worksheet->getRowDimension($rowNumber)->setRowHeight($rowAttributes['rowHeight']);
|
||||
}
|
||||
}
|
||||
|
||||
public function load(?IReadFilter $readFilter = null, bool $readDataOnly = false, bool $ignoreRowsWithNoCells = false): void
|
||||
{
|
||||
if ($this->worksheetXml === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$columnsAttributes = [];
|
||||
$rowsAttributes = [];
|
||||
if (isset($this->worksheetXml->cols)) {
|
||||
$columnsAttributes = $this->readColumnAttributes($this->worksheetXml->cols, $readDataOnly);
|
||||
}
|
||||
|
||||
if ($this->worksheetXml->sheetData && $this->worksheetXml->sheetData->row) {
|
||||
$rowsAttributes = $this->readRowAttributes($this->worksheetXml->sheetData->row, $readDataOnly, $ignoreRowsWithNoCells);
|
||||
}
|
||||
|
||||
if ($readFilter !== null && $readFilter::class === DefaultReadFilter::class) {
|
||||
$readFilter = null;
|
||||
}
|
||||
|
||||
// set columns/rows attributes
|
||||
$columnsAttributesAreSet = [];
|
||||
foreach ($columnsAttributes as $columnCoordinate => $columnAttributes) {
|
||||
if (
|
||||
$readFilter === null
|
||||
|| !$this->isFilteredColumn($readFilter, $columnCoordinate, $rowsAttributes)
|
||||
) {
|
||||
if (!isset($columnsAttributesAreSet[$columnCoordinate])) {
|
||||
$this->setColumnAttributes($columnCoordinate, $columnAttributes);
|
||||
$columnsAttributesAreSet[$columnCoordinate] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$rowsAttributesAreSet = [];
|
||||
foreach ($rowsAttributes as $rowCoordinate => $rowAttributes) {
|
||||
if (
|
||||
$readFilter === null
|
||||
|| !$this->isFilteredRow($readFilter, $rowCoordinate, $columnsAttributes)
|
||||
) {
|
||||
if (!isset($rowsAttributesAreSet[$rowCoordinate])) {
|
||||
$this->setRowAttributes($rowCoordinate, $rowAttributes);
|
||||
$rowsAttributesAreSet[$rowCoordinate] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function isFilteredColumn(IReadFilter $readFilter, string $columnCoordinate, array $rowsAttributes): bool
|
||||
{
|
||||
foreach ($rowsAttributes as $rowCoordinate => $rowAttributes) {
|
||||
if (!$readFilter->readCell($columnCoordinate, $rowCoordinate, $this->worksheet->getTitle())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function readColumnAttributes(SimpleXMLElement $worksheetCols, bool $readDataOnly): array
|
||||
{
|
||||
$columnAttributes = [];
|
||||
|
||||
foreach ($worksheetCols->col as $columnx) {
|
||||
$column = $columnx->attributes();
|
||||
if ($column !== null) {
|
||||
$startColumn = Coordinate::stringFromColumnIndex((int) $column['min']);
|
||||
$endColumn = Coordinate::stringFromColumnIndex((int) $column['max']);
|
||||
++$endColumn;
|
||||
for ($columnAddress = $startColumn; $columnAddress !== $endColumn; ++$columnAddress) {
|
||||
$columnAttributes[$columnAddress] = $this->readColumnRangeAttributes($column, $readDataOnly);
|
||||
|
||||
if ((int) ($column['max']) == 16384) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $columnAttributes;
|
||||
}
|
||||
|
||||
private function readColumnRangeAttributes(?SimpleXMLElement $column, bool $readDataOnly): array
|
||||
{
|
||||
$columnAttributes = [];
|
||||
if ($column !== null) {
|
||||
if (isset($column['style']) && !$readDataOnly) {
|
||||
$columnAttributes['xfIndex'] = (int) $column['style'];
|
||||
}
|
||||
if (isset($column['hidden']) && self::boolean($column['hidden'])) {
|
||||
$columnAttributes['visible'] = false;
|
||||
}
|
||||
if (isset($column['collapsed']) && self::boolean($column['collapsed'])) {
|
||||
$columnAttributes['collapsed'] = true;
|
||||
}
|
||||
if (isset($column['outlineLevel']) && ((int) $column['outlineLevel']) > 0) {
|
||||
$columnAttributes['outlineLevel'] = (int) $column['outlineLevel'];
|
||||
}
|
||||
if (isset($column['width'])) {
|
||||
$columnAttributes['width'] = (float) $column['width'];
|
||||
}
|
||||
}
|
||||
|
||||
return $columnAttributes;
|
||||
}
|
||||
|
||||
private function isFilteredRow(IReadFilter $readFilter, int $rowCoordinate, array $columnsAttributes): bool
|
||||
{
|
||||
foreach ($columnsAttributes as $columnCoordinate => $columnAttributes) {
|
||||
if (!$readFilter->readCell($columnCoordinate, $rowCoordinate, $this->worksheet->getTitle())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function readRowAttributes(SimpleXMLElement $worksheetRow, bool $readDataOnly, bool $ignoreRowsWithNoCells): array
|
||||
{
|
||||
$rowAttributes = [];
|
||||
|
||||
foreach ($worksheetRow as $rowx) {
|
||||
$row = $rowx->attributes();
|
||||
if ($row !== null && (!$ignoreRowsWithNoCells || isset($rowx->c))) {
|
||||
if (isset($row['ht']) && !$readDataOnly) {
|
||||
$rowAttributes[(int) $row['r']]['rowHeight'] = (float) $row['ht'];
|
||||
}
|
||||
if (isset($row['hidden']) && self::boolean($row['hidden'])) {
|
||||
$rowAttributes[(int) $row['r']]['visible'] = false;
|
||||
}
|
||||
if (isset($row['collapsed']) && self::boolean($row['collapsed'])) {
|
||||
$rowAttributes[(int) $row['r']]['collapsed'] = true;
|
||||
}
|
||||
if (isset($row['outlineLevel']) && (int) $row['outlineLevel'] > 0) {
|
||||
$rowAttributes[(int) $row['r']]['outlineLevel'] = (int) $row['outlineLevel'];
|
||||
}
|
||||
if (isset($row['s']) && !$readDataOnly) {
|
||||
$rowAttributes[(int) $row['r']]['xfIndex'] = (int) $row['s'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $rowAttributes;
|
||||
}
|
||||
}
|
||||
336
api/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/ConditionalStyles.php
vendored
Normal file
336
api/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/ConditionalStyles.php
vendored
Normal file
@@ -0,0 +1,336 @@
|
||||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Reader\Xlsx;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Reader\Xlsx\Styles as StyleReader;
|
||||
use PhpOffice\PhpSpreadsheet\Style\Color;
|
||||
use PhpOffice\PhpSpreadsheet\Style\Conditional;
|
||||
use PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\ConditionalColorScale;
|
||||
use PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\ConditionalDataBar;
|
||||
use PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\ConditionalFormattingRuleExtension;
|
||||
use PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\ConditionalFormatValueObject;
|
||||
use PhpOffice\PhpSpreadsheet\Style\Style as Style;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
||||
use SimpleXMLElement;
|
||||
use stdClass;
|
||||
|
||||
class ConditionalStyles
|
||||
{
|
||||
private Worksheet $worksheet;
|
||||
|
||||
private SimpleXMLElement $worksheetXml;
|
||||
|
||||
private array $ns;
|
||||
|
||||
private array $dxfs;
|
||||
|
||||
private StyleReader $styleReader;
|
||||
|
||||
public function __construct(Worksheet $workSheet, SimpleXMLElement $worksheetXml, array $dxfs, StyleReader $styleReader)
|
||||
{
|
||||
$this->worksheet = $workSheet;
|
||||
$this->worksheetXml = $worksheetXml;
|
||||
$this->dxfs = $dxfs;
|
||||
$this->styleReader = $styleReader;
|
||||
}
|
||||
|
||||
public function load(): void
|
||||
{
|
||||
$selectedCells = $this->worksheet->getSelectedCells();
|
||||
|
||||
$this->setConditionalStyles(
|
||||
$this->worksheet,
|
||||
$this->readConditionalStyles($this->worksheetXml),
|
||||
$this->worksheetXml->extLst
|
||||
);
|
||||
|
||||
$this->worksheet->setSelectedCells($selectedCells);
|
||||
}
|
||||
|
||||
public function loadFromExt(): void
|
||||
{
|
||||
$selectedCells = $this->worksheet->getSelectedCells();
|
||||
|
||||
$this->ns = $this->worksheetXml->getNamespaces(true);
|
||||
$this->setConditionalsFromExt(
|
||||
$this->readConditionalsFromExt($this->worksheetXml->extLst)
|
||||
);
|
||||
|
||||
$this->worksheet->setSelectedCells($selectedCells);
|
||||
}
|
||||
|
||||
private function setConditionalsFromExt(array $conditionals): void
|
||||
{
|
||||
foreach ($conditionals as $conditionalRange => $cfRules) {
|
||||
ksort($cfRules);
|
||||
// Priority is used as the key for sorting; but may not start at 0,
|
||||
// so we use array_values to reset the index after sorting.
|
||||
$this->worksheet->getStyle($conditionalRange)
|
||||
->setConditionalStyles(array_values($cfRules));
|
||||
}
|
||||
}
|
||||
|
||||
private function readConditionalsFromExt(SimpleXMLElement $extLst): array
|
||||
{
|
||||
$conditionals = [];
|
||||
if (!isset($extLst->ext)) {
|
||||
return $conditionals;
|
||||
}
|
||||
|
||||
foreach ($extLst->ext as $extlstcond) {
|
||||
$extAttrs = $extlstcond->attributes() ?? [];
|
||||
$extUri = (string) ($extAttrs['uri'] ?? '');
|
||||
if ($extUri !== '{78C0D931-6437-407d-A8EE-F0AAD7539E65}') {
|
||||
continue;
|
||||
}
|
||||
$conditionalFormattingRuleXml = $extlstcond->children($this->ns['x14']);
|
||||
if (!$conditionalFormattingRuleXml->conditionalFormattings) {
|
||||
return [];
|
||||
}
|
||||
|
||||
foreach ($conditionalFormattingRuleXml->children($this->ns['x14']) as $extFormattingXml) {
|
||||
$extFormattingRangeXml = $extFormattingXml->children($this->ns['xm']);
|
||||
if (!$extFormattingRangeXml->sqref) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$sqref = (string) $extFormattingRangeXml->sqref;
|
||||
$extCfRuleXml = $extFormattingXml->cfRule;
|
||||
|
||||
$attributes = $extCfRuleXml->attributes();
|
||||
if (!$attributes) {
|
||||
continue;
|
||||
}
|
||||
$conditionType = (string) $attributes->type;
|
||||
if (
|
||||
!Conditional::isValidConditionType($conditionType)
|
||||
|| $conditionType === Conditional::CONDITION_DATABAR
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$priority = (int) $attributes->priority;
|
||||
|
||||
$conditional = $this->readConditionalRuleFromExt($extCfRuleXml, $attributes);
|
||||
$cfStyle = $this->readStyleFromExt($extCfRuleXml);
|
||||
$conditional->setStyle($cfStyle);
|
||||
$conditionals[$sqref][$priority] = $conditional;
|
||||
}
|
||||
}
|
||||
|
||||
return $conditionals;
|
||||
}
|
||||
|
||||
private function readConditionalRuleFromExt(SimpleXMLElement $cfRuleXml, SimpleXMLElement $attributes): Conditional
|
||||
{
|
||||
$conditionType = (string) $attributes->type;
|
||||
$operatorType = (string) $attributes->operator;
|
||||
|
||||
$operands = [];
|
||||
foreach ($cfRuleXml->children($this->ns['xm']) as $cfRuleOperandsXml) {
|
||||
$operands[] = (string) $cfRuleOperandsXml;
|
||||
}
|
||||
|
||||
$conditional = new Conditional();
|
||||
$conditional->setConditionType($conditionType);
|
||||
$conditional->setOperatorType($operatorType);
|
||||
if (
|
||||
$conditionType === Conditional::CONDITION_CONTAINSTEXT
|
||||
|| $conditionType === Conditional::CONDITION_NOTCONTAINSTEXT
|
||||
|| $conditionType === Conditional::CONDITION_BEGINSWITH
|
||||
|| $conditionType === Conditional::CONDITION_ENDSWITH
|
||||
|| $conditionType === Conditional::CONDITION_TIMEPERIOD
|
||||
) {
|
||||
$conditional->setText(array_pop($operands) ?? '');
|
||||
}
|
||||
$conditional->setConditions($operands);
|
||||
|
||||
return $conditional;
|
||||
}
|
||||
|
||||
private function readStyleFromExt(SimpleXMLElement $extCfRuleXml): Style
|
||||
{
|
||||
$cfStyle = new Style(false, true);
|
||||
if ($extCfRuleXml->dxf) {
|
||||
$styleXML = $extCfRuleXml->dxf->children();
|
||||
|
||||
if ($styleXML->borders) {
|
||||
$this->styleReader->readBorderStyle($cfStyle->getBorders(), $styleXML->borders);
|
||||
}
|
||||
if ($styleXML->fill) {
|
||||
$this->styleReader->readFillStyle($cfStyle->getFill(), $styleXML->fill);
|
||||
}
|
||||
}
|
||||
|
||||
return $cfStyle;
|
||||
}
|
||||
|
||||
private function readConditionalStyles(SimpleXMLElement $xmlSheet): array
|
||||
{
|
||||
$conditionals = [];
|
||||
foreach ($xmlSheet->conditionalFormatting as $conditional) {
|
||||
foreach ($conditional->cfRule as $cfRule) {
|
||||
if (Conditional::isValidConditionType((string) $cfRule['type']) && (!isset($cfRule['dxfId']) || isset($this->dxfs[(int) ($cfRule['dxfId'])]))) {
|
||||
$conditionals[(string) $conditional['sqref']][(int) ($cfRule['priority'])] = $cfRule;
|
||||
} elseif ((string) $cfRule['type'] == Conditional::CONDITION_DATABAR) {
|
||||
$conditionals[(string) $conditional['sqref']][(int) ($cfRule['priority'])] = $cfRule;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $conditionals;
|
||||
}
|
||||
|
||||
private function setConditionalStyles(Worksheet $worksheet, array $conditionals, SimpleXMLElement $xmlExtLst): void
|
||||
{
|
||||
foreach ($conditionals as $cellRangeReference => $cfRules) {
|
||||
ksort($cfRules);
|
||||
$conditionalStyles = $this->readStyleRules($cfRules, $xmlExtLst);
|
||||
|
||||
// Extract all cell references in $cellRangeReference
|
||||
// N.B. In Excel UI, intersection is space and union is comma.
|
||||
// But in Xml, intersection is comma and union is space.
|
||||
$cellRangeReference = str_replace(['$', ' ', ',', '^'], ['', '^', ' ', ','], strtoupper($cellRangeReference));
|
||||
$worksheet->getStyle($cellRangeReference)->setConditionalStyles($conditionalStyles);
|
||||
}
|
||||
}
|
||||
|
||||
private function readStyleRules(array $cfRules, SimpleXMLElement $extLst): array
|
||||
{
|
||||
$conditionalFormattingRuleExtensions = ConditionalFormattingRuleExtension::parseExtLstXml($extLst);
|
||||
$conditionalStyles = [];
|
||||
|
||||
/** @var SimpleXMLElement $cfRule */
|
||||
foreach ($cfRules as $cfRule) {
|
||||
$objConditional = new Conditional();
|
||||
$objConditional->setConditionType((string) $cfRule['type']);
|
||||
$objConditional->setOperatorType((string) $cfRule['operator']);
|
||||
$objConditional->setNoFormatSet(!isset($cfRule['dxfId']));
|
||||
|
||||
if ((string) $cfRule['text'] != '') {
|
||||
$objConditional->setText((string) $cfRule['text']);
|
||||
} elseif ((string) $cfRule['timePeriod'] != '') {
|
||||
$objConditional->setText((string) $cfRule['timePeriod']);
|
||||
}
|
||||
|
||||
if (isset($cfRule['stopIfTrue']) && (int) $cfRule['stopIfTrue'] === 1) {
|
||||
$objConditional->setStopIfTrue(true);
|
||||
}
|
||||
|
||||
if (count($cfRule->formula) >= 1) {
|
||||
foreach ($cfRule->formula as $formulax) {
|
||||
$formula = (string) $formulax;
|
||||
if ($formula === 'TRUE') {
|
||||
$objConditional->addCondition(true);
|
||||
} elseif ($formula === 'FALSE') {
|
||||
$objConditional->addCondition(false);
|
||||
} else {
|
||||
$objConditional->addCondition($formula);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$objConditional->addCondition('');
|
||||
}
|
||||
|
||||
if (isset($cfRule->dataBar)) {
|
||||
$objConditional->setDataBar(
|
||||
$this->readDataBarOfConditionalRule($cfRule, $conditionalFormattingRuleExtensions)
|
||||
);
|
||||
} elseif (isset($cfRule->colorScale)) {
|
||||
$objConditional->setColorScale(
|
||||
$this->readColorScale($cfRule)
|
||||
);
|
||||
} elseif (isset($cfRule['dxfId'])) {
|
||||
$objConditional->setStyle(clone $this->dxfs[(int) ($cfRule['dxfId'])]);
|
||||
}
|
||||
|
||||
$conditionalStyles[] = $objConditional;
|
||||
}
|
||||
|
||||
return $conditionalStyles;
|
||||
}
|
||||
|
||||
private function readDataBarOfConditionalRule(SimpleXMLElement $cfRule, array $conditionalFormattingRuleExtensions): ConditionalDataBar
|
||||
{
|
||||
$dataBar = new ConditionalDataBar();
|
||||
//dataBar attribute
|
||||
if (isset($cfRule->dataBar['showValue'])) {
|
||||
$dataBar->setShowValue((bool) $cfRule->dataBar['showValue']);
|
||||
}
|
||||
|
||||
//dataBar children
|
||||
//conditionalFormatValueObjects
|
||||
$cfvoXml = $cfRule->dataBar->cfvo;
|
||||
$cfvoIndex = 0;
|
||||
foreach ((count($cfvoXml) > 1 ? $cfvoXml : [$cfvoXml]) as $cfvo) { //* @phpstan-ignore-line
|
||||
if ($cfvoIndex === 0) {
|
||||
$dataBar->setMinimumConditionalFormatValueObject(new ConditionalFormatValueObject((string) $cfvo['type'], (string) $cfvo['val']));
|
||||
}
|
||||
if ($cfvoIndex === 1) {
|
||||
$dataBar->setMaximumConditionalFormatValueObject(new ConditionalFormatValueObject((string) $cfvo['type'], (string) $cfvo['val']));
|
||||
}
|
||||
++$cfvoIndex;
|
||||
}
|
||||
|
||||
//color
|
||||
if (isset($cfRule->dataBar->color)) {
|
||||
$dataBar->setColor($this->styleReader->readColor($cfRule->dataBar->color));
|
||||
}
|
||||
//extLst
|
||||
$this->readDataBarExtLstOfConditionalRule($dataBar, $cfRule, $conditionalFormattingRuleExtensions);
|
||||
|
||||
return $dataBar;
|
||||
}
|
||||
|
||||
private function readColorScale(SimpleXMLElement|stdClass $cfRule): ConditionalColorScale
|
||||
{
|
||||
$colorScale = new ConditionalColorScale();
|
||||
$count = count($cfRule->colorScale->cfvo);
|
||||
$idx = 0;
|
||||
foreach ($cfRule->colorScale->cfvo as $cfvoXml) {
|
||||
$attr = $cfvoXml->attributes() ?? [];
|
||||
$type = (string) ($attr['type'] ?? '');
|
||||
$val = $attr['val'] ?? null;
|
||||
if ($idx === 0) {
|
||||
$method = 'setMinimumConditionalFormatValueObject';
|
||||
} elseif ($idx === 1 && $count === 3) {
|
||||
$method = 'setMidpointConditionalFormatValueObject';
|
||||
} else {
|
||||
$method = 'setMaximumConditionalFormatValueObject';
|
||||
}
|
||||
if ($type !== 'formula') {
|
||||
$colorScale->$method(new ConditionalFormatValueObject($type, $val));
|
||||
} else {
|
||||
$colorScale->$method(new ConditionalFormatValueObject($type, null, $val));
|
||||
}
|
||||
++$idx;
|
||||
}
|
||||
$idx = 0;
|
||||
foreach ($cfRule->colorScale->color as $color) {
|
||||
$rgb = $this->styleReader->readColor($color);
|
||||
if ($idx === 0) {
|
||||
$colorScale->setMinimumColor(new Color($rgb));
|
||||
} elseif ($idx === 1 && $count === 3) {
|
||||
$colorScale->setMidpointColor(new Color($rgb));
|
||||
} else {
|
||||
$colorScale->setMaximumColor(new Color($rgb));
|
||||
}
|
||||
++$idx;
|
||||
}
|
||||
|
||||
return $colorScale;
|
||||
}
|
||||
|
||||
private function readDataBarExtLstOfConditionalRule(ConditionalDataBar $dataBar, SimpleXMLElement $cfRule, array $conditionalFormattingRuleExtensions): void
|
||||
{
|
||||
if (isset($cfRule->extLst)) {
|
||||
$ns = $cfRule->extLst->getNamespaces(true);
|
||||
foreach ((count($cfRule->extLst) > 0 ? $cfRule->extLst->ext : [$cfRule->extLst->ext]) as $ext) { //* @phpstan-ignore-line
|
||||
$extId = (string) $ext->children($ns['x14'])->id;
|
||||
if (isset($conditionalFormattingRuleExtensions[$extId]) && (string) $ext['uri'] === '{B025F937-C7B1-47D3-B67F-A62EFF666E3E}') {
|
||||
$dataBar->setConditionalFormattingRuleExt($conditionalFormattingRuleExtensions[$extId]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
65
api/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/DataValidations.php
vendored
Normal file
65
api/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/DataValidations.php
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Reader\Xlsx;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
||||
use SimpleXMLElement;
|
||||
|
||||
class DataValidations
|
||||
{
|
||||
private Worksheet $worksheet;
|
||||
|
||||
private SimpleXMLElement $worksheetXml;
|
||||
|
||||
public function __construct(Worksheet $workSheet, SimpleXMLElement $worksheetXml)
|
||||
{
|
||||
$this->worksheet = $workSheet;
|
||||
$this->worksheetXml = $worksheetXml;
|
||||
}
|
||||
|
||||
public function load(): void
|
||||
{
|
||||
foreach ($this->worksheetXml->dataValidations->dataValidation as $dataValidation) {
|
||||
// Uppercase coordinate
|
||||
$range = strtoupper((string) $dataValidation['sqref']);
|
||||
$rangeSet = explode(' ', $range);
|
||||
foreach ($rangeSet as $range) {
|
||||
if (preg_match('/^[A-Z]{1,3}\\d{1,7}/', $range, $matches) === 1) {
|
||||
// Ensure left/top row of range exists, thereby
|
||||
// adjusting high row/column.
|
||||
$this->worksheet->getCell($matches[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach ($this->worksheetXml->dataValidations->dataValidation as $dataValidation) {
|
||||
// Uppercase coordinate
|
||||
$range = strtoupper((string) $dataValidation['sqref']);
|
||||
$rangeSet = explode(' ', $range);
|
||||
foreach ($rangeSet as $range) {
|
||||
$stRange = $this->worksheet->shrinkRangeToFit($range);
|
||||
|
||||
// Extract all cell references in $range
|
||||
foreach (Coordinate::extractAllCellReferencesInRange($stRange) as $reference) {
|
||||
// Create validation
|
||||
$docValidation = $this->worksheet->getCell($reference)->getDataValidation();
|
||||
$docValidation->setType((string) $dataValidation['type']);
|
||||
$docValidation->setErrorStyle((string) $dataValidation['errorStyle']);
|
||||
$docValidation->setOperator((string) $dataValidation['operator']);
|
||||
$docValidation->setAllowBlank(filter_var($dataValidation['allowBlank'], FILTER_VALIDATE_BOOLEAN));
|
||||
// showDropDown is inverted (works as hideDropDown if true)
|
||||
$docValidation->setShowDropDown(!filter_var($dataValidation['showDropDown'], FILTER_VALIDATE_BOOLEAN));
|
||||
$docValidation->setShowInputMessage(filter_var($dataValidation['showInputMessage'], FILTER_VALIDATE_BOOLEAN));
|
||||
$docValidation->setShowErrorMessage(filter_var($dataValidation['showErrorMessage'], FILTER_VALIDATE_BOOLEAN));
|
||||
$docValidation->setErrorTitle((string) $dataValidation['errorTitle']);
|
||||
$docValidation->setError((string) $dataValidation['error']);
|
||||
$docValidation->setPromptTitle((string) $dataValidation['promptTitle']);
|
||||
$docValidation->setPrompt((string) $dataValidation['prompt']);
|
||||
$docValidation->setFormula1((string) $dataValidation->formula1);
|
||||
$docValidation->setFormula2((string) $dataValidation->formula2);
|
||||
$docValidation->setSqref($range);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
64
api/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/Hyperlinks.php
vendored
Normal file
64
api/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/Hyperlinks.php
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Reader\Xlsx;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
|
||||
use PhpOffice\PhpSpreadsheet\Reader\Xlsx;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
||||
use SimpleXMLElement;
|
||||
|
||||
class Hyperlinks
|
||||
{
|
||||
private Worksheet $worksheet;
|
||||
|
||||
private array $hyperlinks = [];
|
||||
|
||||
public function __construct(Worksheet $workSheet)
|
||||
{
|
||||
$this->worksheet = $workSheet;
|
||||
}
|
||||
|
||||
public function readHyperlinks(SimpleXMLElement $relsWorksheet): void
|
||||
{
|
||||
foreach ($relsWorksheet->children(Namespaces::RELATIONSHIPS)->Relationship as $elementx) {
|
||||
$element = Xlsx::getAttributes($elementx);
|
||||
if ($element->Type == Namespaces::HYPERLINK) {
|
||||
$this->hyperlinks[(string) $element->Id] = (string) $element->Target;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function setHyperlinks(SimpleXMLElement $worksheetXml): void
|
||||
{
|
||||
foreach ($worksheetXml->children(Namespaces::MAIN)->hyperlink as $hyperlink) {
|
||||
if ($hyperlink !== null) {
|
||||
$this->setHyperlink($hyperlink, $this->worksheet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function setHyperlink(SimpleXMLElement $hyperlink, Worksheet $worksheet): void
|
||||
{
|
||||
// Link url
|
||||
$linkRel = Xlsx::getAttributes($hyperlink, Namespaces::SCHEMA_OFFICE_DOCUMENT);
|
||||
|
||||
$attributes = Xlsx::getAttributes($hyperlink);
|
||||
foreach (Coordinate::extractAllCellReferencesInRange($attributes->ref) as $cellReference) {
|
||||
$cell = $worksheet->getCell($cellReference);
|
||||
if (isset($linkRel['id'])) {
|
||||
$hyperlinkUrl = $this->hyperlinks[(string) $linkRel['id']] ?? null;
|
||||
if (isset($attributes['location'])) {
|
||||
$hyperlinkUrl .= '#' . (string) $attributes['location'];
|
||||
}
|
||||
$cell->getHyperlink()->setUrl($hyperlinkUrl);
|
||||
} elseif (isset($attributes['location'])) {
|
||||
$cell->getHyperlink()->setUrl('sheet://' . (string) $attributes['location']);
|
||||
}
|
||||
|
||||
// Tooltip
|
||||
if (isset($attributes['tooltip'])) {
|
||||
$cell->getHyperlink()->setTooltip((string) $attributes['tooltip']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
118
api/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/Namespaces.php
vendored
Normal file
118
api/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/Namespaces.php
vendored
Normal file
@@ -0,0 +1,118 @@
|
||||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Reader\Xlsx;
|
||||
|
||||
class Namespaces
|
||||
{
|
||||
const SCHEMAS = 'http://schemas.openxmlformats.org';
|
||||
|
||||
const RELATIONSHIPS = 'http://schemas.openxmlformats.org/package/2006/relationships';
|
||||
|
||||
// This one used in Reader\Xlsx
|
||||
const CORE_PROPERTIES = 'http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties';
|
||||
|
||||
// This one used in Reader\Xlsx\Properties
|
||||
const CORE_PROPERTIES2 = 'http://schemas.openxmlformats.org/package/2006/metadata/core-properties';
|
||||
|
||||
const THUMBNAIL = 'http://schemas.openxmlformats.org/package/2006/relationships/metadata/thumbnail';
|
||||
|
||||
const THEME = 'http://schemas.openxmlformats.org/package/2006/relationships/theme';
|
||||
|
||||
const THEME2 = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme';
|
||||
|
||||
const COMPATIBILITY = 'http://schemas.openxmlformats.org/markup-compatibility/2006';
|
||||
|
||||
const MAIN = 'http://schemas.openxmlformats.org/spreadsheetml/2006/main';
|
||||
|
||||
const RELATIONSHIPS_DRAWING = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing';
|
||||
|
||||
const DRAWINGML = 'http://schemas.openxmlformats.org/drawingml/2006/main';
|
||||
|
||||
const CHART = 'http://schemas.openxmlformats.org/drawingml/2006/chart';
|
||||
|
||||
const CHART_ALTERNATE = 'http://schemas.microsoft.com/office/drawing/2007/8/2/chart';
|
||||
|
||||
const RELATIONSHIPS_CHART = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart';
|
||||
|
||||
const SPREADSHEET_DRAWING = 'http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing';
|
||||
|
||||
const SCHEMA_OFFICE_DOCUMENT = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships';
|
||||
|
||||
const COMMENTS = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments';
|
||||
|
||||
const RELATIONSHIPS_CUSTOM_PROPERTIES = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties';
|
||||
|
||||
const RELATIONSHIPS_EXTENDED_PROPERTIES = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties';
|
||||
|
||||
const RELATIONSHIPS_CTRLPROP = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/ctrlProp';
|
||||
|
||||
const CUSTOM_PROPERTIES = 'http://schemas.openxmlformats.org/officeDocument/2006/custom-properties';
|
||||
|
||||
const EXTENDED_PROPERTIES = 'http://schemas.openxmlformats.org/officeDocument/2006/extended-properties';
|
||||
|
||||
const PROPERTIES_VTYPES = 'http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes';
|
||||
|
||||
const HYPERLINK = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink';
|
||||
|
||||
const OFFICE_DOCUMENT = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument';
|
||||
|
||||
const SHARED_STRINGS = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings';
|
||||
|
||||
const STYLES = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles';
|
||||
|
||||
const IMAGE = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image';
|
||||
|
||||
const VML = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing';
|
||||
|
||||
const WORKSHEET = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet';
|
||||
|
||||
const CHARTSHEET = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chartsheet';
|
||||
|
||||
const SCHEMA_MICROSOFT = 'http://schemas.microsoft.com/office/2006/relationships';
|
||||
|
||||
const EXTENSIBILITY = 'http://schemas.microsoft.com/office/2006/relationships/ui/extensibility';
|
||||
|
||||
const VBA = 'http://schemas.microsoft.com/office/2006/relationships/vbaProject';
|
||||
|
||||
const VBA_SIGNATURE = 'http://schemas.microsoft.com/office/2006/relationships/vbaProject';
|
||||
|
||||
const DATA_VALIDATIONS1 = 'http://schemas.microsoft.com/office/spreadsheetml/2009/9/main';
|
||||
|
||||
const DATA_VALIDATIONS2 = 'http://schemas.microsoft.com/office/excel/2006/main';
|
||||
|
||||
const CONTENT_TYPES = 'http://schemas.openxmlformats.org/package/2006/content-types';
|
||||
|
||||
const RELATIONSHIPS_PRINTER_SETTINGS = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/printerSettings';
|
||||
|
||||
const RELATIONSHIPS_TABLE = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/table';
|
||||
|
||||
const SPREADSHEETML_AC = 'http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac';
|
||||
|
||||
const DC_ELEMENTS = 'http://purl.org/dc/elements/1.1/';
|
||||
|
||||
const DC_TERMS = 'http://purl.org/dc/terms/';
|
||||
|
||||
const DC_DCMITYPE = 'http://purl.org/dc/dcmitype/';
|
||||
|
||||
const SCHEMA_INSTANCE = 'http://www.w3.org/2001/XMLSchema-instance';
|
||||
|
||||
const URN_EXCEL = 'urn:schemas-microsoft-com:office:excel';
|
||||
|
||||
const URN_MSOFFICE = 'urn:schemas-microsoft-com:office:office';
|
||||
|
||||
const URN_VML = 'urn:schemas-microsoft-com:vml';
|
||||
|
||||
const SCHEMA_PURL = 'http://purl.oclc.org/ooxml';
|
||||
|
||||
const PURL_OFFICE_DOCUMENT = 'http://purl.oclc.org/ooxml/officeDocument/relationships/officeDocument';
|
||||
|
||||
const PURL_RELATIONSHIPS = 'http://purl.oclc.org/ooxml/officeDocument/relationships';
|
||||
|
||||
const PURL_MAIN = 'http://purl.oclc.org/ooxml/spreadsheetml/main';
|
||||
|
||||
const PURL_DRAWING = 'http://purl.oclc.org/ooxml/drawingml/main';
|
||||
|
||||
const PURL_CHART = 'http://purl.oclc.org/ooxml/drawingml/chart';
|
||||
|
||||
const PURL_WORKSHEET = 'http://purl.oclc.org/ooxml/officeDocument/relationships/worksheet';
|
||||
}
|
||||
170
api/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/PageSetup.php
vendored
Normal file
170
api/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/PageSetup.php
vendored
Normal file
@@ -0,0 +1,170 @@
|
||||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Reader\Xlsx;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
||||
use SimpleXMLElement;
|
||||
|
||||
class PageSetup extends BaseParserClass
|
||||
{
|
||||
private Worksheet $worksheet;
|
||||
|
||||
private ?SimpleXMLElement $worksheetXml;
|
||||
|
||||
public function __construct(Worksheet $workSheet, ?SimpleXMLElement $worksheetXml = null)
|
||||
{
|
||||
$this->worksheet = $workSheet;
|
||||
$this->worksheetXml = $worksheetXml;
|
||||
}
|
||||
|
||||
public function load(array $unparsedLoadedData): array
|
||||
{
|
||||
$worksheetXml = $this->worksheetXml;
|
||||
if ($worksheetXml === null) {
|
||||
return $unparsedLoadedData;
|
||||
}
|
||||
|
||||
$this->margins($worksheetXml, $this->worksheet);
|
||||
$unparsedLoadedData = $this->pageSetup($worksheetXml, $this->worksheet, $unparsedLoadedData);
|
||||
$this->headerFooter($worksheetXml, $this->worksheet);
|
||||
$this->pageBreaks($worksheetXml, $this->worksheet);
|
||||
|
||||
return $unparsedLoadedData;
|
||||
}
|
||||
|
||||
private function margins(SimpleXMLElement $xmlSheet, Worksheet $worksheet): void
|
||||
{
|
||||
if ($xmlSheet->pageMargins) {
|
||||
$docPageMargins = $worksheet->getPageMargins();
|
||||
$docPageMargins->setLeft((float) ($xmlSheet->pageMargins['left']));
|
||||
$docPageMargins->setRight((float) ($xmlSheet->pageMargins['right']));
|
||||
$docPageMargins->setTop((float) ($xmlSheet->pageMargins['top']));
|
||||
$docPageMargins->setBottom((float) ($xmlSheet->pageMargins['bottom']));
|
||||
$docPageMargins->setHeader((float) ($xmlSheet->pageMargins['header']));
|
||||
$docPageMargins->setFooter((float) ($xmlSheet->pageMargins['footer']));
|
||||
}
|
||||
}
|
||||
|
||||
private function pageSetup(SimpleXMLElement $xmlSheet, Worksheet $worksheet, array $unparsedLoadedData): array
|
||||
{
|
||||
if ($xmlSheet->pageSetup) {
|
||||
$docPageSetup = $worksheet->getPageSetup();
|
||||
|
||||
if (isset($xmlSheet->pageSetup['orientation'])) {
|
||||
$docPageSetup->setOrientation((string) $xmlSheet->pageSetup['orientation']);
|
||||
}
|
||||
if (isset($xmlSheet->pageSetup['paperSize'])) {
|
||||
$docPageSetup->setPaperSize((int) ($xmlSheet->pageSetup['paperSize']));
|
||||
}
|
||||
if (isset($xmlSheet->pageSetup['scale'])) {
|
||||
$docPageSetup->setScale((int) ($xmlSheet->pageSetup['scale']), false);
|
||||
}
|
||||
if (isset($xmlSheet->pageSetup['fitToHeight']) && (int) ($xmlSheet->pageSetup['fitToHeight']) >= 0) {
|
||||
$docPageSetup->setFitToHeight((int) ($xmlSheet->pageSetup['fitToHeight']), false);
|
||||
}
|
||||
if (isset($xmlSheet->pageSetup['fitToWidth']) && (int) ($xmlSheet->pageSetup['fitToWidth']) >= 0) {
|
||||
$docPageSetup->setFitToWidth((int) ($xmlSheet->pageSetup['fitToWidth']), false);
|
||||
}
|
||||
if (
|
||||
isset($xmlSheet->pageSetup['firstPageNumber'], $xmlSheet->pageSetup['useFirstPageNumber'])
|
||||
&& self::boolean((string) $xmlSheet->pageSetup['useFirstPageNumber'])
|
||||
) {
|
||||
$docPageSetup->setFirstPageNumber((int) ($xmlSheet->pageSetup['firstPageNumber']));
|
||||
}
|
||||
if (isset($xmlSheet->pageSetup['pageOrder'])) {
|
||||
$docPageSetup->setPageOrder((string) $xmlSheet->pageSetup['pageOrder']);
|
||||
}
|
||||
|
||||
$relAttributes = $xmlSheet->pageSetup->attributes(Namespaces::SCHEMA_OFFICE_DOCUMENT);
|
||||
if (isset($relAttributes['id'])) {
|
||||
$relid = (string) $relAttributes['id'];
|
||||
if (!str_ends_with($relid, 'ps')) {
|
||||
$relid .= 'ps';
|
||||
}
|
||||
$unparsedLoadedData['sheets'][$worksheet->getCodeName()]['pageSetupRelId'] = $relid;
|
||||
}
|
||||
}
|
||||
|
||||
return $unparsedLoadedData;
|
||||
}
|
||||
|
||||
private function headerFooter(SimpleXMLElement $xmlSheet, Worksheet $worksheet): void
|
||||
{
|
||||
if ($xmlSheet->headerFooter) {
|
||||
$docHeaderFooter = $worksheet->getHeaderFooter();
|
||||
|
||||
if (
|
||||
isset($xmlSheet->headerFooter['differentOddEven'])
|
||||
&& self::boolean((string) $xmlSheet->headerFooter['differentOddEven'])
|
||||
) {
|
||||
$docHeaderFooter->setDifferentOddEven(true);
|
||||
} else {
|
||||
$docHeaderFooter->setDifferentOddEven(false);
|
||||
}
|
||||
if (
|
||||
isset($xmlSheet->headerFooter['differentFirst'])
|
||||
&& self::boolean((string) $xmlSheet->headerFooter['differentFirst'])
|
||||
) {
|
||||
$docHeaderFooter->setDifferentFirst(true);
|
||||
} else {
|
||||
$docHeaderFooter->setDifferentFirst(false);
|
||||
}
|
||||
if (
|
||||
isset($xmlSheet->headerFooter['scaleWithDoc'])
|
||||
&& !self::boolean((string) $xmlSheet->headerFooter['scaleWithDoc'])
|
||||
) {
|
||||
$docHeaderFooter->setScaleWithDocument(false);
|
||||
} else {
|
||||
$docHeaderFooter->setScaleWithDocument(true);
|
||||
}
|
||||
if (
|
||||
isset($xmlSheet->headerFooter['alignWithMargins'])
|
||||
&& !self::boolean((string) $xmlSheet->headerFooter['alignWithMargins'])
|
||||
) {
|
||||
$docHeaderFooter->setAlignWithMargins(false);
|
||||
} else {
|
||||
$docHeaderFooter->setAlignWithMargins(true);
|
||||
}
|
||||
|
||||
$docHeaderFooter->setOddHeader((string) $xmlSheet->headerFooter->oddHeader);
|
||||
$docHeaderFooter->setOddFooter((string) $xmlSheet->headerFooter->oddFooter);
|
||||
$docHeaderFooter->setEvenHeader((string) $xmlSheet->headerFooter->evenHeader);
|
||||
$docHeaderFooter->setEvenFooter((string) $xmlSheet->headerFooter->evenFooter);
|
||||
$docHeaderFooter->setFirstHeader((string) $xmlSheet->headerFooter->firstHeader);
|
||||
$docHeaderFooter->setFirstFooter((string) $xmlSheet->headerFooter->firstFooter);
|
||||
}
|
||||
}
|
||||
|
||||
private function pageBreaks(SimpleXMLElement $xmlSheet, Worksheet $worksheet): void
|
||||
{
|
||||
if ($xmlSheet->rowBreaks && $xmlSheet->rowBreaks->brk) {
|
||||
$this->rowBreaks($xmlSheet, $worksheet);
|
||||
}
|
||||
if ($xmlSheet->colBreaks && $xmlSheet->colBreaks->brk) {
|
||||
$this->columnBreaks($xmlSheet, $worksheet);
|
||||
}
|
||||
}
|
||||
|
||||
private function rowBreaks(SimpleXMLElement $xmlSheet, Worksheet $worksheet): void
|
||||
{
|
||||
foreach ($xmlSheet->rowBreaks->brk as $brk) {
|
||||
$rowBreakMax = isset($brk['max']) ? ((int) $brk['max']) : -1;
|
||||
if ($brk['man']) {
|
||||
$worksheet->setBreak("A{$brk['id']}", Worksheet::BREAK_ROW, $rowBreakMax);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function columnBreaks(SimpleXMLElement $xmlSheet, Worksheet $worksheet): void
|
||||
{
|
||||
foreach ($xmlSheet->colBreaks->brk as $brk) {
|
||||
if ($brk['man']) {
|
||||
$worksheet->setBreak(
|
||||
Coordinate::stringFromColumnIndex(((int) $brk['id']) + 1) . '1',
|
||||
Worksheet::BREAK_COLUMN
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
95
api/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/Properties.php
vendored
Normal file
95
api/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/Properties.php
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Reader\Xlsx;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Document\Properties as DocumentProperties;
|
||||
use PhpOffice\PhpSpreadsheet\Reader\Security\XmlScanner;
|
||||
use SimpleXMLElement;
|
||||
|
||||
class Properties
|
||||
{
|
||||
private XmlScanner $securityScanner;
|
||||
|
||||
private DocumentProperties $docProps;
|
||||
|
||||
public function __construct(XmlScanner $securityScanner, DocumentProperties $docProps)
|
||||
{
|
||||
$this->securityScanner = $securityScanner;
|
||||
$this->docProps = $docProps;
|
||||
}
|
||||
|
||||
private function extractPropertyData(string $propertyData): ?SimpleXMLElement
|
||||
{
|
||||
// okay to omit namespace because everything will be processed by xpath
|
||||
$obj = simplexml_load_string(
|
||||
$this->securityScanner->scan($propertyData)
|
||||
);
|
||||
|
||||
return $obj === false ? null : $obj;
|
||||
}
|
||||
|
||||
public function readCoreProperties(string $propertyData): void
|
||||
{
|
||||
$xmlCore = $this->extractPropertyData($propertyData);
|
||||
|
||||
if (is_object($xmlCore)) {
|
||||
$xmlCore->registerXPathNamespace('dc', Namespaces::DC_ELEMENTS);
|
||||
$xmlCore->registerXPathNamespace('dcterms', Namespaces::DC_TERMS);
|
||||
$xmlCore->registerXPathNamespace('cp', Namespaces::CORE_PROPERTIES2);
|
||||
|
||||
$this->docProps->setCreator($this->getArrayItem($xmlCore->xpath('dc:creator')));
|
||||
$this->docProps->setLastModifiedBy($this->getArrayItem($xmlCore->xpath('cp:lastModifiedBy')));
|
||||
$this->docProps->setCreated($this->getArrayItem($xmlCore->xpath('dcterms:created'))); //! respect xsi:type
|
||||
$this->docProps->setModified($this->getArrayItem($xmlCore->xpath('dcterms:modified'))); //! respect xsi:type
|
||||
$this->docProps->setTitle($this->getArrayItem($xmlCore->xpath('dc:title')));
|
||||
$this->docProps->setDescription($this->getArrayItem($xmlCore->xpath('dc:description')));
|
||||
$this->docProps->setSubject($this->getArrayItem($xmlCore->xpath('dc:subject')));
|
||||
$this->docProps->setKeywords($this->getArrayItem($xmlCore->xpath('cp:keywords')));
|
||||
$this->docProps->setCategory($this->getArrayItem($xmlCore->xpath('cp:category')));
|
||||
}
|
||||
}
|
||||
|
||||
public function readExtendedProperties(string $propertyData): void
|
||||
{
|
||||
$xmlCore = $this->extractPropertyData($propertyData);
|
||||
|
||||
if (is_object($xmlCore)) {
|
||||
if (isset($xmlCore->Company)) {
|
||||
$this->docProps->setCompany((string) $xmlCore->Company);
|
||||
}
|
||||
if (isset($xmlCore->Manager)) {
|
||||
$this->docProps->setManager((string) $xmlCore->Manager);
|
||||
}
|
||||
if (isset($xmlCore->HyperlinkBase)) {
|
||||
$this->docProps->setHyperlinkBase((string) $xmlCore->HyperlinkBase);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function readCustomProperties(string $propertyData): void
|
||||
{
|
||||
$xmlCore = $this->extractPropertyData($propertyData);
|
||||
|
||||
if (is_object($xmlCore)) {
|
||||
foreach ($xmlCore as $xmlProperty) {
|
||||
/** @var SimpleXMLElement $xmlProperty */
|
||||
$cellDataOfficeAttributes = $xmlProperty->attributes();
|
||||
if (isset($cellDataOfficeAttributes['name'])) {
|
||||
$propertyName = (string) $cellDataOfficeAttributes['name'];
|
||||
$cellDataOfficeChildren = $xmlProperty->children('http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes');
|
||||
|
||||
$attributeType = $cellDataOfficeChildren->getName();
|
||||
$attributeValue = (string) $cellDataOfficeChildren->{$attributeType};
|
||||
$attributeValue = DocumentProperties::convertProperty($attributeValue, $attributeType);
|
||||
$attributeType = DocumentProperties::convertPropertyType($attributeType);
|
||||
$this->docProps->setCustomProperty($propertyName, $attributeValue, $attributeType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function getArrayItem(null|array|false $array): string
|
||||
{
|
||||
return is_array($array) ? (string) ($array[0] ?? '') : '';
|
||||
}
|
||||
}
|
||||
26
api/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/SharedFormula.php
vendored
Normal file
26
api/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/SharedFormula.php
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Reader\Xlsx;
|
||||
|
||||
class SharedFormula
|
||||
{
|
||||
private string $master;
|
||||
|
||||
private string $formula;
|
||||
|
||||
public function __construct(string $master, string $formula)
|
||||
{
|
||||
$this->master = $master;
|
||||
$this->formula = $formula;
|
||||
}
|
||||
|
||||
public function master(): string
|
||||
{
|
||||
return $this->master;
|
||||
}
|
||||
|
||||
public function formula(): string
|
||||
{
|
||||
return $this->formula;
|
||||
}
|
||||
}
|
||||
139
api/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/SheetViewOptions.php
vendored
Normal file
139
api/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/SheetViewOptions.php
vendored
Normal file
@@ -0,0 +1,139 @@
|
||||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Reader\Xlsx;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
||||
use SimpleXMLElement;
|
||||
|
||||
class SheetViewOptions extends BaseParserClass
|
||||
{
|
||||
private Worksheet $worksheet;
|
||||
|
||||
private ?SimpleXMLElement $worksheetXml;
|
||||
|
||||
public function __construct(Worksheet $workSheet, ?SimpleXMLElement $worksheetXml = null)
|
||||
{
|
||||
$this->worksheet = $workSheet;
|
||||
$this->worksheetXml = $worksheetXml;
|
||||
}
|
||||
|
||||
public function load(bool $readDataOnly, Styles $styleReader): void
|
||||
{
|
||||
if ($this->worksheetXml === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isset($this->worksheetXml->sheetPr)) {
|
||||
$sheetPr = $this->worksheetXml->sheetPr;
|
||||
$this->tabColor($sheetPr, $styleReader);
|
||||
$this->codeName($sheetPr);
|
||||
$this->outlines($sheetPr);
|
||||
$this->pageSetup($sheetPr);
|
||||
}
|
||||
|
||||
if (isset($this->worksheetXml->sheetFormatPr)) {
|
||||
$this->sheetFormat($this->worksheetXml->sheetFormatPr);
|
||||
}
|
||||
|
||||
if (!$readDataOnly && isset($this->worksheetXml->printOptions)) {
|
||||
$this->printOptions($this->worksheetXml->printOptions);
|
||||
}
|
||||
}
|
||||
|
||||
private function tabColor(SimpleXMLElement $sheetPr, Styles $styleReader): void
|
||||
{
|
||||
if (isset($sheetPr->tabColor)) {
|
||||
$this->worksheet->getTabColor()->setARGB($styleReader->readColor($sheetPr->tabColor));
|
||||
}
|
||||
}
|
||||
|
||||
private function codeName(SimpleXMLElement $sheetPrx): void
|
||||
{
|
||||
$sheetPr = $sheetPrx->attributes() ?? [];
|
||||
if (isset($sheetPr['codeName'])) {
|
||||
$this->worksheet->setCodeName((string) $sheetPr['codeName'], false);
|
||||
}
|
||||
}
|
||||
|
||||
private function outlines(SimpleXMLElement $sheetPr): void
|
||||
{
|
||||
if (isset($sheetPr->outlinePr)) {
|
||||
$attr = $sheetPr->outlinePr->attributes() ?? [];
|
||||
if (
|
||||
isset($attr['summaryRight'])
|
||||
&& !self::boolean((string) $attr['summaryRight'])
|
||||
) {
|
||||
$this->worksheet->setShowSummaryRight(false);
|
||||
} else {
|
||||
$this->worksheet->setShowSummaryRight(true);
|
||||
}
|
||||
|
||||
if (
|
||||
isset($attr['summaryBelow'])
|
||||
&& !self::boolean((string) $attr['summaryBelow'])
|
||||
) {
|
||||
$this->worksheet->setShowSummaryBelow(false);
|
||||
} else {
|
||||
$this->worksheet->setShowSummaryBelow(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function pageSetup(SimpleXMLElement $sheetPr): void
|
||||
{
|
||||
if (isset($sheetPr->pageSetUpPr)) {
|
||||
$attr = $sheetPr->pageSetUpPr->attributes() ?? [];
|
||||
if (
|
||||
isset($attr['fitToPage'])
|
||||
&& !self::boolean((string) $attr['fitToPage'])
|
||||
) {
|
||||
$this->worksheet->getPageSetup()->setFitToPage(false);
|
||||
} else {
|
||||
$this->worksheet->getPageSetup()->setFitToPage(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function sheetFormat(SimpleXMLElement $sheetFormatPrx): void
|
||||
{
|
||||
$sheetFormatPr = $sheetFormatPrx->attributes() ?? [];
|
||||
if (
|
||||
isset($sheetFormatPr['customHeight'])
|
||||
&& self::boolean((string) $sheetFormatPr['customHeight'])
|
||||
&& isset($sheetFormatPr['defaultRowHeight'])
|
||||
) {
|
||||
$this->worksheet->getDefaultRowDimension()
|
||||
->setRowHeight((float) $sheetFormatPr['defaultRowHeight']);
|
||||
}
|
||||
|
||||
if (isset($sheetFormatPr['defaultColWidth'])) {
|
||||
$this->worksheet->getDefaultColumnDimension()
|
||||
->setWidth((float) $sheetFormatPr['defaultColWidth']);
|
||||
}
|
||||
|
||||
if (
|
||||
isset($sheetFormatPr['zeroHeight'])
|
||||
&& ((string) $sheetFormatPr['zeroHeight'] === '1')
|
||||
) {
|
||||
$this->worksheet->getDefaultRowDimension()->setZeroHeight(true);
|
||||
}
|
||||
}
|
||||
|
||||
private function printOptions(SimpleXMLElement $printOptionsx): void
|
||||
{
|
||||
$printOptions = $printOptionsx->attributes() ?? [];
|
||||
// Spec is weird. gridLines (default false)
|
||||
// and gridLinesSet (default true) must both be true.
|
||||
if (isset($printOptions['gridLines']) && self::boolean((string) $printOptions['gridLines'])) {
|
||||
if (!isset($printOptions['gridLinesSet']) || self::boolean((string) $printOptions['gridLinesSet'])) {
|
||||
$this->worksheet->setPrintGridlines(true);
|
||||
}
|
||||
}
|
||||
if (isset($printOptions['horizontalCentered']) && self::boolean((string) $printOptions['horizontalCentered'])) {
|
||||
$this->worksheet->getPageSetup()->setHorizontalCentered(true);
|
||||
}
|
||||
if (isset($printOptions['verticalCentered']) && self::boolean((string) $printOptions['verticalCentered'])) {
|
||||
$this->worksheet->getPageSetup()->setVerticalCentered(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
199
api/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/SheetViews.php
vendored
Normal file
199
api/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/SheetViews.php
vendored
Normal file
@@ -0,0 +1,199 @@
|
||||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Reader\Xlsx;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
|
||||
use PhpOffice\PhpSpreadsheet\Reader\Xlsx;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\Pane;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
||||
use SimpleXMLElement;
|
||||
|
||||
class SheetViews extends BaseParserClass
|
||||
{
|
||||
private SimpleXMLElement $sheetViewXml;
|
||||
|
||||
private SimpleXMLElement $sheetViewAttributes;
|
||||
|
||||
private Worksheet $worksheet;
|
||||
|
||||
private string $activePane = '';
|
||||
|
||||
public function __construct(SimpleXMLElement $sheetViewXml, Worksheet $workSheet)
|
||||
{
|
||||
$this->sheetViewXml = $sheetViewXml;
|
||||
$this->sheetViewAttributes = Xlsx::testSimpleXml($sheetViewXml->attributes());
|
||||
$this->worksheet = $workSheet;
|
||||
}
|
||||
|
||||
public function load(): void
|
||||
{
|
||||
$this->topLeft();
|
||||
$this->zoomScale();
|
||||
$this->view();
|
||||
$this->gridLines();
|
||||
$this->headers();
|
||||
$this->direction();
|
||||
$this->showZeros();
|
||||
|
||||
$usesPanes = false;
|
||||
if (isset($this->sheetViewXml->pane)) {
|
||||
$this->pane();
|
||||
$usesPanes = true;
|
||||
}
|
||||
if (isset($this->sheetViewXml->selection)) {
|
||||
foreach ($this->sheetViewXml->selection as $selection) {
|
||||
$this->selection($selection, $usesPanes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function zoomScale(): void
|
||||
{
|
||||
if (isset($this->sheetViewAttributes->zoomScale)) {
|
||||
$zoomScale = (int) ($this->sheetViewAttributes->zoomScale);
|
||||
if ($zoomScale <= 0) {
|
||||
// setZoomScale will throw an Exception if the scale is less than or equals 0
|
||||
// that is OK when manually creating documents, but we should be able to read all documents
|
||||
$zoomScale = 100;
|
||||
}
|
||||
|
||||
$this->worksheet->getSheetView()->setZoomScale($zoomScale);
|
||||
}
|
||||
|
||||
if (isset($this->sheetViewAttributes->zoomScaleNormal)) {
|
||||
$zoomScaleNormal = (int) ($this->sheetViewAttributes->zoomScaleNormal);
|
||||
if ($zoomScaleNormal <= 0) {
|
||||
// setZoomScaleNormal will throw an Exception if the scale is less than or equals 0
|
||||
// that is OK when manually creating documents, but we should be able to read all documents
|
||||
$zoomScaleNormal = 100;
|
||||
}
|
||||
|
||||
$this->worksheet->getSheetView()->setZoomScaleNormal($zoomScaleNormal);
|
||||
}
|
||||
|
||||
if (isset($this->sheetViewAttributes->zoomScalePageLayoutView)) {
|
||||
$zoomScaleNormal = (int) ($this->sheetViewAttributes->zoomScalePageLayoutView);
|
||||
if ($zoomScaleNormal > 0) {
|
||||
$this->worksheet->getSheetView()->setZoomScalePageLayoutView($zoomScaleNormal);
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($this->sheetViewAttributes->zoomScaleSheetLayoutView)) {
|
||||
$zoomScaleNormal = (int) ($this->sheetViewAttributes->zoomScaleSheetLayoutView);
|
||||
if ($zoomScaleNormal > 0) {
|
||||
$this->worksheet->getSheetView()->setZoomScaleSheetLayoutView($zoomScaleNormal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function view(): void
|
||||
{
|
||||
if (isset($this->sheetViewAttributes->view)) {
|
||||
$this->worksheet->getSheetView()->setView((string) $this->sheetViewAttributes->view);
|
||||
}
|
||||
}
|
||||
|
||||
private function topLeft(): void
|
||||
{
|
||||
if (isset($this->sheetViewAttributes->topLeftCell)) {
|
||||
$this->worksheet->setTopLeftCell($this->sheetViewAttributes->topLeftCell);
|
||||
}
|
||||
}
|
||||
|
||||
private function gridLines(): void
|
||||
{
|
||||
if (isset($this->sheetViewAttributes->showGridLines)) {
|
||||
$this->worksheet->setShowGridLines(
|
||||
self::boolean((string) $this->sheetViewAttributes->showGridLines)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private function headers(): void
|
||||
{
|
||||
if (isset($this->sheetViewAttributes->showRowColHeaders)) {
|
||||
$this->worksheet->setShowRowColHeaders(
|
||||
self::boolean((string) $this->sheetViewAttributes->showRowColHeaders)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private function direction(): void
|
||||
{
|
||||
if (isset($this->sheetViewAttributes->rightToLeft)) {
|
||||
$this->worksheet->setRightToLeft(
|
||||
self::boolean((string) $this->sheetViewAttributes->rightToLeft)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private function showZeros(): void
|
||||
{
|
||||
if (isset($this->sheetViewAttributes->showZeros)) {
|
||||
$this->worksheet->getSheetView()->setShowZeros(
|
||||
self::boolean((string) $this->sheetViewAttributes->showZeros)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private function pane(): void
|
||||
{
|
||||
$xSplit = 0;
|
||||
$ySplit = 0;
|
||||
$topLeftCell = null;
|
||||
$paneAttributes = $this->sheetViewXml->pane->attributes();
|
||||
|
||||
if (isset($paneAttributes->xSplit)) {
|
||||
$xSplit = (int) ($paneAttributes->xSplit);
|
||||
$this->worksheet->setXSplit($xSplit);
|
||||
}
|
||||
|
||||
if (isset($paneAttributes->ySplit)) {
|
||||
$ySplit = (int) ($paneAttributes->ySplit);
|
||||
$this->worksheet->setYSplit($ySplit);
|
||||
}
|
||||
$paneState = isset($paneAttributes->state) ? ((string) $paneAttributes->state) : '';
|
||||
$this->worksheet->setPaneState($paneState);
|
||||
if (isset($paneAttributes->topLeftCell)) {
|
||||
$topLeftCell = (string) $paneAttributes->topLeftCell;
|
||||
$this->worksheet->setPaneTopLeftCell($topLeftCell);
|
||||
if ($paneState === Worksheet::PANE_FROZEN) {
|
||||
$this->worksheet->setTopLeftCell($topLeftCell);
|
||||
}
|
||||
}
|
||||
$activePane = isset($paneAttributes->activePane) ? ((string) $paneAttributes->activePane) : 'topLeft';
|
||||
$this->worksheet->setActivePane($activePane);
|
||||
$this->activePane = $activePane;
|
||||
if ($paneState === Worksheet::PANE_FROZEN || $paneState === Worksheet::PANE_FROZENSPLIT) {
|
||||
$this->worksheet->freezePane(
|
||||
Coordinate::stringFromColumnIndex($xSplit + 1) . ($ySplit + 1),
|
||||
$topLeftCell,
|
||||
$paneState === Worksheet::PANE_FROZENSPLIT
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private function selection(?SimpleXMLElement $selection, bool $usesPanes): void
|
||||
{
|
||||
$attributes = ($selection === null) ? null : $selection->attributes();
|
||||
if ($attributes !== null) {
|
||||
$position = (string) $attributes->pane;
|
||||
if ($usesPanes && $position === '') {
|
||||
$position = 'topLeft';
|
||||
}
|
||||
$activeCell = (string) $attributes->activeCell;
|
||||
$sqref = (string) $attributes->sqref;
|
||||
$sqref = explode(' ', $sqref);
|
||||
$sqref = $sqref[0];
|
||||
if ($position === '') {
|
||||
$this->worksheet->setSelectedCells($sqref);
|
||||
} else {
|
||||
$pane = new Pane($position, $sqref, $activeCell);
|
||||
$this->worksheet->setPane($position, $pane);
|
||||
if ($position === $this->activePane && $sqref !== '') {
|
||||
$this->worksheet->setSelectedCells($sqref);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
434
api/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/Styles.php
vendored
Normal file
434
api/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/Styles.php
vendored
Normal file
@@ -0,0 +1,434 @@
|
||||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Reader\Xlsx;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Reader\Xlsx;
|
||||
use PhpOffice\PhpSpreadsheet\Style\Alignment;
|
||||
use PhpOffice\PhpSpreadsheet\Style\Border;
|
||||
use PhpOffice\PhpSpreadsheet\Style\Borders;
|
||||
use PhpOffice\PhpSpreadsheet\Style\Color;
|
||||
use PhpOffice\PhpSpreadsheet\Style\Fill;
|
||||
use PhpOffice\PhpSpreadsheet\Style\Font;
|
||||
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
|
||||
use PhpOffice\PhpSpreadsheet\Style\Protection;
|
||||
use PhpOffice\PhpSpreadsheet\Style\Style;
|
||||
use SimpleXMLElement;
|
||||
use stdClass;
|
||||
|
||||
class Styles extends BaseParserClass
|
||||
{
|
||||
/**
|
||||
* Theme instance.
|
||||
*/
|
||||
private ?Theme $theme = null;
|
||||
|
||||
private array $workbookPalette = [];
|
||||
|
||||
private array $styles = [];
|
||||
|
||||
private array $cellStyles = [];
|
||||
|
||||
private SimpleXMLElement $styleXml;
|
||||
|
||||
private string $namespace = '';
|
||||
|
||||
public function setNamespace(string $namespace): void
|
||||
{
|
||||
$this->namespace = $namespace;
|
||||
}
|
||||
|
||||
public function setWorkbookPalette(array $palette): void
|
||||
{
|
||||
$this->workbookPalette = $palette;
|
||||
}
|
||||
|
||||
private function getStyleAttributes(SimpleXMLElement $value): SimpleXMLElement
|
||||
{
|
||||
$attr = $value->attributes('');
|
||||
if ($attr === null || count($attr) === 0) {
|
||||
$attr = $value->attributes($this->namespace);
|
||||
}
|
||||
|
||||
return Xlsx::testSimpleXml($attr);
|
||||
}
|
||||
|
||||
public function setStyleXml(SimpleXMLElement $styleXml): void
|
||||
{
|
||||
$this->styleXml = $styleXml;
|
||||
}
|
||||
|
||||
public function setTheme(Theme $theme): void
|
||||
{
|
||||
$this->theme = $theme;
|
||||
}
|
||||
|
||||
public function setStyleBaseData(?Theme $theme = null, array $styles = [], array $cellStyles = []): void
|
||||
{
|
||||
$this->theme = $theme;
|
||||
$this->styles = $styles;
|
||||
$this->cellStyles = $cellStyles;
|
||||
}
|
||||
|
||||
public function readFontStyle(Font $fontStyle, SimpleXMLElement $fontStyleXml): void
|
||||
{
|
||||
if (isset($fontStyleXml->name)) {
|
||||
$attr = $this->getStyleAttributes($fontStyleXml->name);
|
||||
if (isset($attr['val'])) {
|
||||
$fontStyle->setName((string) $attr['val']);
|
||||
}
|
||||
}
|
||||
if (isset($fontStyleXml->sz)) {
|
||||
$attr = $this->getStyleAttributes($fontStyleXml->sz);
|
||||
if (isset($attr['val'])) {
|
||||
$fontStyle->setSize((float) $attr['val']);
|
||||
}
|
||||
}
|
||||
if (isset($fontStyleXml->b)) {
|
||||
$attr = $this->getStyleAttributes($fontStyleXml->b);
|
||||
$fontStyle->setBold(!isset($attr['val']) || self::boolean((string) $attr['val']));
|
||||
}
|
||||
if (isset($fontStyleXml->i)) {
|
||||
$attr = $this->getStyleAttributes($fontStyleXml->i);
|
||||
$fontStyle->setItalic(!isset($attr['val']) || self::boolean((string) $attr['val']));
|
||||
}
|
||||
if (isset($fontStyleXml->strike)) {
|
||||
$attr = $this->getStyleAttributes($fontStyleXml->strike);
|
||||
$fontStyle->setStrikethrough(!isset($attr['val']) || self::boolean((string) $attr['val']));
|
||||
}
|
||||
$fontStyle->getColor()->setARGB($this->readColor($fontStyleXml->color));
|
||||
|
||||
if (isset($fontStyleXml->u)) {
|
||||
$attr = $this->getStyleAttributes($fontStyleXml->u);
|
||||
if (!isset($attr['val'])) {
|
||||
$fontStyle->setUnderline(Font::UNDERLINE_SINGLE);
|
||||
} else {
|
||||
$fontStyle->setUnderline((string) $attr['val']);
|
||||
}
|
||||
}
|
||||
if (isset($fontStyleXml->vertAlign)) {
|
||||
$attr = $this->getStyleAttributes($fontStyleXml->vertAlign);
|
||||
if (isset($attr['val'])) {
|
||||
$verticalAlign = strtolower((string) $attr['val']);
|
||||
if ($verticalAlign === 'superscript') {
|
||||
$fontStyle->setSuperscript(true);
|
||||
} elseif ($verticalAlign === 'subscript') {
|
||||
$fontStyle->setSubscript(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isset($fontStyleXml->scheme)) {
|
||||
$attr = $this->getStyleAttributes($fontStyleXml->scheme);
|
||||
$fontStyle->setScheme((string) $attr['val']);
|
||||
}
|
||||
}
|
||||
|
||||
private function readNumberFormat(NumberFormat $numfmtStyle, SimpleXMLElement $numfmtStyleXml): void
|
||||
{
|
||||
if ((string) $numfmtStyleXml['formatCode'] !== '') {
|
||||
$numfmtStyle->setFormatCode(self::formatGeneral((string) $numfmtStyleXml['formatCode']));
|
||||
|
||||
return;
|
||||
}
|
||||
$numfmt = $this->getStyleAttributes($numfmtStyleXml);
|
||||
if (isset($numfmt['formatCode'])) {
|
||||
$numfmtStyle->setFormatCode(self::formatGeneral((string) $numfmt['formatCode']));
|
||||
}
|
||||
}
|
||||
|
||||
public function readFillStyle(Fill $fillStyle, SimpleXMLElement $fillStyleXml): void
|
||||
{
|
||||
if ($fillStyleXml->gradientFill) {
|
||||
/** @var SimpleXMLElement $gradientFill */
|
||||
$gradientFill = $fillStyleXml->gradientFill[0];
|
||||
$attr = $this->getStyleAttributes($gradientFill);
|
||||
if (!empty($attr['type'])) {
|
||||
$fillStyle->setFillType((string) $attr['type']);
|
||||
}
|
||||
$fillStyle->setRotation((float) ($attr['degree']));
|
||||
$gradientFill->registerXPathNamespace('sml', Namespaces::MAIN);
|
||||
$fillStyle->getStartColor()->setARGB($this->readColor(self::getArrayItem($gradientFill->xpath('sml:stop[@position=0]'))->color)); //* @phpstan-ignore-line
|
||||
$fillStyle->getEndColor()->setARGB($this->readColor(self::getArrayItem($gradientFill->xpath('sml:stop[@position=1]'))->color)); //* @phpstan-ignore-line
|
||||
} elseif ($fillStyleXml->patternFill) {
|
||||
$defaultFillStyle = Fill::FILL_NONE;
|
||||
if ($fillStyleXml->patternFill->fgColor) {
|
||||
$fillStyle->getStartColor()->setARGB($this->readColor($fillStyleXml->patternFill->fgColor, true));
|
||||
$defaultFillStyle = Fill::FILL_SOLID;
|
||||
}
|
||||
if ($fillStyleXml->patternFill->bgColor) {
|
||||
$fillStyle->getEndColor()->setARGB($this->readColor($fillStyleXml->patternFill->bgColor, true));
|
||||
$defaultFillStyle = Fill::FILL_SOLID;
|
||||
}
|
||||
|
||||
$type = '';
|
||||
if ((string) $fillStyleXml->patternFill['patternType'] !== '') {
|
||||
$type = (string) $fillStyleXml->patternFill['patternType'];
|
||||
} else {
|
||||
$attr = $this->getStyleAttributes($fillStyleXml->patternFill);
|
||||
$type = (string) $attr['patternType'];
|
||||
}
|
||||
$patternType = ($type === '') ? $defaultFillStyle : $type;
|
||||
|
||||
$fillStyle->setFillType($patternType);
|
||||
}
|
||||
}
|
||||
|
||||
public function readBorderStyle(Borders $borderStyle, SimpleXMLElement $borderStyleXml): void
|
||||
{
|
||||
$diagonalUp = $this->getAttribute($borderStyleXml, 'diagonalUp');
|
||||
$diagonalUp = self::boolean($diagonalUp);
|
||||
$diagonalDown = $this->getAttribute($borderStyleXml, 'diagonalDown');
|
||||
$diagonalDown = self::boolean($diagonalDown);
|
||||
if ($diagonalUp === false) {
|
||||
if ($diagonalDown === false) {
|
||||
$borderStyle->setDiagonalDirection(Borders::DIAGONAL_NONE);
|
||||
} else {
|
||||
$borderStyle->setDiagonalDirection(Borders::DIAGONAL_DOWN);
|
||||
}
|
||||
} elseif ($diagonalDown === false) {
|
||||
$borderStyle->setDiagonalDirection(Borders::DIAGONAL_UP);
|
||||
} else {
|
||||
$borderStyle->setDiagonalDirection(Borders::DIAGONAL_BOTH);
|
||||
}
|
||||
|
||||
if (isset($borderStyleXml->left)) {
|
||||
$this->readBorder($borderStyle->getLeft(), $borderStyleXml->left);
|
||||
}
|
||||
if (isset($borderStyleXml->right)) {
|
||||
$this->readBorder($borderStyle->getRight(), $borderStyleXml->right);
|
||||
}
|
||||
if (isset($borderStyleXml->top)) {
|
||||
$this->readBorder($borderStyle->getTop(), $borderStyleXml->top);
|
||||
}
|
||||
if (isset($borderStyleXml->bottom)) {
|
||||
$this->readBorder($borderStyle->getBottom(), $borderStyleXml->bottom);
|
||||
}
|
||||
if (isset($borderStyleXml->diagonal)) {
|
||||
$this->readBorder($borderStyle->getDiagonal(), $borderStyleXml->diagonal);
|
||||
}
|
||||
}
|
||||
|
||||
private function getAttribute(SimpleXMLElement $xml, string $attribute): string
|
||||
{
|
||||
$style = '';
|
||||
if ((string) $xml[$attribute] !== '') {
|
||||
$style = (string) $xml[$attribute];
|
||||
} else {
|
||||
$attr = $this->getStyleAttributes($xml);
|
||||
if (isset($attr[$attribute])) {
|
||||
$style = (string) $attr[$attribute];
|
||||
}
|
||||
}
|
||||
|
||||
return $style;
|
||||
}
|
||||
|
||||
private function readBorder(Border $border, SimpleXMLElement $borderXml): void
|
||||
{
|
||||
$style = $this->getAttribute($borderXml, 'style');
|
||||
if ($style !== '') {
|
||||
$border->setBorderStyle((string) $style);
|
||||
} else {
|
||||
$border->setBorderStyle(Border::BORDER_NONE);
|
||||
}
|
||||
if (isset($borderXml->color)) {
|
||||
$border->getColor()->setARGB($this->readColor($borderXml->color));
|
||||
}
|
||||
}
|
||||
|
||||
public function readAlignmentStyle(Alignment $alignment, SimpleXMLElement $alignmentXml): void
|
||||
{
|
||||
$horizontal = (string) $this->getAttribute($alignmentXml, 'horizontal');
|
||||
if ($horizontal !== '') {
|
||||
$alignment->setHorizontal($horizontal);
|
||||
}
|
||||
$vertical = (string) $this->getAttribute($alignmentXml, 'vertical');
|
||||
if ($vertical !== '') {
|
||||
$alignment->setVertical($vertical);
|
||||
}
|
||||
|
||||
$textRotation = (int) $this->getAttribute($alignmentXml, 'textRotation');
|
||||
if ($textRotation > 90) {
|
||||
$textRotation = 90 - $textRotation;
|
||||
}
|
||||
$alignment->setTextRotation($textRotation);
|
||||
|
||||
$wrapText = $this->getAttribute($alignmentXml, 'wrapText');
|
||||
$alignment->setWrapText(self::boolean((string) $wrapText));
|
||||
$shrinkToFit = $this->getAttribute($alignmentXml, 'shrinkToFit');
|
||||
$alignment->setShrinkToFit(self::boolean((string) $shrinkToFit));
|
||||
$indent = (int) $this->getAttribute($alignmentXml, 'indent');
|
||||
$alignment->setIndent(max($indent, 0));
|
||||
$readingOrder = (int) $this->getAttribute($alignmentXml, 'readingOrder');
|
||||
$alignment->setReadOrder(max($readingOrder, 0));
|
||||
}
|
||||
|
||||
private static function formatGeneral(string $formatString): string
|
||||
{
|
||||
if ($formatString === 'GENERAL') {
|
||||
$formatString = NumberFormat::FORMAT_GENERAL;
|
||||
}
|
||||
|
||||
return $formatString;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read style.
|
||||
*/
|
||||
public function readStyle(Style $docStyle, SimpleXMLElement|stdClass $style): void
|
||||
{
|
||||
if ($style instanceof SimpleXMLElement) {
|
||||
$this->readNumberFormat($docStyle->getNumberFormat(), $style->numFmt);
|
||||
} else {
|
||||
$docStyle->getNumberFormat()->setFormatCode(self::formatGeneral((string) $style->numFmt));
|
||||
}
|
||||
|
||||
if (isset($style->font)) {
|
||||
$this->readFontStyle($docStyle->getFont(), $style->font);
|
||||
}
|
||||
|
||||
if (isset($style->fill)) {
|
||||
$this->readFillStyle($docStyle->getFill(), $style->fill);
|
||||
}
|
||||
|
||||
if (isset($style->border)) {
|
||||
$this->readBorderStyle($docStyle->getBorders(), $style->border);
|
||||
}
|
||||
|
||||
if (isset($style->alignment)) {
|
||||
$this->readAlignmentStyle($docStyle->getAlignment(), $style->alignment);
|
||||
}
|
||||
|
||||
// protection
|
||||
if (isset($style->protection)) {
|
||||
$this->readProtectionLocked($docStyle, $style->protection);
|
||||
$this->readProtectionHidden($docStyle, $style->protection);
|
||||
}
|
||||
|
||||
// top-level style settings
|
||||
if (isset($style->quotePrefix)) {
|
||||
$docStyle->setQuotePrefix((bool) $style->quotePrefix);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read protection locked attribute.
|
||||
*/
|
||||
public function readProtectionLocked(Style $docStyle, SimpleXMLElement $style): void
|
||||
{
|
||||
$locked = '';
|
||||
if ((string) $style['locked'] !== '') {
|
||||
$locked = (string) $style['locked'];
|
||||
} else {
|
||||
$attr = $this->getStyleAttributes($style);
|
||||
if (isset($attr['locked'])) {
|
||||
$locked = (string) $attr['locked'];
|
||||
}
|
||||
}
|
||||
if ($locked !== '') {
|
||||
if (self::boolean($locked)) {
|
||||
$docStyle->getProtection()->setLocked(Protection::PROTECTION_PROTECTED);
|
||||
} else {
|
||||
$docStyle->getProtection()->setLocked(Protection::PROTECTION_UNPROTECTED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read protection hidden attribute.
|
||||
*/
|
||||
public function readProtectionHidden(Style $docStyle, SimpleXMLElement $style): void
|
||||
{
|
||||
$hidden = '';
|
||||
if ((string) $style['hidden'] !== '') {
|
||||
$hidden = (string) $style['hidden'];
|
||||
} else {
|
||||
$attr = $this->getStyleAttributes($style);
|
||||
if (isset($attr['hidden'])) {
|
||||
$hidden = (string) $attr['hidden'];
|
||||
}
|
||||
}
|
||||
if ($hidden !== '') {
|
||||
if (self::boolean((string) $hidden)) {
|
||||
$docStyle->getProtection()->setHidden(Protection::PROTECTION_PROTECTED);
|
||||
} else {
|
||||
$docStyle->getProtection()->setHidden(Protection::PROTECTION_UNPROTECTED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function readColor(SimpleXMLElement $color, bool $background = false): string
|
||||
{
|
||||
$attr = $this->getStyleAttributes($color);
|
||||
if (isset($attr['rgb'])) {
|
||||
return (string) $attr['rgb'];
|
||||
}
|
||||
if (isset($attr['indexed'])) {
|
||||
$indexedColor = (int) $attr['indexed'];
|
||||
if ($indexedColor >= count($this->workbookPalette)) {
|
||||
return Color::indexedColor($indexedColor - 7, $background)->getARGB() ?? '';
|
||||
}
|
||||
|
||||
return Color::indexedColor($indexedColor, $background, $this->workbookPalette)->getARGB() ?? '';
|
||||
}
|
||||
if (isset($attr['theme'])) {
|
||||
if ($this->theme !== null) {
|
||||
$returnColour = $this->theme->getColourByIndex((int) $attr['theme']);
|
||||
if (isset($attr['tint'])) {
|
||||
$tintAdjust = (float) $attr['tint'];
|
||||
$returnColour = Color::changeBrightness($returnColour ?? '', $tintAdjust);
|
||||
}
|
||||
|
||||
return 'FF' . $returnColour;
|
||||
}
|
||||
}
|
||||
|
||||
return ($background) ? 'FFFFFFFF' : 'FF000000';
|
||||
}
|
||||
|
||||
public function dxfs(bool $readDataOnly = false): array
|
||||
{
|
||||
$dxfs = [];
|
||||
if (!$readDataOnly && $this->styleXml) {
|
||||
// Conditional Styles
|
||||
if ($this->styleXml->dxfs) {
|
||||
foreach ($this->styleXml->dxfs->dxf as $dxf) {
|
||||
$style = new Style(false, true);
|
||||
$this->readStyle($style, $dxf);
|
||||
$dxfs[] = $style;
|
||||
}
|
||||
}
|
||||
// Cell Styles
|
||||
if ($this->styleXml->cellStyles) {
|
||||
foreach ($this->styleXml->cellStyles->cellStyle as $cellStylex) {
|
||||
$cellStyle = Xlsx::getAttributes($cellStylex);
|
||||
if ((int) ($cellStyle['builtinId']) == 0) {
|
||||
if (isset($this->cellStyles[(int) ($cellStyle['xfId'])])) {
|
||||
// Set default style
|
||||
$style = new Style();
|
||||
$this->readStyle($style, $this->cellStyles[(int) ($cellStyle['xfId'])]);
|
||||
|
||||
// normal style, currently not using it for anything
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $dxfs;
|
||||
}
|
||||
|
||||
public function styles(): array
|
||||
{
|
||||
return $this->styles;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get array item.
|
||||
*
|
||||
* @param mixed $array (usually array, in theory can be false)
|
||||
*/
|
||||
private static function getArrayItem(mixed $array): ?SimpleXMLElement
|
||||
{
|
||||
return is_array($array) ? ($array[0] ?? null) : null;
|
||||
}
|
||||
}
|
||||
116
api/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/TableReader.php
vendored
Normal file
116
api/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/TableReader.php
vendored
Normal file
@@ -0,0 +1,116 @@
|
||||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Reader\Xlsx;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\Table;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\Table\TableStyle;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
||||
use SimpleXMLElement;
|
||||
|
||||
class TableReader
|
||||
{
|
||||
private Worksheet $worksheet;
|
||||
|
||||
private SimpleXMLElement $tableXml;
|
||||
|
||||
/** @var array|SimpleXMLElement */
|
||||
private $tableAttributes;
|
||||
|
||||
public function __construct(Worksheet $workSheet, SimpleXMLElement $tableXml)
|
||||
{
|
||||
$this->worksheet = $workSheet;
|
||||
$this->tableXml = $tableXml;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads Table into the Worksheet.
|
||||
*/
|
||||
public function load(): void
|
||||
{
|
||||
$this->tableAttributes = $this->tableXml->attributes() ?? [];
|
||||
// Remove all "$" in the table range
|
||||
$tableRange = (string) preg_replace('/\$/', '', $this->tableAttributes['ref'] ?? '');
|
||||
if (str_contains($tableRange, ':')) {
|
||||
$this->readTable($tableRange);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read Table from xml.
|
||||
*/
|
||||
private function readTable(string $tableRange): void
|
||||
{
|
||||
$table = new Table($tableRange);
|
||||
$table->setName((string) ($this->tableAttributes['displayName'] ?? ''));
|
||||
$table->setShowHeaderRow(((string) ($this->tableAttributes['headerRowCount'] ?? '')) !== '0');
|
||||
$table->setShowTotalsRow(((string) ($this->tableAttributes['totalsRowCount'] ?? '')) === '1');
|
||||
|
||||
$this->readTableAutoFilter($table, $this->tableXml->autoFilter);
|
||||
$this->readTableColumns($table, $this->tableXml->tableColumns);
|
||||
$this->readTableStyle($table, $this->tableXml->tableStyleInfo);
|
||||
|
||||
(new AutoFilter($table, $this->tableXml))->load();
|
||||
$this->worksheet->addTable($table);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads TableAutoFilter from xml.
|
||||
*/
|
||||
private function readTableAutoFilter(Table $table, SimpleXMLElement $autoFilterXml): void
|
||||
{
|
||||
if ($autoFilterXml->filterColumn === null) {
|
||||
$table->setAllowFilter(false);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($autoFilterXml->filterColumn as $filterColumn) {
|
||||
$attributes = $filterColumn->attributes() ?? ['colId' => 0, 'hiddenButton' => 0];
|
||||
$column = $table->getColumnByOffset((int) $attributes['colId']);
|
||||
$column->setShowFilterButton(((string) $attributes['hiddenButton']) !== '1');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads TableColumns from xml.
|
||||
*/
|
||||
private function readTableColumns(Table $table, SimpleXMLElement $tableColumnsXml): void
|
||||
{
|
||||
$offset = 0;
|
||||
foreach ($tableColumnsXml->tableColumn as $tableColumn) {
|
||||
$attributes = $tableColumn->attributes() ?? ['totalsRowLabel' => 0, 'totalsRowFunction' => 0];
|
||||
$column = $table->getColumnByOffset($offset++);
|
||||
|
||||
if ($table->getShowTotalsRow()) {
|
||||
if ($attributes['totalsRowLabel']) {
|
||||
$column->setTotalsRowLabel((string) $attributes['totalsRowLabel']);
|
||||
}
|
||||
|
||||
if ($attributes['totalsRowFunction']) {
|
||||
$column->setTotalsRowFunction((string) $attributes['totalsRowFunction']);
|
||||
}
|
||||
}
|
||||
|
||||
if ($tableColumn->calculatedColumnFormula) {
|
||||
$column->setColumnFormula((string) $tableColumn->calculatedColumnFormula);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads TableStyle from xml.
|
||||
*/
|
||||
private function readTableStyle(Table $table, SimpleXMLElement $tableStyleInfoXml): void
|
||||
{
|
||||
$tableStyle = new TableStyle();
|
||||
$attributes = $tableStyleInfoXml->attributes();
|
||||
if ($attributes !== null) {
|
||||
$tableStyle->setTheme((string) $attributes['name']);
|
||||
$tableStyle->setShowRowStripes((string) $attributes['showRowStripes'] === '1');
|
||||
$tableStyle->setShowColumnStripes((string) $attributes['showColumnStripes'] === '1');
|
||||
$tableStyle->setShowFirstColumn((string) $attributes['showFirstColumn'] === '1');
|
||||
$tableStyle->setShowLastColumn((string) $attributes['showLastColumn'] === '1');
|
||||
}
|
||||
$table->setStyle($tableStyle);
|
||||
}
|
||||
}
|
||||
64
api/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/Theme.php
vendored
Normal file
64
api/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/Theme.php
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Reader\Xlsx;
|
||||
|
||||
class Theme
|
||||
{
|
||||
/**
|
||||
* Theme Name.
|
||||
*/
|
||||
private string $themeName;
|
||||
|
||||
/**
|
||||
* Colour Scheme Name.
|
||||
*/
|
||||
private string $colourSchemeName;
|
||||
|
||||
/**
|
||||
* Colour Map.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
private array $colourMap;
|
||||
|
||||
/**
|
||||
* Create a new Theme.
|
||||
*
|
||||
* @param string[] $colourMap
|
||||
*/
|
||||
public function __construct(string $themeName, string $colourSchemeName, array $colourMap)
|
||||
{
|
||||
// Initialise values
|
||||
$this->themeName = $themeName;
|
||||
$this->colourSchemeName = $colourSchemeName;
|
||||
$this->colourMap = $colourMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Not called by Reader, never accessible any other time.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function getThemeName(): string
|
||||
{
|
||||
return $this->themeName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Not called by Reader, never accessible any other time.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function getColourSchemeName(): string
|
||||
{
|
||||
return $this->colourSchemeName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get colour Map Value by Position.
|
||||
*/
|
||||
public function getColourByIndex(int $index): ?string
|
||||
{
|
||||
return $this->colourMap[$index] ?? null;
|
||||
}
|
||||
}
|
||||
141
api/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/WorkbookView.php
vendored
Normal file
141
api/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/WorkbookView.php
vendored
Normal file
@@ -0,0 +1,141 @@
|
||||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Reader\Xlsx;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
use SimpleXMLElement;
|
||||
|
||||
class WorkbookView
|
||||
{
|
||||
private Spreadsheet $spreadsheet;
|
||||
|
||||
public function __construct(Spreadsheet $spreadsheet)
|
||||
{
|
||||
$this->spreadsheet = $spreadsheet;
|
||||
}
|
||||
|
||||
public function viewSettings(SimpleXMLElement $xmlWorkbook, string $mainNS, array $mapSheetId, bool $readDataOnly): void
|
||||
{
|
||||
// Default active sheet index to the first loaded worksheet from the file
|
||||
$this->spreadsheet->setActiveSheetIndex(0);
|
||||
|
||||
$workbookView = $xmlWorkbook->children($mainNS)->bookViews->workbookView;
|
||||
if ($readDataOnly !== true && !empty($workbookView)) {
|
||||
$workbookViewAttributes = self::testSimpleXml(self::getAttributes($workbookView));
|
||||
// active sheet index
|
||||
$activeTab = (int) $workbookViewAttributes->activeTab; // refers to old sheet index
|
||||
// keep active sheet index if sheet is still loaded, else first sheet is set as the active worksheet
|
||||
if (isset($mapSheetId[$activeTab]) && $mapSheetId[$activeTab] !== null) {
|
||||
$this->spreadsheet->setActiveSheetIndex($mapSheetId[$activeTab]);
|
||||
}
|
||||
|
||||
$this->horizontalScroll($workbookViewAttributes);
|
||||
$this->verticalScroll($workbookViewAttributes);
|
||||
$this->sheetTabs($workbookViewAttributes);
|
||||
$this->minimized($workbookViewAttributes);
|
||||
$this->autoFilterDateGrouping($workbookViewAttributes);
|
||||
$this->firstSheet($workbookViewAttributes);
|
||||
$this->visibility($workbookViewAttributes);
|
||||
$this->tabRatio($workbookViewAttributes);
|
||||
}
|
||||
}
|
||||
|
||||
public static function testSimpleXml(mixed $value): SimpleXMLElement
|
||||
{
|
||||
return ($value instanceof SimpleXMLElement)
|
||||
? $value
|
||||
: new SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?><root></root>');
|
||||
}
|
||||
|
||||
public static function getAttributes(?SimpleXMLElement $value, string $ns = ''): SimpleXMLElement
|
||||
{
|
||||
return self::testSimpleXml($value === null ? $value : $value->attributes($ns));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an 'xsd:boolean' XML value to a PHP boolean value.
|
||||
* A valid 'xsd:boolean' XML value can be one of the following
|
||||
* four values: 'true', 'false', '1', '0'. It is case sensitive.
|
||||
*
|
||||
* Note that just doing '(bool) $xsdBoolean' is not safe,
|
||||
* since '(bool) "false"' returns true.
|
||||
*
|
||||
* @see https://www.w3.org/TR/xmlschema11-2/#boolean
|
||||
*
|
||||
* @param string $xsdBoolean An XML string value of type 'xsd:boolean'
|
||||
*
|
||||
* @return bool Boolean value
|
||||
*/
|
||||
private function castXsdBooleanToBool(string $xsdBoolean): bool
|
||||
{
|
||||
if ($xsdBoolean === 'false') {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (bool) $xsdBoolean;
|
||||
}
|
||||
|
||||
private function horizontalScroll(SimpleXMLElement $workbookViewAttributes): void
|
||||
{
|
||||
if (isset($workbookViewAttributes->showHorizontalScroll)) {
|
||||
$showHorizontalScroll = (string) $workbookViewAttributes->showHorizontalScroll;
|
||||
$this->spreadsheet->setShowHorizontalScroll($this->castXsdBooleanToBool($showHorizontalScroll));
|
||||
}
|
||||
}
|
||||
|
||||
private function verticalScroll(SimpleXMLElement $workbookViewAttributes): void
|
||||
{
|
||||
if (isset($workbookViewAttributes->showVerticalScroll)) {
|
||||
$showVerticalScroll = (string) $workbookViewAttributes->showVerticalScroll;
|
||||
$this->spreadsheet->setShowVerticalScroll($this->castXsdBooleanToBool($showVerticalScroll));
|
||||
}
|
||||
}
|
||||
|
||||
private function sheetTabs(SimpleXMLElement $workbookViewAttributes): void
|
||||
{
|
||||
if (isset($workbookViewAttributes->showSheetTabs)) {
|
||||
$showSheetTabs = (string) $workbookViewAttributes->showSheetTabs;
|
||||
$this->spreadsheet->setShowSheetTabs($this->castXsdBooleanToBool($showSheetTabs));
|
||||
}
|
||||
}
|
||||
|
||||
private function minimized(SimpleXMLElement $workbookViewAttributes): void
|
||||
{
|
||||
if (isset($workbookViewAttributes->minimized)) {
|
||||
$minimized = (string) $workbookViewAttributes->minimized;
|
||||
$this->spreadsheet->setMinimized($this->castXsdBooleanToBool($minimized));
|
||||
}
|
||||
}
|
||||
|
||||
private function autoFilterDateGrouping(SimpleXMLElement $workbookViewAttributes): void
|
||||
{
|
||||
if (isset($workbookViewAttributes->autoFilterDateGrouping)) {
|
||||
$autoFilterDateGrouping = (string) $workbookViewAttributes->autoFilterDateGrouping;
|
||||
$this->spreadsheet->setAutoFilterDateGrouping($this->castXsdBooleanToBool($autoFilterDateGrouping));
|
||||
}
|
||||
}
|
||||
|
||||
private function firstSheet(SimpleXMLElement $workbookViewAttributes): void
|
||||
{
|
||||
if (isset($workbookViewAttributes->firstSheet)) {
|
||||
$firstSheet = (string) $workbookViewAttributes->firstSheet;
|
||||
$this->spreadsheet->setFirstSheetIndex((int) $firstSheet);
|
||||
}
|
||||
}
|
||||
|
||||
private function visibility(SimpleXMLElement $workbookViewAttributes): void
|
||||
{
|
||||
if (isset($workbookViewAttributes->visibility)) {
|
||||
$visibility = (string) $workbookViewAttributes->visibility;
|
||||
$this->spreadsheet->setVisibility($visibility);
|
||||
}
|
||||
}
|
||||
|
||||
private function tabRatio(SimpleXMLElement $workbookViewAttributes): void
|
||||
{
|
||||
if (isset($workbookViewAttributes->tabRatio)) {
|
||||
$tabRatio = (string) $workbookViewAttributes->tabRatio;
|
||||
$this->spreadsheet->setTabRatio((int) $tabRatio);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user