relations.add(part);\r
}\r
\r
+ /**\r
+ * Remove the specified part in this package.\r
+ */\r
+ public final void removeRelation(POIXMLDocumentPart part){\r
+ getPackagePart().removeRelationship(part.getPackageRelationship().getId());\r
+ getPackagePart().getPackage().removePart(part.getPackagePart());\r
+ relations.remove(part);\r
+ }\r
+\r
/**\r
* Returns the parent POIXMLDocumentPart. All parts except root have not-null parent.\r
*\r
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;
* High level representation of a row of a spreadsheet.
*/
public class XSSFRow implements Row, Comparable<XSSFRow> {
+ private static final POILogger logger = POILogFactory.getLogger(XSSFRow.class);
private static final String FILE_FORMAT_NAME = "BIFF12";
/**
* @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);
}
/**
* </p>
*
* @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,
+ * <code>null</code> 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;
}
}
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;
* </p>
*/
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
public void shiftRows(int startRow, int endRow, int n, boolean copyRowHeight, boolean resetOriginalRowHeight) {
for (Iterator<Row> it = rowIterator() ; it.hasNext() ; ) {
XSSFRow row = (XSSFRow)it.next();
+ int rownum = row.getRowNum();
if (!copyRowHeight) {
row.setHeight((short)-1);
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<Integer, Row> map = new TreeMap<Integer, Row>();
- 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);
+ }
+ }
+
}
/**
workbook.unsetDefinedNames();
}
}
+ }
+ private void saveCalculationChain(){
+ if(calcChain != null){
+ int count = calcChain.getCTCalcChain().getCArray().length;
+ if(count == 0){
+ removeRelation(calcChain);
+ calcChain = null;
+ }
+ }
}
@Override
protected void commit() throws IOException {
saveNamedRanges();
+ saveCalculationChain();
XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS);
xmlOptions.setSaveSyntheticDocumentElement(new QName(CTWorkbook.type.getName().getNamespaceURI(), "workbook"));
--- /dev/null
+/* ====================================================================\r
+ Licensed to the Apache Software Foundation (ASF) under one or more\r
+ contributor license agreements. See the NOTICE file distributed with\r
+ this work for additional information regarding copyright ownership.\r
+ The ASF licenses this file to You under the Apache License, Version 2.0\r
+ (the "License"); you may not use this file except in compliance with\r
+ the License. You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+==================================================================== */\r
+package org.apache.poi.xssf.usermodel;\r
+\r
+import org.apache.poi.ss.usermodel.BaseTestSheetShiftRows;\r
+import org.apache.poi.ss.usermodel.Workbook;\r
+import org.apache.poi.xssf.XSSFTestDataSamples;\r
+\r
+/**\r
+ * @author Yegor Kozlov\r
+ */\r
+public class TestSheetShiftRows extends BaseTestSheetShiftRows {\r
+\r
+ @Override\r
+ protected Workbook openSampleWorkbook(String sampleFileName) {\r
+ return XSSFTestDataSamples.openSampleWorkbook(sampleFileName);\r
+ }\r
+\r
+ @Override\r
+ protected Workbook writeOutAndReadBack(Workbook wb) {\r
+ return XSSFTestDataSamples.writeOutAndReadBack(wb);\r
+ }\r
+\r
+ @Override\r
+ protected Workbook createWorkbook() {\r
+ return new XSSFWorkbook();\r
+ }\r
+\r
+ public void testShiftRows() {\r
+ baseTestShiftRows("SimpleMultiCell.xlsx");\r
+ }\r
+\r
+ public void testShiftRow() {\r
+ baseTestShiftRow();\r
+ }\r
+\r
+ public void testShiftRow0() {\r
+ baseTestShiftRow0();\r
+ }\r
+\r
+ //TODO support shifting of page breaks\r
+ public void $testShiftRowBreaks() {\r
+ baseTestShiftRowBreaks();\r
+ }\r
+\r
+ //TODO support shifting of comments. \r
+ public void $testShiftWithComments() {\r
+ baseTestShiftWithComments("comments.xlsx");\r
+ }\r
+\r
+ public void testShiftWithFormulas() {\r
+ baseTestShiftWithFormulas("ForShifting.xlsx");\r
+ }\r
+}\r
+++ /dev/null
-/* ====================================================================
- 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());
- }
-}
import org.apache.poi.hssf.HSSFTestDataSamples;
import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.ss.usermodel.BaseTestSheetShiftRows;
/**
* Tests row shifting capabilities.
@Override
protected Workbook openSampleWorkbook(String sampleFileName) {
- return HSSFTestDataSamples.openSampleWorkbook(sampleFileName + ".xls");
+ return HSSFTestDataSamples.openSampleWorkbook(sampleFileName);
}
@Override
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");
+ }
+
}
--- /dev/null
+/* ====================================================================\r
+ Licensed to the Apache Software Foundation (ASF) under one or more\r
+ contributor license agreements. See the NOTICE file distributed with\r
+ this work for additional information regarding copyright ownership.\r
+ The ASF licenses this file to You under the Apache License, Version 2.0\r
+ (the "License"); you may not use this file except in compliance with\r
+ the License. You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+==================================================================== */\r
+\r
+package org.apache.poi.ss.usermodel;\r
+\r
+import junit.framework.TestCase;\r
+\r
+/**\r
+ * Tests row shifting capabilities.\r
+ *\r
+ * @author Shawn Laubach (slaubach at apache dot com)\r
+ * @author Toshiaki Kamoshida (kamoshida.toshiaki at future dot co dot jp)\r
+ */\r
+public abstract class BaseTestSheetShiftRows extends TestCase {\r
+ /**\r
+ * Override to provide HSSF / XSSF specific way for re-serialising a workbook\r
+ */\r
+ protected abstract Workbook writeOutAndReadBack(Workbook wb);\r
+ /**\r
+ * Override to provide way of loading HSSF / XSSF sample workbooks\r
+ * @param sampleFileName without the ".xls" or ".xlsx" suffix\r
+ */\r
+ protected abstract Workbook openSampleWorkbook(String sampleFileName);\r
+ /**\r
+ * Override to provide way of creating HSSF / XSSF workbooks\r
+ */\r
+ protected abstract Workbook createWorkbook();\r
+\r
+ /**\r
+ * Tests the shiftRows function. Does three different shifts.\r
+ * After each shift, writes the workbook to file and reads back to\r
+ * check. This ensures that if some changes code that breaks\r
+ * writing or what not, they realize it.\r
+ *\r
+ * @author Shawn Laubach (slaubach at apache dot org)\r
+ */\r
+ public final void baseTestShiftRows(String sampleName){\r
+ // Read initial file in\r
+ Workbook wb = openSampleWorkbook(sampleName);\r
+ Sheet s = wb.getSheetAt( 0 );\r
+\r
+ // Shift the second row down 1 and write to temp file\r
+ s.shiftRows( 1, 1, 1 );\r
+\r
+ wb = writeOutAndReadBack(wb);\r
+\r
+ // Read from temp file and check the number of cells in each\r
+ // row (in original file each row was unique)\r
+ s = wb.getSheetAt( 0 );\r
+\r
+ assertEquals(s.getRow(0).getPhysicalNumberOfCells(), 1);\r
+ confirmEmptyRow(s, 1);\r
+ assertEquals(s.getRow(2).getPhysicalNumberOfCells(), 2);\r
+ assertEquals(s.getRow(3).getPhysicalNumberOfCells(), 4);\r
+ assertEquals(s.getRow(4).getPhysicalNumberOfCells(), 5);\r
+\r
+ // Shift rows 1-3 down 3 in the current one. This tests when\r
+ // 1 row is blank. Write to a another temp file\r
+ s.shiftRows( 0, 2, 3 );\r
+ wb = writeOutAndReadBack(wb);\r
+\r
+ // Read and ensure things are where they should be\r
+ s = wb.getSheetAt(0);\r
+ confirmEmptyRow(s, 0);\r
+ confirmEmptyRow(s, 1);\r
+ confirmEmptyRow(s, 2);\r
+ assertEquals(s.getRow(3).getPhysicalNumberOfCells(), 1);\r
+ confirmEmptyRow(s, 4);\r
+ assertEquals(s.getRow(5).getPhysicalNumberOfCells(), 2);\r
+\r
+ // Read the first file again\r
+ wb = openSampleWorkbook(sampleName);\r
+ s = wb.getSheetAt( 0 );\r
+\r
+ // Shift rows 3 and 4 up and write to temp file\r
+ s.shiftRows( 2, 3, -2 );\r
+ wb = writeOutAndReadBack(wb);\r
+ s = wb.getSheetAt( 0 );\r
+ assertEquals(s.getRow(0).getPhysicalNumberOfCells(), 3);\r
+ assertEquals(s.getRow(1).getPhysicalNumberOfCells(), 4);\r
+ confirmEmptyRow(s, 2);\r
+ confirmEmptyRow(s, 3);\r
+ assertEquals(s.getRow(4).getPhysicalNumberOfCells(), 5);\r
+ }\r
+ private static void confirmEmptyRow(Sheet s, int rowIx) {\r
+ Row row = s.getRow(rowIx);\r
+ assertTrue(row == null || row.getPhysicalNumberOfCells() == 0);\r
+ }\r
+\r
+ /**\r
+ * Tests when rows are null.\r
+ *\r
+ * @author Toshiaki Kamoshida (kamoshida.toshiaki at future dot co dot jp)\r
+ */\r
+ public final void baseTestShiftRow() {\r
+ Workbook b = createWorkbook();\r
+ Sheet s = b.createSheet();\r
+ s.createRow(0).createCell(0).setCellValue("TEST1");\r
+ s.createRow(3).createCell(0).setCellValue("TEST2");\r
+ s.shiftRows(0,4,1);\r
+ }\r
+\r
+ /**\r
+ * Tests when shifting the first row.\r
+ *\r
+ * @author Toshiaki Kamoshida (kamoshida.toshiaki at future dot co dot jp)\r
+ */\r
+ public final void baseTestShiftRow0() {\r
+ Workbook b = createWorkbook();\r
+ Sheet s = b.createSheet();\r
+ s.createRow(0).createCell(0).setCellValue("TEST1");\r
+ s.createRow(3).createCell(0).setCellValue("TEST2");\r
+ s.shiftRows(0,4,1);\r
+ }\r
+\r
+ /**\r
+ * When shifting rows, the page breaks should go with it\r
+ *\r
+ */\r
+ public final void baseTestShiftRowBreaks() {\r
+ Workbook b = createWorkbook();\r
+ Sheet s = b.createSheet();\r
+ Row row = s.createRow(4);\r
+ row.createCell(0).setCellValue("test");\r
+ s.setRowBreak(4);\r
+\r
+ s.shiftRows(4, 4, 2);\r
+ assertTrue("Row number 6 should have a pagebreak", s.isRowBroken(6));\r
+ }\r
+\r
+\r
+ public final void baseTestShiftWithComments(String sampleName) {\r
+ Workbook wb = openSampleWorkbook(sampleName);\r
+\r
+ Sheet sheet = wb.getSheet("Sheet1");\r
+ assertEquals(3, sheet.getLastRowNum());\r
+\r
+ // Verify comments are in the position expected\r
+ assertNotNull(sheet.getCellComment(0,0));\r
+ assertNull(sheet.getCellComment(1,0));\r
+ assertNotNull(sheet.getCellComment(2,0));\r
+ assertNotNull(sheet.getCellComment(3,0));\r
+\r
+ String comment1 = sheet.getCellComment(0,0).getString().getString();\r
+ assertEquals(comment1,"comment top row1 (index0)\n");\r
+ String comment3 = sheet.getCellComment(2,0).getString().getString();\r
+ assertEquals(comment3,"comment top row3 (index2)\n");\r
+ String comment4 = sheet.getCellComment(3,0).getString().getString();\r
+ assertEquals(comment4,"comment top row4 (index3)\n");\r
+\r
+ // Shifting all but first line down to test comments shifting\r
+ sheet.shiftRows(1, sheet.getLastRowNum(), 1, true, true);\r
+\r
+ // Test that comments were shifted as expected\r
+ assertEquals(4, sheet.getLastRowNum());\r
+ assertNotNull(sheet.getCellComment(0,0));\r
+ assertNull(sheet.getCellComment(1,0));\r
+ assertNull(sheet.getCellComment(2,0));\r
+ assertNotNull(sheet.getCellComment(3,0));\r
+ assertNotNull(sheet.getCellComment(4,0));\r
+\r
+ String comment1_shifted = sheet.getCellComment(0,0).getString().getString();\r
+ assertEquals(comment1,comment1_shifted);\r
+ String comment3_shifted = sheet.getCellComment(3,0).getString().getString();\r
+ assertEquals(comment3,comment3_shifted);\r
+ String comment4_shifted = sheet.getCellComment(4,0).getString().getString();\r
+ assertEquals(comment4,comment4_shifted);\r
+\r
+ // Write out and read back in again\r
+ // Ensure that the changes were persisted\r
+ wb = writeOutAndReadBack(wb);\r
+ sheet = wb.getSheet("Sheet1");\r
+ assertEquals(4, sheet.getLastRowNum());\r
+\r
+ // Verify comments are in the position expected after the shift\r
+ assertNotNull(sheet.getCellComment(0,0));\r
+ assertNull(sheet.getCellComment(1,0));\r
+ assertNull(sheet.getCellComment(2,0));\r
+ assertNotNull(sheet.getCellComment(3,0));\r
+ assertNotNull(sheet.getCellComment(4,0));\r
+\r
+ comment1_shifted = sheet.getCellComment(0,0).getString().getString();\r
+ assertEquals(comment1,comment1_shifted);\r
+ comment3_shifted = sheet.getCellComment(3,0).getString().getString();\r
+ assertEquals(comment3,comment3_shifted);\r
+ comment4_shifted = sheet.getCellComment(4,0).getString().getString();\r
+ assertEquals(comment4,comment4_shifted);\r
+ }\r
+\r
+ /**\r
+ * See bug #34023\r
+ */\r
+ public void baseTestShiftWithFormulas(String sampleName) {\r
+ Workbook wb = openSampleWorkbook(sampleName);\r
+\r
+ Sheet sheet = wb.getSheet("Sheet1");\r
+ assertEquals(20, sheet.getLastRowNum());\r
+\r
+ confirmRow(sheet, 0, 1, 171, 1, "ROW(D1)", "100+B1", "COUNT(D1:E1)");\r
+ confirmRow(sheet, 1, 2, 172, 1, "ROW(D2)", "100+B2", "COUNT(D2:E2)");\r
+ confirmRow(sheet, 2, 3, 173, 1, "ROW(D3)", "100+B3", "COUNT(D3:E3)");\r
+\r
+ confirmCell(sheet, 6, 1, 271, "200+B1");\r
+ confirmCell(sheet, 7, 1, 272, "200+B2");\r
+ confirmCell(sheet, 8, 1, 273, "200+B3");\r
+\r
+ confirmCell(sheet, 14, 0, 0.0, "A12"); // the cell referred to by this formula will be replaced\r
+\r
+ // -----------\r
+ // Row index 1 -> 11 (row "2" -> row "12")\r
+ sheet.shiftRows(1, 1, 10);\r
+\r
+ // Now check what sheet looks like after move\r
+\r
+ // no changes on row "1"\r
+ confirmRow(sheet, 0, 1, 171, 1, "ROW(D1)", "100+B1", "COUNT(D1:E1)");\r
+\r
+ // row "2" is now empty\r
+ confirmEmptyRow(sheet, 1);\r
+\r
+ // Row "2" moved to row "12", and the formula has been updated.\r
+ // note however that the cached formula result (2) has not been updated. (POI differs from Excel here)\r
+ confirmRow(sheet, 11, 2, 172, 1, "ROW(D12)", "100+B12", "COUNT(D12:E12)");\r
+\r
+ // no changes on row "3"\r
+ confirmRow(sheet, 2, 3, 173, 1, "ROW(D3)", "100+B3", "COUNT(D3:E3)");\r
+\r
+\r
+ confirmCell(sheet, 14, 0, 0.0, "#REF!");\r
+\r
+\r
+ // Formulas on rows that weren't shifted:\r
+ confirmCell(sheet, 6, 1, 271, "200+B1");\r
+ confirmCell(sheet, 7, 1, 272, "200+B12"); // this one moved\r
+ confirmCell(sheet, 8, 1, 273, "200+B3");\r
+\r
+ // check formulas on other sheets\r
+ Sheet sheet2 = wb.getSheet("Sheet2");\r
+ confirmCell(sheet2, 0, 0, 371, "300+Sheet1!B1");\r
+ confirmCell(sheet2, 1, 0, 372, "300+Sheet1!B12");\r
+ confirmCell(sheet2, 2, 0, 373, "300+Sheet1!B3");\r
+\r
+ confirmCell(sheet2, 11, 0, 300, "300+Sheet1!#REF!");\r
+\r
+\r
+ // Note - named ranges formulas have not been updated\r
+ }\r
+\r
+ private static void confirmRow(Sheet sheet, int rowIx, double valA, double valB, double valC,\r
+ String formulaA, String formulaB, String formulaC) {\r
+ confirmCell(sheet, rowIx, 4, valA, formulaA);\r
+ confirmCell(sheet, rowIx, 5, valB, formulaB);\r
+ confirmCell(sheet, rowIx, 6, valC, formulaC);\r
+ }\r
+\r
+ private static void confirmCell(Sheet sheet, int rowIx, int colIx,\r
+ double expectedValue, String expectedFormula) {\r
+ Cell cell = sheet.getRow(rowIx).getCell(colIx);\r
+ assertEquals(expectedValue, cell.getNumericCellValue(), 0.0);\r
+ assertEquals(expectedFormula, cell.getCellFormula());\r
+ }\r
+}\r