/** * @param rs record stream with all {@link SharedFormulaRecord} {@link ArrayRecord}, {@link * TableRecord} {@link MergeCellsRecord} Records removed * @param svm an initialised {@link SharedValueManager} (from the shared formula, array and table * records of the current sheet). Never <code>null</code>. */ public RowRecordsAggregate(RecordStream rs, SharedValueManager svm) { this(svm); while (rs.hasNext()) { Record rec = rs.getNext(); switch (rec.getSid()) { case RowRecord.sid: insertRow((RowRecord) rec); continue; case DConRefRecord.sid: addUnknownRecord(rec); continue; case DBCellRecord.sid: // end of 'Row Block'. Should only occur after cell records // ignore DBCELL records because POI generates them upon re-serialization continue; } if (rec instanceof UnknownRecord) { // might need to keep track of where exactly these belong addUnknownRecord(rec); while (rs.peekNextSid() == ContinueRecord.sid) { addUnknownRecord(rs.getNext()); } continue; } if (rec instanceof MulBlankRecord) { _valuesAgg.addMultipleBlanks((MulBlankRecord) rec); continue; } if (!(rec instanceof CellValueRecordInterface)) { throw new RuntimeException("Unexpected record type (" + rec.getClass().getName() + ")"); } _valuesAgg.construct((CellValueRecordInterface) rec, rs, svm); } }
public DimensionsRecord createDimensions() { DimensionsRecord result = new DimensionsRecord(); result.setFirstRow(_firstrow); result.setLastRow(_lastrow); result.setFirstCol((short) _valuesAgg.getFirstCellNum()); result.setLastCol((short) _valuesAgg.getLastCellNum()); return result; }
public IndexRecord createIndexRecord(int indexRecordOffset, int sizeOfInitialSheetRecords) { IndexRecord result = new IndexRecord(); result.setFirstRow(_firstrow); result.setLastRowAdd1(_lastrow + 1); // Calculate the size of the records from the end of the BOF // and up to the RowRecordsAggregate... // Add the references to the DBCells in the IndexRecord (one for each block) // Note: The offsets are relative to the Workbook BOF. Assume that this is // 0 for now..... int blockCount = getRowBlockCount(); // Calculate the size of this IndexRecord int indexRecSize = IndexRecord.getRecordSizeForBlockCount(blockCount); int currentOffset = indexRecordOffset + indexRecSize + sizeOfInitialSheetRecords; for (int block = 0; block < blockCount; block++) { // each row-block has a DBCELL record. // The offset of each DBCELL record needs to be updated in the INDEX record // account for row records in this row-block currentOffset += getRowBlockSize(block); // account for cell value records after those currentOffset += _valuesAgg.getRowCellBlockSize( getStartRowNumberForBlock(block), getEndRowNumberForBlock(block)); // currentOffset is now the location of the DBCELL record for this row-block result.addDbcell(currentOffset); // Add space required to write the DBCELL record (whose reference was just added). currentOffset += (8 + (getRowCountForBlock(block) * 2)); } return result; }
@Override public void visitContainedRecords(RecordVisitor rv) { PositionTrackingVisitor stv = new PositionTrackingVisitor(rv, 0); // DBCells are serialized before row records. final int blockCount = getRowBlockCount(); for (int blockIndex = 0; blockIndex < blockCount; blockIndex++) { // Serialize a block of rows. // Hold onto the position of the first row in the block int pos = 0; // Hold onto the size of this block that was serialized final int rowBlockSize = visitRowRecordsForBlock(blockIndex, rv); pos += rowBlockSize; // Serialize a block of cells for those rows final int startRowNumber = getStartRowNumberForBlock(blockIndex); final int endRowNumber = getEndRowNumberForBlock(blockIndex); DBCellRecord.Builder dbcrBuilder = new DBCellRecord.Builder(); // Note: Cell references start from the second row... int cellRefOffset = (rowBlockSize - RowRecord.ENCODED_SIZE); for (int row = startRowNumber; row <= endRowNumber; row++) { if (_valuesAgg.rowHasCells(row)) { stv.setPosition(0); _valuesAgg.visitCellsForRow(row, stv); int rowCellSize = stv.getPosition(); pos += rowCellSize; // Add the offset to the first cell for the row into the // DBCellRecord. dbcrBuilder.addCellOffset(cellRefOffset); cellRefOffset = rowCellSize; } } // Calculate Offset from the start of a DBCellRecord to the first Row rv.visitRecord(dbcrBuilder.build(pos)); } for (int i = 0; i < _unknownRecords.size(); i++) { // Potentially breaking the file here since we don't know exactly where to write these records rv.visitRecord(_unknownRecords.get(i)); } }
public void removeRow(RowRecord row) { int rowIndex = row.getRowNumber(); _valuesAgg.removeAllCellsValuesForRow(rowIndex); Integer key = Integer.valueOf(rowIndex); RowRecord rr = _rowRecords.remove(key); if (rr == null) { throw new RuntimeException("Invalid row index (" + key.intValue() + ")"); } if (row != rr) { _rowRecords.put(key, rr); throw new RuntimeException("Attempt to remove row that does not belong to this sheet"); } // Clear the cached values _rowRecordValues = null; }
public void updateFormulasAfterRowShift( FormulaShifter formulaShifter, int currentExternSheetIndex) { _valuesAgg.updateFormulasAfterRowShift(formulaShifter, currentExternSheetIndex); }
public void removeCell(CellValueRecordInterface cvRec) { if (cvRec instanceof FormulaRecordAggregate) { ((FormulaRecordAggregate) cvRec).notifyFormulaChanging(); } _valuesAgg.removeCell(cvRec); }
public void insertCell(CellValueRecordInterface cvRec) { _valuesAgg.insertCell(cvRec); }
/** @deprecated use {@link #getCellValueIterator()} instead */ public CellValueRecordInterface[] getValueRecords() { return _valuesAgg.getValueRecords(); }
/** Returns an iterator for the cell values */ public Iterator<CellValueRecordInterface> getCellValueIterator() { return _valuesAgg.iterator(); }