try to improve performance when removing rows

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1895125 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
PJ Fanning 2021-11-17 22:41:00 +00:00
parent 9c81d7f588
commit 106557ede6
1 changed files with 27 additions and 36 deletions

View File

@ -24,18 +24,7 @@ import static org.apache.poi.xssf.usermodel.helpers.XSSFPasswordHelper.validateP
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.ArrayList; import java.util.*;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
import javax.xml.namespace.QName; import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamException;
@ -3034,13 +3023,15 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
} }
// remove all rows which will be overwritten // remove all rows which will be overwritten
private void removeOverwritten(XSSFVMLDrawing vml, int startRow, int endRow, final int n){ private void removeOverwritten(XSSFVMLDrawing vml, int startRow, int endRow, final int n) {
HashSet<Integer> rowsToRemoveSet = new HashSet<>();
for (Iterator<Row> it = rowIterator() ; it.hasNext() ; ) { for (Iterator<Row> it = rowIterator() ; it.hasNext() ; ) {
XSSFRow row = (XSSFRow)it.next(); XSSFRow row = (XSSFRow)it.next();
int rownum = row.getRowNum(); int rownum = row.getRowNum();
// check if we should remove this row as it will be overwritten by the data later // check if we should remove this row as it will be overwritten by the data later
if (shouldRemoveRow(startRow, endRow, n, rownum)) { if (shouldRemoveRow(startRow, endRow, n, rownum)) {
rowsToRemoveSet.add(rownum);
for (Cell c : row) { for (Cell c : row) {
if (!c.isPartOfArrayFormulaGroup()) { if (!c.isPartOfArrayFormulaGroup()) {
//the support for deleting cells that are part of array formulas is not implemented yet //the support for deleting cells that are part of array formulas is not implemented yet
@ -3056,35 +3047,35 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
// remove row from _rows // remove row from _rows
it.remove(); it.remove();
}
}
// FIXME: (performance optimization) this should be moved outside the for-loop so that comments only needs to be iterated over once. // also remove any comments associated with this row
// also remove any comments associated with this row if (sheetComments != null) {
if(sheetComments != null){ CTCommentList lst = sheetComments.getCTComments().getCommentList();
CTCommentList lst = sheetComments.getCTComments().getCommentList(); for (CTComment comment : lst.getCommentArray()) {
for (CTComment comment : lst.getCommentArray()) { String strRef = comment.getRef();
String strRef = comment.getRef(); CellAddress ref = new CellAddress(strRef);
CellAddress ref = new CellAddress(strRef);
// is this comment part of the current row? // is this comment part of the current row?
if(ref.getRow() == rownum) { if(rowsToRemoveSet.contains(ref.getRow())) {
sheetComments.removeComment(ref); sheetComments.removeComment(ref);
vml.removeCommentShape(ref.getRow(), ref.getColumn()); vml.removeCommentShape(ref.getRow(), ref.getColumn());
}
}
}
// FIXME: (performance optimization) this should be moved outside the for-loop so that hyperlinks only needs to be iterated over once.
// also remove any hyperlinks associated with this row
if (hyperlinks != null) {
for (XSSFHyperlink link : new ArrayList<>(hyperlinks)) {
CellReference ref = new CellReference(link.getCellRef());
if (ref.getRow() == rownum) {
hyperlinks.remove(link);
}
}
} }
} }
} }
// also remove any hyperlinks associated with this row
if (hyperlinks != null) {
for (XSSFHyperlink link : new ArrayList<>(hyperlinks)) {
CellReference ref = new CellReference(link.getCellRef());
if (rowsToRemoveSet.contains(ref.getRow())) {
hyperlinks.remove(link);
}
}
}
} }
private void shiftCommentsAndRows(XSSFVMLDrawing vml, int startRow, int endRow, final int n){ private void shiftCommentsAndRows(XSSFVMLDrawing vml, int startRow, int endRow, final int n){