Как читать реальные числовые значения вместо форматированного значения с помощью API потоковой передачи POI Apache XSSF?
Я использую потоковый API POI и хотел бы прочитать реальное значение ячейки вместо отформатированной. Мой код, который приведен ниже, работает нормально, но если пользователь не отображает все цифры значения в листе Excel, который читается моим кодом, я получаю такое же усеченное значение в моем результате. Я не нашел никакого решения в API потоковой передачи - что необходимо в моем случае для решения проблемы с памятью, которая возникла при использовании API POI без потоковой передачи.
/**
* @see org.apache.poi.xssf.eventusermodel.XSSFSheetXMLHandler.SheetContentsHandler cell(java.lang.String,
* java.lang.String)
*/
@Override
void cell(String cellReference, String formattedValue, XSSFComment comment) {
useTheCellValue(formattedValue)
}
2 ответа
Если вы создаете XSSFSheetXMLHandler, вы можете предоставить DataFormatter. Так что, если вы создаете свой собственный DataFormatter
этот DataFormatter
может дать вам полный доступ к вопросам форматирования.
Пример того, как это может выглядеть, изменяя public void processSheet
примера XLSX2CSV в SVN:
...
public void processSheet(
StylesTable styles,
ReadOnlySharedStringsTable strings,
SheetContentsHandler sheetHandler,
InputStream sheetInputStream) throws IOException, SAXException {
//DataFormatter formatter = new DataFormatter();
DataFormatter formatter = new DataFormatter(java.util.Locale.US) {
//do never formatting double values but do formatting dates
public java.lang.String formatRawCellContents(double value, int formatIndex, java.lang.String formatString) {
if (org.apache.poi.ss.usermodel.DateUtil.isADateFormat(formatIndex, formatString)) {
return super.formatRawCellContents(value, formatIndex, formatString);
} else {
//return java.lang.String.valueOf(value);
return super.formatRawCellContents(value, 0, "General");
}
}
};
InputSource sheetSource = new InputSource(sheetInputStream);
try {
XMLReader sheetParser = SAXHelper.newXMLReader();
ContentHandler handler = new XSSFSheetXMLHandler(
styles, null, strings, sheetHandler, formatter, false);
sheetParser.setContentHandler(handler);
sheetParser.parse(sheetSource);
} catch(ParserConfigurationException e) {
throw new RuntimeException("SAX parser appears to be broken - " + e.getMessage());
}
}
...
Я видел тикет на POI об этом: https://bz.apache.org/bugzilla/show_bug.cgi?id=61858
Это обеспечивает первое решение путем изменения существующего класса.
Это может быть интересным решением, даже если идеальным решением будет использование стандартного.