目录
准备工作
监听器类
导入测试
导出测试
上传Excel
下载Excel
混合导出+模板导出
headRowNumber(1):从第几行开始读
准备工作
导入依赖
<!--easyexcel-->
<dependency><groupId>com.alibaba</groupId>x<artifactId>easyexcel</artifactId><version>2.2.6</version>
</dependency>
<!--文件上传-->
<dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>1.4</version>
</dependency>
创建实体类
@HeadRowHeight():设置导出的Excle表格标题的行高
@ExcelProperty():对当前列的操作
value:设置列的名字
value = {"value1","value2"}:一级标题,二级标题
index = 2:这个字段放在第几列,默认从0开始
@ExcelIgnore:不导入导出这个字段
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("user")
@HeadRowHeight(30) // 标题行高
public class User {/*** @ExcelProperty* value:列名称* index:写:写内容到第几列,读:第几列的内容放到这个字段* {}:给头在加一个头,所有都加,就会合并** @ExcelIgnore* 导入或导出时候,不要这个字段**/@TableId(value = "id", type = IdType.AUTO)@ExcelProperty(value = {"用户信息表","ID"},index = 5)@ExcelIgnoreprivate Integer id;@ExcelProperty(value = {"用户信息表","姓名"},index = 1)@ColumnWidth(20)private String name;@ExcelProperty(value = {"用户信息表","年龄"},index = 2)private Integer age;@ExcelProperty(value = {"用户信息表","性别"},index = 3)private Integer sex;@ExcelProperty(value = {"用户信息表","日期"},index = 4)@ColumnWidth(20)private Date dateTime;}
第二个实体类
package com.zsh.esayexcel.domain.po;@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserVO {private Integer sum;private Integer avg;
}
Mapper
package com.zsh.esayexcel.mapper;/*** <p>* Mapper 接口* </p>** @author KaiLangJiaoJiao* @since 2024-02-12*/
@Mapper
public interface UserMapper extends BaseMapper<User> {}
Service
package com.zsh.esayexcel.service;/*** <p>* 服务类* </p>** @author KaiLangJiaoJiao* @since 2024-02-12*/
public interface IUserService extends IService<User> {}
ServiceImpl
package com.zsh.esayexcel.service.impl;/*** <p>* 服务实现类* </p>** @author KaiLangJiaoJiao* @since 2024-02-12*/
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {}
Controller
package com.zsh.esayexcel.controller;/*** <p>* 前端控制器* </p>** @author KaiLangJiaoJiao* @since 2024-02-12*/
@RestController
@RequestMapping("/user")
public class UserController {}
监听器类
创建listener包
UserListener
package com.zsh.esayexcel.listener;/*** 读取文档的监听器类*/
public class UserListener extends AnalysisEventListener<User> {/*** 读监听器,每读一行内容,都会调用一次该对象的invoke,在invoke可以操作使用读取到的数据* @param user* @param analysisContext*/@Overridepublic void invoke(User user, AnalysisContext analysisContext) {System.out.println("user = " + user);}/*** 读取完整个文档之后调用的方法* @param analysisContext*/@Overridepublic void doAfterAllAnalysed(AnalysisContext analysisContext) {}
}
WebUserListener
package com.zsh.esayexcel.listener;@Scope("prototype") // 官方要求,这个类需要是多例对象,不能是单例
public class WebUserListener extends AnalysisEventListener<User> {// @Autowired
// private IUserService userService;List<User> userList = new ArrayList<>();@Overridepublic void invoke(User user, AnalysisContext analysisContext) {userList.add(user);// 判断条数为5时添加一次if (userList.size() % 5 == 0) {IUserService userService = new UserServiceImpl();// 添加userService.saveBatch(userList);// 添加完清空数组userList.clear();}}@Overridepublic void doAfterAllAnalysed(AnalysisContext analysisContext) {// 剩下数据不足5条时添加if (userList.size() != 0) {IUserService userService = new UserServiceImpl();// 添加userService.saveBatch(userList);// 添加完清空数组userList.clear();}}
}
导入测试
这是一个Test测试类
package com.zsh.esayexcel;@SpringBootTest
public class ExcelTest {/*** 读excel*/@Testpublic void test(){/*** pathName:要读取的文件路径** head:文件中每一行数据要存储到的实体类行的class** readListener:读监听器,每读一行内容,都会调用一次该对象的invoke,在invoke可以操作使用读取到的数据*/// 获得一个工作簿对象ExcelReaderBuilder readWorkBook = EasyExcel.read("C:\\Users\\开朗觉觉\\Desktop\\用户表.xlsx", User.class, new UserListener());// 获得工作簿对象ExcelReaderSheetBuilder sheet = readWorkBook.sheet();/*** headRowNumber()* 从第几行开始读,默认是1*/// 读取工作表中内容sheet.headRowNumber(1).doRead();}}
导出测试
这是一个测试类
package com.zsh.esayexcel;@SpringBootTest
public class ExcelTest {/*** 写excel*/@Testpublic void test2(){// 工作簿对象// .xml会直接放到Module里ExcelWriterBuilder writeWorkBook = EasyExcel.write("学生表的写操作.xlsx", User.class); // 工作表对象ExcelWriterSheetBuilder sheet = writeWorkBook.sheet();// 准备数据List<User> userList = new ArrayList<>();for (int i = 0; i < 5; i++) {User user = new User(i,"张三"+i,10,2,new Date());userList.add(user);}// 写sheet.doWrite(userList);}}
上传Excel
package com.zsh.esayexcel.controller;/*** <p>* 前端控制器* </p>** @author KaiLangJiaoJiao* @since 2024-02-12*/
@RestController
@RequestMapping("/user")
public class UserController {@Autowiredprivate IUserService userService;/*** 测试* @return*/@GetMapping("/test")private String test(){return "ok";}/*** Excel导入* @param uploadExcel* @return*/@PostMapping("/read")public String readExcel(@RequestBody MultipartFile uploadExcel){try {// 工作簿ExcelReaderBuilder readWorkBook = EasyExcel.read(uploadExcel.getInputStream(), User.class, new WebUserListener());// 工作表ExcelReaderSheetBuilder sheet = readWorkBook.sheet();// 读sheet.doRead();return "success";} catch (IOException e) {e.printStackTrace();return "fail";}}}
下载Excel
package com.zsh.esayexcel.controller;/*** <p>* 前端控制器* </p>** @author KaiLangJiaoJiao* @since 2024-02-12*/
@RestController
@RequestMapping("/user")
public class UserController {@Autowiredprivate IUserService userService;/*** Excel导出* @param response*/@GetMapping("/write")@ResponseBodypublic void writeExcel(HttpServletResponse response) throws IOException {response.setContentType("application/vnd.ms-excel");response.setCharacterEncoding("utf-8");// 防止中文乱码String fileName = URLEncoder.encode("学生表测试", "UTF-8");response.setHeader("Content-Disposition","attachment; filename*=UTF-8''" + fileName + ".xlsx");// 收集要写的数据装进一个工作簿中ServletOutputStream outputStream = response.getOutputStream();// 获取工作簿ExcelWriterBuilder writeWrokBook = EasyExcel.write(outputStream, User.class);// 获取工作表ExcelWriterSheetBuilder sheet = writeWrokBook.sheet();// 获取数据List<User> userList = userService.list(null);// 写sheet.doWrite(userList);}}
混合导出+模板导出
模板设计
{.xxxx}:填充多行
{xxxx}:填充单行
代码开发
package com.zsh.esayexcel;@SpringBootTest
public class ExcelTest {@Autowiredprivate IUserService userService;/*** 混合导出*/@Testpublic void test3(){// 准备模板String tempalte = "用户表模板.xlsx";/*** withTemplate()* 使用模板创建表*/// 创建一个工作簿对象ExcelWriter workBook = EasyExcel.write("用户信息表.xlsx", User.class).withTemplate(tempalte).build();// 创建工作表对象WriteSheet sheet = EasyExcel.writerSheet().build();// 准备数据
// IUserService userService = new UserServiceImpl();List<User> userList = userService.list(null);UserVO userVO = new UserVO();// 总人数userVO.setSum(userList.size());// 年龄总和Integer agesum = userList.stream().map(user -> user.getAge()).reduce(0, (result, element) -> result + element);// 平均年龄userVO.setAvg(agesum / userList.size());// 数据填充FillConfig fillConfig = FillConfig.builder().forceNewRow(true).build();// 因为多组填充的数据不确定,需要在多组数据填充完之后另起一行// 多组填充workBook.fill(userList,fillConfig,sheet);// 单组填充workBook.fill(userVO,sheet);// 关闭流workBook.finish();}}