Я разбираю листы excel (xlsx) в веб-приложении. Я использую Apache POI, Streaming API, потому что у меня большие файлы. Теперь Excel внутренне сохраняет даты как число, например, например. Я получаю 42035 вместо 31.01.2012. Поскольку я использую разбор XML, я не могу получить доступ к методам dateformatting, предоставляемым POI. Есть идеи?Как извлечь дату как дату не как текст из Excel с помощью потоковой передачи POI (SAX XML)
Вот анализатор (из этого примера https://poi.apache.org/spreadsheet/how-to.html#xssf_sax_api, но изменилось):
/**
* See org.xml.sax.helpers.DefaultHandler javadocs
*/
private static class SheetHandler extends DefaultHandler {
private SharedStringsTable table;
private String lastContents;
private boolean nextIsString;
boolean isFirstRow = true;
private int quantityOfColumns;
private int currentColumnNumber = 1;
int currentRowNumber = 1;
private int rowNumberOfLastCell = 1;
private DataSet data = new DataSet();
private Tuple tuple;
static final Logger LOG = LoggerFactory.getLogger(SheetHandler.class);
private SheetHandler(SharedStringsTable sst) {
this.table = sst;
LOG.debug("Sheethandler created");
}
@Override
public void startElement(String uri, String localName, String name,
Attributes attributes) throws SAXException {
// c => cell
LOG.debug("Reading element of type {} ", name);
if (name.equals("c")) {
rowNumberOfLastCell = currentRowNumber;
String cellType = attributes.getValue("t");
LOG.debug("Extracting cell {} with type {}", attributes.getValue("r"), cellType);
currentRowNumber = extractIntFromString(attributes.getValue("r"));
if (isFinishedRowHeaderRow()) {
extractHeaders();
}
// Figure out if the value is an index in the SST (Static String Table)
if (cellType != null && cellType.equals("s")) {
System.out.println("We have content!");
nextIsString = true;
} else {
nextIsString = false;
}
}
// Clear contents cache
lastContents = "";
}
private boolean isFinishedRowHeaderRow() {
return (rowNumberOfLastCell != currentRowNumber) && isFirstRow;
}
private void extractHeaders() {
quantityOfColumns = data.getHeaders().size();
LOG.debug("{} rows detected", quantityOfColumns);
LOG.debug("{} headers parsed", data.getHeaders().size());
isFirstRow = false;
currentColumnNumber = 1;
tuple = new Tuple(quantityOfColumns);
}
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
lastContents += new String(ch, start, length);
LOG.debug("Extracted value \"{}\"", lastContents);
}
@Override
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) {
extractStringFromCell();
}
// v => contents of a cell
// Output after we've seen the string contents
if (name.equals("v")) {
addExtractedValueToDataSet();
LOG.debug("Ended parsing of column {}", currentColumnNumber);
if (currentColumnNumber == (quantityOfColumns)) {
concludeRow();
} else {
currentColumnNumber++;
}
}
}
private void concludeRow() {
data.addRow(tuple);
LOG.debug("Row added to DataSet");
tuple = new Tuple(quantityOfColumns);
currentColumnNumber = 1;
LOG.debug("Row {} parsed", rowNumberOfLastCell);
}
private void addExtractedValueToDataSet() {
if (isFirstRow) {
data.getHeaders().add(lastContents);
} else {
tuple.getRowEntries()[currentColumnNumber - 1] = lastContents;
}
}
private void extractStringFromCell() throws NumberFormatException {
int idx = Integer.parseInt(lastContents);
lastContents = new XSSFRichTextString(table.getEntryAt(idx)).toString();
LOG.debug("Extracted value \"{}\"", lastContents);
nextIsString = false;
}
public int extractIntFromString(String original) {
char[] chars = original.toCharArray();
for (int i = 0; i < chars.length; i++) {
try {
return Integer.valueOf(original.substring(i, original.length()));
} catch (NumberFormatException ex) {
}
}
return 0;
}
public DataSet getData() {
return data;
}
}
Вы пробовали [DateUtil.getJavaDate (double)] (https://poi.apache.org/apidocs/org/apache/poi/ss/usermodel/DateUtil.html#getJavaDate (double)) (просто гадать)? – agad
Пробовал ли вы читать какие-либо потоковые примеры Apache POI xlsx, большинство из которых показывают, как использовать даты? – Gagravarr