1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > java使用 easyexcel 实现Excel 批量导入导出

java使用 easyexcel 实现Excel 批量导入导出

时间:2020-03-02 07:26:53

相关推荐

java使用 easyexcel 实现Excel 批量导入导出

本章提供了java使用阿里的easyexcel实现Excel导入,导出示例,还有网络下载的方法。

模板大家可以随意制作,本例中使用模板表头及数据已经截图,以供参考。

easyexcel背景:

Java解析,生成Excel比较有名的框架有Apache poi,jxl。但他们都存在一个严重的问题就是非常的耗内存,poi有一套SAX模式的API可以一定程度的解决一些内存溢出的问题,但POI还是有一些缺陷,比如07版的Excel解压缩以及解压后存储都是在内存中完成的,内存消耗依然很大.easyexcel重写了POI对07版的Excel的解析,能够原本一个3M的Excel的用POI sax依然需要100M左右内存降低到KB级别,并且再大的Excel中不会出现内存溢出,03版依赖POI的萨克斯模式。在上层做了模型转换的封装,让使用者更加简单方便。

优缺点比较:

easyexcel在解析耗时上比poiuserModel模式弱了一些主要原因是我内部采用了反射做模型字段映射,中间我也加了缓存,但感觉这点差距可以接受的但在内存消耗上差别就比较明显了,easye userxodel就不一大了,简直就要爆掉了。想想一个excel解析200M,同时有20个人再用估计一台机器就挂了。

本例中,工具类整合了easyexcel的导入导出,对导入的数据操作在监听类中实现,在这里可以做一些自己的业务逻辑,这也是使用easyexcel的一个原因,可以更加清晰的去关注业务逻辑。

1.准备:d:\\ .xlsx

内容如下:

2.添加依赖(建议去maven仓库搜索easyexcel下载最新的依赖)

<dependency>

<groupId>com.alibaba</groupId>

<artifactId>easyexcel</artifactId>

<version>1.1.2-beat1</version>

</dependency>

3.添加Excel的映射实体

