try to improve performance of XSSFSheet row/col grouping/ungrouping

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1907065 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
PJ Fanning 2023-01-28 20:13:33 +00:00
parent edaeb54967
commit 1cf4094e2d
2 changed files with 59 additions and 21 deletions

View File

@ -1245,7 +1245,7 @@ public class SXSSFSheet implements Sheet, OoxmlSheetExtensions {
} }
/** /**
* Ungroup a range of columns that were previously groupped * Ungroup a range of columns that were previously grouped
* *
* @param fromColumn start column (0-based) * @param fromColumn start column (0-based)
* @param toColumn end column (0-based) * @param toColumn end column (0-based)
@ -1340,7 +1340,7 @@ public class SXSSFSheet implements Sheet, OoxmlSheetExtensions {
} }
/** /**
* Ungroup a range of rows that were previously groupped * Ungroup a range of rows that were previously grouped
* *
* @param fromRow start row (0-based) * @param fromRow start row (0-based)
* @param toRow end row (0-based) * @param toRow end row (0-based)
@ -1355,7 +1355,7 @@ public class SXSSFSheet implements Sheet, OoxmlSheetExtensions {
* *
* <i>Not implemented for expanding (i.e. collapse == false)</i> * <i>Not implemented for expanding (i.e. collapse == false)</i>
* *
* @param row start row of a groupped range of rows (0-based) * @param row start row of a grouped range of rows (0-based)
* @param collapse whether to expand/collapse the detail rows * @param collapse whether to expand/collapse the detail rows
* @throws IllegalStateException if collapse is false as this is not implemented for SXSSF. * @throws IllegalStateException if collapse is false as this is not implemented for SXSSF.
*/ */

View File

