From 63bc348d04769e99014a62f526bbd1f28d461b9e Mon Sep 17 00:00:00 2001 From: Nick Burch Date: Tue, 14 Dec 2010 06:41:08 +0000 Subject: [PATCH] Fix bug #50416 - Correct shifting of the first or last row in a sheet by multiple rows git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1048951 13f79535-47bb-0310-9956-ffa450edef68 --- src/documentation/content/xdocs/status.xml | 1 + .../apache/poi/hssf/usermodel/HSSFSheet.java | 41 ++++++++++++-- .../apache/poi/hssf/usermodel/TestBugs.java | 54 +++++++++++++++++++ 3 files changed, 93 insertions(+), 3 deletions(-) diff --git a/src/documentation/content/xdocs/status.xml b/src/documentation/content/xdocs/status.xml index 05d4d10bd..5eb09cae6 100644 --- a/src/documentation/content/xdocs/status.xml +++ b/src/documentation/content/xdocs/status.xml @@ -34,6 +34,7 @@ + 50416 - Correct shifting of the first or last row in a sheet by multiple rows 50440 - Support evaluating formulas with newlines in them, which XSSF may have (but HSSF may not) Added inline string support to XSSF EventModel 50246 - Properly position GutsRecord when reading HSSF workbooks diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java b/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java index 9a772e15d..679bfdd8d 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java @@ -1221,10 +1221,14 @@ public final class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet { if (n < 0) { s = startRow; inc = 1; - } else { + } else if (n > 0) { s = endRow; inc = -1; + } else { + // Nothing to do + return; } + NoteRecord[] noteRecs; if (moveComments) { noteRecs = _sheet.getNoteRecords(); @@ -1302,8 +1306,39 @@ public final class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet { } } } - if ( endRow == _lastrow || endRow + n > _lastrow ) _lastrow = Math.min( endRow + n, SpreadsheetVersion.EXCEL97.getLastRowIndex() ); - if ( startRow == _firstrow || startRow + n < _firstrow ) _firstrow = Math.max( startRow + n, 0 ); + + // 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 + _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 diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java b/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java index cb7cdbd1f..09ff05c0c 100644 --- a/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java @@ -1899,4 +1899,58 @@ if(1==2) { HSSFWorkbook wb = openSample("50426.xls"); writeOutAndReadBack(wb); } + + /** + * Last row number when shifting rows + */ + public void test50416LastRowNumber() { + // Create the workbook with 1 sheet which contains 3 rows + HSSFWorkbook workbook = new HSSFWorkbook(); + Sheet sheet = workbook.createSheet("Bug50416"); + Row row1 = sheet.createRow(0); + Cell cellA_1 = row1.createCell(0,Cell.CELL_TYPE_STRING); + cellA_1.setCellValue("Cell A,1"); + Row row2 = sheet.createRow(1); + Cell cellA_2 = row2.createCell(0,Cell.CELL_TYPE_STRING); + cellA_2.setCellValue("Cell A,2"); + Row row3 = sheet.createRow(2); + Cell cellA_3 = row3.createCell(0,Cell.CELL_TYPE_STRING); + cellA_3.setCellValue("Cell A,3"); + + // Test the last Row number it currently correct + assertEquals(2, sheet.getLastRowNum()); + + // Shift the first row to the end + sheet.shiftRows(0, 0, 3); + assertEquals(3, sheet.getLastRowNum()); + assertEquals(-1, sheet.getRow(0).getLastCellNum()); + assertEquals("Cell A,2", sheet.getRow(1).getCell(0).getStringCellValue()); + assertEquals("Cell A,3", sheet.getRow(2).getCell(0).getStringCellValue()); + assertEquals("Cell A,1", sheet.getRow(3).getCell(0).getStringCellValue()); + + // Shift the 2nd row up to the first one + sheet.shiftRows(1, 1, -1); + assertEquals(3, sheet.getLastRowNum()); + assertEquals("Cell A,2", sheet.getRow(0).getCell(0).getStringCellValue()); + assertEquals(-1, sheet.getRow(1).getLastCellNum()); + assertEquals("Cell A,3", sheet.getRow(2).getCell(0).getStringCellValue()); + assertEquals("Cell A,1", sheet.getRow(3).getCell(0).getStringCellValue()); + + // Shift the 4th row up into the gap in the 3rd row + sheet.shiftRows(3, 3, -2); + assertEquals(2, sheet.getLastRowNum()); + assertEquals("Cell A,2", sheet.getRow(0).getCell(0).getStringCellValue()); + assertEquals("Cell A,1", sheet.getRow(1).getCell(0).getStringCellValue()); + assertEquals("Cell A,3", sheet.getRow(2).getCell(0).getStringCellValue()); + assertEquals(-1, sheet.getRow(3).getLastCellNum()); + + // Now zap the empty 4th row - won't do anything + sheet.removeRow(sheet.getRow(3)); + + // Test again the last row number which should be 2 + assertEquals(2, sheet.getLastRowNum()); + assertEquals("Cell A,2", sheet.getRow(0).getCell(0).getStringCellValue()); + assertEquals("Cell A,1", sheet.getRow(1).getCell(0).getStringCellValue()); + assertEquals("Cell A,3", sheet.getRow(2).getCell(0).getStringCellValue()); + } }