记一次java使用POI读取Excel-xlsx
1、Excel分类:xls格式,xlsx格式,(Strict xlsx格式这次也接触到了)
2、两种类型的文件有两种不同的方式去读,另外也要注意文件创建的Excel版本
xls:HSSFReader
xlsx:XSSFReader
3、需求:将定量数据导入到mysql中
要求:使用poi去读取strict Excel格式的文件(xlsx),为了安全起见,觉得有种可行性,所以采取这种方式
尝试过后,一是不知道数据类型难以处理,二是网上很少有资料可供查询,最后实在读取不了,改为了读普通的xlsx
4、读取还是有两种方式可以采取
(1)数据量很小时,直接读就行了。
https://www.cnblogs.com/muliu/p/6812347.html
(2)数据量很大时,超过65535(16位)时,会造成内存泄露。
采用流式读取,其实Excel2007版的xlsx底层采用的是xml,故将xlsx转为xml,读取xml,通过自定义解析器去读取。
读取后注意类型的转换
[code]public class ExampleEventUserModel{ 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); // 获得第一个sheet InputStream sheet2 = r.getSheet("rId1"); InputSource sheetSource = new InputSource(sheet2); parser.parse(sheetSource); sheet2.close(); } 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; } /** * 处理sax的handler */ private static class SheetHandler extends DefaultHandler { private SharedStringsTable sst; private String lastContents; private boolean nextIsString; private SheetHandler(SharedStringsTable sst) { this.sst = sst; } //元素开始时的handler public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException { // c => 单元格 if(name.equals("c")) { System.out.print(attributes.getValue("r") + " - "); // 获取单元格类型 String cellType = attributes.getValue("t"); if(cellType != null && cellType.equals("s")) { nextIsString = true; } else { nextIsString = false; } } lastContents = ""; } //元素结束时的handler public void endElement(String uri, String localName, String name) throws SAXException { if(nextIsString) { int idx = Integer.parseInt(lastContents); lastContents = new XSSFRichTextString(sst.getEntryAt(idx)).toString(); nextIsString = false; } // v => 单元格内容 if(name.equals("v")) { System.out.println(lastContents); } } //读取元素间内容时的handler public void characters(char[] ch, int start, int length) throws SAXException { lastContents += new String(ch, start, length); } } public static void main(String[] args) throws Exception { ExampleEventUserModel example = new ExampleEventUserModel(); example.processOneSheet("d://large.xlsx"); } }
5、其他问题
(1)时间戳类型的转换,excel中存的是long串
解决方案:java类Timestamp 转换之后可以直接存到数据库里,对应datetime类型。
[code]Long createTime = Long.valueOf(rowlist.get(i)); Timestamp timestamp = new Timestamp(createTime);
时间戳类型大小比较
timestamp.before(timestamp2)
timestamp.after(timestamp2)
(2)存到数据库遇到障碍:在静态类中无法调用dao层数据库语句
解决:将读到的数据,存到Entity中,然后存到List链中,然后返回出去,第一次体会到List的强大,40万条大概占用内存400M
粗暴了一点,哈哈哈哈
(3)依赖包问题:有些依赖包不支持XSSF方式读取文件
最后用的3.15-beta2....引入这一个依赖就ok,就包含了poi,poi-ooxml-schemas
开始都引入了,反而报缺少schemas的错误了。删去就行了。
[code]<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>3.15-beta2</version> </dependency>
6、碰完错才发现poi还是蛮强大的,会用了就好了。
阅读更多- java使用POI读取excel文件,兼容xls和xlsx
- java使用poi读取excel数据(xlsx)
- java的poi技术读取Excel[xls,xlsx]
- java使用poi读取excel
- java使用poi读取ppt文件和poi读取excel、word示例
- java使用poi读取excel内容方法实例
- java使用POI读取properties文件并写到Excel的方法
- Java使用poi包读取Excel文档
- 使用java读取Excel——poi
- Java使用poi读取excel数据(excel可能很大,先转换为csv再读取)
- Java中通过POI读取Excel 2003 - 2007的xls,xlsx格式
- java:poi读取excel文件,分xls和xlsx
- java使用poi.3.10读取excel 2007以上版本(xlsx格式)
- java使用poi读取excel文档的一种解决方案
- 使用poi Java封装对Excel内容的读取,支持合并列形式
- Java使用poi包读取Excel文档
- Java使用poi包读取Excel文档
- java使用poi读取ppt文件和poi读取excel、word示例
- java 使用POI读取excel数据
- java使用POI实现excel文件的读取,兼容后缀名xls和xlsx