diff options
author | Nick Burch <nick@apache.org> | 2015-05-03 07:53:09 +0000 |
---|---|---|
committer | Nick Burch <nick@apache.org> | 2015-05-03 07:53:09 +0000 |
commit | 638e91a06c6999ff0c32bdb78d86e16edc6ae527 (patch) | |
tree | 68aa615ea8046a71b63bdfbd4a5935dbb3c5f3e8 /src | |
parent | 1a68cc6a2ebd96731cd5269841cd3411240868c9 (diff) | |
download | poi-638e91a06c6999ff0c32bdb78d86e16edc6ae527.tar.gz poi-638e91a06c6999ff0c32bdb78d86e16edc6ae527.zip |
Somewhat speed up creating data formats with large counts, and add maximum format/style count checking. #57884
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1677368 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src')
-rw-r--r-- | src/ooxml/java/org/apache/poi/xssf/model/StylesTable.java | 38 |
1 files changed, 24 insertions, 14 deletions
diff --git a/src/ooxml/java/org/apache/poi/xssf/model/StylesTable.java b/src/ooxml/java/org/apache/poi/xssf/model/StylesTable.java index 53d1b76515..d0383754f0 100644 --- a/src/ooxml/java/org/apache/poi/xssf/model/StylesTable.java +++ b/src/ooxml/java/org/apache/poi/xssf/model/StylesTable.java @@ -22,7 +22,7 @@ import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.Arrays; -import java.util.LinkedHashMap; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -30,6 +30,7 @@ import java.util.Map.Entry; import org.apache.poi.POIXMLDocumentPart; import org.apache.poi.openxml4j.opc.PackagePart; import org.apache.poi.openxml4j.opc.PackageRelationship; +import org.apache.poi.ss.SpreadsheetVersion; import org.apache.poi.ss.usermodel.BuiltinFormats; import org.apache.poi.ss.usermodel.FontFamily; import org.apache.poi.ss.usermodel.FontScheme; @@ -59,11 +60,10 @@ import org.openxmlformats.schemas.spreadsheetml.x2006.main.StyleSheetDocument; /** * Table of styles shared across all sheets in a workbook. - * - * @author ugo */ public class StylesTable extends POIXMLDocumentPart { - private final Map<Integer, String> numberFormats = new LinkedHashMap<Integer,String>(); + private final Map<Integer, String> numberFormats = new HashMap<Integer,String>(); + private final boolean[] usedNumberFormats = new boolean[SpreadsheetVersion.EXCEL2007.getMaxCellStyles()]; private final List<XSSFFont> fonts = new ArrayList<XSSFFont>(); private final List<XSSFCellFill> fills = new ArrayList<XSSFCellFill>(); private final List<XSSFCellBorder> borders = new ArrayList<XSSFCellBorder>(); @@ -76,6 +76,7 @@ public class StylesTable extends POIXMLDocumentPart { * The first style id available for use as a custom style */ public static final int FIRST_CUSTOM_STYLE_ID = BuiltinFormats.FIRST_USER_DEFINED_FORMAT_INDEX + 1; + private static final int MAXIMUM_STYLE_ID = SpreadsheetVersion.EXCEL2007.getMaxCellStyles(); private StyleSheetDocument doc; private ThemesTable theme; @@ -130,7 +131,9 @@ public class StylesTable extends POIXMLDocumentPart { CTNumFmts ctfmts = styleSheet.getNumFmts(); if( ctfmts != null){ for (CTNumFmt nfmt : ctfmts.getNumFmtArray()) { - numberFormats.put((int)nfmt.getNumFmtId(), nfmt.getFormatCode()); + int formatId = (int)nfmt.getNumFmtId(); + numberFormats.put(formatId, nfmt.getFormatCode()); + usedNumberFormats[formatId] = true; } } @@ -183,21 +186,24 @@ public class StylesTable extends POIXMLDocumentPart { public int putNumberFormat(String fmt) { if (numberFormats.containsValue(fmt)) { // Find the key, and return that - for(Integer key : numberFormats.keySet() ) { - if(numberFormats.get(key).equals(fmt)) { - return key; + for (Entry<Integer,String> numFmt : numberFormats.entrySet()) { + if(numFmt.getValue().equals(fmt)) { + return numFmt.getKey(); } } throw new IllegalStateException("Found the format, but couldn't figure out where - should never happen!"); } // Find a spare key, and add that - int newKey = FIRST_CUSTOM_STYLE_ID; - while(numberFormats.containsKey(newKey)) { - newKey++; + for (int i=FIRST_CUSTOM_STYLE_ID; i<usedNumberFormats.length; i++) { + if (!usedNumberFormats[i]) { + usedNumberFormats[i] = true; + numberFormats.put(i, fmt); + return i; + } } - numberFormats.put(newKey, fmt); - return newKey; + throw new IllegalStateException("The maximum number of Data Formats was exceeded. " + + "You can define up to " + usedNumberFormats.length + " formats in a .xlsx Workbook"); } public XSSFFont getFontAt(int idx) { @@ -532,13 +538,17 @@ public class StylesTable extends POIXMLDocumentPart { } public XSSFCellStyle createCellStyle() { + int xfSize = styleXfs.size(); + if (xfSize > MAXIMUM_STYLE_ID) + throw new IllegalStateException("The maximum number of Cell Styles was exceeded. " + + "You can define up to " + MAXIMUM_STYLE_ID + " style in a .xlsx Workbook"); + CTXf xf = CTXf.Factory.newInstance(); xf.setNumFmtId(0); xf.setFontId(0); xf.setFillId(0); xf.setBorderId(0); xf.setXfId(0); - int xfSize = styleXfs.size(); int indexXf = putCellXf(xf); return new XSSFCellStyle(indexXf - 1, xfSize - 1, this, theme); } |