From f6730d9a3ab11107f3a46f02a4f1b4e96077ab02 Mon Sep 17 00:00:00 2001 From: Nick Burch Date: Thu, 10 Jul 2008 17:52:33 +0000 Subject: [PATCH] Apply some changes inspired by bug # 45373, which improve the performance of HSSFSheet.shiftRows git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@675661 13f79535-47bb-0310-9956-ffa450edef68 --- src/documentation/content/xdocs/changes.xml | 1 + src/documentation/content/xdocs/status.xml | 1 + .../apache/poi/hssf/usermodel/HSSFRow.java | 13 +++ .../apache/poi/hssf/usermodel/HSSFSheet.java | 99 ++++++++++++------- 4 files changed, 81 insertions(+), 33 deletions(-) diff --git a/src/documentation/content/xdocs/changes.xml b/src/documentation/content/xdocs/changes.xml index 6756dcc36..16a82aa3a 100644 --- a/src/documentation/content/xdocs/changes.xml +++ b/src/documentation/content/xdocs/changes.xml @@ -37,6 +37,7 @@ + 45373 - Improve the performance of HSSFSheet.shiftRows 45367 - Fixed bug when last row removed from sheet is row zero 45348 - Tweaks to RVA formula logic 45354 - Fixed recognition of named ranges within formulas diff --git a/src/documentation/content/xdocs/status.xml b/src/documentation/content/xdocs/status.xml index bbf536e73..7143b98d7 100644 --- a/src/documentation/content/xdocs/status.xml +++ b/src/documentation/content/xdocs/status.xml @@ -34,6 +34,7 @@ + 45373 - Improve the performance of HSSFSheet.shiftRows 45367 - Fixed bug when last row removed from sheet is row zero 45348 - Tweaks to RVA formula logic 45354 - Fixed recognition of named ranges within formulas diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFRow.java b/src/java/org/apache/poi/hssf/usermodel/HSSFRow.java index 0a2d6ecbb..e7de1df5d 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFRow.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFRow.java @@ -168,6 +168,19 @@ public final class HSSFRow implements Comparable { row.setFirstCol(findFirstCell(row.getFirstCol())); } } + + /** + * Removes all the cells from the row, and their + * records too. + */ + protected void removeAllCells() { + for(int i=0; i + * Additionally shifts merged regions that are completely defined in these + * rows (ie. merged 2 cells on a row to be shifted). + *

+ * 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, e, inc; if ( n < 0 ) @@ -1233,44 +1255,55 @@ public final class HSSFSheet { row2Replace = createRow( rowNum + n ); HSSFCell cell; + + // Remove all the old cells from the row we'll + // be writing too, before we start overwriting + // any cells. This avoids issues with cells + // changing type, and records not being correctly + // overwritten + row2Replace.removeAllCells(); + // If this row doesn't exist, nothing needs to + // be done for the now empty destination row + if (row == null) continue; // Nothing to do for this row + // Fetch the first and last columns of the + // row now, so we still have them to hand + // once we start removing cells + short firstCol = row.getFirstCellNum(); + short lastCol = row.getLastCellNum(); - - // Removes the cells before over writting them. - for ( short col = row2Replace.getFirstCellNum(); col <= row2Replace.getLastCellNum(); col++ ) - { - cell = row2Replace.getCell( col ); - if ( cell != null ) - row2Replace.removeCell( cell ); + // Fix up row heights if required + if (copyRowHeight) { + row2Replace.setHeight(row.getHeight()); + } + if (resetOriginalRowHeight) { + row.setHeight((short)0xff); } - if (row == null) continue; // Nothing to do for this row - else { - if (copyRowHeight) { - row2Replace.setHeight(row.getHeight()); - } - if (resetOriginalRowHeight) { - row.setHeight((short)0xff); - } - } - for ( short col = row.getFirstCellNum(); col <= row.getLastCellNum(); col++ ) - { - cell = row.getCell( col ); - if ( cell != null ) - { - row.removeCell( cell ); - CellValueRecordInterface cellRecord = cell.getCellValueRecord(); - cellRecord.setRow( rowNum + n ); - row2Replace.createCellFromRecord( cellRecord ); - sheet.addValueRecord( rowNum + n, cellRecord ); - } - - // move comments if exist (can exist even if cell is null) - HSSFComment comment = getCellComment(rowNum, col); - if (comment != null) { - comment.setRow(rowNum + n); - } + // Copy each cell from the source row to + // the destination row + for(Iterator cells = row.cellIterator(); cells.hasNext(); ) { + cell = (HSSFCell)cells.next(); + row.removeCell( cell ); + CellValueRecordInterface cellRecord = cell.getCellValueRecord(); + cellRecord.setRow( rowNum + n ); + row2Replace.createCellFromRecord( cellRecord ); + sheet.addValueRecord( rowNum + n, cellRecord ); + } + // Now zap all the cells in the source row + row.removeAllCells(); + + // Move comments from the source row to the + // destination row. Note that comments can + // exist for cells which are null + if(moveComments) { + for( short col = firstCol; col <= lastCol; col++ ) { + HSSFComment comment = getCellComment(rowNum, col); + if (comment != null) { + comment.setRow(rowNum + n); + } + } } } if ( endRow == lastrow || endRow + n > lastrow ) lastrow = Math.min( endRow + n, 65535 );