in poi/src/main/java/org/apache/poi/hssf/usermodel/HSSFOptimiser.java [175:359]
public static void optimiseCellStyles(HSSFWorkbook workbook) {
// Where each style has ended up, and if we need to
// delete the record for it. Start off with no change
short[] newPos = new short[workbook.getWorkbook().getNumExFormats()];
boolean[] isUsed = new boolean[newPos.length];
boolean[] zapRecords = new boolean[newPos.length];
// to speed up the optimisation for workbooks with a large number of
// styles we perform the isUserDefined() check only once as it is
// costly according to some profiling
boolean[] userDefined = new boolean[newPos.length];
// Get each style record, so we can do deletes
// without getting confused
ExtendedFormatRecord[] xfrs = new ExtendedFormatRecord[newPos.length];
for(int i=0; i<newPos.length; i++) {
isUsed[i] = false;
newPos[i] = (short)i;
zapRecords[i] = false;
userDefined[i] = isUserDefined(workbook, i);
xfrs[i] = workbook.getWorkbook().getExFormatAt(i);
}
// Loop over each style, seeing if it is the same
// as an earlier one. If it is, point users of the
// later duplicate copy to the earlier one, and
// mark the later one as needing deleting
// Only work on user added ones, which come after 20
for (int i = 21; i < newPos.length; i++) {
// Check this one for being a duplicate
// of an earlier one
int earlierDuplicate = -1;
for (int j = 0; j < i; j++) {
ExtendedFormatRecord xfCheck = workbook.getWorkbook().getExFormatAt(j);
if (xfCheck.equals(xfrs[i]) &&
// never duplicate user defined styles
!userDefined[j]) {
earlierDuplicate = j;
break;
}
}
// If we got a duplicate, mark it as such
if(earlierDuplicate != -1) {
newPos[i] = (short)earlierDuplicate;
zapRecords[i] = true;
}
}
// Loop over all the cells in the file, and identify any user defined
// styles aren't actually being used (don't touch built-in ones)
for (int sheetNum = 0; sheetNum < workbook.getNumberOfSheets(); sheetNum++) {
HSSFSheet s = workbook.getSheetAt(sheetNum);
for (Row row : s) {
for (Cell cellI : row) {
HSSFCell cell = (HSSFCell) cellI;
short oldXf = cell.getCellValueRecord().getXFIndex();
// some documents contain invalid values here
if(oldXf < newPos.length) {
isUsed[oldXf] = true;
}
}
// also mark row style as being used
short oldXf = ((HSSFRow) row).getRowRecord().getXFIndex();
// some documents contain invalid values here
if(oldXf < newPos.length) {
isUsed[oldXf] = true;
}
}
// also mark column styles as being used
for (int col = s.getSheet().getMinColumnIndex(); col <= s.getSheet().getMaxColumnIndex(); col++) {
short oldXf = s.getSheet().getXFIndexForColAt((short) col);
// some documents contain invalid values here
if(oldXf < newPos.length) {
isUsed[oldXf] = true;
}
}
}
// Propagate isUsed for duplicates and always set user styles to being used to never optimize them away
for (int i = 21; i < isUsed.length; i++) {
// user defined styles are always "used"
if (isUserDefined(workbook, i)) {
isUsed[i] = true;
}
// If we got a duplicate which is used, mark the one we're keeping as used
if(newPos[i] != i && isUsed[i]) {
isUsed[newPos[i]] = true;
}
}
// Mark any that aren't used as needing zapping
for (int i=21; i<isUsed.length; i++) {
if (! isUsed[i]) {
// Un-used style, can be removed
zapRecords[i] = true;
newPos[i] = 0;
}
}
// Update the new positions based on
// deletes that have occurred between
// the start and them
// Only work on user added ones, which come after 20
for(int i=21; i<newPos.length; i++) {
// Find the number deleted to that
// point, and adjust
short preDeletePos = newPos[i];
short newPosition = preDeletePos;
for(int j=0; j<preDeletePos; j++) {
if(zapRecords[j]) newPosition--;
}
// Update the new position
newPos[i] = newPosition;
// also update StyleRecord and Parent-link
if (i != newPosition && newPosition != 0) {
workbook.getWorkbook().updateStyleRecord(i, newPosition);
ExtendedFormatRecord exFormat = workbook.getWorkbook().getExFormatAt(i);
short oldParent = exFormat.getParentIndex();
// some documents contain invalid values here
if(oldParent < newPos.length) {
short newParent = newPos[oldParent];
exFormat.setParentIndex(newParent);
}
}
}
// Zap the un-needed user style records
// removing by index, because removing by object may delete
// styles we did not intend to (the ones that _were_ duplicated and not the duplicates)
int max = newPos.length;
int removed = 0; // to adjust index after deletion
for(int i=21; i<max; i++) {
if(zapRecords[i + removed]) {
workbook.getWorkbook().removeExFormatRecord(i);
i--;
max--;
removed++;
}
}
// Finally, update the cells to point at their new extended format records
for (int sheetNum = 0; sheetNum < workbook.getNumberOfSheets(); sheetNum++) {
HSSFSheet s = workbook.getSheetAt(sheetNum);
for (Row row : s) {
for (Cell cell : row) {
short oldXf = ((HSSFCell) cell).getCellValueRecord().getXFIndex();
// some documents contain invalid values here
if(oldXf >= newPos.length) {
continue;
}
HSSFCellStyle newStyle = workbook.getCellStyleAt(newPos[oldXf]);
cell.setCellStyle(newStyle);
}
// adjust row column style
short oldXf = ((HSSFRow) row).getRowRecord().getXFIndex();
// some documents contain invalid values here
if(oldXf >= newPos.length) {
continue;
}
HSSFCellStyle newStyle = workbook.getCellStyleAt(newPos[oldXf]);
row.setRowStyle(newStyle);
}
// adjust cell column style
for (int col = s.getSheet().getMinColumnIndex(); col <= s.getSheet().getMaxColumnIndex(); col++) {
short oldXf = s.getSheet().getXFIndexForColAt((short) col);
// some documents contain invalid values here
if(oldXf >= newPos.length) {
continue;
}
HSSFCellStyle newStyle = workbook.getCellStyleAt(newPos[oldXf]);
s.setDefaultColumnStyle(col, newStyle);
}
}
}