我正在使用POI的Event API处理大量记录而没有任何内存占用问题。 Here是对它的引用。
当我处理XLSX表时,我得到的日期值格式与excel表格中的指定格式不同。 excel表中列的日期格式为'dd-mm-yyyy',其中我以'mm / dd / yy'格式获取值。
有人可以告诉我如何获得excel表中给出的实际格式。下面给出了代码片段的参考。
ContentHandler handler = new XSSFSheetXMLHandler(styles, strings,
new SheetContentsHandler() {
public void startRow(int rowNum) {
}
public void endRow() {
}
public void cell(String cellReference, String formattedValue) {
System.out.println(formattedValue);
} catch (IOException e) {
System.out.println(
"Exception during file writing");
}
}
在date列的单元格方法中获取formmatedValue就像'mm / dd / yy',因此我无法在pl / sql程序中正确地进行验证。
答案 0 :(得分:4)
我遇到了同样的问题。经过几天的谷歌搜索和研究,我想出了一个解决方案。不幸的是,它并不好,但它确实有效:
org.apache.poi.xssf.eventusermodel.XSSFSheetXMLHandler
课程的副本。SheetContentsHandler
。String overriddenFormat(String cellRef, int formatIndex, String formatString);
public void endElement(String uri, String localName, String name) throws SAXException
。NUMBER
的情况下,有一个if语句:if (this.formatString != null) {...
在此之前,粘贴此代码:
String overriddenFormat = output.overriddenFormat(cellRef, formatIndex, formatString);
if (overriddenFormat != null) {
this.formatIndex = -1;
this.formatString = overriddenFormat;
}
请按照本文/回答:https://stackoverflow.com/a/11345859使用您的新课程和界面。
我的用例是:
在给定工作表中,我在G,H和I列中有日期值,因此SheetContentsHandler.overriddenFormat
的实现是:
@Override
public String overriddenFormat(String cellRef, int formatIndex, String formatString) {
if (cellRef.matches("(G|H|I)\\d+")) { //matches all cells in G, H, and I columns
return "yyyy-mm-dd;@"; //this is the hungarian date format in excel
}
return null;
}
如您所见,在endElement
方法中,我覆盖了formatIndex和formatString。 formatIndex的可能值在org.apache.poi.ss.usermodel.DateUtil.isInternalDateFormat(int format)
中描述。如果给定值不适合这些(并且-1不适合),则将通过格式化时间戳值来使用formatString。 (时间戳值从大约1900.01.01开始计算并具有日期分辨率。)
答案 1 :(得分:2)
Excel使用区域设置存储一些日期。例如,在Excel中的数字格式对话框中,您将看到如下警告:
根据您指定的类型和区域设置(位置),将日期和时间序列号显示为日期值。以星号(*)开头的日期格式会响应“控制面板”中指定的区域日期和时间设置的更改。没有星号的格式不受控制面板设置的影响。
您正在阅读的Excel文件可能正在使用其中一个*日期。在这种情况下,POI可能使用美国默认值。
您可能需要添加一些变通方法代码,以便将日期格式字符串映射到您想要的格式。
有关regional date settings in Excel的讨论,请参阅以下内容。
答案 2 :(得分:1)
请记住两点:
另一种控制日期和其他数值格式的方法是提供您自己的自定义 DataFormatter,以扩展org.apache.poi.ss.usermodel.DataFormatter。
您只需重写formatRawCellContents()方法(或其他根据您需要的方法):
构造解析器/处理程序的示例代码:
public void processSheet(Styles styles, SharedStrings strings,
SheetContentsHandler sheetHandler, InputStream sheetInputStream)
throws IOException, SAXException {
DataFormatter formatter = new CustomDataFormatter();
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());
}
}
private class CustomDataFormatter extends DataFormatter {
@Override
public String formatRawCellContents(double value, int formatIndex, String formatString,
boolean use1904Windowing) {
// Is it a date?
if (DateUtil.isADateFormat(formatIndex, formatString)) {
if (DateUtil.isValidExcelDate(value)) {
Date d = DateUtil.getJavaDate(value, use1904Windowing);
try {
return new SimpleDateFormat("yyyyMMdd").format(d);
} catch (Exception e) {
logger.log(Level.SEVERE, "Bad date value in Excel: " + d, e);
}
}
}
return new DecimalFormat("##0.#####").format(value);
}
}