You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by fa...@apache.org on 2021/10/25 09:32:51 UTC

svn commit: r1894549 - in /poi/trunk: poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/ poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/ poi/src/main/java/org/apache/poi/ss/formula/ poi/src/main/java/org/apache/poi/ss/formula/ptg/ poi/src/te...

Author: fanningpj
Date: Mon Oct 25 09:32:50 2021
New Revision: 1894549

URL: http://svn.apache.org/viewvc?rev=1894549&view=rev
Log:
[github-267] Issue with sheet range in formula With spaces and quotes. Thanks to aspojo. This closes #267

Modified:
    poi/trunk/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFCell.java
    poi/trunk/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFFormulaParser.java
    poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/FormulaParser.java
    poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/ptg/ExternSheetNameResolver.java
    poi/trunk/poi/src/test/java/org/apache/poi/hssf/model/TestFormulaParser.java

Modified: poi/trunk/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFCell.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFCell.java?rev=1894549&r1=1894548&r2=1894549&view=diff
==============================================================================
--- poi/trunk/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFCell.java (original)
+++ poi/trunk/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFCell.java Mon Oct 25 09:32:50 2021
@@ -474,7 +474,10 @@ public final class XSSFCell extends Cell
         if (wb.getCellFormulaValidation()) {
             XSSFEvaluationWorkbook fpb = XSSFEvaluationWorkbook.create(wb);
             //validate through the FormulaParser
-            FormulaParser.parse(formula, fpb, formulaType, wb.getSheetIndex(getSheet()), getRowIndex());
+            Ptg[] ptgs = FormulaParser.parse(formula, fpb, formulaType, wb.getSheetIndex(getSheet()), getRowIndex());
+            // Make its format consistent with Excel.
+            // eg: "SUM('Sheet1:Sheet2'!A1:B1)" will be trans to "SUM(Sheet1:Sheet2!A1:B1)"
+            formula = FormulaRenderer.toFormulaString(fpb, ptgs);
         }
 
         CTCellFormula f;

Modified: poi/trunk/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFFormulaParser.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFFormulaParser.java?rev=1894549&r1=1894548&r2=1894549&view=diff
==============================================================================
--- poi/trunk/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFFormulaParser.java (original)
+++ poi/trunk/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFFormulaParser.java Mon Oct 25 09:32:50 2021
@@ -723,4 +723,49 @@ public final class TestXSSFFormulaParser
 
         wb.close();
     }
+
+    @Test
+    void testQuotedSheetNamesReference() {
+        // quoted sheet names bug fix (https://github.com/apache/poi/pull/267)
+        Workbook[] wbs = new Workbook[]{new HSSFWorkbook(), new XSSFWorkbook()};
+        for (Workbook wb : wbs) {
+            Sheet sheet1 = wb.createSheet("Sheet1");
+            Sheet sheet2 = wb.createSheet("Sheet2");
+            Sheet sheet3 = wb.createSheet("Sheet 3");
+
+            Row tempRow = sheet1.createRow(0);
+            tempRow.createCell(0).setCellValue(1);
+            tempRow.createCell(1).setCellValue(2);
+
+            tempRow = sheet2.createRow(0);
+            tempRow.createCell(0).setCellValue(3);
+            tempRow.createCell(1).setCellValue(4);
+
+            tempRow = sheet3.createRow(0);
+            tempRow.createCell(0).setCellValue(5);
+            tempRow.createCell(1).setCellValue(6);
+
+            Cell cell = tempRow.createCell(2);
+
+            // unquoted sheet names
+            String formula = "SUM(Sheet1:Sheet2!A1:B1)";
+            cell.setCellFormula(formula);
+            String cellFormula = cell.getCellFormula();
+            assertEquals(formula, cellFormula);
+
+            // quoted sheet names with no space
+            cell = tempRow.createCell(3);
+            formula = "SUM('Sheet1:Sheet2'!A1:B1)";
+            cell.setCellFormula(formula);
+            cellFormula = cell.getCellFormula();
+            assertEquals("SUM(Sheet1:Sheet2!A1:B1)", cellFormula);
+
+            // quoted sheet names with space
+            cell = tempRow.createCell(4);
+            formula = "SUM('Sheet1:Sheet 3'!A1:B1)";
+            cell.setCellFormula(formula);
+            cellFormula = cell.getCellFormula();
+            assertEquals(formula, cellFormula);
+        }
+    }
 }

