java - Apache POI 通过 XSSF 阅读器读取错误日期格式的 Excel 表格
问题描述
我想读取 Excel 表中单元格的特定值。目前我的代码给出的是通用值而不是单元格的自定义值。
举个例子: - 现在,
- 我在 Excel 表自定义(单元格类型)--> 01/10/2250 中提供输入。
- 输出转换为 Cell 的 General 值--->128110 (单元格的格式为“General”,这一点很重要,因为正是这种特定条件导致了我们遇到的错误)。
由于工作簿的内存问题,我们正在使用 XSSF 阅读器和 XMLReader,现在使用工作簿。(我们在工作簿上看到很多答案,而不是 XSSF)
测试用例
- 输入 --> 01/10/2250
- 所需的输出 --> 2250 年 1 月 10 日
- 实际输出---->128110
- 输入 --> 12-25-2250
- 所需输出 --> 12-25-2250
- 实际输出---->128110
- 输入 --> 2250-25-12
- 所需输出 --> 2250-25-12
- 实际输出---->128195
请注意所有带有连字符(-)和斜杠(/)的输入模式。
强文本 这是代码---->
import java.io.InputStream;
import java.util.Iterator;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xssf.eventusermodel.XSSFReader;
import org.apache.poi.xssf.model.SharedStringsTable;
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.helpers.XMLReaderFactory;
public class DateCellDemo {
public void processOneSheet(String filename) throws Exception {
OPCPackage pkg = OPCPackage.open(filename);
XSSFReader r = new XSSFReader( pkg );
SharedStringsTable sst = r.getSharedStringsTable();
XMLReader parser = fetchSheetParser(sst);
InputStream sheet2 = r.getSheet("rId1");
InputSource sheetSource = new InputSource(sheet2);
parser.parse(sheetSource);
sheet2.close();
}
public void processAllSheets(String filename) throws Exception {
OPCPackage pkg = OPCPackage.open(filename);
XSSFReader r = new XSSFReader( pkg );
SharedStringsTable sst = r.getSharedStringsTable();
XMLReader parser = fetchSheetParser(sst);
Iterator<InputStream> sheets = r.getSheetsData();
while(sheets.hasNext()) {
System.out.println("Processing new sheet:\n");
InputStream sheet = sheets.next();
InputSource sheetSource = new InputSource(sheet);
parser.parse(sheetSource);
sheet.close();
System.out.println("");
}
}
public XMLReader fetchSheetParser(SharedStringsTable sst) throws SAXException {
XMLReader parser =
XMLReaderFactory.createXMLReader(
"org.apache.xerces.parsers.SAXParser"
);
ContentHandler handler = new SheetHandler(sst);
parser.setContentHandler(handler);
return parser;
}
private static class SheetHandler extends DefaultHandler {
private SharedStringsTable sst;
private String lastContents;
private boolean nextIsString;
private SheetHandler(SharedStringsTable sst) {
this.sst = sst;
}
public void startElement(String uri, String localName, String name,
Attributes attributes) throws SAXException {
// c => cell
if(name.equals("c")) {
// Print the cell reference
System.out.print(attributes.getValue("r") + " - ");
// Figure out if the value is an index in the SST
String cellType = attributes.getValue("t");
//System.out.println("------ cellType :"+cellType);
if(cellType != null && cellType.equals("s")) {
nextIsString = true;
} else {
nextIsString = false;
}
}
// Clear contents cache
lastContents = "";
}
public void endElement(String uri, String localName, String name)
throws SAXException {
// Process the last contents as required.
// Do now, as characters() may be called more than once
if(nextIsString) {
System.out.println("Date Pattren : "+nextIsString);
int idx = Integer.parseInt(lastContents);
lastContents = new XSSFRichTextString(sst.getEntryAt(idx)).toString();
}
// v => contents of a cell
// Output after we've seen the string contents
if(name.equals("v")) {
System.out.println("Last_Content : "+lastContents);
}
}
public void characters(char[] ch, int start, int length)
throws SAXException {
lastContents += new String(ch, start, length);
}
}
public static void main(String[] args) {
try {
DateCellDemo howto = new DateCellDemo();
howto.processOneSheet("C:\\Users\\Dell\\Downloads\\Source11_Data.xlsx");
} catch (Exception e) {
e.printStackTrace();
}
}
}
解决方案
还有另一个 Apache POI 示例 (XLSX2CSV),可让您流式传输输入 xlsx,但可以访问格式化的单元格数据。您的代码基于另一个示例,该示例从 xlsx 文件中读取原始 XML(原始 XML 具有数字格式的日期)。
推荐阅读
- sql - Oracle查询显示计数和开始,序列结束
- android - RxJava2。对列表中的每个项目执行请求
- php - php - 尝试从 CSV 下载 URL,它在随机 URL 处停止
- ios - 从情节提要更改选项卡栏按钮序列
- python - Python 中的分钟数
- powerbi-embedded - PowerBi 嵌入式警报和通知
- git - 从没有子文件夹结构的 git 存储库中克隆特定文件夹
- apache-kafka - 为什么我不能运行 Kafka 的消费者?
- java - 放心。将字符串分配给 baseUri 时的 StackOverflowError
- stream - 通过流组件来自 UNIX 管道的 XML 消息