我正在用sax阅读excel文件,所有工作都在预期日期。日期读作“41751”,这是从1900年开始的天数。应该有一些formatString,我可以用它来格式化,但它是null。
起始元素()
Meteor.Error
结束元素()
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);
}
如何获取该日期或如何找到该单元格包含日期而不是某个整数。完整的处理程序代码在这里http://pastebin.com/GveeMf4n 感谢
答案 0 :(得分:3)
如果你查看Apache POI Example for converting a .xlsx file to .csv with SAX event parsing,就会看到你需要做什么
基本上,当您读取单元格时,不仅需要捕获类型和内容,还需要捕获s
样式索引属性,然后从加载的样式表中查找类似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格式化数字字符串。