]> source.dussan.org Git - poi.git/commitdiff
Fix bug #49928 for HSSF too - refactor HSSFDataFormat to allow overriding of built...
authorNick Burch <nick@apache.org>
Thu, 20 Jan 2011 13:20:24 +0000 (13:20 +0000)
committerNick Burch <nick@apache.org>
Thu, 20 Jan 2011 13:20:24 +0000 (13:20 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1061288 13f79535-47bb-0310-9956-ffa450edef68

src/documentation/content/xdocs/status.xml
src/java/org/apache/poi/hssf/model/InternalWorkbook.java
src/java/org/apache/poi/hssf/usermodel/HSSFDataFormat.java
src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFDataFormat.java
src/testcases/org/apache/poi/hssf/usermodel/TestHSSFDataFormat.java
src/testcases/org/apache/poi/ss/usermodel/BaseTestDataFormat.java
test-data/spreadsheet/49928.xls [new file with mode: 0644]

index 202938cffdf0063d2d511cc1ae8f7dfa1ddc0bf1..71143cde3de49fbf41620907aa4705a93db07b7a 100644 (file)
@@ -34,6 +34,7 @@
 
     <changes>
         <release version="3.8-beta1" date="2010-??-??">
+           <action dev="poi-developers" type="add">49928 - allow overridden built-in formats in HSSFCellStyle</action>
            <action dev="POI-DEVELOPERS" type="add">50607 - Added implementation for CLEAN(), CHAR() and ADDRESS()</action>
            <action dev="poi-developers" type="add">50587 - Improved documentation on user-defined functions</action>
            <action dev="poi-developers" type="add">Inside ExtractorFactory, support finding embedded OOXML documents and providing extractors for them</action>
index 12bd39d633e285048c5fd7d7afca3feb92390dda..62796a62f22bd7b4d58b52e48800249d0108e49f 100644 (file)
@@ -88,6 +88,7 @@ import org.apache.poi.ss.formula.ptg.Ptg;
 import org.apache.poi.hssf.util.HSSFColor;
 import org.apache.poi.ss.formula.EvaluationWorkbook.ExternalName;
 import org.apache.poi.ss.formula.EvaluationWorkbook.ExternalSheet;
+import org.apache.poi.ss.usermodel.BuiltinFormats;
 import org.apache.poi.util.Internal;
 import org.apache.poi.util.POILogFactory;
 import org.apache.poi.util.POILogger;
@@ -1284,15 +1285,16 @@ public final class InternalWorkbook {
         // we'll need multiple editions for
         // the different formats
 
+        
         switch (id) {
-            case 0: return new FormatRecord(5, "\"$\"#,##0_);\\(\"$\"#,##0\\)");
-            case 1: return new FormatRecord(6, "\"$\"#,##0_);[Red]\\(\"$\"#,##0\\)");
-            case 2: return new FormatRecord(7, "\"$\"#,##0.00_);\\(\"$\"#,##0.00\\)");
-            case 3: return new FormatRecord(8, "\"$\"#,##0.00_);[Red]\\(\"$\"#,##0.00\\)");
-            case 4: return new FormatRecord(0x2a, "_(\"$\"* #,##0_);_(\"$\"* \\(#,##0\\);_(\"$\"* \"-\"_);_(@_)");
-            case 5: return new FormatRecord(0x29, "_(* #,##0_);_(* \\(#,##0\\);_(* \"-\"_);_(@_)");
-            case 6: return new FormatRecord(0x2c, "_(\"$\"* #,##0.00_);_(\"$\"* \\(#,##0.00\\);_(\"$\"* \"-\"??_);_(@_)");
-            case 7: return new FormatRecord(0x2b, "_(* #,##0.00_);_(* \\(#,##0.00\\);_(* \"-\"??_);_(@_)");
+            case 0: return new FormatRecord(5, BuiltinFormats.getBuiltinFormat(5)); 
+            case 1: return new FormatRecord(6, BuiltinFormats.getBuiltinFormat(6)); 
+            case 2: return new FormatRecord(7, BuiltinFormats.getBuiltinFormat(7)); 
+            case 3: return new FormatRecord(8, BuiltinFormats.getBuiltinFormat(8)); 
+            case 4: return new FormatRecord(0x2a, BuiltinFormats.getBuiltinFormat(0x2a)); 
+            case 5: return new FormatRecord(0x29, BuiltinFormats.getBuiltinFormat(0x29)); 
+            case 6: return new FormatRecord(0x2c, BuiltinFormats.getBuiltinFormat(0x2c)); 
+            case 7: return new FormatRecord(0x2b, BuiltinFormats.getBuiltinFormat(0x2b)); 
         }
         throw new  IllegalArgumentException("Unexpected id " + id);
     }
index beb22a2a41d2b763def88e58be678da6291d4647..382452ca97d15026f3b114e6edeab2a1f734c93f 100644 (file)
@@ -71,9 +71,7 @@ public final class HSSFDataFormat implements DataFormat {
                Iterator<FormatRecord> i = workbook.getFormats().iterator();
                while (i.hasNext()) {
                        FormatRecord r = i.next();
-                       if (_formats.size() < r.getIndexCode() + 1) {
-                               _formats.setSize(r.getIndexCode() + 1);
-                       }
+                       ensureFormatsSize(r.getIndexCode());
                        _formats.set(r.getIndexCode(), r.getFormatString());
                }
        }
@@ -100,7 +98,7 @@ public final class HSSFDataFormat implements DataFormat {
         * @return index of format.
         */
        public short getFormat(String pFormat) {
-
+          // Normalise the format string
                String format;
                if (pFormat.toUpperCase().equals("TEXT")) {
                        format = "@";
@@ -108,31 +106,31 @@ public final class HSSFDataFormat implements DataFormat {
                        format = pFormat;
                }
 
+               // Merge in the built in formats if we haven't already
                if (!_movedBuiltins) {
                        for (int i=0; i<_builtinFormats.length; i++) {
-                               if (_formats.size() < i + 1) {
-                                       _formats.setSize(i + 1);
+                          ensureFormatsSize(i);
+                               if (_formats.get(i) == null) {
+                                  _formats.set(i, _builtinFormats[i]);
+                               } else {
+                                  // The workbook overrides this default format
                                }
-                               _formats.set(i, _builtinFormats[i]);
                        }
                        _movedBuiltins = true;
                }
-               ListIterator<String> i;
-               i = _formats.listIterator();
-               int ind;
-               while (i.hasNext()) {
-                       ind = i.nextIndex();
-                       if (format.equals(i.next())) {
-                               return (short) ind;
-                       }
+               
+               // See if we can find it
+               for(int i=0; i<_formats.size(); i++) {
+                  if(format.equals(_formats.get(i))) {
+                     return (short)i;
+                  }
                }
 
-               ind = _workbook.getFormat(format, true);
-               if (_formats.size() <= ind)
-                       _formats.setSize(ind + 1);
-               _formats.set(ind, format);
-
-               return (short) ind;
+               // We can't find it, so add it as a new one
+               short index = _workbook.getFormat(format, true);
+               ensureFormatsSize(index);
+               _formats.set(index, format);
+               return index;
        }
 
        /**
@@ -144,10 +142,19 @@ public final class HSSFDataFormat implements DataFormat {
                if (_movedBuiltins) {
                        return _formats.get(index);
                }
+               
+               String fmt = _formats.get(index);
                if (_builtinFormats.length > index && _builtinFormats[index] != null) {
-                       return _builtinFormats[index];
+                  // It's in the built in range
+                  if (fmt != null) {
+                     // It's been overriden, use that value
+                     return fmt;
+                  } else {
+                     // Standard built in format
+                return _builtinFormats[index];
+                  }
                }
-               return _formats.get(index);
+               return fmt;
        }
 
        /**
@@ -166,4 +173,14 @@ public final class HSSFDataFormat implements DataFormat {
        public static int getNumberOfBuiltinBuiltinFormats() {
                return _builtinFormats.length;
        }
+       
+       /**
+        * Ensures that the formats list can hold entries
+        *  up to and including the entry with this index
+        */
+       private void ensureFormatsSize(int index) {
+          if(_formats.size() <= index) {
+             _formats.setSize(index+1);
+          }
+       }
 }
index 3769ccf196e94a2c174ded8570d666ab7d760454..32bcaef785628aca3fa929883e5304459030d890 100644 (file)
@@ -19,7 +19,7 @@ package org.apache.poi.xssf.usermodel;
 
 import org.apache.poi.ss.usermodel.BaseTestDataFormat;
 import org.apache.poi.ss.usermodel.BuiltinFormats;
-import org.apache.poi.ss.usermodel.DataFormatter;
+import org.apache.poi.ss.usermodel.DataFormat;
 import org.apache.poi.xssf.XSSFITestDataProvider;
 import org.apache.poi.xssf.XSSFTestDataSamples;
 
@@ -37,33 +37,16 @@ public final class TestXSSFDataFormat extends BaseTestDataFormat {
      */
     public void test49928(){
         XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("49928.xlsx");
-        DataFormatter df = new DataFormatter();
-
-        XSSFSheet sheet = wb.getSheetAt(0);
-        XSSFCell cell = sheet.getRow(0).getCell(0);
-        XSSFCellStyle style = cell.getCellStyle();
-
-        String poundFmt = "\"\u00a3\"#,##0;[Red]\\-\"\u00a3\"#,##0";
-        // not expected normally, id of a custom format should be gerater 
-        // than BuiltinFormats.FIRST_USER_DEFINED_FORMAT_INDEX
-        short  poundFmtIdx = 6;
-
-        assertEquals(poundFmt, style.getDataFormatString());
-        assertEquals(poundFmtIdx, style.getDataFormat());
-        assertEquals("\u00a31", df.formatCellValue(cell));
-
-
-        XSSFDataFormat dataFormat = wb.createDataFormat();
-        assertEquals(poundFmtIdx, dataFormat.getFormat(poundFmt));
-        assertEquals(poundFmt, dataFormat.getFormat(poundFmtIdx));
+        doTest49928Core(wb);
 
         // an attempt to register an existing format returns its index
+        int poundFmtIdx = wb.getSheetAt(0).getRow(0).getCell(0).getCellStyle().getDataFormat();
         assertEquals(poundFmtIdx, wb.getStylesSource().putNumberFormat(poundFmt));
 
         // now create a custom format with Pound (\u00a3)
+        DataFormat dataFormat = wb.createDataFormat();
         short customFmtIdx = dataFormat.getFormat("\u00a3##.00[Yellow]");
         assertTrue(customFmtIdx > BuiltinFormats.FIRST_USER_DEFINED_FORMAT_INDEX );
         assertEquals("\u00a3##.00[Yellow]", dataFormat.getFormat(customFmtIdx));
-
     }
 }
index c04f162205aea7081215d72a72c5f27d1f648e13..6eb9b8dbbbc64c075312642909f49bddc8a755c6 100644 (file)
 package org.apache.poi.hssf.usermodel;
 
 import org.apache.poi.hssf.HSSFITestDataProvider;
+import org.apache.poi.hssf.HSSFTestDataSamples;
 import org.apache.poi.ss.usermodel.BaseTestDataFormat;
+import org.apache.poi.ss.usermodel.BuiltinFormats;
+import org.apache.poi.ss.usermodel.DataFormat;
 
 /**
  * Tests for {@link HSSFDataFormat}
@@ -28,4 +31,22 @@ public final class TestHSSFDataFormat extends BaseTestDataFormat {
     public TestHSSFDataFormat() {
         super(HSSFITestDataProvider.instance);
     }
+
+    /**
+     * [Bug 49928] formatCellValue returns incorrect value for \u00a3 formatted cells
+     */
+    public void test49928(){
+        HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("49928.xls");
+        doTest49928Core(wb);
+
+        // an attempt to register an existing format returns its index
+        int poundFmtIdx = wb.getSheetAt(0).getRow(0).getCell(0).getCellStyle().getDataFormat();
+        assertEquals(poundFmtIdx, wb.createDataFormat().getFormat(poundFmt));
+
+        // now create a custom format with Pound (\u00a3)
+        DataFormat dataFormat = wb.createDataFormat();
+        short customFmtIdx = dataFormat.getFormat("\u00a3##.00[Yellow]");
+        assertTrue(customFmtIdx >= BuiltinFormats.FIRST_USER_DEFINED_FORMAT_INDEX );
+        assertEquals("\u00a3##.00[Yellow]", dataFormat.getFormat(customFmtIdx));
+    }
 }
index 46f8204f11279b63e1d72ef528bfbccaa99792b7..cd161a52dc2f29cb6a1bffcadd695d398d1aed77 100644 (file)
@@ -20,6 +20,12 @@ package org.apache.poi.ss.usermodel;
 import junit.framework.TestCase;
 
 import org.apache.poi.ss.ITestDataProvider;
+import org.apache.poi.xssf.XSSFTestDataSamples;
+import org.apache.poi.xssf.usermodel.XSSFCell;
+import org.apache.poi.xssf.usermodel.XSSFCellStyle;
+import org.apache.poi.xssf.usermodel.XSSFDataFormat;
+import org.apache.poi.xssf.usermodel.XSSFSheet;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 
 /**
  * Tests of implementation of {@link DataFormat}
@@ -60,4 +66,31 @@ public abstract class BaseTestDataFormat extends TestCase {
         //read and verify the string representation
         assertEquals(customFmt, df.getFormat((short)customIdx));
     }
+    
+    /**
+     * [Bug 49928] formatCellValue returns incorrect value for \u00a3 formatted cells
+     */
+    public abstract void test49928();
+    protected final String poundFmt = "\"\u00a3\"#,##0;[Red]\\-\"\u00a3\"#,##0";
+    public void doTest49928Core(Workbook wb){
+        DataFormatter df = new DataFormatter();
+
+        Sheet sheet = wb.getSheetAt(0);
+        Cell cell = sheet.getRow(0).getCell(0);
+        CellStyle style = cell.getCellStyle();
+
+        String poundFmt = "\"\u00a3\"#,##0;[Red]\\-\"\u00a3\"#,##0";
+        // not expected normally, id of a custom format should be greater 
+        // than BuiltinFormats.FIRST_USER_DEFINED_FORMAT_INDEX
+        short  poundFmtIdx = 6;
+
+        assertEquals(poundFmt, style.getDataFormatString());
+        assertEquals(poundFmtIdx, style.getDataFormat());
+        assertEquals("\u00a31", df.formatCellValue(cell));
+
+
+        DataFormat dataFormat = wb.createDataFormat();
+        assertEquals(poundFmtIdx, dataFormat.getFormat(poundFmt));
+        assertEquals(poundFmt, dataFormat.getFormat(poundFmtIdx));
+    }
 }
diff --git a/test-data/spreadsheet/49928.xls b/test-data/spreadsheet/49928.xls
new file mode 100644 (file)
index 0000000..d7249e7
Binary files /dev/null and b/test-data/spreadsheet/49928.xls differ