I've been using SAX parser to read data from an Excel sheet but I have a problem. I need to save the first four rows and then iterate the others, but when I save the initial row into different HashMap
, these are overwritten, and I obtain in the all structure the same fields.
This is the code of the endElement
method:
public void endElement(String uri, String localName, String name)
throws SAXException {
String cellValue = null;
//String thisStr = null;
// v => contents of a cell
if ("v".equals(name)) {
// Process the value contents as required.
// Do now, as characters() may be called more than once
switch (nextDataType) {
case BOOL:
char first = value.charAt(0);
cellValue=first == '0' ? "false" : "true";
break;
case ERROR:
cellValue=new String(value.toString());
break;
case FORMULA:
// A formula could result in a string value,
// so always add double-quote characters.
cellValue=new String(value.toString());
break;
case INLINESTR:
XSSFRichTextString rtsi = new XSSFRichTextString(value.toString());
cellValue=new String(rtsi.toString());
break;
case SSTINDEX:
String sstIndex = value.toString();
try {
int idx = Integer.parseInt(sstIndex);
XSSFRichTextString rtss = new XSSFRichTextString(sharedStringsTable.getEntryAt(idx));
cellValue=new String(rtss.toString());
}
catch (NumberFormatException ex) {
System.out.println("Failed to parse SST index '" + sstIndex + "': " + ex.toString());
}
break;
case NUMBER:
String n = value.toString();
if (this.formatString != null && n.length() > 0){
cellValue = formatter.formatRawCellContents(Double.parseDouble(n), this.formatIndex, this.formatString);
}
else{
cellValue=new String(n);
}
break;
default:
cellValue="";
break;
}
// Output after we've seen the string contents
// Emit commas for any fields that were missing on this row
if (lastColumnNumber == -1) {
lastColumnNumber = 0;
}
// Might be the empty string.
rowValues.put(cellCoordinate,cellValue);
// Update column
if (thisColumn > -1)
lastColumnNumber = thisColumn;
} else if ("row".equals(name)) {
// We're onto a new row
databaseServices.archiveAcquisition(rowValues,rowCount);
//Clear the structure used to store row data
rowValues.clear();
rowCount++;
lastColumnNumber = -1;
}
}
and archiveAcquisition
method:
@Override
public void archiveAcquisition(HashMap<String,String> actualRowValues, int index) {
switch(index){
case 1:
firstRowValues=actualRowValues;
break;
case 2:
secondRowValues=actualRowValues;
break;
case 3:
thirdRowValues=actualRowValues;
break;
default:
//CREATE ALL THE OBJECT TO STORE THE ACQUISITION
//Create shift object, if it already exists, it'll be updated
Shift shift=new Shift(actualRowValues.get(ExcelMappingCoordinate.shift.getCoordinate()+index));
shiftServices.create(shift);
I don't undestand where is the problem, an hidden behavior of SAX library? I tried also with an external object where to store but the problem was the same.
Problem was that the same HashMap object (rowValues) was repeatedly added, clearing it in between.
A quick hack would be to make every time a copy of the map:
databaseServices.archiveAcquisition(new HashMap<>(rowValues),rowCount);
Better start with a new rowValues
, maybe as local variable.