mirror of https://github.com/apache/poi.git
[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
This commit is contained in:
parent
11b2c7e898
commit
b594ec2947
|
@ -22,6 +22,7 @@ import java.util.List;
|
||||||
import java.util.StringTokenizer;
|
import java.util.StringTokenizer;
|
||||||
|
|
||||||
import org.apache.poi.ss.SpreadsheetVersion;
|
import org.apache.poi.ss.SpreadsheetVersion;
|
||||||
|
import org.apache.poi.util.StringUtil;
|
||||||
|
|
||||||
public class AreaReference {
|
public class AreaReference {
|
||||||
|
|
||||||
|
@ -166,14 +167,7 @@ public class AreaReference {
|
||||||
* {@link #generateContiguous(SpreadsheetVersion, String)})
|
* {@link #generateContiguous(SpreadsheetVersion, String)})
|
||||||
*/
|
*/
|
||||||
public static boolean isContiguous(String reference) {
|
public static boolean isContiguous(String reference) {
|
||||||
// If there's a sheet name, strip it off
|
return splitAreaReferences(reference).length == 1;
|
||||||
int sheetRefEnd = reference.indexOf('!');
|
|
||||||
if(sheetRefEnd != -1) {
|
|
||||||
reference = reference.substring(sheetRefEnd);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for the , as a sign of non-coniguous
|
|
||||||
return !reference.contains(",");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static AreaReference getWholeRow(SpreadsheetVersion version, String start, String end) {
|
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.
|
version = DEFAULT_SPREADSHEET_VERSION; // how the code used to behave.
|
||||||
}
|
}
|
||||||
List<AreaReference> refs = new ArrayList<>();
|
List<AreaReference> refs = new ArrayList<>();
|
||||||
StringTokenizer st = new StringTokenizer(reference, ",");
|
String[] splitReferences = splitAreaReferences(reference);
|
||||||
while(st.hasMoreTokens()) {
|
for (String ref : splitReferences) {
|
||||||
refs.add(
|
refs.add(new AreaReference(ref, version));
|
||||||
new AreaReference(st.nextToken(), version)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
return refs.toArray(new AreaReference[0]);
|
return refs.toArray(new AreaReference[0]);
|
||||||
}
|
}
|
||||||
|
@ -405,4 +397,31 @@ public class AreaReference {
|
||||||
|
|
||||||
return new String [] { partA, sheetName + partB, };
|
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]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,15 +55,15 @@ public final class TestAreaReference {
|
||||||
CellReference cf = ar.getFirstCell();
|
CellReference cf = ar.getFirstCell();
|
||||||
assertEquals("row is 4", 0, cf.getRow());
|
assertEquals("row is 4", 0, cf.getRow());
|
||||||
assertEquals("col is 1", 0, cf.getCol());
|
assertEquals("col is 1", 0, cf.getCol());
|
||||||
assertTrue("row is abs",cf.isRowAbsolute());
|
assertTrue("row is abs", cf.isRowAbsolute());
|
||||||
assertTrue("col is abs",cf.isColAbsolute());
|
assertTrue("col is abs", cf.isColAbsolute());
|
||||||
assertEquals("string is $A$1", "$A$1", cf.formatAsString());
|
assertEquals("string is $A$1", "$A$1", cf.formatAsString());
|
||||||
|
|
||||||
cf = ar.getLastCell();
|
cf = ar.getLastCell();
|
||||||
assertEquals("row is 4", 1, cf.getRow());
|
assertEquals("row is 4", 1, cf.getRow());
|
||||||
assertEquals("col is 1", 1, cf.getCol());
|
assertEquals("col is 1", 1, cf.getCol());
|
||||||
assertTrue("row is abs",cf.isRowAbsolute());
|
assertTrue("row is abs", cf.isRowAbsolute());
|
||||||
assertTrue("col is abs",cf.isColAbsolute());
|
assertTrue("col is abs", cf.isColAbsolute());
|
||||||
assertEquals("string is $B$2", "$B$2", cf.formatAsString());
|
assertEquals("string is $B$2", "$B$2", cf.formatAsString());
|
||||||
|
|
||||||
CellReference[] refs = ar.getAllReferencedCells();
|
CellReference[] refs = ar.getAllReferencedCells();
|
||||||
|
@ -87,8 +87,8 @@ public final class TestAreaReference {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* References failed when sheet names were being used
|
* References failed when sheet names were being used Reported by
|
||||||
* Reported by Arne.Clauss@gedas.de
|
* Arne.Clauss@gedas.de
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testReferenceWithSheet() {
|
public void testReferenceWithSheet() {
|
||||||
|
@ -100,7 +100,6 @@ public final class TestAreaReference {
|
||||||
|
|
||||||
assertEquals(1, ar.getAllReferencedCells().length);
|
assertEquals(1, ar.getAllReferencedCells().length);
|
||||||
|
|
||||||
|
|
||||||
ar = new AreaReference("Tabelle1!$B$5:$B$7", SpreadsheetVersion.EXCEL97);
|
ar = new AreaReference("Tabelle1!$B$5:$B$7", SpreadsheetVersion.EXCEL97);
|
||||||
assertFalse(ar.isSingleCell());
|
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 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 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 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
|
// Check that we detect as contiguous properly
|
||||||
assertTrue(AreaReference.isContiguous(refSimple));
|
assertTrue(AreaReference.isContiguous(refSimple));
|
||||||
|
@ -129,6 +130,8 @@ public final class TestAreaReference {
|
||||||
assertFalse(AreaReference.isContiguous(refDCSimple));
|
assertFalse(AreaReference.isContiguous(refDCSimple));
|
||||||
assertFalse(AreaReference.isContiguous(refDC2D));
|
assertFalse(AreaReference.isContiguous(refDC2D));
|
||||||
assertFalse(AreaReference.isContiguous(refDC3D));
|
assertFalse(AreaReference.isContiguous(refDC3D));
|
||||||
|
assertFalse(AreaReference.isContiguous(refComma));
|
||||||
|
assertTrue(AreaReference.isContiguous(refCommaExp));
|
||||||
|
|
||||||
// Check we can only create contiguous entries
|
// Check we can only create contiguous entries
|
||||||
new AreaReference(refSimple, SpreadsheetVersion.EXCEL97);
|
new AreaReference(refSimple, SpreadsheetVersion.EXCEL97);
|
||||||
|
@ -136,20 +139,20 @@ public final class TestAreaReference {
|
||||||
try {
|
try {
|
||||||
new AreaReference(refDCSimple, SpreadsheetVersion.EXCEL97);
|
new AreaReference(refDCSimple, SpreadsheetVersion.EXCEL97);
|
||||||
fail("expected IllegalArgumentException");
|
fail("expected IllegalArgumentException");
|
||||||
} catch(IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
// expected during successful test
|
// expected during successful test
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
new AreaReference(refDC2D, SpreadsheetVersion.EXCEL97);
|
new AreaReference(refDC2D, SpreadsheetVersion.EXCEL97);
|
||||||
fail("expected IllegalArgumentException");
|
fail("expected IllegalArgumentException");
|
||||||
} catch(IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
// expected during successful test
|
// expected during successful test
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
new AreaReference(refDC3D, SpreadsheetVersion.EXCEL97);
|
new AreaReference(refDC3D, SpreadsheetVersion.EXCEL97);
|
||||||
fail("expected IllegalArgumentException");
|
fail("expected IllegalArgumentException");
|
||||||
} catch(IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
// expected during successful test
|
// expected during successful test
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test that we split as expected
|
// Test that we split as expected
|
||||||
|
@ -193,6 +196,21 @@ public final class TestAreaReference {
|
||||||
assertEquals("Tabelle1", refs[0].getLastCell().getSheetName());
|
assertEquals("Tabelle1", refs[0].getLastCell().getSheetName());
|
||||||
assertEquals("Tabelle1", refs[1].getFirstCell().getSheetName());
|
assertEquals("Tabelle1", refs[1].getFirstCell().getSheetName());
|
||||||
assertEquals("Tabelle1", refs[1].getLastCell().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
|
@Test
|
||||||
|
@ -274,6 +292,9 @@ public final class TestAreaReference {
|
||||||
|
|
||||||
ar = new AreaReference("'one:many'!A1:B2", SpreadsheetVersion.EXCEL97);
|
ar = new AreaReference("'one:many'!A1:B2", SpreadsheetVersion.EXCEL97);
|
||||||
confirmAreaSheetName(ar, "one:many", "'one:many'!A1:B2");
|
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) {
|
private static void confirmAreaSheetName(AreaReference ar, String sheetName, String expectedFullText) {
|
||||||
|
|
Loading…
Reference in New Issue