Search in sources :

Example 11 with CellValueRecordInterface

use of org.apache.poi.hssf.record.CellValueRecordInterface in project poi by apache.

the class HSSFSheet method shiftRows.

/**
     * Shifts rows between startRow and endRow n number of rows.
     * If you use a negative number, it will shift rows up.
     * Code ensures that rows don't wrap around<p>
     * 
     * Additionally shifts merged regions that are completely defined in these
     * rows (ie. merged 2 cells on a row to be shifted).<p>
     * 
     * TODO Might want to add bounds checking here
     *
     * @param startRow               the row to start shifting
     * @param endRow                 the row to end shifting
     * @param n                      the number of rows to shift
     * @param copyRowHeight          whether to copy the row height during the shift
     * @param resetOriginalRowHeight whether to set the original row's height to the default
     * @param moveComments           whether to move comments at the same time as the cells they are attached to
     */
public void shiftRows(int startRow, int endRow, int n, boolean copyRowHeight, boolean resetOriginalRowHeight, boolean moveComments) {
    int s, inc;
    if (endRow < startRow) {
        throw new IllegalArgumentException("startRow must be less than or equal to endRow. To shift rows up, use n<0.");
    }
    if (n < 0) {
        s = startRow;
        inc = 1;
    } else if (n > 0) {
        s = endRow;
        inc = -1;
    } else {
        // Nothing to do
        return;
    }
    final RowShifter rowShifter = new HSSFRowShifter(this);
    // bounds or deleting them
    if (moveComments) {
        final HSSFPatriarch patriarch = createDrawingPatriarch();
        for (final HSSFShape shape : patriarch.getChildren()) {
            if (!(shape instanceof HSSFComment)) {
                continue;
            }
            final HSSFComment comment = (HSSFComment) shape;
            final int r = comment.getRow();
            if (startRow <= r && r <= endRow) {
                comment.setRow(clip(r + n));
            }
        }
    }
    // Shift Merged Regions
    rowShifter.shiftMergedRegions(startRow, endRow, n);
    // Shift Row Breaks
    _sheet.getPageSettings().shiftRowBreaks(startRow, endRow, n);
    // Delete overwritten hyperlinks
    final int firstOverwrittenRow = startRow + n;
    final int lastOverwrittenRow = endRow + n;
    for (HSSFHyperlink link : getHyperlinkList()) {
        // If hyperlink is fully contained in the rows that will be overwritten, delete the hyperlink
        final int firstRow = link.getFirstRow();
        final int lastRow = link.getLastRow();
        if (firstOverwrittenRow <= firstRow && firstRow <= lastOverwrittenRow && lastOverwrittenRow <= lastRow && lastRow <= lastOverwrittenRow) {
            removeHyperlink(link);
        }
    }
    for (int rowNum = s; rowNum >= startRow && rowNum <= endRow && rowNum >= 0 && rowNum < 65536; rowNum += inc) {
        HSSFRow row = getRow(rowNum);
        // if the row contains cells included in a multi-cell array formula
        if (row != null)
            notifyRowShifting(row);
        HSSFRow row2Replace = getRow(rowNum + n);
        if (row2Replace == null)
            row2Replace = createRow(rowNum + n);
        // Remove all the old cells from the row we'll
        //  be writing to, before we start overwriting
        //  any cells. This avoids issues with cells
        //  changing type, and records not being correctly
        //  overwritten
        row2Replace.removeAllCells();
        // Nothing to do for this row
        if (row == null)
            continue;
        // Fix up row heights if required
        if (copyRowHeight) {
            row2Replace.setHeight(row.getHeight());
        }
        if (resetOriginalRowHeight) {
            row.setHeight((short) 0xff);
        }
        //  the destination row
        for (Iterator<Cell> cells = row.cellIterator(); cells.hasNext(); ) {
            HSSFCell cell = (HSSFCell) cells.next();
            HSSFHyperlink link = cell.getHyperlink();
            row.removeCell(cell);
            CellValueRecordInterface cellRecord = cell.getCellValueRecord();
            cellRecord.setRow(rowNum + n);
            row2Replace.createCellFromRecord(cellRecord);
            _sheet.addValueRecord(rowNum + n, cellRecord);
            if (link != null) {
                link.setFirstRow(link.getFirstRow() + n);
                link.setLastRow(link.getLastRow() + n);
            }
        }
        // Now zap all the cells in the source row
        row.removeAllCells();
    }
    // Re-compute the first and last rows of the sheet as needed
    if (n > 0) {
        // Rows are moving down
        if (startRow == _firstrow) {
            // Need to walk forward to find the first non-blank row
            _firstrow = Math.max(startRow + n, 0);
            for (int i = startRow + 1; i < startRow + n; i++) {
                if (getRow(i) != null) {
                    _firstrow = i;
                    break;
                }
            }
        }
        if (endRow + n > _lastrow) {
            _lastrow = Math.min(endRow + n, SpreadsheetVersion.EXCEL97.getLastRowIndex());
        }
    } else {
        // Rows are moving up
        if (startRow + n < _firstrow) {
            _firstrow = Math.max(startRow + n, 0);
        }
        if (endRow == _lastrow) {
            // Need to walk backward to find the last non-blank row
            // NOTE: n is always negative here
            _lastrow = Math.min(endRow + n, SpreadsheetVersion.EXCEL97.getLastRowIndex());
            for (int i = endRow - 1; i > endRow + n; i--) {
                if (getRow(i) != null) {
                    _lastrow = i;
                    break;
                }
            }
        }
    }
    // Update any formulas on this sheet that point to
    //  rows which have been moved
    int sheetIndex = _workbook.getSheetIndex(this);
    String sheetName = _workbook.getSheetName(sheetIndex);
    short externSheetIndex = _book.checkExternSheet(sheetIndex);
    FormulaShifter shifter = FormulaShifter.createForRowShift(externSheetIndex, sheetName, startRow, endRow, n, SpreadsheetVersion.EXCEL97);
    _sheet.updateFormulasAfterCellShift(shifter, externSheetIndex);
    int nSheets = _workbook.getNumberOfSheets();
    for (int i = 0; i < nSheets; i++) {
        InternalSheet otherSheet = _workbook.getSheetAt(i).getSheet();
        if (otherSheet == this._sheet) {
            continue;
        }
        short otherExtSheetIx = _book.checkExternSheet(i);
        otherSheet.updateFormulasAfterCellShift(shifter, otherExtSheetIx);
    }
    _workbook.getWorkbook().updateNamesAfterCellShift(shifter);
}
Also used : HSSFRowShifter(org.apache.poi.hssf.usermodel.helpers.HSSFRowShifter) CellValueRecordInterface(org.apache.poi.hssf.record.CellValueRecordInterface) RowShifter(org.apache.poi.ss.usermodel.helpers.RowShifter) HSSFRowShifter(org.apache.poi.hssf.usermodel.helpers.HSSFRowShifter) FormulaShifter(org.apache.poi.ss.formula.FormulaShifter) InternalSheet(org.apache.poi.hssf.model.InternalSheet) Cell(org.apache.poi.ss.usermodel.Cell)

