diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java b/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java index ac84059467..9ed29e00f5 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java @@ -1187,6 +1187,12 @@ public final class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet { cellRecord.setRow( rowNum + n ); row2Replace.createCellFromRecord( cellRecord ); sheet.addValueRecord( rowNum + n, cellRecord ); + + HSSFHyperlink link = cell.getHyperlink(); + if(link != null){ + link.setFirstRow(link.getFirstRow() + n); + link.setLastRow(link.getLastRow() + n); + } } // Now zap all the cells in the source row row.removeAllCells(); diff --git a/src/testcases/org/apache/poi/hssf/data/46445.xls b/src/testcases/org/apache/poi/hssf/data/46445.xls new file mode 100755 index 0000000000..30aaf343ad Binary files /dev/null and b/src/testcases/org/apache/poi/hssf/data/46445.xls differ diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java b/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java index 040d3cfae8..76c61dd35d 100644 --- a/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java @@ -1642,4 +1642,28 @@ public final class TestBugs extends TestCase { assertEquals("\u0161\u017E\u010D\u0148\u0159", sheet.getRow(1).getCell(0).getStringCellValue()); } + /** + * Multiple calls of HSSFWorkbook.write result in corrupted xls + */ + public void test32191() throws IOException { + HSSFWorkbook wb = openSample("27394.xls"); + + ByteArrayOutputStream out = new ByteArrayOutputStream(); + wb.write(out); + out.close(); + int size1 = out.size(); + + out = new ByteArrayOutputStream(); + wb.write(out); + out.close(); + int size2 = out.size(); + + assertEquals(size1, size2); + out = new ByteArrayOutputStream(); + wb.write(out); + out.close(); + int size3 = out.size(); + assertEquals(size2, size3); + + } } diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFHyperlink.java b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFHyperlink.java index e741166b00..09443427a3 100755 --- a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFHyperlink.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFHyperlink.java @@ -184,4 +184,49 @@ public final class TestHSSFHyperlink extends TestCase { assertNotNull(link); assertEquals("http://poi.apache.org/hssf/", link.getAddress()); } + + /** + * Test that HSSFSheet#shiftRows moves hyperlinks, + * see bugs #46445 and #29957 + */ + public void testShiftRows(){ + HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("46445.xls"); + + + HSSFSheet sheet = wb.getSheetAt(0); + + //verify existing hyperlink in A3 + HSSFCell cell1 = sheet.getRow(2).getCell(0); + HSSFHyperlink link1 = cell1.getHyperlink(); + assertNotNull(link1); + assertEquals(2, link1.getFirstRow()); + assertEquals(2, link1.getLastRow()); + + //assign a hyperlink to A4 + HSSFHyperlink link2 = new HSSFHyperlink(HSSFHyperlink.LINK_DOCUMENT); + link2.setAddress("Sheet2!A2"); + HSSFCell cell2 = sheet.getRow(3).getCell(0); + cell2.setHyperlink(link2); + assertEquals(3, link2.getFirstRow()); + assertEquals(3, link2.getLastRow()); + + //move the 3rd row two rows down + sheet.shiftRows(sheet.getFirstRowNum(), sheet.getLastRowNum(), 2); + + //cells A3 and A4 don't contain hyperlinks anymore + assertNull(sheet.getRow(2).getCell(0).getHyperlink()); + assertNull(sheet.getRow(3).getCell(0).getHyperlink()); + + //the first hypelink now belongs to A5 + HSSFHyperlink link1_shifted = sheet.getRow(2+2).getCell(0).getHyperlink(); + assertNotNull(link1_shifted); + assertEquals(4, link1_shifted.getFirstRow()); + assertEquals(4, link1_shifted.getLastRow()); + + //the second hypelink now belongs to A6 + HSSFHyperlink link2_shifted = sheet.getRow(3+2).getCell(0).getHyperlink(); + assertNotNull(link2_shifted); + assertEquals(5, link2_shifted.getFirstRow()); + assertEquals(5, link2_shifted.getLastRow()); + } }