easyexcel实现文件导入导出
1,环境配置
我用的是springboot项目
(1)首先pom.xml
<!--阿里巴巴easyexcel-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>1.1.2-beta5</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.17</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.17</version>
</dependency>
(2)放几个工具类
1,Excelexception,excel异常类
package cn.project.cnfedu.utils;
/**
* Created with IntelliJ IDEA
*
* @Author liangjiansong [email protected]
* @Description Excel 解析 Exception
* @Date 2020-6-2
* @Time 20:05
*/
public class ExcelException extends RuntimeException {
public ExcelException(String message) {
super(message);
}
}
2,Excellistener,excel监听类
package cn.project.cnfedu.utils;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import java.util.ArrayList;
import java.util.List;
/**
* Created with IntelliJ IDEA
*
*@Author liangjiansong [email protected]
*@Description Excel 解析 Exception
*@Date 2020-6-2
*@Time 20:05
*/
public class ExcelListener extends AnalysisEventListener {
//自定义用于暂时存储data。
//可以通过实例获取该值
private List<Object> datas = new ArrayList<>();
/**
* 通过 AnalysisContext 对象还可以获取当前 sheet,当前行等数据
*/
@Override
public void invoke(Object object, AnalysisContext context) {
//数据存储到list,供批量处理,或后续自己业务逻辑处理。
datas.add(object);
//根据业务自行 do something
doSomething();
/*
如数据过大,可以进行定量分批处理
if(datas.size()<=100){
datas.add(object);
}else {
doSomething();
datas = new ArrayList<Object>();
}
*/
}
/**
* 根据业务自行实现该方法
*/
private void doSomething() {
}
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
/*
datas.clear();
解析结束销毁不用的资源
*/
}
public List<Object> getDatas() {
return datas;
}
public void setDatas(List<Object> datas) {
this.datas = datas;
}
}
3,excelUtil工具类
package cn.project.cnfedu.utils;
import com.alibaba.excel.ExcelReader;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.metadata.BaseRowModel;
import com.alibaba.excel.metadata.Sheet;
import com.alibaba.excel.support.ExcelTypeEnum;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.List;
/**
* Created with IntelliJ IDEA
*
*@Author liangjiansong [email protected]
*@Description Excel 解析 Exception
*@Date 2020-6-2
*@Time 20:05
*/
public class ExcelUtil {
/**
* 读取 Excel(多个 sheet)
*
* @param excel 文件
* @param rowModel 实体类映射,继承 BaseRowModel 类
* @return Excel 数据 list
*/
public static List<Object> readExcel(MultipartFile excel, BaseRowModel rowModel) throws Exception {
ExcelListener excelListener = new ExcelListener();
ExcelReader reader = getReader(excel, excelListener);
if (reader == null) {
return null;
}
for (Sheet sheet : reader.getSheets()) {
if (rowModel != null) {
sheet.setClazz(rowModel.getClass());
}
reader.read(sheet);
}
return excelListener.getDatas();
}
/**
* 读取某个 sheet 的 Excel
*
* @param excel 文件
* @param rowModel 实体类映射,继承 BaseRowModel 类
* @param sheetNo sheet 的序号 从1开始
* @return Excel 数据 list
*/
public static List<Object> readExcel(MultipartFile excel, BaseRowModel rowModel, int sheetNo) throws Exception {
return readExcel(excel, rowModel, sheetNo, 1);
}
/**
* 读取某个 sheet 的 Excel
*
* @param excel 文件
* @param rowModel 实体类映射,继承 BaseRowModel 类
* @param sheetNo sheet 的序号 从1开始
* @param headLineNum 表头行数,默认为1
* @return Excel 数据 list
*/
public static List<Object> readExcel(MultipartFile excel, BaseRowModel rowModel, int sheetNo,
int headLineNum) throws Exception {
ExcelListener excelListener = new ExcelListener();
ExcelReader reader = getReader(excel, excelListener);
if (reader == null) {
return null;
}
reader.read(new Sheet(sheetNo, headLineNum, rowModel.getClass()));
return excelListener.getDatas();
}
/**
* 导出 Excel :一个 sheet,带表头
*
* @param response HttpServletResponse
* @param list 数据 list,每个元素为一个 BaseRowModel
* @param fileName 导出的文件名
* @param sheetName 导入文件的 sheet 名
* @param object 映射实体类,Excel 模型
*/
public static void writeExcel(HttpServletResponse response, List<? extends BaseRowModel> list,
String fileName, String sheetName, BaseRowModel object) {
ExcelWriter writer = new ExcelWriter(getOutputStream(fileName, response), ExcelTypeEnum.XLSX);
Sheet sheet = new Sheet(1, 0, object.getClass());
sheet.setSheetName(sheetName);
writer.write(list, sheet);
writer.finish();
}
/**
* 导出 Excel :多个 sheet,带表头
*
* @param response HttpServletResponse
* @param list 数据 list,每个元素为一个 BaseRowModel
* @param fileName 导出的文件名
* @param sheetName 导入文件的 sheet 名
* @param object 映射实体类,Excel 模型
*/
public static ExcelWriterFactroy writeExcelWithSheets(HttpServletResponse response, List<? extends BaseRowModel> list,
String fileName, String sheetName, BaseRowModel object) {
ExcelWriterFactroy writer = new ExcelWriterFactroy(getOutputStream(fileName, response), ExcelTypeEnum.XLSX);
Sheet sheet = new Sheet(1, 0, object.getClass());
sheet.setSheetName(sheetName);
writer.write(list, sheet);
return writer;
}
/**
* 导出文件时为Writer生成OutputStream
*/
private static OutputStream getOutputStream(String fileName, HttpServletResponse response) {
//创建本地文件
String filePath = fileName + ".xlsx";
File dbfFile = new File(filePath);
try {
if (!dbfFile.exists() || dbfFile.isDirectory()) {
dbfFile.createNewFile();
}
fileName = new String(filePath.getBytes(), "ISO-8859-1");
response.addHeader("Content-Disposition", "filename=" + fileName);
return response.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
/**
* 返回 ExcelReader
*
* @param excel 需要解析的 Excel 文件
* @param excelListener new ExcelListener()
*/
private static ExcelReader getReader(MultipartFile excel,
ExcelListener excelListener) throws Exception {
String filename = excel.getOriginalFilename();
if (filename == null || (!filename.toLowerCase().endsWith(".xls") && !filename.toLowerCase().endsWith(".xlsx"))) {
throw new Exception("文件格式错误!");
}
InputStream inputStream;
try {
inputStream = new BufferedInputStream(excel.getInputStream());
return new ExcelReader(inputStream, null, excelListener, false);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
4,excelWriterFactory
package cn.project.cnfedu.utils;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.metadata.BaseRowModel;
import com.alibaba.excel.metadata.Sheet;
import com.alibaba.excel.support.ExcelTypeEnum;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
/**
* Created with IntelliJ IDEA
*
*@Author liangjiansong [email protected]
*@Description Excel 解析 Exception
*@Date 2020-6-2
*@Time 20:05
*/
public class ExcelWriterFactroy extends ExcelWriter {
private OutputStream outputStream;
private int sheetNo = 1;
public ExcelWriterFactroy(OutputStream outputStream, ExcelTypeEnum typeEnum) {
super(outputStream, typeEnum);
this.outputStream = outputStream;
}
public ExcelWriterFactroy write(List<? extends BaseRowModel> list, String sheetName,
BaseRowModel object) {
this.sheetNo++;
try {
Sheet sheet = new Sheet(sheetNo, 0, object.getClass());
sheet.setSheetName(sheetName);
this.write(list, sheet);
} catch (Exception ex) {
ex.printStackTrace();
try {
outputStream.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
return this;
}
@Override
public void finish() {
super.finish();
try {
outputStream.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
2,导出(根据数据表,导出为excel)
(1)pojo层
package cn.project.cnfedu.pojo;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.metadata.BaseRowModel;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.format.annotation.NumberFormat;
import java.util.Date;
//@EqualsAndHashCode(callSuper = true)
@Data
public class StudentExcelFileModel extends BaseRowModel {
/**
* value: 表头名称
* index: 列的号, 0表示第一列
*/
//学员编号
@ExcelProperty(value = "序号", index = 0)
private Long id;
//学员姓名
@ExcelProperty(value = "姓名", index = 1)
private String name;
//学员手机号码
@ExcelProperty(value = "手机", index = 2)
private String phone;
//学员qq号
@ExcelProperty(value = "qq", index = 3)
private String qq;
//学员微信号
@ExcelProperty(value = "微信", index = 4)
private String wechat;
//学员性别
@ExcelProperty(value = "性别", index = 5)
private Integer gender;
//上课城区
@ExcelProperty(value = "上课城区", index = 6)
private Integer areaid;
//上课地址
@ExcelProperty(value = "上课地址", index = 7)
private String address;
//年级
@ExcelProperty(value = "年级", index = 8)
private Integer gradeid;
//辅导科目
@ExcelProperty(value = "辅导科目", index = 9)
private String subject;
//每周次数
@ExcelProperty(value = "每周次数", index = 10)
private Integer num;
//每次时数
@ExcelProperty(value = "每周时数", index = 11)
private Integer hour;
//可授课时间
@ExcelProperty(value = "可授课时间", index = 12)
private String teachingtimeid;
//学员情况描述
@ExcelProperty(value = "学员描述情况", index = 13)
private String desc;
//教员性别
@ExcelProperty(value = "教员性别", index = 14)
private Integer teacherGender;
//教员类别
@ExcelProperty(value = "教员类别", index = 15)
private Integer teachertype;
//对教员要求
@ExcelProperty(value = "对教员的要求", index = 16)
private String teacherwant;
//支付报酬 decimal BigDecimal
@ExcelProperty(value = "薪资要求", index = 17)
@NumberFormat(pattern="#.##")
private double payment;
//学员密码
@ExcelProperty(value = "密码", index = 18)
private String password;
//学员状态
@ExcelProperty(value = "学员状态", index = 19)
private Integer stuStatus;
//是否已经支付
@ExcelProperty(value = "是否支付", index = 20)
private Integer ispay;
//籍贯
@ExcelProperty(value = "籍贯", index = 21)
private Integer nativeplace;
//学员审核状态
@ExcelProperty(value = "学员审核状态", index = 22)
private Integer stuAuditstatus;
//检索ID
@ExcelProperty(value = "检索id", index = 23)
private Long indexid;
//预约情况
@ExcelProperty(value = "预约情况", index = 24)
private Integer appointment;
//创建者编号
@ExcelProperty(value = "创建者", index = 25)
private Integer createdby;
//创建时间
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@ExcelProperty(value = "创建时间", index = 26)
private Date creationdate;
//修改者编号
@ExcelProperty(value = "修改者", index = 27)
private Integer modifyby;
//修改时间
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@ExcelProperty(value = "修改时间", index = 28)
private Date modifyDate;
}
(2)dao层
@Mapper
public interface ExcelStudentMapper {
//导出excel的方法
List getAllStudent();
}
(3)xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="cn.project.cnfedu.dao.ExcelStudentMapper" >
<resultMap id="BaseResultMap" type="cn.project.cnfedu.pojo.StudentExcelFileModel2">
<id column="id" property="id" jdbcType="BIGINT"/>
<result column="name" property="name" jdbcType="VARCHAR"/>
<result column="phone" property="phone" jdbcType="VARCHAR"/>
<result column="qq" property="qq" jdbcType="VARCHAR"/>
<result column="weChat" property="wechat" jdbcType="VARCHAR"/>
<result column="gender" property="gender" jdbcType="INTEGER"/>
<result column="areaId" property="areaid" jdbcType="INTEGER"/>
<result column="address" property="address" jdbcType="VARCHAR"/>
<result column="gradeId" property="gradeid" jdbcType="INTEGER"/>
<result column="subject" property="subject" jdbcType="VARCHAR"/>
<result column="num" property="num" jdbcType="INTEGER"/>
<result column="hour" property="hour" jdbcType="INTEGER"/>
<result column="teachingTimeId" property="teachingtimeid" jdbcType="VARCHAR"/>
<result column="desc" property="desc" jdbcType="VARCHAR"/>
<result column="teacherGender" property="teachergender" jdbcType="INTEGER"/>
<result column="teacherType" property="teachertype" jdbcType="INTEGER"/>
<result column="teacherWant" property="teacherwant" jdbcType="VARCHAR"/>
<result column="payment" property="payment" jdbcType="DECIMAL"/>
<result column="password" property="password" jdbcType="VARCHAR"/>
<result column="stuStatus" property="stuStatus" jdbcType="INTEGER"/>
<result column="isPay" property="ispay" jdbcType="INTEGER"/>
<result column="nativePlace" property="nativeplace" jdbcType="INTEGER"/>
<result column="stuAuditstatus" property="stuAuditstatus" jdbcType="INTEGER"/>
<result column="indexId" property="indexid" jdbcType="BIGINT"/>
<result column="Appointment" property="Appointment" jdbcType="INTEGER"/>
<result column="createdBy" property="createdby" jdbcType="INTEGER"/>
<result column="creationDate" property="creationdate" jdbcType="TIMESTAMP"/>
<result column="modifyBy" property="modifyby" jdbcType="INTEGER"/>
<result column="modifyDate" property="modifydate" jdbcType="TIMESTAMP"/>
</resultMap>
<sql id="Base_Column_List">
id, `name`, phone,qq, weChat, gender, areaId, address, gradeId, subject, num, `hour`, teachingTimeId,
`desc`, teacherGender, teacherType, teacherWant, payment, password, stuStatus, isPay,
nativePlace, stuAuditStatus, indexId, Appointment, createdBy, creationDate, modifyBy,
modifyDate
</sql>
<!--导出excel-->
<select id="getAllStudent" resultType="StudentExcelFileModel">
select id,`name`,phone,qq,wechat,gender,areaid,address,gradeid,subject,num,`hour`,teachingtimeid,
`desc`,teachergender,teachertype,teacherwant,payment,password,stuStatus,ispay,nativeplace,stuAuditstatus,
indexid,Appointment,createdby,creationdate,modifyby,modifydate
from fedu_student
</select>
(4)service
public interface ExcelService {
//导出所有的学生
List<StudentExcelFileModel> getAllStudent(HttpServletResponse response) throws IOException;
}
(5)serviceimpl
import cn.project.cnfedu.service.ExcelService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
@Service
public class ExcelServiceImpl implements ExcelService {
@Resource
private ExcelStudentMapper excelMapper;
@Override
public List<StudentExcelFileModel> getAllStudent(HttpServletResponse response)throws IOException {
List<StudentExcelFileModel>list=excelMapper.getAllStudent();
return list;
}
(6)controller
package cn.project.cnfedu.controller;
import cn.project.cnfedu.pojo.StudentExcelFileModel;
import cn.project.cnfedu.pojo.StudentExcelFileModel2;
import cn.project.cnfedu.service.ExcelService;
import cn.project.cnfedu.utils.ExcelUtil;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/excel")
public class ExcelController {
@Resource
private ExcelService excelService;
//导出
@GetMapping(value="/export")
public void exportStudentinfo(HttpServletResponse response){
try {
List<StudentExcelFileModel> list=excelService.getAllStudent(response);
//excel的名称
String fileName="导出学生";
String sheetName = "学生列表";
ExcelUtil.writeExcel(response, list, fileName, sheetName, new StudentExcelFileModel());
} catch (IOException e) {
e.printStackTrace();
}
}
fileName就是excel文件名,先查询出list。再调用writeExcel方法。将list丢进去。
(7)测试
直接用谷歌浏览器访问接口即可
自动下载
打开后数据正常
3,导入(excel表导入数据库,请准备一个空表)
(1)pojo
package cn.project.cnfedu.pojo;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.metadata.BaseRowModel;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.format.annotation.NumberFormat;
import java.util.Date;
@Data
public class StudentExcelFileModel2 extends BaseRowModel {
//学员编号
@ExcelProperty(index = 0)
private Long id;
//学员姓名
@ExcelProperty(index = 1)
private String name;
//学员手机号码
@ExcelProperty(index = 2)
private String phone;
//学员qq号
@ExcelProperty(index = 3)
private String qq;
//学员微信号
@ExcelProperty(index = 4)
private String wechat;
//学员性别
@ExcelProperty(index = 5)
private Integer gender;
//上课城区
@ExcelProperty(index = 6)
private Integer areaid;
//上课地址
@ExcelProperty(index = 7)
private String address;
//年级
@ExcelProperty(index = 8)
private Integer gradeid;
//辅导科目
@ExcelProperty(index = 9)
private String subject;
//每周次数
@ExcelProperty(index = 10)
private Integer num;
//每次时数
@ExcelProperty(index = 11)
private Integer hour;
//可授课时间
@ExcelProperty(index = 12)
private String teachingtimeid;
//学员情况描述
@ExcelProperty(index = 13)
private String desc;
//ljs
//教员性别
@ExcelProperty(index = 14)
private Integer teacherGender;
//教员类别
@ExcelProperty(index = 15)
private Integer teachertype;
//对教员要求
@ExcelProperty(index = 16)
private String teacherwant;
//支付报酬 decimal BigDecimal
@ExcelProperty(index = 17)
@NumberFormat(pattern="#.##")
private double payment;
//学员密码
@ExcelProperty(index = 18)
private String password;
//学员状态
@ExcelProperty(index = 19)
private Integer stuStatus;
//是否已经支付
@ExcelProperty(index = 20)
private Integer ispay;
//籍贯
@ExcelProperty(index = 21)
private Integer nativeplace;
//学员审核状态
@ExcelProperty(index = 22)
private Integer stuAuditstatus;
//检索ID
@ExcelProperty(index = 23)
private Long indexid;
//预约情况
@ExcelProperty(index = 24)
private Integer Appointment;
//创建者编号
@ExcelProperty(index = 25)
private Integer createdby;
//创建时间
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@ExcelProperty(index = 26)
private Date creationdate;
//修改者编号
@ExcelProperty(index = 27)
private Integer modifyby;
//修改时间
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@ExcelProperty(index = 28)
private Date modifyDate;
}
(2)dao
//excel导入数据库的方法
int getTabsByConditionLike(StudentExcelFileModel2 studentExcelFileModel2);
(3)xml
<!--导入-->
<insert id="getTabsByConditionLike" parameterType="StudentExcelFileModel2">
insert into fedu_student (<include refid="Base_Column_List"/>)
values
(#{id},#{name},#{phone},#{qq},#{wechat},#{gender},#{areaid},#{address},#{gradeid},
#{subject},#{num},#{hour},#{teachingtimeid},#{desc},#{teacherGender},#{teachertype},
#{teacherwant},#{payment},#{password},#{stuStatus},#{ispay},#{nativeplace},#{stuAuditstatus},
#{indexid},#{appointment},#{createdby},now(),#{modifyby},#{modifyDate})
</insert>
(4)service
//excel导入数据库的方法
int getTabsByConditionLike(StudentExcelFileModel2 studentExcelFileModel2);
(5)serviceImpl
@Override
public int getTabsByConditionLike(StudentExcelFileModel2 studentExcelFileModel2) {
return excelMapper.getTabsByConditionLike(studentExcelFileModel2);
}
(6)##controller
//导入
@PostMapping(value="/import")
public void importStudentinfo(@RequestParam("file") MultipartFile excel){
try {
List list= ExcelUtil.readExcel(excel,new StudentExcelFileModel2());
//调用底层数据库批量插入
int count=0;
for(Object obj:list){
/*System.out.println(((StudentExcelFileModel2)obj).getId());*/
count=excelService.getTabsByConditionLike(((StudentExcelFileModel2)obj));
count++;
}
Map<String,Object>map=new HashMap<>();
if(count!=0){
map.put("msg","插入成功");
map.put("result",true);
map.put("data","受影响行数"+count);
}else{
map.put("msg","插入失败");
map.put("result",false);
}
} catch (Exception e) {
e.printStackTrace();
}
}
注意点:导入的尽量用post请求。因为是multipart文件导入。post请求请给@requestparam,并且接口请求时候一定要指定这个file。。。否则会有错。
这里我采用for循环,插入数据库。
(7)测试用postman
先准备一个空表。
删了跑路
打开postman
(1)这里填好
(2)设置headers
(3)设置body,选择刚才导出来的excel,放进去
(4)
(5)
可以点发送了
看控制台很没有毛病
再看看刚才删掉的表。。。