Example 12 with CellValueRecordInterface

use of org.apache.poi.hssf.record.CellValueRecordInterface in project poi by apache.

the class ValueRecordsAggregate method countBlanks.

/**
	 * @return the number of <em>consecutive</em> {@link BlankRecord}s in the specified row
	 * starting from startIx.
	 */
private static int countBlanks(CellValueRecordInterface[] rowCellValues, int startIx) {
    int i = startIx;
    while (i < rowCellValues.length) {
        CellValueRecordInterface cvr = rowCellValues[i];
        if (!(cvr instanceof BlankRecord)) {
            break;
        }
        i++;
    }
    return i - startIx;
}
Also used : MulBlankRecord(org.apache.poi.hssf.record.MulBlankRecord) BlankRecord(org.apache.poi.hssf.record.BlankRecord) CellValueRecordInterface(org.apache.poi.hssf.record.CellValueRecordInterface)

Example 13 with CellValueRecordInterface

use of org.apache.poi.hssf.record.CellValueRecordInterface in project poi by apache.

the class ValueRecordsAggregate method updateFormulasAfterRowShift.

public void updateFormulasAfterRowShift(FormulaShifter shifter, int currentExternSheetIndex) {
    for (int i = 0; i < records.length; i++) {
        CellValueRecordInterface[] rowCells = records[i];
        if (rowCells == null) {
            continue;
        }
        for (int j = 0; j < rowCells.length; j++) {
            CellValueRecordInterface cell = rowCells[j];
            if (cell instanceof FormulaRecordAggregate) {
                FormulaRecordAggregate fra = (FormulaRecordAggregate) cell;
                // needs clone() inside this getter?
                Ptg[] ptgs = fra.getFormulaTokens();
                // needs clone() inside this getter?
                Ptg[] ptgs2 = ((FormulaRecordAggregate) cell).getFormulaRecord().getParsedExpression();
                if (shifter.adjustFormula(ptgs, currentExternSheetIndex)) {
                    fra.setParsedExpression(ptgs);
                }
            }
        }
    }
}
Also used : Ptg(org.apache.poi.ss.formula.ptg.Ptg) CellValueRecordInterface(org.apache.poi.hssf.record.CellValueRecordInterface)

