Fix for bug #62130. Turns out there were cases when a workbook with multiple edit/save cycles on the same instance would save stale cell data, resulting in incorrect copies.

Includes new unit test.

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1825277 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Greg Woolsey 2018-02-24 21:30:47 +00:00
parent 617013a376
commit 02719ac4ba
2 changed files with 36 additions and 35 deletions

View File

@ -498,43 +498,21 @@ public class XSSFRow implements Row, Comparable<XSSFRow> {
* @see org.apache.poi.xssf.usermodel.XSSFSheet#write(java.io.OutputStream) ()
*/
protected void onDocumentWrite(){
// check if cells in the CTRow are ordered
boolean isOrdered = true;
CTCell[] cArray = _row.getCArray();
if (cArray.length != _cells.size()) {
isOrdered = false;
} else {
int i = 0;
for (XSSFCell cell : _cells.values()) {
CTCell c1 = cell.getCTCell();
CTCell c2 = cArray[i++];
String r1 = c1.getR();
String r2 = c2.getR();
if (!(r1==null ? r2==null : r1.equals(r2))){
isOrdered = false;
break;
}
}
CTCell[] cArray = new CTCell[_cells.size()];
int i = 0;
for (XSSFCell xssfCell : _cells.values()) {
cArray[i] = (CTCell) xssfCell.getCTCell().copy();
// we have to copy and re-create the XSSFCell here because the
// elements as otherwise setCArray below invalidates all the columns!
// see Bug 56170, XMLBeans seems to always release previous objects
// in the CArray, so we need to provide completely new ones here!
//_cells.put(entry.getKey(), new XSSFCell(this, cArray[i]));
xssfCell.setCTCell(cArray[i]);
i++;
}
if(!isOrdered){
cArray = new CTCell[_cells.size()];
int i = 0;
for (XSSFCell xssfCell : _cells.values()) {
cArray[i] = (CTCell) xssfCell.getCTCell().copy();
// we have to copy and re-create the XSSFCell here because the
// elements as otherwise setCArray below invalidates all the columns!
// see Bug 56170, XMLBeans seems to always release previous objects
// in the CArray, so we need to provide completely new ones here!
//_cells.put(entry.getKey(), new XSSFCell(this, cArray[i]));
xssfCell.setCTCell(cArray[i]);
i++;
}
_row.setCArray(cArray);
}
_row.setCArray(cArray);
}
/**

View File

@ -18,6 +18,7 @@
package org.apache.poi.xssf.usermodel;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertSame;
@ -27,9 +28,11 @@ import org.apache.poi.ss.usermodel.BaseTestXRow;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellCopyPolicy;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.RichTextString;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.XSSFITestDataProvider;
import org.apache.poi.xssf.XSSFTestDataSamples;
import org.junit.Test;
/**
@ -193,4 +196,24 @@ public final class TestXSSFRow extends BaseTestXRow {
workbook.close();
}
@Test
public void testMultipleEditWriteCycles() {
final XSSFWorkbook wb1 = new XSSFWorkbook();
final XSSFSheet sheet1 = wb1.createSheet("Sheet1");
final XSSFRow srcRow = sheet1.createRow(0);
srcRow.createCell(0).setCellValue("hello");
srcRow.createCell(3).setCellValue("world");
// discard result
XSSFTestDataSamples.writeOutAndReadBack(wb1);
srcRow.createCell(1).setCellValue("cruel");
// discard result
XSSFTestDataSamples.writeOutAndReadBack(wb1);
srcRow.getCell(1).setCellValue((RichTextString) null);
XSSFWorkbook wb3 = XSSFTestDataSamples.writeOutAndReadBack(wb1);
assertEquals("Cell not blank", CellType.BLANK, wb3.getSheet("Sheet1").getRow(0).getCell(1).getCellType());
}
}