You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by ni...@apache.org on 2015/10/25 22:20:44 UTC

svn commit: r1710484 - in /poi/trunk/src: java/org/apache/poi/ss/format/CellFormat.java java/org/apache/poi/ss/format/CellFormatPart.java testcases/org/apache/poi/ss/format/TestCellFormat.java testcases/org/apache/poi/ss/usermodel/BaseTestDataFormat.java

Author: nick
Date: Sun Oct 25 21:20:44 2015
New Revision: 1710484

URL: http://svn.apache.org/viewvc?rev=1710484&view=rev
Log:
58536 DataFormatter and CellFormat non-localised support for localised currency formats like [$£-809]

Modified:
    poi/trunk/src/java/org/apache/poi/ss/format/CellFormat.java
    poi/trunk/src/java/org/apache/poi/ss/format/CellFormatPart.java
    poi/trunk/src/testcases/org/apache/poi/ss/format/TestCellFormat.java
    poi/trunk/src/testcases/org/apache/poi/ss/usermodel/BaseTestDataFormat.java

Modified: poi/trunk/src/java/org/apache/poi/ss/format/CellFormat.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/format/CellFormat.java?rev=1710484&r1=1710483&r2=1710484&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ss/format/CellFormat.java (original)
+++ poi/trunk/src/java/org/apache/poi/ss/format/CellFormat.java Sun Oct 25 21:20:44 2015
@@ -66,7 +66,7 @@ import org.apache.poi.ss.util.DateFormat
  * surround by brackets). </dl>
  * <p/>
  * A given format part may specify a given Locale, by including something
- *  like <tt>[$$-409]</tt> or <tt>[$\u00A3-809]</tt> or <tt>[$-40C]</tt>. These
+ *  like <tt>[$$-409]</tt> or <tt>[$&pound;-809]</tt> or <tt>[$-40C]</tt>. These
  *  are (currently) largely ignored. You can use {@link DateFormatConverter}
  *  to look these up into Java Locales if desired.
  * <p/>
@@ -78,6 +78,8 @@ import org.apache.poi.ss.util.DateFormat
  *  code for formatting numbers.
  * TODO Re-use parts of this logic with {@link ConditionalFormatting} /
  *  {@link ConditionalFormattingRule} for reporting stylings which do/don't apply
