Browse Source

improved XSSFSheet.shiftRows: 1. properly update cell references of the shifted cells (bugzilla 4663) 2. When shifting rows, update formulas on that sheet to point to the new location of those rows (bugzilla 46536)

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@742126 13f79535-47bb-0310-9956-ffa450edef68
pull/1/head
Yegor Kozlov 15 years ago
parent
commit
56d9c7a528

+ 2
- 0
src/documentation/content/xdocs/changes.xml View File

@@ -37,6 +37,8 @@

<!-- Don't forget to update status.xml too! -->
<release version="3.5-beta5" date="2008-??-??">
<action dev="POI-DEVELOPERS" type="fix">46536 - When shifting rows, update formulas on that sheet to point to the new location of those rows</action>
<action dev="POI-DEVELOPERS" type="fix">46663 - Fixed XSSFSheet.shiftRows to properly update references of the shifted cells</action>
<action dev="POI-DEVELOPERS" type="fix">46535 - Remove reference from calculation chain when a formula is deleted</action>
<action dev="POI-DEVELOPERS" type="fix">46654 - HSSFRow/RowRecord to properly update cell boundary indexes</action>
<action dev="POI-DEVELOPERS" type="fix">46643 - Fixed formula parser to encode range operator with tMemFunc</action>

+ 2
- 0
src/documentation/content/xdocs/status.xml View File

@@ -34,6 +34,8 @@
<!-- Don't forget to update changes.xml too! -->
<changes>
<release version="3.5-beta5" date="2008-??-??">
<action dev="POI-DEVELOPERS" type="fix">46536 - When shifting rows, update formulas on that sheet to point to the new location of those rows</action>
<action dev="POI-DEVELOPERS" type="fix">46663 - Fixed XSSFSheet.shiftRows to properly update references of the shifted cells</action>
<action dev="POI-DEVELOPERS" type="fix">46535 - Remove reference from calculation chain when a formula is deleted</action>
<action dev="POI-DEVELOPERS" type="fix">46654 - HSSFRow/RowRecord to properly update cell boundary indexes</action>
<action dev="POI-DEVELOPERS" type="fix">46643 - Fixed formula parser to encode range operator with tMemFunc</action>

+ 0
- 13
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCell.java View File

@@ -826,17 +826,4 @@ public final class XSSFCell implements Cell {
return cell;
}

/**
* update cell reference when shifting rows
*
* @param row
*/
protected void modifyCellReference(XSSFRow row) {
this.cell.setR(new CellReference(row.getRowNum(), cellNum).formatAsString());

CTCell[] ctCells = row.getCTRow().getCArray();
for (CTCell ctCell : ctCells) {
ctCell.setR(new CellReference(row.getRowNum(), cellNum).formatAsString());
}
}
}

+ 65
- 0
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFRow.java View File

@@ -21,8 +21,16 @@ import java.util.*;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.util.CellReference;
import org.apache.poi.ss.formula.FormulaParser;
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.SharedFormulaRecord;
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.
@@ -391,4 +399,61 @@ public class XSSFRow implements Row, Comparable<XSSFRow> {
public String toString(){
return row.toString();
}

/**
* update cell references when shifting rows
*
* @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;
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());

CTCell ctCell = cell.getCTCell();
String r = new CellReference(rownum, cell.getColumnIndex()).formatAsString();
ctCell.setR(r);

if(ctCell.isSetF()){
CTCellFormula f = ctCell.getF();
String fmla = f.getStringValue();
if(fmla.length() > 0) {
String shiftedFmla = shiftFormula(fmla, n);
f.setStringValue(shiftedFmla);
}
if(f.isSetRef()){ //Range of cells which the formula applies to.
String ref = f.getRef();
String shiftedRef = shiftFormula(ref, n);
f.setRef(shiftedRef);
}
}
}
setRowNum(rownum);
}

/**
* Shift a formula by the specified number of rows
* <p>
* Example: shiftFormula("A1+B1+C1", 3) will return "A4+B4+C4"
* </p>
*
* @param formula the formula to shift
* @param n the number of rows to shift
* @return the shifted formula
*/
private String shiftFormula(String formula, int n){
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);
}

}

+ 10
- 20
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java View File

@@ -24,14 +24,17 @@ import java.util.*;
import javax.xml.namespace.QName;

