aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPJ Fanning <fanningpj@apache.org>2020-01-09 21:19:34 +0000
committerPJ Fanning <fanningpj@apache.org>2020-01-09 21:19:34 +0000
commitb594ec2947685dd658bfa19107d71f8716736d2a (patch)
tree9a8526e166b0a7bbdee059f362c5233623c0fe00 /src
parent11b2c7e8985294679eb315da9d78cf17c87bcca3 (diff)
downloadpoi-b594ec2947685dd658bfa19107d71f8716736d2a.tar.gz
poi-b594ec2947685dd658bfa19107d71f8716736d2a.zip
[bug-63998] Support commas, exclamation marks correctly in AreaReference. Thanks to hzwhuang
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1872567 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src')
-rw-r--r--src/java/org/apache/poi/ss/util/AreaReference.java45
-rw-r--r--src/testcases/org/apache/poi/hssf/util/TestAreaReference.java47
2 files changed, 66 insertions, 26 deletions
diff --git a/src/java/org/apache/poi/ss/util/AreaReference.java b/src/java/org/apache/poi/ss/util/AreaReference.java
index 4dd4771be6..a832fec6b4 100644
--- a/src/java/org/apache/poi/ss/util/AreaReference.java
+++ b/src/java/org/apache/poi/ss/util/AreaReference.java
@@ -22,6 +22,7 @@ import java.util.List;
import java.util.StringTokenizer;
import org.apache.poi.ss.SpreadsheetVersion;
+import org.apache.poi.util.StringUtil;
public class AreaReference {
@@ -166,14 +167,7 @@ public class AreaReference {
* {@link #generateContiguous(SpreadsheetVersion, String)})
*/
public static boolean isContiguous(String reference) {
- // If there's a sheet name, strip it off
- int sheetRefEnd = reference.indexOf('!');
- if(sheetRefEnd != -1) {
- reference = reference.substring(sheetRefEnd);
- }
-
- // Check for the , as a sign of non-coniguous
- return !reference.contains(",");
+ return splitAreaReferences(reference).length == 1;
}
public static AreaReference getWholeRow(SpreadsheetVersion version, String start, String end) {
@@ -220,11 +214,9 @@ public class AreaReference {
version = DEFAULT_SPREADSHEET_VERSION; // how the code used to behave.
}
List<AreaReference> refs = new ArrayList<>();
- StringTokenizer st = new StringTokenizer(reference, ",");
- while(st.hasMoreTokens()) {
- refs.add(
- new AreaReference(st.nextToken(), version)
- );
+ String[] splitReferences = splitAreaReferences(reference);
+ for (String ref : splitReferences) {
+ refs.add(new AreaReference(ref, version));
}
return refs.toArray(new AreaReference[0]);
}
@@ -405,4 +397,31 @@ public class AreaReference {
return new String [] { partA, sheetName + partB, };
}
+
+ /**
+ * Splits a comma-separated area references string into an array of
+ * individual references
+ * @param reference Area references, i.e. A1:B2, 'Sheet1'!A1:B2
+ * @return Area references in an array, size >= 1
+ */
+ private static String[] splitAreaReferences(String reference) {
+ List<String> results = new ArrayList<>();
+ String currentSegment = "";
+ StringTokenizer st = new StringTokenizer(reference, ",");
+ while(st.hasMoreTokens()) {
+ if (currentSegment.length() > 0) {
+ currentSegment += ",";
+ }
+ currentSegment += st.nextToken();
+ int numSingleQuotes = StringUtil.countMatches(currentSegment, '\'');
+ if (numSingleQuotes == 0 || numSingleQuotes == 2) {
+ results.add(currentSegment);
+ currentSegment = "";
+ }
+ }
+ if (currentSegment.length() > 0) {
+ results.add(currentSegment);
+ }
+ return results.toArray(new String[0]);
+ }
}
diff --git a/src/testcases/org/apache/poi/hssf/util/TestAreaReference.java b/src/testcases/org/apache/poi/hssf/util/TestAreaReference.java
index 6c2c8829c6..b92b65adb7 100644
--- a/src/testcases/org/apache/poi/hssf/util/TestAreaReference.java
+++ b/src/testcases/org/apache/poi/hssf/util/TestAreaReference.java
@@ -55,15 +55,15 @@ public final class TestAreaReference {
CellReference cf = ar.getFirstCell();
assertEquals("row is 4", 0, cf.getRow());
assertEquals("col is 1", 0, cf.getCol());
- assertTrue("row is abs",cf.isRowAbsolute());
- assertTrue("col is abs",cf.isColAbsolute());
+ assertTrue("row is abs", cf.isRowAbsolute());
+ assertTrue("col is abs", cf.isColAbsolute());
assertEquals("string is $A$1", "$A$1", cf.formatAsString());
cf = ar.getLastCell();
assertEquals("row is 4", 1, cf.getRow());
assertEquals("col is 1", 1, cf.getCol());
- assertTrue("row is abs",cf.isRowAbsolute());
- assertTrue("col is abs",cf.isColAbsolute());
+ assertTrue("row is abs", cf.isRowAbsolute());
+ assertTrue("col is abs", cf.isColAbsolute());
assertEquals("string is $B$2", "$B$2", cf.formatAsString());
CellReference[] refs = ar.getAllReferencedCells();
@@ -87,8 +87,8 @@ public final class TestAreaReference {
}
/**
- * References failed when sheet names were being used
- * Reported by Arne.Clauss@gedas.de
+ * References failed when sheet names were being used Reported by
+ * Arne.Clauss@gedas.de
*/
@Test
public void testReferenceWithSheet() {
@@ -100,7 +100,6 @@ public final class TestAreaReference {
assertEquals(1, ar.getAllReferencedCells().length);
-
ar = new AreaReference("Tabelle1!$B$5:$B$7", SpreadsheetVersion.EXCEL97);
assertFalse(ar.isSingleCell());
@@ -122,6 +121,8 @@ public final class TestAreaReference {
String refDCSimple = "$C$10:$C$10,$D$12:$D$12,$E$14:$E$14";
String refDC2D = "$C$10:$C$11,$D$12:$D$12,$E$14:$E$20";
String refDC3D = "Tabelle1!$C$10:$C$14,Tabelle1!$D$10:$D$12";
+ String refComma = "'A,Sheet'!$A$1:$A$1,'A,Sheet'!$A$4:$A$5";
+ String refCommaExp = "'!Sheet,Comma!'!$A$1:$B$1";
// Check that we detect as contiguous properly
assertTrue(AreaReference.isContiguous(refSimple));
@@ -129,6 +130,8 @@ public final class TestAreaReference {
assertFalse(AreaReference.isContiguous(refDCSimple));
assertFalse(AreaReference.isContiguous(refDC2D));
assertFalse(AreaReference.isContiguous(refDC3D));
+ assertFalse(AreaReference.isContiguous(refComma));
+ assertTrue(AreaReference.isContiguous(refCommaExp));
// Check we can only create contiguous entries
new AreaReference(refSimple, SpreadsheetVersion.EXCEL97);
@@ -136,20 +139,20 @@ public final class TestAreaReference {
try {
new AreaReference(refDCSimple, SpreadsheetVersion.EXCEL97);
fail("expected IllegalArgumentException");
- } catch(IllegalArgumentException e) {
- // expected during successful test
+ } catch (IllegalArgumentException e) {
+ // expected during successful test
}
try {
new AreaReference(refDC2D, SpreadsheetVersion.EXCEL97);
fail("expected IllegalArgumentException");
- } catch(IllegalArgumentException e) {
- // expected during successful test
+ } catch (IllegalArgumentException e) {
+ // expected during successful test
}
try {
new AreaReference(refDC3D, SpreadsheetVersion.EXCEL97);
fail("expected IllegalArgumentException");
- } catch(IllegalArgumentException e) {
- // expected during successful test
+ } catch (IllegalArgumentException e) {
+ // expected during successful test
}
// Test that we split as expected
@@ -193,6 +196,21 @@ public final class TestAreaReference {
assertEquals("Tabelle1", refs[0].getLastCell().getSheetName());
assertEquals("Tabelle1", refs[1].getFirstCell().getSheetName());
assertEquals("Tabelle1", refs[1].getLastCell().getSheetName());
+
+ refs = AreaReference.generateContiguous(SpreadsheetVersion.EXCEL97, refComma);
+ assertEquals(2, refs.length);
+ System.out.println(refs[0].formatAsString());
+ assertTrue(refs[0].isSingleCell());
+ assertEquals("'A,Sheet'!$A$1", refs[0].formatAsString());
+ assertEquals("A,Sheet", refs[0].getLastCell().getSheetName());
+ assertEquals("'A,Sheet'!$A$4:$A$5", refs[1].formatAsString());
+ assertEquals("A,Sheet", refs[1].getLastCell().getSheetName());
+
+ refs = AreaReference.generateContiguous(SpreadsheetVersion.EXCEL97, refCommaExp);
+ assertEquals(1, refs.length);
+ assertFalse(refs[0].isSingleCell());
+ assertEquals("'!Sheet,Comma!'!$A$1:$B$1", refs[0].formatAsString());
+ assertEquals("!Sheet,Comma!", refs[0].getLastCell().getSheetName());
}
@Test
@@ -274,6 +292,9 @@ public final class TestAreaReference {
ar = new AreaReference("'one:many'!A1:B2", SpreadsheetVersion.EXCEL97);
confirmAreaSheetName(ar, "one:many", "'one:many'!A1:B2");
+
+ ar = new AreaReference("'O,Comma'!A1:B1", SpreadsheetVersion.EXCEL97);
+ confirmAreaSheetName(ar, "O,Comma", "'O,Comma'!A1:B1");
}
private static void confirmAreaSheetName(AreaReference ar, String sheetName, String expectedFullText) {