/** * Move forward to next element. Empty rows will be skipped. * @link http://php.net/manual/en/iterator.next.php * * @return void * @throws \Box\Spout\Reader\Exception\SharedStringNotFoundException If a shared string was not found * @throws \Box\Spout\Common\Exception\IOException If unable to read the sheet data XML */ public function next() { $rowData = []; try { while ($this->xmlReader->read()) { if ($this->xmlReader->isPositionedOnStartingNode(self::XML_NODE_DIMENSION)) { // Read dimensions of the sheet $dimensionRef = $this->xmlReader->getAttribute(self::XML_ATTRIBUTE_REF); // returns 'A1:M13' for instance (or 'A1' for empty sheet) if (preg_match('/[A-Z\\d]+:([A-Z\\d]+)/', $dimensionRef, $matches)) { $lastCellIndex = $matches[1]; $this->numColumns = CellHelper::getColumnIndexFromCellIndex($lastCellIndex) + 1; } } else { if ($this->xmlReader->isPositionedOnStartingNode(self::XML_NODE_ROW)) { // Start of the row description // Reset index of the last processed column $this->lastColumnIndexProcessed = -1; // Read spans info if present $numberOfColumnsForRow = $this->numColumns; $spans = $this->xmlReader->getAttribute(self::XML_ATTRIBUTE_SPANS); // returns '1:5' for instance if ($spans) { list(, $numberOfColumnsForRow) = explode(':', $spans); $numberOfColumnsForRow = intval($numberOfColumnsForRow); } $rowData = $numberOfColumnsForRow !== 0 ? array_fill(0, $numberOfColumnsForRow, '') : []; } else { if ($this->xmlReader->isPositionedOnStartingNode(self::XML_NODE_CELL)) { // Start of a cell description $currentColumnIndex = $this->getCellIndex($this->xmlReader); $node = $this->xmlReader->expand(); $rowData[$currentColumnIndex] = $this->getCellValue($node); $this->lastColumnIndexProcessed = $currentColumnIndex; } else { if ($this->xmlReader->isPositionedOnEndingNode(self::XML_NODE_ROW)) { // End of the row description // If needed, we fill the empty cells $rowData = $this->numColumns !== 0 ? $rowData : CellHelper::fillMissingArrayIndexes($rowData); $this->numReadRows++; break; } else { if ($this->xmlReader->isPositionedOnEndingNode(self::XML_NODE_WORKSHEET)) { // The closing "</worksheet>" marks the end of the file $this->hasReachedEndOfFile = true; break; } } } } } } } catch (XMLProcessingException $exception) { throw new IOException("The {$this->sheetDataXMLFilePath} file cannot be read. [{$exception->getMessage()}]"); } $this->rowDataBuffer = $rowData; }
/** * @return int A return code that indicates what action should the processor take next */ protected function processRowEndingNode() { // if the fetched row is empty and we don't want to preserve it.., if (!$this->shouldPreserveEmptyRows && $this->isEmptyRow($this->currentlyProcessedRowData)) { // ... skip it return XMLProcessor::PROCESSING_CONTINUE; } $this->numReadRows++; // If needed, we fill the empty cells if ($this->numColumns === 0) { $this->currentlyProcessedRowData = CellHelper::fillMissingArrayIndexes($this->currentlyProcessedRowData); } // at this point, we have all the data we need for the row // so that we can populate the buffer return XMLProcessor::PROCESSING_STOP; }