POI sax 从单元格获取日期
POI sax get Date from Cell
我正在使用 sax 阅读 excel 文件,一切正常,预计日期。日期读起来像“41751”,这是从 1900 年开始的天数。应该有一些 formatString,我可以用它来格式化,但它是空的。
开始元素()
this.nextDataType = xssfDataType.NUMBER;
this.formatIndex = -1;
this.formatString = null;
String cellType = attributes.getValue("t");
String cellStyleStr = attributes.getValue("s");
if ("b".equals(cellType))
nextDataType = xssfDataType.BOOL;
else if ("e".equals(cellType))
nextDataType = xssfDataType.ERROR;
else if ("inlineStr".equals(cellType))
nextDataType = xssfDataType.INLINESTR;
else if ("s".equals(cellType))
nextDataType = xssfDataType.SSTINDEX;
else if ("str".equals(cellType))
nextDataType = xssfDataType.FORMULA;
else if (cellType == null) {
maybeNull=true;
} else if (cellStyleStr != null) {
// It's a number, but almost certainly one
// with a special style or format
int styleIndex = Integer.parseInt(cellStyleStr);
XSSFCellStyle style = stylesTable.getStyleAt(styleIndex);
this.formatIndex = style.getDataFormat();
this.formatString = style.getDataFormatString();
if (this.formatString == null)
this.formatString = BuiltinFormats.getBuiltinFormat(this.formatIndex);
}
EndElement()
case NUMBER:
String n = value.toString();
if (this.formatString != null) {
thisStr = formatter.formatRawCellContents(Double.parseDouble(n), this.formatIndex, this.formatString);
try {
int intV = Integer.valueOf(thisStr);
cv.set(CellTypes.INT, intV);
} catch (NumberFormatException ignored) {}
if (cv.getType() == null) {
try {
Double doubleV = Double.valueOf(thisStr);
cv.set(CellTypes.DOUBLE, doubleV);
} catch (NumberFormatException e) {
cv.set(CellTypes.STRING, thisStr);
}
}
}
如何获取该日期或如何找到该单元格包含日期而不是某个整数。完整的处理程序代码在这里 http://pastebin.com/GveeMf4n
谢谢
如果您查看 Apache POI Example for converting a .xlsx file to .csv with SAX event parsing,您就会知道需要做什么
基本上,当你读取单元格时,不仅需要捕获类型和内容,还需要捕获 s
样式索引属性,然后从你的 StylesTable 中查找以类似 DOM 的方式加载(它很小),例如
public void startElement(String uri, String localName, String name,
Attributes attributes) throws SAXException {
this.formatIndex = -1;
this.formatString = null;
String cellStyleStr = attributes.getValue("s");
if (cellStyleStr != null) {
// It's a number, but almost certainly one
// with a special style or format
XSSFCellStyle style = null;
if (cellStyleStr != null) {
int styleIndex = Integer.parseInt(cellStyleStr);
style = stylesTable.getStyleAt(styleIndex);
} else if (stylesTable.getNumCellStyles() > 0) {
style = stylesTable.getStyleAt(0);
}
if (style != null) {
this.formatIndex = style.getDataFormat();
this.formatString = style.getDataFormatString();
if (this.formatString == null)
this.formatString = BuiltinFormats.getBuiltinFormat(this.formatIndex);
}
}
// Rest of start element logic here
然后,当您到达单元格的结束标记时,您可以使用 DataFormatter 根据您找到的样式格式化单元格的数字内容(日期、% 或类似内容)早些时候,例如
public void endElement(String uri, String localName, String name)
throws SAXException {
String thisStr = null;
// v => contents of a cell
if ("v".equals(name)) {
// Process the value contents as required.
// Do now, as characters() may be called more than once
switch (nextDataType) {
case NUMBER:
String n = value.toString();
if (this.formatString != null)
thisStr = formatter.formatRawCellContents(Double.parseDouble(n), this.formatIndex, this.formatString);
else
thisStr = n;
break;
但基本上,技巧是读取 StylesTable
,在开始读取单元格时捕获格式字符串,然后在您有单元格内容时使用它通过 DataFormatter 格式化数字字符串。
查看 source code to the XLSX2CSV example 的工作实施
我正在使用 sax 阅读 excel 文件,一切正常,预计日期。日期读起来像“41751”,这是从 1900 年开始的天数。应该有一些 formatString,我可以用它来格式化,但它是空的。
开始元素()
this.nextDataType = xssfDataType.NUMBER;
this.formatIndex = -1;
this.formatString = null;
String cellType = attributes.getValue("t");
String cellStyleStr = attributes.getValue("s");
if ("b".equals(cellType))
nextDataType = xssfDataType.BOOL;
else if ("e".equals(cellType))
nextDataType = xssfDataType.ERROR;
else if ("inlineStr".equals(cellType))
nextDataType = xssfDataType.INLINESTR;
else if ("s".equals(cellType))
nextDataType = xssfDataType.SSTINDEX;
else if ("str".equals(cellType))
nextDataType = xssfDataType.FORMULA;
else if (cellType == null) {
maybeNull=true;
} else if (cellStyleStr != null) {
// It's a number, but almost certainly one
// with a special style or format
int styleIndex = Integer.parseInt(cellStyleStr);
XSSFCellStyle style = stylesTable.getStyleAt(styleIndex);
this.formatIndex = style.getDataFormat();
this.formatString = style.getDataFormatString();
if (this.formatString == null)
this.formatString = BuiltinFormats.getBuiltinFormat(this.formatIndex);
}
EndElement()
case NUMBER:
String n = value.toString();
if (this.formatString != null) {
thisStr = formatter.formatRawCellContents(Double.parseDouble(n), this.formatIndex, this.formatString);
try {
int intV = Integer.valueOf(thisStr);
cv.set(CellTypes.INT, intV);
} catch (NumberFormatException ignored) {}
if (cv.getType() == null) {
try {
Double doubleV = Double.valueOf(thisStr);
cv.set(CellTypes.DOUBLE, doubleV);
} catch (NumberFormatException e) {
cv.set(CellTypes.STRING, thisStr);
}
}
}
如何获取该日期或如何找到该单元格包含日期而不是某个整数。完整的处理程序代码在这里 http://pastebin.com/GveeMf4n 谢谢
如果您查看 Apache POI Example for converting a .xlsx file to .csv with SAX event parsing,您就会知道需要做什么
基本上,当你读取单元格时,不仅需要捕获类型和内容,还需要捕获 s
样式索引属性,然后从你的 StylesTable 中查找以类似 DOM 的方式加载(它很小),例如
public void startElement(String uri, String localName, String name,
Attributes attributes) throws SAXException {
this.formatIndex = -1;
this.formatString = null;
String cellStyleStr = attributes.getValue("s");
if (cellStyleStr != null) {
// It's a number, but almost certainly one
// with a special style or format
XSSFCellStyle style = null;
if (cellStyleStr != null) {
int styleIndex = Integer.parseInt(cellStyleStr);
style = stylesTable.getStyleAt(styleIndex);
} else if (stylesTable.getNumCellStyles() > 0) {
style = stylesTable.getStyleAt(0);
}
if (style != null) {
this.formatIndex = style.getDataFormat();
this.formatString = style.getDataFormatString();
if (this.formatString == null)
this.formatString = BuiltinFormats.getBuiltinFormat(this.formatIndex);
}
}
// Rest of start element logic here
然后,当您到达单元格的结束标记时,您可以使用 DataFormatter 根据您找到的样式格式化单元格的数字内容(日期、% 或类似内容)早些时候,例如
public void endElement(String uri, String localName, String name)
throws SAXException {
String thisStr = null;
// v => contents of a cell
if ("v".equals(name)) {
// Process the value contents as required.
// Do now, as characters() may be called more than once
switch (nextDataType) {
case NUMBER:
String n = value.toString();
if (this.formatString != null)
thisStr = formatter.formatRawCellContents(Double.parseDouble(n), this.formatIndex, this.formatString);
else
thisStr = n;
break;
但基本上,技巧是读取 StylesTable
,在开始读取单元格时捕获格式字符串,然后在您有单元格内容时使用它通过 DataFormatter 格式化数字字符串。
查看 source code to the XLSX2CSV example 的工作实施