public class ExcelEntity extends BaseRowModel {

@ExcelProperty(index = 0 , value = "工号")

private String staff_code;

@ExcelProperty(index = 1 , value = "姓名")

private String name;

@ExcelProperty(index = 2 , value = "性别")

private String sex;

@ExcelProperty(index = 3 , value = "联系电话")

private String tel;

@ExcelProperty(index = 4 , value = "邮箱")

private String email;

@ExcelProperty(index = 5 , value = "微信号")

private String weixin;

@ExcelProperty(index = 6 , value = "部门")

private Integer department_id;

@ExcelProperty(index = 7 , value = "职位")

private Integer position_id;

public String getStaff_code() {

return staff_code;

}

public void setStaff_code(String staff_code) {

this.staff_code = staff_code;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public String getSex() {

return sex;

}

public void setSex(String sex) {

this.sex = sex;

}

public String getTel() {

return tel;

}

public void setTel(String tel) {

this.tel = tel;

}

public String getEmail() {

return email;

}

public void setEmail(String email) {

this.email = email;

}

public String getWeixin() {

return weixin;

}

public void setWeixin(String weixin) {

this.weixin = weixin;

}

public Integer getDepartment_id() {

return department_id;

}

public void setDepartment_id(Integer department_id) {

this.department_id = department_id;

}

public Integer getPosition_id() {

return position_id;

}

public void setPosition_id(Integer position_id) {

this.position_id = position_id;

}

@Override

public String toString() {

return "ExcelEntity{" +

"staff_code="" + staff_code + "\"" +

", name="" + name + "\"" +

", sex="" + sex + "\"" +

", tel="" + tel + "\"" +

", email="" + email + "\"" +

", weixin="" + weixin + "\"" +

", department_id=" + department_id +

", position_id=" + position_id +

"}";

}

}

4.添加导入数据监听类

import com.alibaba.excel.context.AnalysisContext;

import com.alibaba.excel.event.AnalysisEventListener;

import com.mon.excelUtils.entity.ExcelEntity;

import java.util.ArrayList;

import java.util.List;

/** 解析监听器,

* 每解析一行会回调invoke()方法。

* 整个excel解析结束会执行doAfterAllAnalysed()方法

*

* 下面只是我写的一个样例而已,可以根据自己的逻辑修改该类。

*/

public class ExcelListener extends AnalysisEventListener {

//自定义用于暂时存储data。

//可以通过实例获取该值

private List<Object> datas = new ArrayList<Object>();

public void invoke(Object object, AnalysisContext context) {

System.out.println("当前行:"+context.getCurrentRowNum());

System.out.println(object);

datas.add(object);//数据存储到list,供批量处理,或后续自己业务逻辑处理。

doSomething(object);//根据自己业务做处理

}

private void doSomething(Object object) {

ExcelEntity excel = (ExcelEntity) object;

//1、入库调用接口

}

public void doAfterAllAnalysed(AnalysisContext context) {

// datas.clear();//解析结束销毁不用的资源

}

public List<Object> getDatas() {

return datas;

}

public void setDatas(List<Object> datas) {

this.datas = datas;

}

}

5.编写导入导出工具类

import com.alibaba.excel.ExcelReader;

import com.alibaba.excel.ExcelWriter;

import com.alibaba.excel.event.AnalysisEventListener;

import com.alibaba.excel.metadata.BaseRowModel;

import com.alibaba.excel.metadata.Sheet;

import com.alibaba.excel.support.ExcelTypeEnum;

import com.mon.excelUtils.entity.ExcelEntity;

import com.mon.excelUtils.listen.ExcelListener;

import java.io.*;

import java.util.ArrayList;

import java.util.List;

public class ExcelUtils {

/**

* @param is 导入文件输入流

* @param clazz Excel实体映射类

* @return

*/

public static Boolean readExcel(InputStream is, Class clazz){

BufferedInputStream bis = null;

try {

bis = new BufferedInputStream(is);

// 解析每行结果在listener中处理

AnalysisEventListener listener = new ExcelListener();

ExcelReader excelReader = EasyExcelFactory.getReader(bis, listener);

excelReader.read(new Sheet(1, 1, clazz));

} catch (Exception e) {

e.printStackTrace();

return false;

} finally {

if (bis != null) {

try {

bis.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

return true;

}

/**

*

* @param os 文件输出流

* @param clazz Excel实体映射类

* @param data 导出数据

* @return

*/

public static Boolean writeExcel(OutputStream os, Class clazz, List<? extends BaseRowModel> data){

BufferedOutputStream bos= null;

try {

bos = new BufferedOutputStream(os);

ExcelWriter writer = new ExcelWriter(bos, ExcelTypeEnum.XLSX);

//写第一个sheet, sheet1 数据全是List<String> 无模型映射关系

Sheet sheet1 = new Sheet(1, 0,clazz);

writer.write(data, sheet1);

writer.finish();

} catch (Exception e) {

e.printStackTrace();

return false;

} finally {

if (bos != null) {

try {

bos.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

return true;

}

public static void main(String[] args) {

//1.读Excel

FileInputStream fis = null;

try {

fis = new FileInputStream("D:\\.xlsx");

Boolean flag = ExcelUtils.readExcel(fis, ExcelEntity.class);

System.out.println("导入是否成功:"+flag);

} catch (FileNotFoundException e) {

e.printStackTrace();

}finally {

if (fis != null){

try {

fis.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

//2.读Excel

FileOutputStream fos = null;

try {

fos = new FileOutputStream("D:\\export.xlsx");

//FileOutputStream fos, Class clazz, List<? extends BaseRowModel> data

List<ExcelEntity> list = new ArrayList<>();

for (int i = 0; i < 5; i++){

ExcelEntity excelEntity = new ExcelEntity();

excelEntity.setName("我是名字"+i);

list.add(excelEntity);

}

Boolean flag = ExcelUtils.writeExcel(fos,ExcelEntity.class,list);

System.out.println("导出是否成功:"+flag);

} catch (FileNotFoundException e) {

e.printStackTrace();

}finally {

if (fos != null){

try {

fos.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

}

}

6.大功告成!在ExcelUtils中运行主方法,简单的导入导出就已经完成了!

7.运行结果截图:

7.1导入数据控制台打印:

7.2导出数据添加姓名+循环次数:

另外,阿里easyexcel还提供了复杂格式的表头使用,和表格样式,有需要的小伙伴可以去github上一睹真容。

附:阿里巴巴开源easyexcel github地址:https:///alibaba/easyexcel

8.最后多一嘴,文件导入,导出,下载模板的时候,Controller层的写法也加上来,记录一下。

/**

* @Auther : guojianmin

* @Date : /5/24 17:03

* @Description : TODO用一句话描述此类的作用

*/

@Api(tags = "ExcelDownloadController", description = "Excel 导入下载模板,导出 相关接口")

@RestController

@RequestMapping("/excel")

public class ExcelDownloadController {

private static final Logger log = LoggerFactory.getLogger(ExcelDownloadController.class);

@Resource

StaffService staffService;

/**

* 单个文件上传

* @param file

* @return

*/

@ApiOperation(value="接口说明",httpMethod="POST",notes="单个文件上传")

@RequestMapping(value = "/upload")

public ResponseMsg upload(@RequestParam("file") MultipartFile file) {

ResponseMsg msg = new ResponseMsg();

try {

if (file.isEmpty()) {

msg.setMsg("文件为空");

msg.setResult(false);

return msg;

}

// 获取文件名

String fileName = file.getOriginalFilename();

log.info("上传的文件名为:" + fileName);

// 获取文件的后缀名

String suffixName = fileName.substring(fileName.lastIndexOf("."));

log.info("文件的后缀名为:" + suffixName);

//创建一个临时文件,用于暂时存放

File tmpFile = File.createTempFile("tmp", null);

//将MultipartFile 转换为 File 临时文件

file.transferTo(tmpFile);

//将临时文件转为输入流

InputStream inputStream = new FileInputStream(tmpFile);

ExcelUtils.readExcel(inputStream, ExcelModel.class);

msg.setResult(true);

msg.setMsg("上传成功");

//上传完成 删除临时文件

tmpFile.delete();

return msg;

} catch (IllegalStateException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

msg.setResult(false);

msg.setMsg("上传失败");

return msg;

}

/**

* 下载模板,用于填写导入数据

* @param request

* @param response

*/

@ApiOperation(value="接口说明",httpMethod="POST",notes="下载模板,用于填写导入数据")

@RequestMapping("/downloadExcel")

public void cooperation(HttpServletRequest request, HttpServletResponse response) {

ServletOutputStream out = null;

try {

out = response.getOutputStream();

response.setContentType("multipart/form-data");

response.setCharacterEncoding("utf-8");

String fileName = "导入模板";

response.setHeader("Content-disposition", "attachment;filename="+ URLEncoder.encode(fileName,"UTF-8")+".xlsx");

ExcelUtils.writeExcel(out,ExcelModel.class,null);

out.flush();

} catch (IOException e) {

e.printStackTrace();

}finally {

if (out != null){

try {

out.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

}

/**

* 导出数据文件

* @param request

* @param response

*/

@ApiOperation(value="接口说明",httpMethod="POST",notes="导出数据文件")

@RequestMapping("/downloadExcelData")

public void cooperationData(HttpServletRequest request, HttpServletResponse response) {

ServletOutputStream out = null;

try {

out = response.getOutputStream();

response.setContentType("multipart/form-data");

response.setCharacterEncoding("utf-8");

String fileName = "导出明细";

response.setHeader("Content-disposition", "attachment;filename="+ URLEncoder.encode(fileName,"UTF-8")+".xlsx");

//List<ExcelModel> data = 此处为 数据接口 返回一个list ;

//把数据明细放在list data中

System.out.println("把数据明细放在list data中:请完善查询数据接口调用,并把查询结果写入list data中");

Boolean flag = ExcelUtils.writeExcel(out, ExcelModel.class, data);

System.out.println("导出是否成功:"+flag);

out.flush();

} catch (IOException e) {

e.printStackTrace();

}finally {

if (out != null){

try {

out.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

}

}

9.最后,真的是最后,顺便了解一下Java 中File类的createNewFile()与createTempFile(), delete和deleteOnExit区别

感谢博主:/kungfupanda/p/9472137.html

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。