From 627105e288b7135c905d6724c0d9dd3ce77abc3b Mon Sep 17 00:00:00 2001 From: Yegor Kozlov Date: Sun, 15 Feb 2009 20:47:36 +0000 Subject: [PATCH] refactored XSSFSheet.shiftRows to use FormulaShifter, use a common test superclass for both hssf and xssf git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@744750 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/poi/POIXMLDocumentPart.java | 9 + .../apache/poi/xssf/usermodel/XSSFRow.java | 49 ++- .../apache/poi/xssf/usermodel/XSSFSheet.java | 34 ++- .../poi/xssf/usermodel/XSSFWorkbook.java | 10 + .../xssf/usermodel/TestSheetShiftRows.java | 68 +++++ .../org/apache/poi/hssf/data/ForShifting.xlsx | Bin 0 -> 9642 bytes .../apache/poi/hssf/data/SimpleMultiCell.xlsx | Bin 0 -> 8123 bytes .../org/apache/poi/hssf/data/comments.xlsx | Bin 0 -> 10046 bytes .../usermodel/BaseTestSheetShiftRows.java | 285 ------------------ .../hssf/usermodel/TestSheetShiftRows.java | 28 +- .../ss/usermodel/BaseTestSheetShiftRows.java | 276 +++++++++++++++++ 11 files changed, 456 insertions(+), 303 deletions(-) create mode 100755 src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestSheetShiftRows.java create mode 100755 src/testcases/org/apache/poi/hssf/data/ForShifting.xlsx create mode 100755 src/testcases/org/apache/poi/hssf/data/SimpleMultiCell.xlsx create mode 100755 src/testcases/org/apache/poi/hssf/data/comments.xlsx delete mode 100755 src/testcases/org/apache/poi/hssf/usermodel/BaseTestSheetShiftRows.java create mode 100755 src/testcases/org/apache/poi/ss/usermodel/BaseTestSheetShiftRows.java diff --git a/src/ooxml/java/org/apache/poi/POIXMLDocumentPart.java b/src/ooxml/java/org/apache/poi/POIXMLDocumentPart.java index f01cae8ce4..aa7f72df19 100755 --- a/src/ooxml/java/org/apache/poi/POIXMLDocumentPart.java +++ b/src/ooxml/java/org/apache/poi/POIXMLDocumentPart.java @@ -127,6 +127,15 @@ public class POIXMLDocumentPart { relations.add(part); } + /** + * Remove the specified part in this package. + */ + public final void removeRelation(POIXMLDocumentPart part){ + getPackagePart().removeRelationship(part.getPackageRelationship().getId()); + getPackagePart().getPackage().removePart(part.getPackagePart()); + relations.remove(part); + } + /** * Returns the parent POIXMLDocumentPart. All parts except root have not-null parent. * diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFRow.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFRow.java index 88563ec268..7c8ff976a1 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFRow.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFRow.java @@ -27,7 +27,10 @@ import org.apache.poi.ss.formula.FormulaType; import org.apache.poi.ss.formula.FormulaRenderer; import org.apache.poi.xssf.model.CalculationChain; import org.apache.poi.hssf.record.formula.Ptg; +import org.apache.poi.hssf.record.formula.FormulaShifter; import org.apache.poi.hssf.record.SharedFormulaRecord; +import org.apache.poi.util.POILogger; +import org.apache.poi.util.POILogFactory; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCell; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRow; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCellFormula; @@ -36,6 +39,7 @@ import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCellFormula; * High level representation of a row of a spreadsheet. */ public class XSSFRow implements Row, Comparable { + private static final POILogger logger = POILogFactory.getLogger(XSSFRow.class); private static final String FILE_FORMAT_NAME = "BIFF12"; /** @@ -406,34 +410,45 @@ public class XSSFRow implements Row, Comparable { * @param n the number of rows to move */ protected void shift(int n) { - XSSFSheet sheet = getSheet(); - CalculationChain calcChain = sheet.getWorkbook().getCalculationChain(); int rownum = getRowNum() + n; + CalculationChain calcChain = sheet.getWorkbook().getCalculationChain(); + int sheetId = (int)sheet.sheet.getSheetId(); for(Cell c : this){ XSSFCell cell = (XSSFCell)c; //remove the reference in the calculation chain - if(calcChain != null) calcChain.removeItem((int)sheet.sheet.getSheetId(), cell.getReference()); + if(calcChain != null) calcChain.removeItem(sheetId, cell.getReference()); CTCell ctCell = cell.getCTCell(); String r = new CellReference(rownum, cell.getColumnIndex()).formatAsString(); ctCell.setR(r); + } + setRowNum(rownum); + } + + protected void updateFormulasAfterCellShift(FormulaShifter shifter) { + for(Cell c : this){ + XSSFCell cell = (XSSFCell)c; + CTCell ctCell = cell.getCTCell(); if(ctCell.isSetF()){ CTCellFormula f = ctCell.getF(); - String fmla = f.getStringValue(); - if(fmla.length() > 0) { - String shiftedFmla = shiftFormula(fmla, n); - f.setStringValue(shiftedFmla); + String formula = f.getStringValue(); + if(formula.length() > 0) { + String shiftedFormula = shiftFormula(formula, shifter); + if (shiftedFormula != null) { + f.setStringValue(shiftedFormula); + } } + if(f.isSetRef()){ //Range of cells which the formula applies to. String ref = f.getRef(); - String shiftedRef = shiftFormula(ref, n); - f.setRef(shiftedRef); + String shiftedRef = shiftFormula(ref, shifter); + if(shiftedRef != null) f.setRef(shiftedRef); } } + } - setRowNum(rownum); } /** @@ -443,17 +458,21 @@ public class XSSFRow implements Row, Comparable { *

* * @param formula the formula to shift - * @param n the number of rows to shift - * @return the shifted formula + * @param shifter the FormulaShifter object that operates on the parsed formula tokens + * @return the shifted formula if the formula was changed, + * null if the formula wasn't modified */ - private String shiftFormula(String formula, int n){ + private String shiftFormula(String formula, FormulaShifter shifter){ XSSFSheet sheet = getSheet(); XSSFWorkbook wb = sheet.getWorkbook(); int sheetIndex = wb.getSheetIndex(sheet); XSSFEvaluationWorkbook fpb = XSSFEvaluationWorkbook.create(wb); Ptg[] ptgs = FormulaParser.parse(formula, fpb, FormulaType.CELL, sheetIndex); - Ptg[] fmla = SharedFormulaRecord.convertSharedFormulas(ptgs, n, 0); - return FormulaRenderer.toFormulaString(fpb, fmla); + String shiftedFmla = null; + if (shifter.adjustFormula(ptgs, sheetIndex)) { + shiftedFmla = FormulaRenderer.toFormulaString(fpb, ptgs); + } + return shiftedFmla; } } diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java index 90f920c3e7..e44208b75e 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java @@ -25,6 +25,7 @@ import javax.xml.namespace.QName; import org.apache.poi.hssf.util.PaneInformation; import org.apache.poi.hssf.record.formula.Ptg; +import org.apache.poi.hssf.record.formula.FormulaShifter; import org.apache.poi.hssf.record.SharedFormulaRecord; import org.apache.poi.ss.usermodel.*; import org.apache.poi.ss.util.CellRangeAddress; @@ -60,7 +61,7 @@ import org.openxmlformats.schemas.officeDocument.x2006.relationships.STRelations *

*/ public class XSSFSheet extends POIXMLDocumentPart implements Sheet { - private static POILogger logger = POILogFactory.getLogger(XSSFSheet.class); + private static final POILogger logger = POILogFactory.getLogger(XSSFSheet.class); /** * Column width measured as the number of characters of the maximum digit width of the @@ -1442,6 +1443,7 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet { public void shiftRows(int startRow, int endRow, int n, boolean copyRowHeight, boolean resetOriginalRowHeight) { for (Iterator it = rowIterator() ; it.hasNext() ; ) { XSSFRow row = (XSSFRow)it.next(); + int rownum = row.getRowNum(); if (!copyRowHeight) { row.setHeight((short)-1); @@ -1456,11 +1458,39 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet { else if (row.getRowNum() >= startRow && row.getRowNum() <= endRow) { row.shift(n); } + + if(sheetComments != null){ + //TODO shift Note's anchor in the associated /xl/drawing/vmlDrawings#.vml + CTCommentList lst = sheetComments.getCTComments().getCommentList(); + for (CTComment comment : lst.getCommentArray()) { + CellReference ref = new CellReference(comment.getRef()); + if(ref.getRow() == rownum){ + ref = new CellReference(rownum + n, ref.getCol()); + comment.setRef(ref.formatAsString()); + } + } + } } //rebuild the rows map + int sheetIndex = getWorkbook().getSheetIndex(this); + FormulaShifter shifter = FormulaShifter.createForRowShift(sheetIndex, startRow, endRow, n); TreeMap map = new TreeMap(); - for(Row r : this) map.put(r.getRowNum(), r); + for(Row r : this) { + XSSFRow row = (XSSFRow)r; + row.updateFormulasAfterCellShift(shifter); + map.put(r.getRowNum(), r); + } rows = map; + + //update formulas on other sheets + for(XSSFSheet sheet : getWorkbook()) { + if (sheet == this) continue; + for(Row r : sheet) { + XSSFRow row = (XSSFRow)r; + row.updateFormulasAfterCellShift(shifter); + } + } + } /** diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java index ce1724aed1..c2cdcd06d4 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java @@ -1068,12 +1068,22 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook, IterablebZ2n-}isC07U$(+f5r29(3 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 literal 0 HcmV?d00001 diff --git a/src/testcases/org/apache/poi/hssf/data/SimpleMultiCell.xlsx b/src/testcases/org/apache/poi/hssf/data/SimpleMultiCell.xlsx new file mode 100755 index 0000000000000000000000000000000000000000..d5dfe7adc3eb0e8228713da69f653f467624c1ef GIT binary patch literal 8123 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 literal 0 HcmV?d00001 diff --git a/src/testcases/org/apache/poi/hssf/data/comments.xlsx b/src/testcases/org/apache/poi/hssf/data/comments.xlsx new file mode 100755 index 0000000000000000000000000000000000000000..d4e139853c2ddf39be6c6d565e867c4b44b4c018 GIT binary patch literal 10046 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

K>nXEW6p+10^c`y} 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 P#sn505`>+23fK?_4 literal 0 HcmV?d00001 diff --git a/src/testcases/org/apache/poi/hssf/usermodel/BaseTestSheetShiftRows.java b/src/testcases/org/apache/poi/hssf/usermodel/BaseTestSheetShiftRows.java deleted file mode 100755 index 5c6716c7f4..0000000000 --- a/src/testcases/org/apache/poi/hssf/usermodel/BaseTestSheetShiftRows.java +++ /dev/null @@ -1,285 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.usermodel; - -import junit.framework.TestCase; - -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; - -/** - * Tests row shifting capabilities (common base class for HSSF and XSSF tests). - * - * - * @author Shawn Laubach (slaubach at apache dot com) - * @author Toshiaki Kamoshida (kamoshida.toshiaki at future dot co dot jp) - */ -public abstract class BaseTestSheetShiftRows extends TestCase { - /** - * Override to provide HSSF / XSSF specific way for re-serialising a workbook - */ - protected abstract Workbook writeOutAndReadBack(Workbook wb); - /** - * Override to provide way of loading HSSF / XSSF sample workbooks - * @param sampleFileName without the ".xls" or ".xlsx" suffix - */ - protected abstract Workbook openSampleWorkbook(String sampleFileName); - /** - * Override to provide way of creating HSSF / XSSF workbooks - */ - protected abstract Workbook createWorkbook(); - - /** - * Tests the shiftRows function. Does three different shifts. - * After each shift, writes the workbook to file and reads back to - * check. This ensures that if some changes code that breaks - * writing or what not, they realize it. - * - * @author Shawn Laubach (slaubach at apache dot org) - */ - public final void testShiftRows(){ - final String sampleName = "SimpleMultiCell"; - // Read initial file in - Workbook wb = openSampleWorkbook(sampleName); - Sheet s = wb.getSheetAt( 0 ); - - // Shift the second row down 1 and write to temp file - s.shiftRows( 1, 1, 1 ); - - wb = writeOutAndReadBack(wb); - - // Read from temp file and check the number of cells in each - // row (in original file each row was unique) - s = wb.getSheetAt( 0 ); - - assertEquals(s.getRow(0).getPhysicalNumberOfCells(), 1); - confirmEmptyRow(s, 1); - assertEquals(s.getRow(2).getPhysicalNumberOfCells(), 2); - assertEquals(s.getRow(3).getPhysicalNumberOfCells(), 4); - assertEquals(s.getRow(4).getPhysicalNumberOfCells(), 5); - - // Shift rows 1-3 down 3 in the current one. This tests when - // 1 row is blank. Write to a another temp file - s.shiftRows( 0, 2, 3 ); - wb = writeOutAndReadBack(wb); - - // Read and ensure things are where they should be - s = wb.getSheetAt(0); - confirmEmptyRow(s, 0); - confirmEmptyRow(s, 1); - confirmEmptyRow(s, 2); - assertEquals(s.getRow(3).getPhysicalNumberOfCells(), 1); - confirmEmptyRow(s, 4); - assertEquals(s.getRow(5).getPhysicalNumberOfCells(), 2); - - // Read the first file again - wb = openSampleWorkbook(sampleName); - s = wb.getSheetAt( 0 ); - - // Shift rows 3 and 4 up and write to temp file - s.shiftRows( 2, 3, -2 ); - wb = writeOutAndReadBack(wb); - s = wb.getSheetAt( 0 ); - assertEquals(s.getRow(0).getPhysicalNumberOfCells(), 3); - assertEquals(s.getRow(1).getPhysicalNumberOfCells(), 4); - confirmEmptyRow(s, 2); - confirmEmptyRow(s, 3); - assertEquals(s.getRow(4).getPhysicalNumberOfCells(), 5); - } - private static void confirmEmptyRow(Sheet s, int rowIx) { - Row row = s.getRow(rowIx); - assertTrue(row == null || row.getPhysicalNumberOfCells() == 0); - } - - /** - * Tests when rows are null. - * - * @author Toshiaki Kamoshida (kamoshida.toshiaki at future dot co dot jp) - */ - public final void testShiftRow() { - Workbook b = createWorkbook(); - Sheet s = b.createSheet(); - s.createRow(0).createCell(0).setCellValue("TEST1"); - s.createRow(3).createCell(0).setCellValue("TEST2"); - s.shiftRows(0,4,1); - } - - /** - * Tests when shifting the first row. - * - * @author Toshiaki Kamoshida (kamoshida.toshiaki at future dot co dot jp) - */ - public final void testShiftRow0() { - Workbook b = createWorkbook(); - Sheet s = b.createSheet(); - s.createRow(0).createCell(0).setCellValue("TEST1"); - s.createRow(3).createCell(0).setCellValue("TEST2"); - s.shiftRows(0,4,1); - } - - /** - * When shifting rows, the page breaks should go with it - * - */ - public final void testShiftRowBreaks() { - Workbook b = createWorkbook(); - Sheet s = b.createSheet(); - Row row = s.createRow(4); - row.createCell(0).setCellValue("test"); - s.setRowBreak(4); - - s.shiftRows(4, 4, 2); - assertTrue("Row number 6 should have a pagebreak", s.isRowBroken(6)); - } - - - public final void testShiftWithComments() { - final String sampleName = "comments"; - Workbook wb = openSampleWorkbook(sampleName); - - Sheet sheet = wb.getSheet("Sheet1"); - assertEquals(3, sheet.getLastRowNum()); - - // Verify comments are in the position expected - assertNotNull(sheet.getCellComment(0,0)); - assertNull(sheet.getCellComment(1,0)); - assertNotNull(sheet.getCellComment(2,0)); - assertNotNull(sheet.getCellComment(3,0)); - - String comment1 = sheet.getCellComment(0,0).getString().getString(); - assertEquals(comment1,"comment top row1 (index0)\n"); - String comment3 = sheet.getCellComment(2,0).getString().getString(); - assertEquals(comment3,"comment top row3 (index2)\n"); - String comment4 = sheet.getCellComment(3,0).getString().getString(); - assertEquals(comment4,"comment top row4 (index3)\n"); - - // Shifting all but first line down to test comments shifting - sheet.shiftRows(1, sheet.getLastRowNum(), 1, true, true); - - // Test that comments were shifted as expected - assertEquals(4, sheet.getLastRowNum()); - assertNotNull(sheet.getCellComment(0,0)); - assertNull(sheet.getCellComment(1,0)); - assertNull(sheet.getCellComment(2,0)); - assertNotNull(sheet.getCellComment(3,0)); - assertNotNull(sheet.getCellComment(4,0)); - - String comment1_shifted = sheet.getCellComment(0,0).getString().getString(); - assertEquals(comment1,comment1_shifted); - String comment3_shifted = sheet.getCellComment(3,0).getString().getString(); - assertEquals(comment3,comment3_shifted); - String comment4_shifted = sheet.getCellComment(4,0).getString().getString(); - assertEquals(comment4,comment4_shifted); - - // Write out and read back in again - // Ensure that the changes were persisted - wb = writeOutAndReadBack(wb); - sheet = wb.getSheet("Sheet1"); - assertEquals(4, sheet.getLastRowNum()); - - // Verify comments are in the position expected after the shift - assertNotNull(sheet.getCellComment(0,0)); - assertNull(sheet.getCellComment(1,0)); - assertNull(sheet.getCellComment(2,0)); - assertNotNull(sheet.getCellComment(3,0)); - assertNotNull(sheet.getCellComment(4,0)); - - comment1_shifted = sheet.getCellComment(0,0).getString().getString(); - assertEquals(comment1,comment1_shifted); - comment3_shifted = sheet.getCellComment(3,0).getString().getString(); - assertEquals(comment3,comment3_shifted); - comment4_shifted = sheet.getCellComment(4,0).getString().getString(); - assertEquals(comment4,comment4_shifted); - } - - /** - * See bug #34023 - */ - public void testShiftWithFormulas() { - String sampleName = "ForShifting"; - Workbook wb = openSampleWorkbook(sampleName); - - Sheet sheet = wb.getSheet("Sheet1"); - assertEquals(20, sheet.getLastRowNum()); - - confirmRow(sheet, 0, 1, 171, 1, "ROW(D1)", "100+B1", "COUNT(D1:E1)"); - confirmRow(sheet, 1, 2, 172, 1, "ROW(D2)", "100+B2", "COUNT(D2:E2)"); - confirmRow(sheet, 2, 3, 173, 1, "ROW(D3)", "100+B3", "COUNT(D3:E3)"); - - confirmCell(sheet, 6, 1, 271, "200+B1"); - confirmCell(sheet, 7, 1, 272, "200+B2"); - confirmCell(sheet, 8, 1, 273, "200+B3"); - - confirmCell(sheet, 14, 0, 0.0, "A12"); // the cell referred to by this formula will be replaced - - // ----------- - // Row index 1 -> 11 (row "2" -> row "12") - sheet.shiftRows(1, 1, 10); - - // Now check what sheet looks like after move - - // no changes on row "1" - confirmRow(sheet, 0, 1, 171, 1, "ROW(D1)", "100+B1", "COUNT(D1:E1)"); - - // row "2" is now empty - assertEquals(0, sheet.getRow(1).getPhysicalNumberOfCells()); - - // Row "2" moved to row "12", and the formula has been updated. - // note however that the cached formula result (2) has not been updated. (POI differs from Excel here) - confirmRow(sheet, 11, 2, 172, 1, "ROW(D12)", "100+B12", "COUNT(D12:E12)"); - - // no changes on row "3" - confirmRow(sheet, 2, 3, 173, 1, "ROW(D3)", "100+B3", "COUNT(D3:E3)"); - - - confirmCell(sheet, 14, 0, 0.0, "#REF!"); - - - // Formulas on rows that weren't shifted: - confirmCell(sheet, 6, 1, 271, "200+B1"); - confirmCell(sheet, 7, 1, 272, "200+B12"); // this one moved - confirmCell(sheet, 8, 1, 273, "200+B3"); - - // check formulas on other sheets - Sheet sheet2 = wb.getSheet("Sheet2"); - confirmCell(sheet2, 0, 0, 371, "300+Sheet1!B1"); - confirmCell(sheet2, 1, 0, 372, "300+Sheet1!B12"); - confirmCell(sheet2, 2, 0, 373, "300+Sheet1!B3"); - - confirmCell(sheet2, 11, 0, 300, "300+Sheet1!#REF!"); - - - // Note - named ranges formulas have not been updated - } - - private static void confirmRow(Sheet sheet, int rowIx, double valA, double valB, double valC, - String formulaA, String formulaB, String formulaC) { - confirmCell(sheet, rowIx, 4, valA, formulaA); - confirmCell(sheet, rowIx, 5, valB, formulaB); - confirmCell(sheet, rowIx, 6, valC, formulaC); - } - - private static void confirmCell(Sheet sheet, int rowIx, int colIx, - double expectedValue, String expectedFormula) { - Cell cell = sheet.getRow(rowIx).getCell(colIx); - assertEquals(expectedValue, cell.getNumericCellValue(), 0.0); - assertEquals(expectedFormula, cell.getCellFormula()); - } -} diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestSheetShiftRows.java b/src/testcases/org/apache/poi/hssf/usermodel/TestSheetShiftRows.java index d29469111d..962a565503 100755 --- a/src/testcases/org/apache/poi/hssf/usermodel/TestSheetShiftRows.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestSheetShiftRows.java @@ -19,6 +19,7 @@ package org.apache.poi.hssf.usermodel; import org.apache.poi.hssf.HSSFTestDataSamples; import org.apache.poi.ss.usermodel.Workbook; +import org.apache.poi.ss.usermodel.BaseTestSheetShiftRows; /** * Tests row shifting capabilities. @@ -31,7 +32,7 @@ public final class TestSheetShiftRows extends BaseTestSheetShiftRows { @Override protected Workbook openSampleWorkbook(String sampleFileName) { - return HSSFTestDataSamples.openSampleWorkbook(sampleFileName + ".xls"); + return HSSFTestDataSamples.openSampleWorkbook(sampleFileName); } @Override @@ -46,4 +47,29 @@ public final class TestSheetShiftRows extends BaseTestSheetShiftRows { protected Workbook createWorkbook() { return new HSSFWorkbook(); } + + public void testShiftRows() { + baseTestShiftRows("SimpleMultiCell.xls"); + } + + public void testShiftRow() { + baseTestShiftRow(); + } + + public void testShiftRow0() { + baseTestShiftRow0(); + } + + public void testShiftRowBreaks() { + baseTestShiftRowBreaks(); + } + + public void testShiftWithComments() { + baseTestShiftWithComments("comments.xls"); + } + + public void testShiftWithFormulas() { + baseTestShiftWithFormulas("ForShifting.xls"); + } + } diff --git a/src/testcases/org/apache/poi/ss/usermodel/BaseTestSheetShiftRows.java b/src/testcases/org/apache/poi/ss/usermodel/BaseTestSheetShiftRows.java new file mode 100755 index 0000000000..7b83cbbd53 --- /dev/null +++ b/src/testcases/org/apache/poi/ss/usermodel/BaseTestSheetShiftRows.java @@ -0,0 +1,276 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.ss.usermodel; + +import junit.framework.TestCase; + +/** + * Tests row shifting capabilities. + * + * @author Shawn Laubach (slaubach at apache dot com) + * @author Toshiaki Kamoshida (kamoshida.toshiaki at future dot co dot jp) + */ +public abstract class BaseTestSheetShiftRows extends TestCase { + /** + * Override to provide HSSF / XSSF specific way for re-serialising a workbook + */ + protected abstract Workbook writeOutAndReadBack(Workbook wb); + /** + * Override to provide way of loading HSSF / XSSF sample workbooks + * @param sampleFileName without the ".xls" or ".xlsx" suffix + */ + protected abstract Workbook openSampleWorkbook(String sampleFileName); + /** + * Override to provide way of creating HSSF / XSSF workbooks + */ + protected abstract Workbook createWorkbook(); + + /** + * Tests the shiftRows function. Does three different shifts. + * After each shift, writes the workbook to file and reads back to + * check. This ensures that if some changes code that breaks + * writing or what not, they realize it. + * + * @author Shawn Laubach (slaubach at apache dot org) + */ + public final void baseTestShiftRows(String sampleName){ + // Read initial file in + Workbook wb = openSampleWorkbook(sampleName); + Sheet s = wb.getSheetAt( 0 ); + + // Shift the second row down 1 and write to temp file + s.shiftRows( 1, 1, 1 ); + + wb = writeOutAndReadBack(wb); + + // Read from temp file and check the number of cells in each + // row (in original file each row was unique) + s = wb.getSheetAt( 0 ); + + assertEquals(s.getRow(0).getPhysicalNumberOfCells(), 1); + confirmEmptyRow(s, 1); + assertEquals(s.getRow(2).getPhysicalNumberOfCells(), 2); + assertEquals(s.getRow(3).getPhysicalNumberOfCells(), 4); + assertEquals(s.getRow(4).getPhysicalNumberOfCells(), 5); + + // Shift rows 1-3 down 3 in the current one. This tests when + // 1 row is blank. Write to a another temp file + s.shiftRows( 0, 2, 3 ); + wb = writeOutAndReadBack(wb); + + // Read and ensure things are where they should be + s = wb.getSheetAt(0); + confirmEmptyRow(s, 0); + confirmEmptyRow(s, 1); + confirmEmptyRow(s, 2); + assertEquals(s.getRow(3).getPhysicalNumberOfCells(), 1); + confirmEmptyRow(s, 4); + assertEquals(s.getRow(5).getPhysicalNumberOfCells(), 2); + + // Read the first file again + wb = openSampleWorkbook(sampleName); + s = wb.getSheetAt( 0 ); + + // Shift rows 3 and 4 up and write to temp file + s.shiftRows( 2, 3, -2 ); + wb = writeOutAndReadBack(wb); + s = wb.getSheetAt( 0 ); + assertEquals(s.getRow(0).getPhysicalNumberOfCells(), 3); + assertEquals(s.getRow(1).getPhysicalNumberOfCells(), 4); + confirmEmptyRow(s, 2); + confirmEmptyRow(s, 3); + assertEquals(s.getRow(4).getPhysicalNumberOfCells(), 5); + } + private static void confirmEmptyRow(Sheet s, int rowIx) { + Row row = s.getRow(rowIx); + assertTrue(row == null || row.getPhysicalNumberOfCells() == 0); + } + + /** + * Tests when rows are null. + * + * @author Toshiaki Kamoshida (kamoshida.toshiaki at future dot co dot jp) + */ + public final void baseTestShiftRow() { + Workbook b = createWorkbook(); + Sheet s = b.createSheet(); + s.createRow(0).createCell(0).setCellValue("TEST1"); + s.createRow(3).createCell(0).setCellValue("TEST2"); + s.shiftRows(0,4,1); + } + + /** + * Tests when shifting the first row. + * + * @author Toshiaki Kamoshida (kamoshida.toshiaki at future dot co dot jp) + */ + public final void baseTestShiftRow0() { + Workbook b = createWorkbook(); + Sheet s = b.createSheet(); + s.createRow(0).createCell(0).setCellValue("TEST1"); + s.createRow(3).createCell(0).setCellValue("TEST2"); + s.shiftRows(0,4,1); + } + + /** + * When shifting rows, the page breaks should go with it + * + */ + public final void baseTestShiftRowBreaks() { + Workbook b = createWorkbook(); + Sheet s = b.createSheet(); + Row row = s.createRow(4); + row.createCell(0).setCellValue("test"); + s.setRowBreak(4); + + s.shiftRows(4, 4, 2); + assertTrue("Row number 6 should have a pagebreak", s.isRowBroken(6)); + } + + + public final void baseTestShiftWithComments(String sampleName) { + Workbook wb = openSampleWorkbook(sampleName); + + Sheet sheet = wb.getSheet("Sheet1"); + assertEquals(3, sheet.getLastRowNum()); + + // Verify comments are in the position expected + assertNotNull(sheet.getCellComment(0,0)); + assertNull(sheet.getCellComment(1,0)); + assertNotNull(sheet.getCellComment(2,0)); + assertNotNull(sheet.getCellComment(3,0)); + + String comment1 = sheet.getCellComment(0,0).getString().getString(); + assertEquals(comment1,"comment top row1 (index0)\n"); + String comment3 = sheet.getCellComment(2,0).getString().getString(); + assertEquals(comment3,"comment top row3 (index2)\n"); + String comment4 = sheet.getCellComment(3,0).getString().getString(); + assertEquals(comment4,"comment top row4 (index3)\n"); + + // Shifting all but first line down to test comments shifting + sheet.shiftRows(1, sheet.getLastRowNum(), 1, true, true); + + // Test that comments were shifted as expected + assertEquals(4, sheet.getLastRowNum()); + assertNotNull(sheet.getCellComment(0,0)); + assertNull(sheet.getCellComment(1,0)); + assertNull(sheet.getCellComment(2,0)); + assertNotNull(sheet.getCellComment(3,0)); + assertNotNull(sheet.getCellComment(4,0)); + + String comment1_shifted = sheet.getCellComment(0,0).getString().getString(); + assertEquals(comment1,comment1_shifted); + String comment3_shifted = sheet.getCellComment(3,0).getString().getString(); + assertEquals(comment3,comment3_shifted); + String comment4_shifted = sheet.getCellComment(4,0).getString().getString(); + assertEquals(comment4,comment4_shifted); + + // Write out and read back in again + // Ensure that the changes were persisted + wb = writeOutAndReadBack(wb); + sheet = wb.getSheet("Sheet1"); + assertEquals(4, sheet.getLastRowNum()); + + // Verify comments are in the position expected after the shift + assertNotNull(sheet.getCellComment(0,0)); + assertNull(sheet.getCellComment(1,0)); + assertNull(sheet.getCellComment(2,0)); + assertNotNull(sheet.getCellComment(3,0)); + assertNotNull(sheet.getCellComment(4,0)); + + comment1_shifted = sheet.getCellComment(0,0).getString().getString(); + assertEquals(comment1,comment1_shifted); + comment3_shifted = sheet.getCellComment(3,0).getString().getString(); + assertEquals(comment3,comment3_shifted); + comment4_shifted = sheet.getCellComment(4,0).getString().getString(); + assertEquals(comment4,comment4_shifted); + } + + /** + * See bug #34023 + */ + public void baseTestShiftWithFormulas(String sampleName) { + Workbook wb = openSampleWorkbook(sampleName); + + Sheet sheet = wb.getSheet("Sheet1"); + assertEquals(20, sheet.getLastRowNum()); + + confirmRow(sheet, 0, 1, 171, 1, "ROW(D1)", "100+B1", "COUNT(D1:E1)"); + confirmRow(sheet, 1, 2, 172, 1, "ROW(D2)", "100+B2", "COUNT(D2:E2)"); + confirmRow(sheet, 2, 3, 173, 1, "ROW(D3)", "100+B3", "COUNT(D3:E3)"); + + confirmCell(sheet, 6, 1, 271, "200+B1"); + confirmCell(sheet, 7, 1, 272, "200+B2"); + confirmCell(sheet, 8, 1, 273, "200+B3"); + + confirmCell(sheet, 14, 0, 0.0, "A12"); // the cell referred to by this formula will be replaced + + // ----------- + // Row index 1 -> 11 (row "2" -> row "12") + sheet.shiftRows(1, 1, 10); + + // Now check what sheet looks like after move + + // no changes on row "1" + confirmRow(sheet, 0, 1, 171, 1, "ROW(D1)", "100+B1", "COUNT(D1:E1)"); + + // row "2" is now empty + confirmEmptyRow(sheet, 1); + + // Row "2" moved to row "12", and the formula has been updated. + // note however that the cached formula result (2) has not been updated. (POI differs from Excel here) + confirmRow(sheet, 11, 2, 172, 1, "ROW(D12)", "100+B12", "COUNT(D12:E12)"); + + // no changes on row "3" + confirmRow(sheet, 2, 3, 173, 1, "ROW(D3)", "100+B3", "COUNT(D3:E3)"); + + + confirmCell(sheet, 14, 0, 0.0, "#REF!"); + + + // Formulas on rows that weren't shifted: + confirmCell(sheet, 6, 1, 271, "200+B1"); + confirmCell(sheet, 7, 1, 272, "200+B12"); // this one moved + confirmCell(sheet, 8, 1, 273, "200+B3"); + + // check formulas on other sheets + Sheet sheet2 = wb.getSheet("Sheet2"); + confirmCell(sheet2, 0, 0, 371, "300+Sheet1!B1"); + confirmCell(sheet2, 1, 0, 372, "300+Sheet1!B12"); + confirmCell(sheet2, 2, 0, 373, "300+Sheet1!B3"); + + confirmCell(sheet2, 11, 0, 300, "300+Sheet1!#REF!"); + + + // Note - named ranges formulas have not been updated + } + + private static void confirmRow(Sheet sheet, int rowIx, double valA, double valB, double valC, + String formulaA, String formulaB, String formulaC) { + confirmCell(sheet, rowIx, 4, valA, formulaA); + confirmCell(sheet, rowIx, 5, valB, formulaB); + confirmCell(sheet, rowIx, 6, valC, formulaC); + } + + private static void confirmCell(Sheet sheet, int rowIx, int colIx, + double expectedValue, String expectedFormula) { + Cell cell = sheet.getRow(rowIx).getCell(colIx); + assertEquals(expectedValue, cell.getNumericCellValue(), 0.0); + assertEquals(expectedFormula, cell.getCellFormula()); + } +} -- 2.39.5