From ce77cd62701744ba37dc37d46baea7ceb3153f29 Mon Sep 17 00:00:00 2001 From: Dominik Stadler Date: Sun, 5 Nov 2017 20:33:28 +0000 Subject: Bug #57517: Fix various things in HSSFOptimiser to make many more cases work fine: Column styles, row styles, user defined styles, ... Also call optimise in integration-tests and handle some cases of invalid content in files. git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1814373 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/poi/hssf/model/InternalSheet.java | 8 + .../apache/poi/hssf/model/InternalWorkbook.java | 21 +++ .../aggregates/ColumnInfoRecordsAggregate.java | 33 ++++ .../apache/poi/hssf/usermodel/HSSFOptimiser.java | 169 +++++++++++++++------ 4 files changed, 182 insertions(+), 49 deletions(-) (limited to 'src/java') diff --git a/src/java/org/apache/poi/hssf/model/InternalSheet.java b/src/java/org/apache/poi/hssf/model/InternalSheet.java index 650b4de270..83e1d37907 100644 --- a/src/java/org/apache/poi/hssf/model/InternalSheet.java +++ b/src/java/org/apache/poi/hssf/model/InternalSheet.java @@ -1680,4 +1680,12 @@ public final class InternalSheet { public int getColumnOutlineLevel(int columnIndex) { return _columnInfos.getOutlineLevel(columnIndex); } + + public int getMinColumnIndex() { + return _columnInfos.getMinColumnIndex(); + } + + public int getMaxColumnIndex() { + return _columnInfos.getMaxColumnIndex(); + } } diff --git a/src/java/org/apache/poi/hssf/model/InternalWorkbook.java b/src/java/org/apache/poi/hssf/model/InternalWorkbook.java index 5b9e7c57ae..d16eec62ee 100644 --- a/src/java/org/apache/poi/hssf/model/InternalWorkbook.java +++ b/src/java/org/apache/poi/hssf/model/InternalWorkbook.java @@ -936,6 +936,27 @@ public final class InternalWorkbook { return null; } + /** + * Update the StyleRecord to point to the new + * given index. + * + * @param oldXf the extended format index that was previously associated with this StyleRecord + * @param newXf the extended format index that is now associated with this StyleRecord + */ + public void updateStyleRecord(int oldXf, int newXf) { + // Style records always follow after + // the ExtendedFormat records + for(int i=records.getXfpos(); iColumnInfoRecord which contains the specified columnIndex * @param columnIndex index of the column (not the index of the ColumnInfoRecord) @@ -504,6 +505,7 @@ public final class ColumnInfoRecordsAggregate extends RecordAggregate implements } return null; } + public int getMaxOutlineLevel() { int result = 0; int count=records.size(); @@ -513,6 +515,7 @@ public final class ColumnInfoRecordsAggregate extends RecordAggregate implements } return result; } + public int getOutlineLevel(int columnIndex) { ColumnInfoRecord ci = findColumnInfo(columnIndex); if (ci != null) { @@ -521,4 +524,34 @@ public final class ColumnInfoRecordsAggregate extends RecordAggregate implements return 0; } } + + public int getMinColumnIndex() { + if(records.isEmpty()) { + return 0; + } + + int minIndex = Integer.MAX_VALUE; + int nInfos = records.size(); + for(int i=0; i< nInfos; i++) { + ColumnInfoRecord ci = getColInfo(i); + minIndex = Math.min(minIndex, ci.getFirstColumn()); + } + + return minIndex; + } + + public int getMaxColumnIndex() { + if(records.isEmpty()) { + return 0; + } + + int maxIndex = 0; + int nInfos = records.size(); + for(int i=0; i< nInfos; i++) { + ColumnInfoRecord ci = getColInfo(i); + maxIndex = Math.max(maxIndex, ci.getLastColumn()); + } + + return maxIndex; + } } diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFOptimiser.java b/src/java/org/apache/poi/hssf/usermodel/HSSFOptimiser.java index c38fd375b2..f4287ce4b5 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFOptimiser.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFOptimiser.java @@ -20,6 +20,7 @@ import java.util.HashSet; import org.apache.poi.hssf.record.ExtendedFormatRecord; import org.apache.poi.hssf.record.FontRecord; +import org.apache.poi.hssf.record.StyleRecord; import org.apache.poi.hssf.record.common.UnicodeString; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellType; @@ -185,50 +186,81 @@ public class HSSFOptimiser { // Get each style record, so we can do deletes // without getting confused - ExtendedFormatRecord[] xfrs = new ExtendedFormatRecord[newPos.length]; + ExtendedFormatRecord[] xfrs = new ExtendedFormatRecord[newPos.length]; for(int i=0; i= 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); + } - HSSFCellStyle newStyle = workbook.getCellStyleAt( - newPos[oldXf] - ); - cell.setCellStyle(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); + } + } } + + private static boolean isUserDefined(HSSFWorkbook workbook, int index) { + StyleRecord styleRecord = workbook.getWorkbook().getStyleRecord(index); + return styleRecord != null && + !styleRecord.isBuiltin() && + styleRecord.getName() != null; + } } -- cgit v1.2.3