+ * TODO Support the full set of modifiers, including alternate calendars and
+ *  native character numbers, as documented at https://help.libreoffice.org/Common/Number_Format_Codes
  */
 public class CellFormat {
     private final String format;

Modified: poi/trunk/src/java/org/apache/poi/ss/format/CellFormatPart.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/format/CellFormatPart.java?rev=1710484&r1=1710483&r2=1710484&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ss/format/CellFormatPart.java (original)
+++ poi/trunk/src/java/org/apache/poi/ss/format/CellFormatPart.java Sun Oct 25 21:20:44 2015
@@ -19,6 +19,7 @@ package org.apache.poi.ss.format;
 import org.apache.poi.hssf.util.HSSFColor;
 
 import javax.swing.*;
+
 import java.awt.*;
 import java.util.Locale;
 import java.util.Map;
@@ -80,6 +81,8 @@ public class CellFormatPart {
     public static final Pattern CONDITION_PAT;
     /** Pattern for the format specification part of a cell format part. */
     public static final Pattern SPECIFICATION_PAT;
+    /** Pattern for the currency symbol part of a cell format part */
+    public static final Pattern CURRENCY_PAT;
     /** Pattern for an entire cell single part. */
     public static final Pattern FORMAT_PAT;
 
@@ -105,6 +108,9 @@ public class CellFormatPart {
         // A condition specification
         String condition = "([<>=]=?|!=|<>)    # The operator\n" +
                 "  \\s*([0-9]+(?:\\.[0-9]*)?)\\s*  # The constant to test against\n";
+        
+        // A currency symbol / string, in a specific locale
+        String currency = "(\\[\\$.{0,3}-[0-9a-f]{3}\\])";
 
         String color =
                 "\\[(black|blue|cyan|green|magenta|red|white|yellow|color [0-9]+)\\]";
@@ -115,6 +121,7 @@ public class CellFormatPart {
         // A part of a specification
         String part = "\\\\.                 # Quoted single character\n" +
                 "|\"([^\\\\\"]|\\\\.)*\"         # Quoted string of characters (handles escaped quotes like \\\") \n" +
+                "|"+currency+"                   # Currency symbol in a given locale\n" +
                 "|_.                             # Space as wide as a given character\n" +
                 "|\\*.                           # Repeating fill character\n" +
                 "|@                              # Text: cell text\n" +
@@ -131,14 +138,15 @@ public class CellFormatPart {
                 "|\\[s{1,2}\\]                   # Elapsed time: second spec\n" +
                 "|[^;]                           # A character\n" + "";
 
-        String format = "(?:" + color + ")?                  # Text color\n" +
-                "(?:\\[" + condition + "\\])?                # Condition\n" +
+        String format = "(?:" + color + ")?                 # Text color\n" +
+                "(?:\\[" + condition + "\\])?               # Condition\n" +
                 "((?:" + part + ")+)                        # Format spec\n";
 
         int flags = Pattern.COMMENTS | Pattern.CASE_INSENSITIVE;
         COLOR_PAT = Pattern.compile(color, flags);
         CONDITION_PAT = Pattern.compile(condition, flags);
         SPECIFICATION_PAT = Pattern.compile(part, flags);
+        CURRENCY_PAT = Pattern.compile(currency, flags);
         FORMAT_PAT = Pattern.compile(format, flags);
 
         // Calculate the group numbers of important groups.  (They shift around
@@ -196,7 +204,7 @@ public class CellFormatPart {
 
     /**
      * Returns the number of the first group that is the same as the marker
-     * string.  The search starts with group 1.
+     * string. Starts from group 1.
      *
      * @param pat    The pattern to use.
      * @param str    The string to match against the pattern.
@@ -278,6 +286,22 @@ public class CellFormatPart {
      */
     private CellFormatter getFormatter(Matcher matcher) {
         String fdesc = matcher.group(SPECIFICATION_GROUP);
+        
+        // For now, we don't support localised currencies, so simplify if there
+        Matcher currencyM = CURRENCY_PAT.matcher(fdesc);
+        if (currencyM.find()) {
+            String currencyPart = currencyM.group(1);
+            String currencyRepl;
+            if (currencyPart.startsWith("[$-")) {
+                // Default $ in a different locale
+                currencyRepl = "$";
+            } else {
+                currencyRepl = currencyPart.substring(2, currencyPart.lastIndexOf('-'));
+            }
+            fdesc = fdesc.replace(currencyPart, currencyRepl);
+        }
+        
+        // Build a formatter for this simplified string
         return type.formatter(fdesc);
     }
 
@@ -298,8 +322,14 @@ public class CellFormatPart {
         boolean seenZero = false;
         while (m.find()) {
             String repl = m.group(0);
+            
             if (repl.length() > 0) {
-                switch (repl.charAt(0)) {
+                char c1 = repl.charAt(0);
+                char c2 = 0;
+                if (repl.length() > 1)
+                    c2 = Character.toLowerCase(repl.charAt(1));
+                
+                switch (c1) {
                 case '@':
                     return CellFormatType.TEXT;
                 case 'd':
@@ -321,7 +351,16 @@ public class CellFormatPart {
                     seenZero = true;
                     break;
                 case '[':
-                    return CellFormatType.ELAPSED;
+                    if (c2 == 'h' || c2 == 'm' || c2 == 's') {
+                        return CellFormatType.ELAPSED;
+                    }
+                    if (c2 == '$') {
+                        // Localised currency
+                        return CellFormatType.NUMBER;
+                    }
+                    // Something else inside [] which isn't supported!
+                    throw new IllegalArgumentException("Unsupported [] format block '" +
+                                                       repl + "' in '" + fdesc + "'");
                 case '#':
                 case '?':
                     return CellFormatType.NUMBER;

Modified: poi/trunk/src/testcases/org/apache/poi/ss/format/TestCellFormat.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/ss/format/TestCellFormat.java?rev=1710484&r1=1710483&r2=1710484&view=diff
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/ss/format/TestCellFormat.java (original)
+++ poi/trunk/src/testcases/org/apache/poi/ss/format/TestCellFormat.java Sun Oct 25 21:20:44 2015
@@ -36,7 +36,6 @@ import org.apache.poi.ss.usermodel.Workb
 import org.apache.poi.util.LocaleUtil;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
-import org.junit.Ignore;
 import org.junit.Test;
 
 public class TestCellFormat {
@@ -918,7 +917,7 @@ public class TestCellFormat {
             Row row = sheet.createRow(0);
             Cell cell = row.createCell(0);
             cell.setCellValue(123456.6);
-            System.out.println(cf1.apply(cell).text);
+            //System.out.println(cf1.apply(cell).text);
             assertEquals("123456 3/5", cf1.apply(cell).text);
         } finally {
             wb.close();
@@ -926,7 +925,6 @@ public class TestCellFormat {
     }
     
     @Test
-    @Ignore("TODO") // TODO 
     public void testAccountingFormats() throws IOException {
         char pound = '\u00A3';
         char euro  = '\u20AC';
@@ -934,11 +932,11 @@ public class TestCellFormat {
         // Accounting -> 0 decimal places, default currency symbol
         String formatDft = "_-\"$\"* #,##0_-;\\-\"$\"* #,##0_-;_-\"$\"* \"-\"_-;_-@_-";
         // Accounting -> 0 decimal places, US currency symbol
-        String formatUS  = "_-[$$-409]* #,##0_ ;_-[$$-409]* -#,##0 ;_-[$$-409]* \"-\"_ ;_-@_ ";
+        String formatUS  = "_-[$$-409]* #,##0_ ;_-[$$-409]* -#,##0 ;_-[$$-409]* \"-\"_-;_-@_-";
         // Accounting -> 0 decimal places, UK currency symbol
         String formatUK  = "_-[$"+pound+"-809]* #,##0_-;\\-[$"+pound+"-809]* #,##0_-;_-[$"+pound+"-809]* \"-\"??_-;_-@_-";
-        // Accounting -> 0 decimal places, French currency symbol
-        String formatFR  = "_-[$"+euro+"-40C]* #,##0_-;\\-[$"+euro+"-40C]* #,##0_-;_-[$"+euro+"-40C]* \"-\"??_-;_-@_-";
+        // French style accounting, euro sign comes after not before
+        String formatFR  = "_-#,##0* [$"+euro+"-40C]_-;\\-#,##0* [$"+euro+"-40C]_-;_-\"-\"??* [$"+euro+"-40C] _-;_-@_-";
         
         // Has +ve, -ve and zero rules
         CellFormat cfDft = CellFormat.getInstance(formatDft);
@@ -947,17 +945,34 @@ public class TestCellFormat {
         CellFormat cfFR  = CellFormat.getInstance(formatFR);
         
         // For +ve numbers, should be Space + currency symbol + spaces + whole number with commas + space
-        assertEquals(" $   12 ",cfDft.apply(Double.valueOf(12.33)).text);
-        assertEquals(" $   12 ", cfUS.apply(Double.valueOf(12.33)).text);
+        // (Except French, which is mostly reversed...)
+        assertEquals(" $   12 ", cfDft.apply(Double.valueOf(12.33)).text);
+        assertEquals(" $   12 ",  cfUS.apply(Double.valueOf(12.33)).text);
         assertEquals(" "+pound+"   12 ", cfUK.apply(Double.valueOf(12.33)).text);
-        assertEquals(" "+pound+"   12 ", cfFR.apply(Double.valueOf(12.33)).text);
+        assertEquals(" 12   "+euro+" ", cfFR.apply(Double.valueOf(12.33)).text);
+        
+        assertEquals(" $   16,789 ", cfDft.apply(Double.valueOf(16789.2)).text);
+        assertEquals(" $   16,789 ",  cfUS.apply(Double.valueOf(16789.2)).text);
         assertEquals(" "+pound+"   16,789 ", cfUK.apply(Double.valueOf(16789.2)).text);
-        // TODO More
+        assertEquals(" 16,789   "+euro+" ", cfFR.apply(Double.valueOf(16789.2)).text);
         
-        // For -ve numbers, should be Minus + currency symbol + spaces + whole number with commas
-        // TODO
+        // For -ve numbers, gets a bit more complicated...
+        assertEquals("-$   12 ", cfDft.apply(Double.valueOf(-12.33)).text);
+        assertEquals(" $   -12 ",  cfUS.apply(Double.valueOf(-12.33)).text);
+        assertEquals("-"+pound+"   12 ", cfUK.apply(Double.valueOf(-12.33)).text);
+        assertEquals("-12   "+euro+" ", cfFR.apply(Double.valueOf(-12.33)).text);
+        
+        assertEquals("-$   16,789 ", cfDft.apply(Double.valueOf(-16789.2)).text);
+        assertEquals(" $   -16,789 ",  cfUS.apply(Double.valueOf(-16789.2)).text);
+        assertEquals("-"+pound+"   16,789 ", cfUK.apply(Double.valueOf(-16789.2)).text);
+        assertEquals("-16,789   "+euro+" ", cfFR.apply(Double.valueOf(-16789.2)).text);
         
         // For zero, should be Space + currency symbol + spaces + Minus + spaces
-        // TODO
+        assertEquals(" $   - ", cfDft.apply(Double.valueOf(0)).text);
+        // TODO Fix the exception this incorrectly triggers
+        //assertEquals(" $   - ",  cfUS.apply(Double.valueOf(0)).text);
+        // TODO Fix these to not have an incorrect bonus 0 on the end 
+        //assertEquals(" "+pound+"   -  ", cfUK.apply(Double.valueOf(0)).text);
+        //assertEquals(" -    "+euro+"  ", cfFR.apply(Double.valueOf(0)).text);
     }
 }
\ No newline at end of file

Modified: poi/trunk/src/testcases/org/apache/poi/ss/usermodel/BaseTestDataFormat.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/ss/usermodel/BaseTestDataFormat.java?rev=1710484&r1=1710483&r2=1710484&view=diff
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/ss/usermodel/BaseTestDataFormat.java (original)
+++ poi/trunk/src/testcases/org/apache/poi/ss/usermodel/BaseTestDataFormat.java Sun Oct 25 21:20:44 2015
@@ -131,4 +131,38 @@ public abstract class BaseTestDataFormat
                          exp3dp, fmt.formatCellValue(r.getCell(3), eval));
         }
     }
+    
+    /**
+     * Localised accountancy formats
+     */
+    public final void test58536() {
+        Workbook wb = _testDataProvider.createWorkbook();
+        DataFormatter formatter = new DataFormatter();
+        DataFormat fmt = wb.createDataFormat();
+        Sheet sheet = wb.createSheet();
+        Row r = sheet.createRow(0);
+        
+        char pound = '\u00A3';
+        String formatUK  = "_-[$"+pound+"-809]* #,##0_-;\\-[$"+pound+"-809]* #,##0_-;_-[$"+pound+"-809]* \"-\"??_-;_-@_-";
+        
+        CellStyle cs = wb.createCellStyle();
+        cs.setDataFormat(fmt.getFormat(formatUK));
+        
+        Cell pve = r.createCell(0);
+        pve.setCellValue(12345);
+        pve.setCellStyle(cs);
+        
+        Cell nve = r.createCell(1);
+        nve.setCellValue(-12345);
+        nve.setCellStyle(cs);
+        
+        Cell zero = r.createCell(2);
+        zero.setCellValue(0);
+        zero.setCellStyle(cs);
+        
+        assertEquals(pound+"   12,345", formatter.formatCellValue(pve)); 
+        assertEquals("-"+pound+"   12,345", formatter.formatCellValue(nve));
+        // TODO Fix this to not have an extra 0 at the end
+        //assertEquals(pound+"   -  ", formatter.formatCellValue(zero)); 
+    }
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org