首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Apache读取错误的日期格式

Apache读取错误的日期格式
EN

Stack Overflow用户
提问于 2020-02-20 16:09:31
回答 1查看 999关注 0票数 0

Apache阅读器的实现类似于这个众所周知的示例,https://github.com/pjfanning/poi-shared-strings-sample/blob/master/src/main/java/com/github/pjfanning/poi/sample/XLSX2CSV.java读取一些日期值,而不是像在excel中显示的那样,尽管它应该读取“格式化值”。

值在excel文件中:1/1/2019,读取器读取的“格式化值”:1/1/19

知道为什么会有区别吗?

Apache版本3.17

读者代码:

代码语言:javascript
运行
复制
package com.lopuch.sk.lita.is.importer;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

import javax.xml.parsers.ParserConfigurationException;

import org.apache.log4j.Logger;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.util.ZipSecureFile;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.ss.util.CellAddress;
import org.apache.poi.ss.util.CellReference;
import org.apache.poi.util.SAXHelper;
import org.apache.poi.xssf.eventusermodel.ReadOnlySharedStringsTable;
import org.apache.poi.xssf.eventusermodel.XSSFReader;
import org.apache.poi.xssf.eventusermodel.XSSFSheetXMLHandler;
import org.apache.poi.xssf.eventusermodel.XSSFSheetXMLHandler.SheetContentsHandler;
import org.apache.poi.xssf.model.StylesTable;
import org.apache.poi.xssf.usermodel.XSSFComment;
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;

import com.lopuch.sk.lita.is.importer.fileImport.ExcelRowReadListener;

public class ExcelSaxImporter {

    private static final Logger logger = Logger.getLogger(ExcelSaxImporter.class);

    private ExcelRowReadListener listener;

    public void setOnRowRead(ExcelRowReadListener listener) {
        this.listener = listener;
    }

    public ExcelRowReadListener getListener() {
        return listener;
    };

    public void process(byte[] fileByteArray)
            throws IOException, OpenXML4JException, ParserConfigurationException, SAXException {
        ZipSecureFile.setMinInflateRatio(0.0d);
        OPCPackage opcpPackage = OPCPackage.open(new ByteArrayInputStream(fileByteArray));
        ReadOnlySharedStringsTable strings = new ReadOnlySharedStringsTable(opcpPackage);
        XSSFReader xssfReader = new XSSFReader(opcpPackage);
        StylesTable styles = xssfReader.getStylesTable();
        XSSFReader.SheetIterator iter = (XSSFReader.SheetIterator) xssfReader.getSheetsData();

        while (iter.hasNext()) {
            InputStream stream = iter.next();
            processSheet(styles, strings, getHandler(), stream);
            stream.close();
        }
    }

    private SheetContentsHandler getHandler() {
        return new SheetContentsHandler() {

            private boolean firstCellOfRow = false;
            private int currentRow = -1;
            private int currentCol = -1;

            // Maps column Letter name to its value.
            // Does not contain key-value pair if cell value is null for
            // currently
            // processed column and row.
            private Map<String, String> rowValues;

            @Override
            public void startRow(int rowNum) {
                // Prepare for this row
                firstCellOfRow = true;
                currentRow = rowNum;
                currentCol = -1;
                rowValues = new HashMap<String, String>();
            }

            @Override
            public void endRow(int rowNum) {
                if (rowValues.keySet().size() == 0) {
                    logger.trace("Skipping calling rowRead() because of empty row");
                } else {
                    ExcelSaxImporter.this.getListener().rowRead(rowValues);
                }
            }

            @Override
            public void cell(String cellReference, String formattedValue, XSSFComment comment) {
                if (firstCellOfRow) {
                    firstCellOfRow = false;
                }

                // gracefully handle missing CellRef here in a similar way
                // as XSSFCell does
                if (cellReference == null) {
                    cellReference = new CellAddress(currentRow, currentCol).formatAsString();
                }

                // Did we miss any cells?
                int thisCol = (new CellReference(cellReference)).getCol();
                currentCol = thisCol;

                cellReference = cellReference.replaceAll("\\d","");
                rowValues.put(cellReference, formattedValue);

            }

            @Override
            public void headerFooter(String text, boolean isHeader, String tagName) {
            }
        };
    }

    /**
     * Parses and shows the content of one sheet using the specified styles and
     * shared-strings tables.
     *
     * @param styles
     * @param strings
     * @param sheetInputStream
     */
    public void processSheet(StylesTable styles, ReadOnlySharedStringsTable strings, SheetContentsHandler sheetHandler,
            InputStream sheetInputStream) throws IOException, ParserConfigurationException, SAXException {
        DataFormatter formatter = new DataFormatter();
        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());
        }
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-02-21 12:27:19

excel显示的值与Apache读取的值的差异来自于对用户语言设置作出反应的日期格式。来自Excel:

以星号(*)开头的

日期格式响应为操作系统指定的区域日期和时间设置的更改。

Apache忽略这些特定于地区的格式,并返回默认的美国格式日期。来自Apache文档:

某些格式通过Excel自动“本地化”,例如在某些地区加载到Excel中时显示为mm/dd/yyyy,而在另一些地区则显示为dd/mm/yyyy。这些文件总是以“默认”(US)格式返回,存储在文件中。

若要处理此行为,请参见对Java: excel to csv date conversion issue with Apache Poi的回答

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60324162

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档