Modified: poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/FormulaParser.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/FormulaParser.java?rev=1894549&r1=1894548&r2=1894549&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/FormulaParser.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/FormulaParser.java Mon Oct 25 09:32:50 2021
@@ -1171,10 +1171,11 @@ public final class FormulaParser {
             while(!done) {
                 sb.appendCodePoint(look);
                 GetChar();
-                if(look == '\'')
-                {
-                    Match('\'');
-                    done = look != '\'';
+                switch (look){
+                    case '\'' :
+                        GetChar();
+                    case ':' :
+                        done = true;
                 }
             }
 
@@ -1200,6 +1201,9 @@ public final class FormulaParser {
                 sb.appendCodePoint(look);
                 GetChar();
             }
+            if (look == '\'') {
+                GetChar();
+            }
             NameIdentifier iden = new NameIdentifier(sb.toString(), false);
             SkipWhite();
             if (look == '!') {
@@ -1249,6 +1253,7 @@ public final class FormulaParser {
         switch(ch) {
             case '.': // dot is OK
             case '_': // underscore is OK
+            case ' ': // space is OK
                 return true;
         }
         return false;

Modified: poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/ptg/ExternSheetNameResolver.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/ptg/ExternSheetNameResolver.java?rev=1894549&r1=1894548&r2=1894549&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/ptg/ExternSheetNameResolver.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/ptg/ExternSheetNameResolver.java Mon Oct 25 09:32:50 2021
@@ -44,7 +44,16 @@ final class ExternSheetNameResolver {
                 ExternalSheetRange r = (ExternalSheetRange)externalSheet;
                 if (! r.getFirstSheetName().equals(r.getLastSheetName())) {
                     sb.append(':');
-                    SheetNameFormatter.appendFormat(sb, r.getLastSheetName());
+                    // quote should appear at the beginning and end.
+                    StringBuilder innerBuilder = new StringBuilder();
+                    SheetNameFormatter.appendFormat(innerBuilder, r.getLastSheetName());
+                    char quote = '\'';
+                    if (innerBuilder.charAt(0) == quote){
+                        sb.insert(0 , quote);
+                        sb.append(innerBuilder.substring(1));
+                    } else {
+                        sb.append(innerBuilder);
+                    }
                 }
             }
         } else {

Modified: poi/trunk/poi/src/test/java/org/apache/poi/hssf/model/TestFormulaParser.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/test/java/org/apache/poi/hssf/model/TestFormulaParser.java?rev=1894549&r1=1894548&r2=1894549&view=diff
==============================================================================
--- poi/trunk/poi/src/test/java/org/apache/poi/hssf/model/TestFormulaParser.java (original)
+++ poi/trunk/poi/src/test/java/org/apache/poi/hssf/model/TestFormulaParser.java Mon Oct 25 09:32:50 2021
@@ -535,9 +535,9 @@ final class TestFormulaParser {
         assertEquals("'Test Sheet'!A1", formula);
 
         // Now both
-        cell.setCellFormula("Cash_Flow:'Test Sheet'!A1");
+        cell.setCellFormula("'Cash_Flow:Test Sheet'!A1");
         formula = cell.getCellFormula();
-        assertEquals("Cash_Flow:'Test Sheet'!A1", formula);
+        assertEquals("'Cash_Flow:Test Sheet'!A1", formula);
 
 
         // References to a range (area) of cells:
@@ -553,9 +553,9 @@ final class TestFormulaParser {
         assertEquals("'Test Sheet'!A1:B2", formula);
 
         // Now both
-        cell.setCellFormula("Cash_Flow:'Test Sheet'!A1:B2");
+        cell.setCellFormula("'Cash_Flow:Test Sheet'!A1:B2");
         formula = cell.getCellFormula();
-        assertEquals("Cash_Flow:'Test Sheet'!A1:B2", formula);
+        assertEquals("'Cash_Flow:Test Sheet'!A1:B2", formula);
 
         wb.close();
     }



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