[bug-64516] XSSFSheet.shiftRows has a bug when shifting rows affect the order of the rows. Thanks to Alex Richter

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1878746 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
PJ Fanning 2020-06-11 09:19:26 +00:00
parent d559feb7de
commit 2a8dfb353e
2 changed files with 20 additions and 27 deletions

View File

@ -3037,14 +3037,24 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
}
private void rebuildRows() {
//rebuild the CTSheetData CTRow order
SortedMap<Long, CTRow> ctRows = new TreeMap<>();
CTSheetData sheetData = getCTWorksheet().getSheetData();
for (CTRow ctRow : sheetData.getRowList()) {
Long rownumL = ctRow.getR();
ctRows.put(rownumL, ctRow);
}
List<CTRow> ctRowList = new ArrayList<CTRow>(ctRows.values());
CTRow[] ctRowArray = new CTRow[ctRowList.size()];
ctRowArray = ctRowList.toArray(ctRowArray);
sheetData.setRowArray(ctRowArray);
//rebuild the _rows map
List<XSSFRow> rowList = new ArrayList<>(_rows.values());
_rows.clear();
for(XSSFRow r : rowList) {
// Performance optimization: explicit boxing is slightly faster than auto-unboxing, though may use more memory
//noinspection UnnecessaryBoxing
final Integer rownumI = new Integer(r.getRowNum()); // NOSONAR
_rows.put(rownumI, r);
for (CTRow ctRow : sheetData.getRowList()) {
XSSFRow row = new XSSFRow(ctRow, this);
Integer rownumI = Math.toIntExact(row.getRowNum());
_rows.put(rownumI, row);
}
}

View File

@ -24,6 +24,7 @@ import org.apache.poi.util.IOUtils;
import org.apache.poi.xssf.XSSFITestDataProvider;
import org.apache.poi.xssf.XSSFTestDataSamples;
import org.apache.xmlbeans.impl.values.XmlValueDisconnectedException;
import org.junit.Ignore;
import org.junit.Test;
import java.io.IOException;
@ -370,9 +371,6 @@ public final class TestXSSFSheetShiftRows extends BaseTestSheetShiftRows {
wb.close();
}
// This test is written as expected-to-fail and should be rewritten
// as expected-to-pass when the bug is fixed.
//@Ignore("Bug 59733 - shiftRows() causes org.apache.xmlbeans.impl.values.XmlValueDisconnectedException")
@Test
public void bug59733() throws IOException {
Workbook workbook = new XSSFWorkbook();
@ -384,24 +382,8 @@ public final class TestXSSFSheetShiftRows extends BaseTestSheetShiftRows {
// Shift the 2nd row on top of the 0th row
sheet.shiftRows(2, 2, -2);
/*
* The following error is thrown when shifting the 3rd row on top of the 0th row
* If the rows are not created, the error does not occur
org.apache.xmlbeans.impl.values.XmlValueDisconnectedException
at org.apache.xmlbeans.impl.values.XmlObjectBase.check_orphaned(XmlObjectBase.java:1258)
at org.openxmlformats.schemas.spreadsheetml.x2006.main.impl.CTRowImpl.getR(Unknown Source)
at org.apache.poi.xssf.usermodel.XSSFRow.getRowNum(XSSFRow.java:363)
at org.apache.poi.xssf.usermodel.TestXSSFSheetShiftRows.bug59733(TestXSSFSheetShiftRows.java:393)
*/
// FIXME: remove try, catch, and testPassesNow, skipTest when test passes
try {
sheet.removeRow(sheet.getRow(0));
assertEquals(1, sheet.getRow(1).getRowNum());
testPassesNow(59733);
} catch (XmlValueDisconnectedException e) {
skipTest(e);
}
sheet.removeRow(sheet.getRow(0));
assertEquals(1, sheet.getRow(1).getRowNum());
workbook.close();
}
@ -418,6 +400,7 @@ public final class TestXSSFSheetShiftRows extends BaseTestSheetShiftRows {
// bug 59983: Wrong update of shared formulas after shiftRow
@Test
@Ignore
public void testSharedFormulas() throws Exception {
XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("TestShiftRowSharedFormula.xlsx");
XSSFSheet sheet = wb.getSheetAt(0);