bug 61034: Call to XSSFReader.getSheetsData() returns duplicate sheets.
Thanks to Mauricio Eastmond for the Excel test file and unit test. Thanks to Sebastian Wikalinski for isolating the problem and providing a patch. git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1793223 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
a98eaeb917
commit
e39ae9cd30
@ -428,15 +428,18 @@ public class XSSFReader {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void startElement(String uri, String localName, String qName, Attributes attrs) throws SAXException {
|
public void startElement(String uri, String localName, String qName, Attributes attrs) throws SAXException {
|
||||||
if (localName.toLowerCase(Locale.US).equals(SHEET)) {
|
if (localName.equalsIgnoreCase(SHEET)) {
|
||||||
String name = null;
|
String name = null;
|
||||||
String id = null;
|
String id = null;
|
||||||
for (int i = 0; i < attrs.getLength(); i++) {
|
for (int i = 0; i < attrs.getLength(); i++) {
|
||||||
if (attrs.getLocalName(i).toLowerCase(Locale.US).equals(NAME)) {
|
final String attrName = attrs.getLocalName(i);
|
||||||
|
if (attrName.equalsIgnoreCase(NAME)) {
|
||||||
name = attrs.getValue(i);
|
name = attrs.getValue(i);
|
||||||
} else if (attrs.getLocalName(i).toLowerCase(Locale.US).equals(ID)) {
|
} else if (attrName.equalsIgnoreCase(ID)) {
|
||||||
id = attrs.getValue(i);
|
id = attrs.getValue(i);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (name != null && id != null) {
|
||||||
sheetRefs.add(new XSSFSheetRef(id, name));
|
sheetRefs.add(new XSSFSheetRef(id, name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,10 +18,13 @@
|
|||||||
package org.apache.poi.xssf.eventusermodel;
|
package org.apache.poi.xssf.eventusermodel;
|
||||||
|
|
||||||
import static org.apache.poi.POITestCase.assertContains;
|
import static org.apache.poi.POITestCase.assertContains;
|
||||||
|
import static org.apache.poi.POITestCase.assertNotContained;
|
||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.HashSet;
|
||||||
|
|
||||||
import org.apache.poi.POIDataSamples;
|
import org.apache.poi.POIDataSamples;
|
||||||
import org.apache.poi.POIXMLException;
|
import org.apache.poi.POIXMLException;
|
||||||
@ -267,4 +270,31 @@ public final class TestXSSFReader extends TestCase {
|
|||||||
|
|
||||||
pkg.close();
|
pkg.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* bug 61304: Call to XSSFReader.getSheetsData() returns duplicate sheets.
|
||||||
|
*
|
||||||
|
* The problem seems to be caused only by those xlsx files which have a specific
|
||||||
|
* order of the attributes inside the <sheet> tag of workbook.xml
|
||||||
|
*
|
||||||
|
* Example (which causes the problems):
|
||||||
|
* <sheet name="Sheet6" r:id="rId6" sheetId="4"/>
|
||||||
|
*
|
||||||
|
* While this one works correctly:
|
||||||
|
* <sheet name="Sheet6" sheetId="4" r:id="rId6"/>
|
||||||
|
*/
|
||||||
|
public void test61034() throws Exception {
|
||||||
|
OPCPackage pkg = XSSFTestDataSamples.openSamplePackage("61034.xlsx");
|
||||||
|
XSSFReader reader = new XSSFReader(pkg);
|
||||||
|
XSSFReader.SheetIterator iter = (XSSFReader.SheetIterator) reader.getSheetsData();
|
||||||
|
Set<String> seen = new HashSet<String>();
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
InputStream stream = iter.next();
|
||||||
|
String sheetName = iter.getSheetName();
|
||||||
|
assertNotContained(seen, sheetName);
|
||||||
|
seen.add(sheetName);
|
||||||
|
stream.close();
|
||||||
|
}
|
||||||
|
pkg.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,7 @@ import static org.hamcrest.CoreMatchers.containsString;
|
|||||||
import static org.hamcrest.CoreMatchers.startsWith;
|
import static org.hamcrest.CoreMatchers.startsWith;
|
||||||
import static org.hamcrest.CoreMatchers.endsWith;
|
import static org.hamcrest.CoreMatchers.endsWith;
|
||||||
import static org.hamcrest.CoreMatchers.not;
|
import static org.hamcrest.CoreMatchers.not;
|
||||||
|
import static org.hamcrest.CoreMatchers.hasItem;
|
||||||
|
|
||||||
import java.lang.reflect.AccessibleObject;
|
import java.lang.reflect.AccessibleObject;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
@ -41,6 +42,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import org.apache.poi.util.SuppressForbidden;
|
import org.apache.poi.util.SuppressForbidden;
|
||||||
import org.apache.poi.util.Internal;
|
import org.apache.poi.util.Internal;
|
||||||
@ -111,6 +113,13 @@ public final class POITestCase {
|
|||||||
fail("Unable to find " + key + " in " + map);
|
fail("Unable to find " + key + " in " + map);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static <T> void assertNotContained(Set<T> set, T element) {
|
||||||
|
assertThat(set, not(hasItem(element)));
|
||||||
|
/*if (set.contains(element)) {
|
||||||
|
fail("Set should not contain " + element);
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility method to get the value of a private/protected field.
|
* Utility method to get the value of a private/protected field.
|
||||||
* Only use this method in test cases!!!
|
* Only use this method in test cases!!!
|
||||||
|
BIN
test-data/spreadsheet/61034.xlsx
Normal file
BIN
test-data/spreadsheet/61034.xlsx
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user