git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@742126 13f79535-47bb-0310-9956-ffa450edef68pull/1/head
@@ -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> |
@@ -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> |
@@ -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()); | |||
} | |||
} | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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). |
@@ -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(); |