@ -1695,15 +1695,20 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet, OoxmlSheetEx
this.columnHelper.setColumnAttributes(fixCol_before, fixCol_after); this.columnHelper.setColumnAttributes(fixCol_before, fixCol_after);
} }
for(int index=fromColumn;index<=toColumn;index++){ int maxLevelCol = -1;
CTCol col=columnHelper.getColumn1Based(index, false); for(int index = fromColumn; index <= toColumn; index++){
CTCol col = columnHelper.getColumn1Based(index, false);
//col must exist //col must exist
short outlineLevel=col.getOutlineLevel(); final short outlineLevel = col.getOutlineLevel();
col.setOutlineLevel((short)(outlineLevel+1)); final int newOutlineLevel = outlineLevel + 1;
col.setOutlineLevel((short) newOutlineLevel);
maxLevelCol = Math.max(maxLevelCol, newOutlineLevel);
index = Math.toIntExact(col.getMax()); index = Math.toIntExact(col.getMax());
} }
worksheet.setColsArray(0,ctCols); worksheet.setColsArray(0, ctCols);
setSheetFormatPrOutlineLevelCol(); if (maxLevelCol > getSheetFormatPrOutlineLevelCol()) {
increaseSheetFormatPrOutlineLevelColIfNecessary((short) maxLevelCol);
}
} }
/** /**
@ -1726,16 +1731,21 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet, OoxmlSheetEx
*/ */
@Override @Override
public void groupRow(int fromRow, int toRow) { public void groupRow(int fromRow, int toRow) {
int maxOutlineLevel = -1;
for (int i = fromRow; i <= toRow; i++) { for (int i = fromRow; i <= toRow; i++) {
XSSFRow xrow = getRow(i); XSSFRow xrow = getRow(i);
if (xrow == null) { if (xrow == null) {
xrow = createRow(i); xrow = createRow(i);
} }
CTRow ctrow = xrow.getCTRow(); CTRow ctrow = xrow.getCTRow();
short outlineLevel = ctrow.getOutlineLevel(); final short outlineLevel = ctrow.getOutlineLevel();
ctrow.setOutlineLevel((short) (outlineLevel + 1)); final int newOutlineLevel = outlineLevel + 1;
maxOutlineLevel = Math.max(maxOutlineLevel, newOutlineLevel);
ctrow.setOutlineLevel((short) newOutlineLevel);
}
if (maxOutlineLevel >= 0) {
increaseSheetFormatPrOutlineLevelRowIfNecessary((short) maxOutlineLevel);
} }
setSheetFormatPrOutlineLevelRow();
} }
private short getMaxOutlineLevelRows(){ private short getMaxOutlineLevelRows(){
@ -3391,10 +3401,12 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet, OoxmlSheetEx
@Override @Override
public void ungroupColumn(int fromColumn, int toColumn) { public void ungroupColumn(int fromColumn, int toColumn) {
CTCols cols = worksheet.getColsArray(0); CTCols cols = worksheet.getColsArray(0);
int maxLevelCol = -1;
for (int index = fromColumn; index <= toColumn; index++) { for (int index = fromColumn; index <= toColumn; index++) {
CTCol col = columnHelper.getColumn(index, false); CTCol col = columnHelper.getColumn(index, false);
if (col != null) { if (col != null) {
short outlineLevel = col.getOutlineLevel(); final short outlineLevel = col.getOutlineLevel();
maxLevelCol = Math.max(maxLevelCol, outlineLevel);
col.setOutlineLevel((short) (outlineLevel - 1)); col.setOutlineLevel((short) (outlineLevel - 1));
index = Math.toIntExact(col.getMax()); index = Math.toIntExact(col.getMax());
@ -3405,39 +3417,65 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet, OoxmlSheetEx
} }
} }
worksheet.setColsArray(0, cols); worksheet.setColsArray(0, cols);
setSheetFormatPrOutlineLevelCol(); if (maxLevelCol >= getSheetFormatPrOutlineLevelCol()) {
setSheetFormatPrOutlineLevelCol();
}
} }
/** /**
* Ungroup a range of rows that were previously groupped * Ungroup a range of rows that were previously grouped
* *
* @param fromRow start row (0-based) * @param fromRow start row (0-based)
* @param toRow end row (0-based) * @param toRow end row (0-based)
*/ */
@Override @Override
public void ungroupRow(int fromRow, int toRow) { public void ungroupRow(int fromRow, int toRow) {
int maxOutlineLevel = -1;
for (int i = fromRow; i <= toRow; i++) { for (int i = fromRow; i <= toRow; i++) {
XSSFRow xrow = getRow(i); XSSFRow xrow = getRow(i);
if (xrow != null) { if (xrow != null) {
CTRow ctRow = xrow.getCTRow(); CTRow ctRow = xrow.getCTRow();
int outlineLevel = ctRow.getOutlineLevel(); final short outlineLevel = ctRow.getOutlineLevel();
ctRow.setOutlineLevel((short) (outlineLevel - 1)); ctRow.setOutlineLevel((short) (outlineLevel - 1));
maxOutlineLevel = Math.max(maxOutlineLevel, outlineLevel);
//remove a row only if the row has no cell and if the outline level is 0 //remove a row only if the row has no cell and if the outline level is 0
if (outlineLevel == 1 && xrow.getFirstCellNum() == -1) { if (outlineLevel == 1 && xrow.getFirstCellNum() == -1) {
removeRow(xrow); removeRow(xrow);
} }
} }
} }
setSheetFormatPrOutlineLevelRow(); if (maxOutlineLevel >= getSheetFormatPrOutlineLevelRow()) {
setSheetFormatPrOutlineLevelRow();
}
} }
private void setSheetFormatPrOutlineLevelRow(){ private void increaseSheetFormatPrOutlineLevelRowIfNecessary(final short levelRow) {
short maxLevelRow=getMaxOutlineLevelRows(); if (levelRow > getSheetFormatPrOutlineLevelRow()) {
getSheetTypeSheetFormatPr().setOutlineLevelRow(levelRow);
}
}
private void increaseSheetFormatPrOutlineLevelColIfNecessary(final short levelCol) {
if (levelCol > getSheetFormatPrOutlineLevelCol()) {
getSheetTypeSheetFormatPr().setOutlineLevelCol(levelCol);
}
}
private void setSheetFormatPrOutlineLevelRow() {
final short maxLevelRow = getMaxOutlineLevelRows();
getSheetTypeSheetFormatPr().setOutlineLevelRow(maxLevelRow); getSheetTypeSheetFormatPr().setOutlineLevelRow(maxLevelRow);
} }
private void setSheetFormatPrOutlineLevelCol(){ private short getSheetFormatPrOutlineLevelRow() {
short maxLevelCol=getMaxOutlineLevelCols(); return getSheetTypeSheetFormatPr().getOutlineLevelRow();
}
private short getSheetFormatPrOutlineLevelCol() {
return getSheetTypeSheetFormatPr().getOutlineLevelCol();
}
private void setSheetFormatPrOutlineLevelCol() {
final short maxLevelCol = getMaxOutlineLevelCols();
getSheetTypeSheetFormatPr().setOutlineLevelCol(maxLevelCol); getSheetTypeSheetFormatPr().setOutlineLevelCol(maxLevelCol);
} }