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
This commit is contained in:
Nick Burch 2008-07-10 17:52:33 +00:00
parent 00c3543d99
commit f6730d9a3a
4 changed files with 81 additions and 33 deletions

View File

@ -37,6 +37,7 @@
<!-- Don't forget to update status.xml too! -->
<release version="3.1.1-alpha1" date="2008-??-??">
<action dev="POI-DEVELOPERS" type="fix">45373 - Improve the performance of HSSFSheet.shiftRows</action>
<action dev="POI-DEVELOPERS" type="fix">45367 - Fixed bug when last row removed from sheet is row zero</action>
<action dev="POI-DEVELOPERS" type="fix">45348 - Tweaks to RVA formula logic</action>
<action dev="POI-DEVELOPERS" type="fix">45354 - Fixed recognition of named ranges within formulas</action>

View File

@ -34,6 +34,7 @@
<!-- Don't forget to update changes.xml too! -->
<changes>
<release version="3.1.1-alpha1" date="2008-??-??">
<action dev="POI-DEVELOPERS" type="fix">45373 - Improve the performance of HSSFSheet.shiftRows</action>
<action dev="POI-DEVELOPERS" type="fix">45367 - Fixed bug when last row removed from sheet is row zero</action>
<action dev="POI-DEVELOPERS" type="fix">45348 - Tweaks to RVA formula logic</action>
<action dev="POI-DEVELOPERS" type="fix">45354 - Fixed recognition of named ranges within formulas</action>

View File

@ -169,6 +169,19 @@ public final class HSSFRow implements Comparable {
}
}
/**
* Removes all the cells from the row, and their
* records too.
*/
protected void removeAllCells() {
for(int i=0; i<cells.length; i++) {
if(cells[i] != null) {
removeCell(cells[i], true);
}
}
cells=new HSSFCell[INITIAL_CAPACITY];
}
/**
* create a high level HSSFCell object from an existing low level record. Should
* only be called from HSSFSheet or HSSFRow itself.

View File

@ -1207,6 +1207,28 @@ public final class HSSFSheet {
* @param resetOriginalRowHeight whether to set the original row's height to the default
*/
public void shiftRows( int startRow, int endRow, int n, boolean copyRowHeight, boolean resetOriginalRowHeight)
{
shiftRows(startRow, endRow, n, copyRowHeight, resetOriginalRowHeight, true);
}
/**
* 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, e, inc;
if ( n < 0 )
@ -1234,45 +1256,56 @@ public final class HSSFSheet {
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();
// 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 );
}
// 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
else {
// 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();
// Fix up row heights if required
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 )
{
// 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 if exist (can exist even if cell is null)
// 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 );
if ( startRow == firstrow || startRow + n < firstrow ) firstrow = Math.max( startRow + n, 0 );