一、EasyExcel的介绍
EasyExcel 是一款基于 Java 的简单易用的 Excel 文件操作工具。它提供了丰富的 API,可以方便地读取、写入和操作 Excel 文件,支持常见的 Excel 操作,如读取/写入单元格数据、合并单元格、设置样式、处理大数据量等。EasyExcel能大大减少占用内存的主要原因是在解析Excel时没有将文件数据一次性全部加载到内存中,而是从磁盘上一行行读取数据,逐个解析。
1、在pom.xml引入依赖
<!-- https://mvnrepository.com/artifact/com.alibaba/easyexcel -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.3.2</version>
</dependency>
2、创建导出实体类跟表头
**
* 用户 Excel 导出 VO
*/
@Data
public class UserExcelVO {
@ExcelProperty("用户编号")
private Long id;
@ExcelProperty("用户名称")
private String username;
@ExcelProperty("用户昵称")
private String nickname;
@ExcelProperty("用户邮箱")
private String email;
@ExcelProperty("手机号码")
private String mobile;
@ExcelProperty(value = "用户性别", converter = DictConvert.class)
@DictFormat(DictTypeConstants.USER_SEX)
private Integer sex;
@ExcelProperty(value = "帐号状态", converter = DictConvert.class)
@DictFormat(DictTypeConstants.COMMON_STATUS)
private Integer status;
@ExcelProperty("最后登录IP")
private String loginIp;
@ExcelProperty("最后登录时间")
private LocalDateTime loginDate;
@ExcelProperty("部门名称")
private String deptName;
@ExcelProperty("部门负责人")
private String deptLeaderNickname;
}
① 每个字段上的 @ExcelProperty (opens new window)注解,声明 Excel Head 头部的名字
② 每个字段的值,就是它对应的 Excel Row 行的数据值
③ @ExcelProperty 注解的 converter 属性是 DictConvert 转换器,通过它将 status = 1 转换成“开启”列,status = 0 转换成”禁用”列,注解 @DictFormat (opens new window)为对应的字典数据的类型。
更多《EasyExcel 中的注解 》
3、ExcelUtils类 写入以及读取
public class ExcelUtils {
/**
* 将列表以 Excel 响应给前端
*
* @param response 响应
* @param filename 文件名
* @param sheetName Excel sheet 名
* @param head Excel head 头
* @param data 数据列表哦
* @param <T> 泛型,保证 head 和 data 类型的一致性
* @throws IOException 写入失败的情况
*/
public static <T> void write(HttpServletResponse response, String filename, String sheetName,
Class<T> head, List<T> data) throws IOException {
// 输出 Excel
EasyExcel.write(response.getOutputStream(), head)
.autoCloseStream(false) // 不要自动关闭,交给 Servlet 自己处理
.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()) // 基于 column 长度,自动适配。最大 255 宽度
.sheet(sheetName).doWrite(data);
// 设置 header 和 contentType。写在最后的原因是,避免报错时,响应 contentType 已经被修改了
response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));
response.setContentType("application/vnd.ms-excel;charset=UTF-8");
}
public static <T> List<T> read(MultipartFile file, Class<T> head) throws IOException {
return EasyExcel.read(file.getInputStream(), head, null)
.autoCloseStream(false) // 不要自动关闭,交给 Servlet 自己处理
.doReadAllSync();
}
}
4、Controller类实现
@GetMapping("/export")
@Operation(summary = "导出用户")
@OperateLog(type = EXPORT)
public void exportUserList(@Validated UserExportReqVO reqVO,
HttpServletResponse response) throws IOException {
// 获得用户列表
List<UserDO> users = userService.getUserList(reqVO);
UserExcelVO excelVO = UserConvert.INSTANCE.convert02(user);
// 输出
ExcelUtils.write(response, "用户数据.xls", "用户列表", UserExcelVO.class, excelVO );
}
/**
* 客户信息导入
*/
@PostMapping("ImportExcel")
public R<Object> importExcel(MultipartFile file, HttpServletRequest request) throws IOException {
if (file.isEmpty()) {
throw new RRException("excel文件内容为空!");
}
String userId = AuthContext.getLoginId().toString();
// 这里 需要指定读用哪个class去读,然后读取第一个sheet 文件流会自动关闭
// 这里每次会读取3000条数据 然后返回过来 直接调用使用数据就行
List<CustomerManageEntity> vos = com.sxbctv.tone.business.utils.ExcelUtils.read(file, CustomerManageEntity.class);
customerManageService.importExcel(vos,userId);
return R.ok();
}
/**
* 客户信息模板导出
* @param response
* @param request
* @throws IOException
*/
@GetMapping("/exportDownload")
@ApiOperation("新增客户信息导出")
public void downloadExcel(HttpServletResponse response, HttpServletRequest request)throws IOException {
//获取输入流,原始模板位置
InputStream bis = getClass().getResourceAsStream("/excel/客户信息导入模板.xlsx");
//假如以中文名下载的话,设置下载文件名称
String filename = "客户信息模板.xlsx";
//转码,免得文件名中文乱码
filename = URLEncoder.encode(filename,"UTF-8");
//设置文件下载头
response.addHeader("Content-Disposition", "attachment;filename=" + filename);
//1.设置文件ContentType类型,这样设置,会自动判断下载文件类型
response.setContentType("multipart/form-data");
BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
int len = 0;
while((len = bis.read()) != -1){
out.write(len);
out.flush();
}
out.close();
}
5、前端导入实现
<el-upload style="display: inline-block;padding-left: 10px;" ref="upload" class="upload-demo" :action="actionUrl" :show-file-list="false"
:limit="1" :on-success="uploadSucess" accept=".xlsx,.xls">
<el-button type="primary">excel导入</el-button>
</el-upload>
data() {
return {
actionUrl: this.$http.adornUrl("/business/customer/manage/ImportExcel?" + "&token=" + this.$cookie.get('localhostx-tone-token'))
}
},
本文介绍了EasyExcel,一个用于Java的高效Excel操作工具,支持读写、数据转换和内存优化。文章详细讲解了如何在项目中添加依赖、创建导出实体类、使用注解处理数据和格式、以及控制器类的实现和前端导入功能。
5711