import org.apache.poi.hssf.util.PaneInformation;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Footer;
import org.apache.poi.ss.usermodel.Header;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.hssf.record.formula.Ptg;
import org.apache.poi.hssf.record.SharedFormulaRecord;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.CellReference;
import org.apache.poi.ss.util.AreaReference;
import org.apache.poi.ss.formula.FormulaParser;
import org.apache.poi.ss.formula.FormulaType;
import org.apache.poi.ss.formula.FormulaRenderer;
import org.apache.poi.xssf.model.CommentsTable;
import org.apache.poi.xssf.model.CalculationChain;
import org.apache.poi.xssf.usermodel.helpers.ColumnHelper;
import org.apache.poi.POIXMLDocumentPart;
import org.apache.poi.POIXMLException;
@@ -1438,7 +1441,7 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
*/
public void shiftRows(int startRow, int endRow, int n, boolean copyRowHeight, boolean resetOriginalRowHeight) {
for (Iterator<Row> it = rowIterator() ; it.hasNext() ; ) {
Row row = it.next();
XSSFRow row = (XSSFRow)it.next();

if (!copyRowHeight) {
row.setHeight((short)-1);
@@ -1451,10 +1454,7 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
it.remove();
}
else if (row.getRowNum() >= startRow && row.getRowNum() <= endRow) {
row.setRowNum(row.getRowNum() + n);
if (row.getFirstCellNum() > -1) {
modifyCellReference((XSSFRow) row);
}
row.shift(n);
}
}
//rebuild the rows map
@@ -1463,16 +1463,6 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
rows = map;
}


private void modifyCellReference(XSSFRow row) {
for (int i = row.getFirstCellNum(); i <= row.getLastCellNum(); i++) {
XSSFCell c = row.getCell(i);
if (c != null) {
c.modifyCellReference(row);
}
}
}

/**
* Location of the top left visible cell Location of the top left visible cell in the bottom right
* pane (when in Left-to-Right mode).

+ 42
- 8
src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheet.java View File

@@ -27,16 +27,11 @@ import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.model.CommentsTable;
import org.apache.poi.xssf.model.StylesTable;
import org.apache.poi.xssf.model.CalculationChain;
import org.apache.poi.xssf.usermodel.helpers.ColumnHelper;
import org.apache.poi.xssf.XSSFTestDataSamples;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCol;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCols;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTComments;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRow;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTXf;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STPane;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.*;


public class TestXSSFSheet extends TestCase {
@@ -608,7 +603,46 @@ public class TestXSSFSheet extends TestCase {
assertNull(sheet6.getRow(7));
assertEquals(8, sheet6.getPhysicalNumberOfRows());
}

/**
* When shifting rows, update formulas on that sheet to point to the new location of those rows
* (see bugzilla 46536)
*/
public void testShiftRows_46536() {
XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("46536.xlsx");
CalculationChain calcChain = wb.getCalculationChain();
int numItems = calcChain.getCTCalcChain().getCArray().length;
assertEquals(3, numItems);

XSSFSheet sheet = wb.getSheet("Test");
XSSFRow row2 = sheet.getRow(1);
XSSFCell cell_A2 = row2.getCell(0);
assertEquals("A2", cell_A2.getReference());

XSSFRow row3 = sheet.getRow(2);
XSSFCell cell_B3 = row3.getCell(1);
assertEquals("B3", cell_B3.getReference());

XSSFCell cell_E2 = row2.getCell(4);
CTCellFormula f = cell_E2.getCTCell().getF();
assertEquals("B2+C2+D2", f.getStringValue());
assertEquals("E2:E3", f.getRef());

sheet.shiftRows(1, sheet.getLastRowNum(), 3, false, true);

assertEquals(4, row2.getRowNum());
assertEquals(5, row3.getRowNum());
assertEquals("A5", cell_A2.getReference());
assertEquals("B6", cell_B3.getReference());

assertEquals("B5+C5+D5", f.getStringValue());
assertEquals("E5:E6", f.getRef());

numItems = calcChain.getCTCalcChain().getCArray().length;
assertEquals(1, numItems);

}

public void testGetCellComment() {
XSSFWorkbook workbook = new XSSFWorkbook();
XSSFSheet sheet = workbook.createSheet();

BIN
src/testcases/org/apache/poi/hssf/data/46536.xlsx View File


Loading…
Cancel
Save