Trying to read a rather large excel file, and therefore using an SheetContentsHandler
.
Here's my main code:
OPCPackage pkg = OPCPackage.open(file);
XSSFReader reader = new XSSFReader(pkg);
InputStream sheet = reader.getSheet("rId1");
XMLReader parser = XMLHelper.newXMLReader();
CustomXSSFSheetHandler sheetHandler = new CustomXSSFSheetHandler();
parser.setContentHandler(new XSSFSheetXMLHandler(null, null, sheetHandler, false));
InputSource sheetSource = new InputSource(sheet);
parser.parse(sheetSource);
recordList = sheetHandler.getRecords();
sheet.close();
Here's my implementation of SheetContentsHandler
:
public class CustomXSSFSheetHandler implements XSSFSheetXMLHandler.SheetContentsHandler
{
private int currentRow = -1;
private final List<Record> recordList = new ArrayList<>();
private Record currentRecord = null;
@Override
public void startRow(int rowNum)
{
if (rowNum > 0)
{
currentRow = rowNum;
currentRecord = new Record();
}
}
@Override
public void endRow(int rowNum)
{
if (currentRow > 0)
{
recordList.add(currentRecord);
}
}
@Override
public void cell(String cellReference, String formattedValue, XSSFComment comment)
{
if (currentRow > 0)
{
int currentCol = getColIndex(cellReference);
if (currentCol == 0)
{
currentRecord.setSerialNo(Long.parseLong(formattedValue));
} else if (currentCol == 1)
{
currentRecord.setReferenceNo(Long.parseLong(formattedValue));
} else if (currentCol == 2)
{
currentRecord.setMsn(Long.parseLong(formattedValue));
} else if (currentCol == 3)
{
currentRecord.setI1(Double.parseDouble(formattedValue));
} else if (currentCol == 4)
{
currentRecord.setI2(Double.parseDouble(formattedValue));
} else if (currentCol == 5)
{
currentRecord.setI3(Double.parseDouble(formattedValue));
} else if (currentCol == 6)
{
currentRecord.setV1(Double.parseDouble(formattedValue));
} else if (currentCol == 7)
{
currentRecord.setV2(Double.parseDouble(formattedValue));
} else if (currentCol == 8)
{
currentRecord.setV3(Double.parseDouble(formattedValue));
}
}
}
private int getColIndex(String cellReference)
{
// Extract the column index from the cell reference (e.g., "A1")
String colStr = cellReference.replaceAll("[0-9]", "");
int colIndex = 0;
for (int i = 0; i < colStr.length(); i++)
{
colIndex = colIndex * 26 + (colStr.charAt(i) - 'A' + 1);
}
return colIndex - 1;
}
public List<Record> getRecords()
{
return recordList;
}
}
As soon as the parsing starts, I get this error:
java.lang.NullPointerException: Attempt to invoke interface method 'org.apache.poi.ss.usermodel.RichTextString org.apache.poi.xssf.model.SharedStrings.getItemAt(int)' on a null object reference
at org.apache.poi.xssf.eventusermodel.XSSFSheetXMLHandler.outputCell(XSSFSheetXMLHandler.java:419)
at org.apache.poi.xssf.eventusermodel.XSSFSheetXMLHandler.endElement(XSSFSheetXMLHandler.java:317)
at org.apache.harmony.xml.ExpatParser.endElement(ExpatParser.java:167)
at org.apache.harmony.xml.ExpatParser.appendBytes(Native Method)
My excel file:
This statement:
parser.setContentHandler(new XSSFSheetXMLHandler(null, null, sheetHandler, false));
was missing the second argument which is a SharedStringsTable
object and is required. Fixed it by using:
parser.setContentHandler(new XSSFSheetXMLHandler(null, new ReadOnlySharedStringsTable(pkg), sheetHandler, false));