Как читать реальные числовые значения вместо форматированного значения с помощью 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

Это обеспечивает первое решение путем изменения существующего класса.

Это может быть интересным решением, даже если идеальным решением будет использование стандартного.

Другие вопросы по тегам