在管理一个系统时,总会有许多的数据,为了方便浏览查看数据,系统总会提供「导出Excel」的功能;有导出就有导入,在要向数据库中插入大量的数据时,我们向程序提供准备好的 Excel,然后程序读取表格内容,并将数据添加到数据库中。
实现这个「导入/导出 Excel」的功能也不复杂,我们使用第三方的类库即可实现。
1.技术选型
能够实现「导入/导出 Excel」的第三方常用类库有 Apache poi、Java Excel(JXL)和阿里巴巴开源的 Easyexcel 等。这么多类库该怎么选呢?在这里我给大家推荐阿里巴巴开源的「Easyexcel」。
性能对比
poi 和 jxl 对内存的消耗很大,在处理大批量的数据时,容易造成内存溢出。比如处理一个 3M 的 Excel,poi 和 jxl 可能需要上百兆的内存,但 easyexcel 可能只需要几百或几千 KB(内存消耗对比有些夸张)。在性能这一块,Excel 完全是吊打 poi 和 jxl。
学习复杂度对比
poi,在学习它的时候,理解起来不难,就是操作的时候太特么的难了。因为 poi 需要自己处理数据,还有复杂的表格样式,就光是处理数据这一款就很头疼了。等你写好所有的代码,没有几百行,你是实现不了的。反观 easyexcel。它能自己处理数据,表格格式也简单,即使是小白也很容易上手。在学习复杂的这块也吊打 poi,而 jxl 我没了解,但多半也是被吊打。
2.easyexc拟解决的问题
Excel读写时内存溢出使用简单Excel格式解析3.工作原理
添加maven依赖
<!-- EasyExcel核心文件 --><dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>2.2.3</version></dependency><!-- fastjson依赖包 --><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.51</version></dependency><!-- 解析上传数据 --><dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>1.4</version></dependency><!-- slf4j/log4j日志 --><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-simple</artifactId><version>1.7.25</version></dependency>
Excel下载
HTML<a href="tAccount/DownLoadExcel">下载</a>
封装数据的Java类
public class User {@ExcelProperty("用户编号")private Integer userId;@ExcelProperty("用户名称")private String userName;@ExcelProperty("用户性别")private String gender;@ExcelProperty("创建时间")private Date createTime;}
下载操作
@GetMapping("DownLoadExcel")public void dopost(HttpServletRequest request, HttpServletResponse response) throws IOException {/*** EasyExcel下载步骤*///设置响应头response.setContentType("application/vnd.ms-excel");response.setCharacterEncoding("utf-8");//设置防止文件名中文乱码String fileName = URLEncoder.encode("user1中文文件名","utf-8");response.setHeader("Content-disposition", "attachment;filename="+ fileName + ".xlsx");//构建写入到Excel中的数据(此数据可以从数据库中获取)List<User> users = new ArrayList<>();User user1 = new User(1001, "李四1", "男", new Date());User user2 = new User(1002, "李四2", "男", new Date());User user3 = new User(1003, "李四3", "男", new Date());users.add(user1);users.add(user2);users.add(user3);EasyExcel.write(response.getOutputStream(),User.class).sheet("用户信息").doWrite(users);}
Excel上传
前端页面<form action="tAccount/UploadExcelServlet" method="post" enctype="multipart/form-data"><input type="file" name="file"><input type="submit" value="上传"></form>
接收从Excel中获取到的数据
public class User {@ExcelProperty("用户编号")private Integer userId;@ExcelProperty("用户名称")private String userName;@ExcelProperty("用户性别")private String gender;@ExcelProperty("创建时间")private Date createTime;}
上传操作
@PostMapping("UploadExcelServlet")public void doposts(HttpServletRequest req, HttpServletResponse resp)throws IOException{DiskFileItemFactory factory = new DiskFileItemFactory();ServletFileUpload fileUpload = new ServletFileUpload(factory);//设置单个文件为3MfileUpload.setFileSizeMax(1024*1024*3);//总文件大小为30MfileUpload.setSizeMax(1024*1024*3*10);try {List<FileItem> list = fileUpload.parseRequest(req);for (FileItem fileItem : list) {//判断是否为附件if(!fileItem.isFormField()) {//是附件InputStream inputStream = fileItem.getInputStream();EasyExcel.read(inputStream,User.class,new AnalysisEventListener<User>() {@Overridepublic void doAfterAllAnalysed(AnalysisContext arg0) {System.out.println("Excel全部读完被执行......");}@Overridepublic void invoke(User data, AnalysisContext arg1) {//读完一行就执行一次(调用数据库进行插入操作)System.out.println("解析一行: "+data);}}).sheet().doRead();}else {//普通表单}}} catch (FileUploadException e) {e.printStackTrace();}//上传完成进行转发或者重定向}