poi读取excel数据(poi读取excel数字类型)
poi实现大数据的导入
之前介绍过通过poi实现数据的导出以及百万数据的导出,今天介绍一般数据以及大数据集的数据导入。之前介绍过poi操作excel2007的三种模式:
用户模式:有许多分装好的方法操作简单事件模式:基于sax方式解析xml,他是一个接口,是一种xml解析的替代方法,不同于dom解析xml文档时把所有数据内容一次性加载到内存,他是逐行扫描sxssf对象:生成海量excel数据文件
poi基于用户模式的数据导出
主要步骤:根据上传信息创建workbok根据workbook创建sheet读取sheet行中数据
@apioperation(value = "导入数据")
@requestmapping(value = "/importpoi", method = requestmethod.post)
@responsebody
public commonresult importexcelpoi(@requestparam(name="file")multipartfile importfile) throws exception{
//根据上传信息创建workbool
workbook sheets = workbookfactory.create(importfile.getinputstream());
//创建一个sheet
sheet sheet= sheets.getsheetat(0);
//从第二行获取数据
list<mesadmin> mesadmins =new arraylist<>();
//从第二行读取数据
for(int rown=1;rown<sheet.getlastrownum();rown++){
row row =sheet.getrow(rown);
mesadmin mesadmin = new mesadmin();
for(int celln=0;celln<row.getlastcellnum();celln++){
//此处为数据每行数据以及对每行数据进行操作
}
}
return commonresult.success(resultcode.success);
}
使用poi的sax(事件)模式读取百万数据
poi在对excel的xml解析以及做了一些封装,我们只有实现这些封才可以安装sax方式进行读取excel,主要就是要实现xssfsheetxmlhandler.sheetcontentshandler接口,给接口有三个方式需要我们去实现:
方法作用public void startrow(int i)开始读取行public void endrow(int i)结束读取行public void cell(string s, string s1, xssfcomment xssfcomment)读取行中单元
需求分析
使用poi的sax模式解析excel文件
解决方案
使用sax模式,逐行扫描文件,一边扫描一遍解析。不需要将数据存储到内存,对于大型文档解析具有很大优势。
步骤分析
设置poi的时间模式
1.根据excel获取文件流
2.根据文件流创建opcpackage
3.创建xssfreader对象
sax解析
1.自定义sheet处理器
2.创建sax的xmlreader
3.设置sheet事件处理器
4.逐行读取
原理分析
excel2007的本质就是一种特殊的xml存储数据,这样就可以使用基于sxa的方式去解析xml完成对excel的读取。sax提供一种从xml文档读取数据的机制,逐行扫描文档,一边扫描一边解析,解析原理如图:
代码实现
自定义实现xssfsheetxmlhandler.sheetcontentshandler处理器
package com.macro.mall.tiny.config;
import org.apache.poi.xssf.eventusermodel.xssfsheetxmlhandler;
import org.apache.poi.xssf.usermodel.xssfcomment;
import java.util.arraylist;
import java.util.list;
//自定义sheet给予sax解析处理器
public class messheethandler implements xssfsheetxmlhandler.sheetcontentshandler {
//行信息
private list<string> lrows = new arraylist<string>(); // 处理一行信息
@override
public void startrow(int i) {
if(i>0){
lrows.clear();
}
}
/**
* 解析行
* @param i
*/
@override
public void endrow(int i) {
//可以每行都对数据进行插入操作,也可以使用监听进行数据操作
system.out.println("i:"+lrows.get(0));
}
/**
* 逐单元读取数据
* @param s
* @param s1
* @param xssfcomment
*/
@override
public void cell(string s, string s1, xssfcomment xssfcomment) {
if(lrows!=null){
lrows.add(s1);
}else{
lrows.add("");
}
}
}
在controller层实现解析
@apioperation(value="批量导入用户数据")
@requestmapping(value = "/importpoi", method = requestmethod.post)
@responsebody
public commonresult importexcelpoisax(@requestparam(name = "file")multipartfile multipartfile,httpservletrequest request) throws exception {
// string file= "c:/users/180454/downloads/1.xlsx";
//根据eccel获取opcpackage对象
opcpackage pkg = opcpackage.open(multipartfile.getinputstream());
//
try{
//创建xssfreader
xssfreader xssfreader = new xssfreader(pkg);
//获取sharedstringtable对象
sharedstringstable sharedstringstable = xssfreader.getsharedstringstable();
//获取stylestable对象
stylestable styles = xssfreader.getstylestable();
xmlreader xmlreader = xmlreaderfactory.createxmlreader();
messheethandler messheethandler = new messheethandler();
xmlreader.setcontenthandler(new xssfsheetxmlhandler(styles,sharedstringstable,messheethandler,false));
xssfreader.sheetiterator sheets = (xssfreader.sheetiterator)xssfreader.getsheetsdata();
//每一个sheet
while(sheets.hasnext()){
inputstream sheetstream = sheets.next();
inputsource sheetsource = new inputsource(sheetstream);
try {
xmlreader.parse(sheetsource);
logger.info("row:"+"结束");
} finally {
sheetstream.close();
}
}
}finally {
pkg.close();
}
return commonresult.success(resultcode.success);
}
总结:
通过简单地介绍excel读取数据的两种模式,可以发现在用户模式下excel读取实现简单但是内存占用量大,不理想,而事件模式操作比较繁琐,但是可以读取大文件的excel。