芝麻web文件管理V1.00
编辑当前文件:/home/qrafawbu/kwesioben.com/paymoney/vendor/openspout/openspout/src/Reader/ODS/SheetIterator.php
*/ final class SheetIterator implements SheetIteratorInterface { public const CONTENT_XML_FILE_PATH = 'content.xml'; public const XML_STYLE_NAMESPACE = 'urn:oasis:names:tc:opendocument:xmlns:style:1.0'; /** * Definition of XML nodes name and attribute used to parse sheet data. */ public const XML_NODE_AUTOMATIC_STYLES = 'office:automatic-styles'; public const XML_NODE_STYLE_TABLE_PROPERTIES = 'table-properties'; public const XML_NODE_TABLE = 'table:table'; public const XML_ATTRIBUTE_STYLE_NAME = 'style:name'; public const XML_ATTRIBUTE_TABLE_NAME = 'table:name'; public const XML_ATTRIBUTE_TABLE_STYLE_NAME = 'table:style-name'; public const XML_ATTRIBUTE_TABLE_DISPLAY = 'table:display'; /** @var string Path of the file to be read */ private string $filePath; private Options $options; /** @var XMLReader The XMLReader object that will help read sheet's XML data */ private XMLReader $xmlReader; /** @var ODS Used to unescape XML data */ private ODS $escaper; /** @var bool Whether there are still at least a sheet to be read */ private bool $hasFoundSheet; /** @var int The index of the sheet being read (zero-based) */ private int $currentSheetIndex; /** @var string The name of the sheet that was defined as active */ private ?string $activeSheetName; /** @var array
Associative array [STYLE_NAME] => [IS_SHEET_VISIBLE] */ private array $sheetsVisibility; public function __construct( string $filePath, Options $options, ODS $escaper, SettingsHelper $settingsHelper ) { $this->filePath = $filePath; $this->options = $options; $this->xmlReader = new XMLReader(); $this->escaper = $escaper; $this->activeSheetName = $settingsHelper->getActiveSheetName($filePath); } /** * Rewind the Iterator to the first element. * * @see http://php.net/manual/en/iterator.rewind.php * * @throws \OpenSpout\Common\Exception\IOException If unable to open the XML file containing sheets' data */ public function rewind(): void { $this->xmlReader->close(); if (false === $this->xmlReader->openFileInZip($this->filePath, self::CONTENT_XML_FILE_PATH)) { $contentXmlFilePath = $this->filePath.'#'.self::CONTENT_XML_FILE_PATH; throw new IOException("Could not open \"{$contentXmlFilePath}\"."); } try { $this->sheetsVisibility = $this->readSheetsVisibility(); $this->hasFoundSheet = $this->xmlReader->readUntilNodeFound(self::XML_NODE_TABLE); } catch (XMLProcessingException $exception) { throw new IOException("The content.xml file is invalid and cannot be read. [{$exception->getMessage()}]"); } $this->currentSheetIndex = 0; } /** * Checks if current position is valid. * * @see http://php.net/manual/en/iterator.valid.php */ public function valid(): bool { $valid = $this->hasFoundSheet; if (!$valid) { $this->xmlReader->close(); } return $valid; } /** * Move forward to next element. * * @see http://php.net/manual/en/iterator.next.php */ public function next(): void { $this->hasFoundSheet = $this->xmlReader->readUntilNodeFound(self::XML_NODE_TABLE); if ($this->hasFoundSheet) { ++$this->currentSheetIndex; } } /** * Return the current element. * * @see http://php.net/manual/en/iterator.current.php */ public function current(): Sheet { $escapedSheetName = $this->xmlReader->getAttribute(self::XML_ATTRIBUTE_TABLE_NAME); \assert(null !== $escapedSheetName); $sheetName = $this->escaper->unescape($escapedSheetName); $isSheetActive = $this->isSheetActive($sheetName, $this->currentSheetIndex, $this->activeSheetName); $sheetStyleName = $this->xmlReader->getAttribute(self::XML_ATTRIBUTE_TABLE_STYLE_NAME); \assert(null !== $sheetStyleName); $isSheetVisible = $this->isSheetVisible($sheetStyleName); return new Sheet( new RowIterator( $this->options, new CellValueFormatter($this->options->SHOULD_FORMAT_DATES, new ODS()), new XMLProcessor($this->xmlReader) ), $this->currentSheetIndex, $sheetName, $isSheetActive, $isSheetVisible ); } /** * Return the key of the current element. * * @see http://php.net/manual/en/iterator.key.php */ public function key(): int { return $this->currentSheetIndex + 1; } /** * Extracts the visibility of the sheets. * * @return array
Associative array [STYLE_NAME] => [IS_SHEET_VISIBLE] */ private function readSheetsVisibility(): array { $sheetsVisibility = []; $this->xmlReader->readUntilNodeFound(self::XML_NODE_AUTOMATIC_STYLES); $automaticStylesNode = $this->xmlReader->expand(); \assert($automaticStylesNode instanceof DOMElement); $tableStyleNodes = $automaticStylesNode->getElementsByTagNameNS(self::XML_STYLE_NAMESPACE, self::XML_NODE_STYLE_TABLE_PROPERTIES); foreach ($tableStyleNodes as $tableStyleNode) { $isSheetVisible = ('false' !== $tableStyleNode->getAttribute(self::XML_ATTRIBUTE_TABLE_DISPLAY)); $parentStyleNode = $tableStyleNode->parentNode; \assert($parentStyleNode instanceof DOMElement); $styleName = $parentStyleNode->getAttribute(self::XML_ATTRIBUTE_STYLE_NAME); $sheetsVisibility[$styleName] = $isSheetVisible; } return $sheetsVisibility; } /** * Returns whether the current sheet was defined as the active one. * * @param string $sheetName Name of the current sheet * @param int $sheetIndex Index of the current sheet * @param null|string $activeSheetName Name of the sheet that was defined as active or NULL if none defined * * @return bool Whether the current sheet was defined as the active one */ private function isSheetActive(string $sheetName, int $sheetIndex, ?string $activeSheetName): bool { // The given sheet is active if its name matches the defined active sheet's name // or if no information about the active sheet was found, it defaults to the first sheet. return (null === $activeSheetName && 0 === $sheetIndex) || ($activeSheetName === $sheetName) ; } /** * Returns whether the current sheet is visible. * * @param string $sheetStyleName Name of the sheet style * * @return bool Whether the current sheet is visible */ private function isSheetVisible(string $sheetStyleName): bool { return $this->sheetsVisibility[$sheetStyleName] ?? true; } }