springboot中easyExcel实现导入导出
导出
1、引入easyExcel依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.2.7</version>
</dependency>
1
2
3
4
5
2、实体类
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.alibaba.excel.annotation.write.style.ContentRowHeight;
import com.alibaba.excel.annotation.write.style.HeadRowHeight;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import java.util.Date;
@Data
@ContentRowHeight(30)//设置导出的excel的内容高度
@HeadRowHeight(40)//设置导出的excel的表头高度
@ColumnWidth(20)//设置导出的excel的列宽
public class UserVo {
/**
* 主键
*/
@TableId(value = "id", type = IdType.AUTO)
@ExcelProperty(value = "用户序号",index = 0)
private Integer userid;
/**
* 用户名
*/
@ExcelProperty(value = "登录名称",index = 1)
private String username;
/**
* 昵称
*/
@ExcelProperty(value = "用户名称",index = 2)
private String nickname;
/** 用户邮箱 */
@ExcelProperty(value = "用户邮箱",index = 3)
private String email;
/** 手机号码 */
@ExcelProperty(value = "手机号码",index = 4)
private String phonenumber;
/** 用户性别 */
@ExcelProperty(value = "用户性别",index = 5)
private String sex;
/** 用户状态 0正常 1 禁用 -1 删除 */
@ExcelProperty(value = "用户状态",index = 6)
private String status;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
3、ExcelUtil工具类
import com.alibaba.excel.EasyExcel;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.InputStream;
import java.util.List;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.mh.common.handler.ExcelListener;
import org.apache.poi.ss.usermodel.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;
/**
* excel导出工具类
*/
public class ExcelUtil {
private static final Logger LOGGER = LoggerFactory.getLogger(ExcelUtil.class);
/**
* 私有化构造方法
*/
private ExcelUtil(){}
/**
* 导出excel
* @param response
* @param list 要导出的数据list
* @param fileName 文件名
* @param clazz 要导出的实体类的class
*/
public static void ExcelWrite(HttpServletResponse response, List list, String fileName,Class clazz) {
try {
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
response.setHeader("Content-disposition", "attachment;filename=" + java.net.URLEncoder.encode(fileName+".xls", "UTF-8"));
response.setHeader("Access-Control-Expose-Headers", "Content-disposition");
//头的策略 样式调整
WriteCellStyle headWriteCellStyle = new WriteCellStyle();
// 头背景 浅绿
headWriteCellStyle.setFillForegroundColor(IndexedColors.LIGHT_GREEN.getIndex());
WriteFont headWriteFont = new WriteFont();
// 头字号
headWriteFont.setFontHeightInPoints((short)14);
// 字体样式
headWriteFont.setFontName("宋体");
headWriteCellStyle.setWriteFont(headWriteFont);
//自动换行
headWriteCellStyle.setWrapped(true);
//设置细边框
headWriteCellStyle.setBorderBottom(BorderStyle.THIN);
headWriteCellStyle.setBorderLeft(BorderStyle.THIN);
headWriteCellStyle.setBorderRight(BorderStyle.THIN);
headWriteCellStyle.setBorderTop(BorderStyle.THIN);
//设置边框颜色 25灰度
headWriteCellStyle.setBottomBorderColor(IndexedColors.GREY_25_PERCENT.getIndex());
headWriteCellStyle.setTopBorderColor(IndexedColors.GREY_25_PERCENT.getIndex());
headWriteCellStyle.setLeftBorderColor(IndexedColors.GREY_25_PERCENT.getIndex());
headWriteCellStyle.setRightBorderColor(IndexedColors.GREY_25_PERCENT.getIndex());
// 水平对齐方式
headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
// 垂直对齐方式
headWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
// 内容的策略 宋体
WriteCellStyle contentStyle = new WriteCellStyle();
//设置垂直居中
contentStyle.setVerticalAlignment(VerticalAlignment.CENTER);
//设置 水平居中
contentStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
WriteFont contentWriteFont = new WriteFont();
// 内容字号
contentWriteFont.setFontHeightInPoints((short)12);
// 字体样式
contentWriteFont.setFontName("宋体");
contentStyle.setWriteFont(contentWriteFont);
// 这个策略是 头是头的样式 内容是内容的样式 其他的策略可以自己实现
HorizontalCellStyleStrategy strategy = new HorizontalCellStyleStrategy(headWriteCellStyle, contentStyle);
EasyExcel.write(response.getOutputStream(), clazz).registerWriteHandler(strategy).sheet("sheet1").doWrite(list);
}catch (Exception e){
e.printStackTrace();
}
}
/**
* 导入
* @param excel 上传的excel文件
* @param clazz 要导入的实体类的class
*/
public static <T> List<T> readerExcel(MultipartFile excel, Class<T> clazz) throws Exception {
if (excel.isEmpty()) {
throw new Exception("请选择excel文件");
}
String fileName = excel.getOriginalFilename();
LOGGER.info("Excel文件解析:文件名 = " + fileName);
if (fileName == null || (!fileName.toLowerCase().endsWith(".xls") && !fileName.toLowerCase().endsWith(".xlsx"))) {
throw new Exception("文件格式错误");
}
try(InputStream fileStream = new BufferedInputStream(excel.getInputStream())) {
ExcelListener<T> excelListener = new ExcelListener<>();
EasyExcel.read(fileStream, clazz, excelListener)
.autoTrim(true)
.sheet()
.doRead();
return excelListener.getList();
} catch (Exception e) {
LOGGER.error("导入失败, 请检查导入数据的准确性", e);
throw new Exception("导入失败, 请检查导入数据的准确性");
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
4、UserController导出
@GetMapping(value = "/exports")
@ResponseBody
public void exports(HttpServletResponse response,UserVo user) throws IOException {
//需要导出的数据
List<UserVo> list = userService.exportsUser(user);
String fileName = "用户信息表格"+System.currentTimeMillis();
//调用工具类
ExcelUtil.ExcelWrite(response,list,fileName,UserVo.class);
}
1
2
3
4
5
6
7
8
9
导入
1、ExcelListener解析excel表数据
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import java.util.ArrayList;
import java.util.List;
public class ExcelListener<T> extends AnalysisEventListener{
private List<T> list = new ArrayList<>();
@Override
public void invoke(Object o, AnalysisContext analysisContext) {
list.add((T)o);
}
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {}
public List<T> getList() {
return list;
}
public void setList(List<T> list) {
this.list = list;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2、UserController导入
导入数据,无非就是将excel表格里面的数据解析出来,得到一个list,然后将这个list中的数据添加到数据库中。添加时可以一次性将list批量添加到数据库,也可以用for循环一条一条将数据添加到数据库中。
/**
*
* @param file
* @param updateSupport 是否更新数据(当list中有数据库中存在的数据时,是否更新,为true 更新,为false 不更新)
* @return
* @throws Exception
*/
@PostMapping("/importData")
@ResponseBody
public String importData(@RequestParam MultipartFile file,@RequestParam boolean updateSupport,HttpServletRequest request) throws Exception {
List<UserVo> userVos = ExcelUtil.readerExcel(file, UserVo.class);
String message = userService.batchInsertUser(userVos ,updateSupport);
return message;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
3、UserService添加数据
private UserMapper userMapper;
/**
* 导入用户
* @param list
* @param isUpdateSupport
* @return
*/
public String batchInsertUser(List<UserVo> list,Boolean isUpdateSupport) {
if (StringUtils.isNull(list) || list.size() == 0) {
throw new CustomException(ResultEnum.IMPORT_ERROR,"导入用户数据不能为空!");
}
int successNum = 0;
int failureNum = 0;
StringBuilder successMsg = new StringBuilder();
StringBuilder failureMsg = new StringBuilder();
for (UserVo user : list) {
try {
// 验证是否存在这个用户
QueryWrapper<UserVo> queryWrapper = new QueryWrapper();
queryWrapper.eq("user_name",user.getUserName());
queryWrapper.ne("status","2");
/**
这里因为用的是mybatis-plus,有自带的增删改查分页这些操作,
只需要 UserMapper extends BaseMapper<UserVo>,UserService extends ServiceImpl<UserMapper, UserVo>。
使用QueryWrapper设置查询条件,直接调用 BaseMapper 中的 selectOne 即可,
就不用自己去写sql语句了,下面的 insert(user) 和 updateById(user) 也是同样的。
当然如果查询条件比较复杂,用 mybatis-plus 自带的查询可能就处理不了了,这种情况还是得自己写sql语句。
*/
UserVo u = userMapper.selectOne(queryWrapper);
if (StringUtils.isNull(u)) {
userMapper.insert(user);
successNum++;
successMsg.append(successNum + "、账号 " + user.getUserName() + " 导入成功。");
} else if (isUpdateSupport) {
userMapper.updateById(user);
successNum++;
successMsg.append(successNum + "、账号 " + user.getUserName() + " 更新成功。");
} else {
failureNum++;
failureMsg.append(failureNum + "、账号 " + user.getUserName() + " 已存在。");
}
} catch (Exception e) {
failureNum++;
String msg = failureNum + "、账号 " + user.getUserName() + " 导入失败:";
failureMsg.append(msg + e.getMessage());
log.error(msg, e);
}
}
if (failureNum > 0) {
failureMsg.insert(0, "很抱歉,导入失败!共 " + failureNum + " 条数据格式不正确,错误如下:");
throw new CustomException(ResultEnum.IMPORT_ERROR,failureMsg.toString());
} else {
successMsg.insert(0, "恭喜您,数据已全部导入成功!共 " + successNum + " 条,数据如下:");
}
return successMsg.toString();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
文章知识点与官方知识档案匹配,可进一步学习相关知识
————————————————
版权声明:本文为CSDN博主「符华-」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_43165220/article/details/113562164
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
2021-10-18 foreach 查出BIGTYPE,SMALLTYPE
2021-10-18 mybatisplus generator
2021-10-18 antd点击跳转页面且有参数_Vue 页面跳转与参数传递