Я новичок в SAX-разборе и имею небольшой опыт использования библиотек Apache POI в прошлом. У меня есть файл Excel в указанном ниже формате. Это огромный файл размером 10-20 МБ, и я хочу прочитать его, используя SAX Api на Java. Сначала я начал с подхода XSSFWorkbook, но затем переключился на синтаксический анализ SAX из-за серии исключений памяти, возникающих в подходе чтения XSSF.
Однако теперь я застрял как неспособный понять, как получить значение ячейки, используя SAX-разбор. Вот мой код ниже:
Excel_Data.xlsx:
Title | Label A | Label B | Label C
Signal 1 | value A1 | value B1 | value C1
Signal 2 | value A2 | value B2 | value C2
Signal 3 | value A3 | value B3 | value C3
Функция извлечения данных:
public void executeExcelDataExtraction() throws IOException,
OpenXML4JException, SAXException, ParserConfigurationException {
OPCPackage pkg = OPCPackage.open(XLSX_FILE_PATH);
XSSFReader r = new XSSFReader( pkg );
SharedStringsTable sst = r.getSharedStringsTable();
XMLReader parser = fetchSheetParser(sst);
Iterator<InputStream> sheets = r.getSheetsData();
InputStream sheet2 = r.getSheet("rId2");
InputSource sheetSource = new InputSource(sheet2);
parser.parse(sheetSource);
ContentHandler handler = (ImportArticleDataSheetHandler)
parser.getContentHandler();
sheet2.close();
}
Функция XMLReader:
public XMLReader fetchSheetParser(SharedStringsTable sst) throws
SAXException, ParserConfigurationException {
SAXParserFactory factory=SAXParserFactory.newInstance();
SAXParser parser = factory.newSAXParser();
XMLReader xmlReader = parser.getXMLReader();
ContentHandler handler = new ImportArticleDataSheetHandler(sst);
xmlReader.setContentHandler(handler);
return xmlReader;
}
ImportArticleDataSheetHandler.java
public class ImportArticleDataSheetHandler extends DefaultHandler{
private static final String ROW_EVENT = "row";
private static final String CELL_EVENT = "c";
private SharedStringsTable sst;
private String lastContents;
private boolean nextIsString;
private List<String> cellCache = new LinkedList<>();
private List<String[]> rowCache = new LinkedList<>();
ImportArticleDataSheetHandler(SharedStringsTable sst) {
this.sst = sst;
}
public void startElement(String uri, String localName, String name,
Attributes attributes) throws SAXException {
// c => cell
if (CELL_EVENT.equals(name)) {
String cellType = attributes.getValue("t");
if(cellType != null && cellType.equals("s")) {
nextIsString = true;
} else {
nextIsString = false;
}
} else if (ROW_EVENT.equals(name)) {
if (!cellCache.isEmpty()) {
rowCache.add(cellCache.toArray(new String[cellCache.size()]));
}
cellCache.clear();
}
// Clear contents cache
lastContents = "";
}
public void endElement(String uri, String localName, String name)
throws SAXException {
// Process the last contents as required.
// Do now, as characters() may be called more than once
if(nextIsString) {
int idx = Integer.parseInt(lastContents);
lastContents = new XSSFRichTextString(sst.getEntryAt(idx)).toString();
nextIsString = false;
}
// v => contents of a cell
// Output after we've seen the string contents
if(name.equals("v")) {
cellCache.add(lastContents);
}
}
public void characters(char[] ch, int start, int length)
throws SAXException {
lastContents += new String(ch, start, length);
}
public List<String[]> getRowCache() {
return rowCache;
}
}
Пока что я могу выложить структуру с помощью поста, показанного здесь , а также в официальном doc .
Что я хочу:
Все, что я хочу сейчас, - это вызвать некоторые методы и начать читать строки / столбцы в ячейках файла Excel. Но я не могу понять, как? Что я могу сделать с помощью описанных выше методов, чтобы можно было извлечь значения ячеек из файлов Excel и сохранить их в, скажем, списках?
Все это было так просто при обычном подходе XSSF и HSSF, SAX сбивает меня с толку.
Что я пробовал
Пробовал читать все, что там есть в google и stackoverflow, но нигде не нашел пример, где они печатают реальные значения из ячеек Excel с использованием SAX-анализа.
Один из подходов в моей голове - реализовать итератор, который может получить несколько значений по порядку, но на самом деле не знаю, как.