Example 14 with CellValueRecordInterface

use of org.apache.poi.hssf.record.CellValueRecordInterface in project poi by apache.

the class TestSheet method testRowValueAggregatesOrder_bug45145.

/**
	 * Prior to bug 45145 <tt>RowRecordsAggregate</tt> and <tt>ValueRecordsAggregate</tt> could
	 * sometimes occur in reverse order.  This test reproduces one of those situations and makes
	 * sure that RRA comes before VRA.<br/>
	 *
	 * The code here represents a normal POI use case where a spreadsheet is created from scratch.
	 */
@Test
public void testRowValueAggregatesOrder_bug45145() {
    InternalSheet sheet = InternalSheet.createSheet();
    RowRecord rr = new RowRecord(5);
    sheet.addRow(rr);
    CellValueRecordInterface cvr = new BlankRecord();
    cvr.setColumn((short) 0);
    cvr.setRow(5);
    sheet.addValueRecord(5, cvr);
    int dbCellRecordPos = getDbCellRecordPos(sheet);
    if (dbCellRecordPos == 252) {
        // DBCELL record pos is calculated wrong if VRA comes before RRA
        throw new AssertionFailedError("Identified  bug 45145");
    }
    //		if (false) {
    //			// make sure that RRA and VRA are in the right place
    //			// (Aug 2008) since the VRA is now part of the RRA, there is much less chance that
    //			// they could get out of order. Still, one could write serialize the sheet here,
    //			// and read back with EventRecordFactory to make sure...
    //		}
    assertEquals(242, dbCellRecordPos);
}
Also used : MulBlankRecord(org.apache.poi.hssf.record.MulBlankRecord) BlankRecord(org.apache.poi.hssf.record.BlankRecord) CellValueRecordInterface(org.apache.poi.hssf.record.CellValueRecordInterface) RowRecord(org.apache.poi.hssf.record.RowRecord) AssertionFailedError(junit.framework.AssertionFailedError) Test(org.junit.Test)

Aggregations

CellValueRecordInterface (org.apache.poi.hssf.record.CellValueRecordInterface)14 MulBlankRecord (org.apache.poi.hssf.record.MulBlankRecord)6 BlankRecord (org.apache.poi.hssf.record.BlankRecord)5 Test (org.junit.Test)5 Record (org.apache.poi.hssf.record.Record)4 RowRecord (org.apache.poi.hssf.record.RowRecord)4 FormulaRecord (org.apache.poi.hssf.record.FormulaRecord)3 FormulaRecordAggregate (org.apache.poi.hssf.record.aggregates.FormulaRecordAggregate)3 DimensionsRecord (org.apache.poi.hssf.record.DimensionsRecord)2 StringRecord (org.apache.poi.hssf.record.StringRecord)2 WindowTwoRecord (org.apache.poi.hssf.record.WindowTwoRecord)2 Cell (org.apache.poi.ss.usermodel.Cell)2 ArrayList (java.util.ArrayList)1 AssertionFailedError (junit.framework.AssertionFailedError)1 EscherRecord (org.apache.poi.ddf.EscherRecord)1 LastCellOfRowDummyRecord (org.apache.poi.hssf.eventusermodel.dummyrecord.LastCellOfRowDummyRecord)1 MissingCellDummyRecord (org.apache.poi.hssf.eventusermodel.dummyrecord.MissingCellDummyRecord)1 MissingRowDummyRecord (org.apache.poi.hssf.eventusermodel.dummyrecord.MissingRowDummyRecord)1 InternalSheet (org.apache.poi.hssf.model.InternalSheet)1 AutoFilterInfoRecord (org.apache.poi.hssf.record.AutoFilterInfoRecord)1