Easy Excel 的使用说明
官方文档地址1:https://www.yuque.com/easyexcel/doc
官方文档地址2:https://alibaba-easyexcel.github.io/index.html
<dependency> <groupId>com.alibaba</groupId> <artifactId>easyexcel</artifactId> <version>3.0.5</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.20</version> </dependency>
02 写excel文件
数据的实体类
@Data @TableName("excel_user") public class ExcelUser { @TableId(value = "id", type = IdType.AUTO) @ExcelIgnore private Long id; @ExcelProperty("姓名") private String name; @ExcelProperty("年龄") private Integer age; @ExcelProperty("身高") private Double height; }
写excel的方法
/** * 写excel文件 * @param excelFile * 导出的文件路径(测试用绝对地址) * @param ignoreFiledNames * 忽略的字段 * @param template * 数据模板(数据的class) * @param sheetName * sheet名 * @param data * 数据 */ public static void writeExcel(String excelFile, Set<String> ignoreFiledNames, Class template, String sheetName, List<?> data) { ExcelWriterBuilder builder = EasyExcel.write(excelFile, template); if (ignoreFiledNames != null) { builder.excludeColumnFiledNames(ignoreFiledNames); } builder.sheet(sheetName).doWrite(data); }
03 文件的下载
@GetMapping("/download") public void download(String filename,HttpServletResponse response) { ExcelFileUtils.downLoadFile(response,filename); }
下载的方法
/** * 下载文件 * * @param response * 相应response * @param filePath * 文件路径 */ public static void downLoadFile(HttpServletResponse response, String filePath) { if (StringUtils.isBlank(filePath)) { return; } File file = new File(filePath); if (!file.exists()) { return; } OutputStream out = null; try { response.reset(); response.setContentType("application/octet-stream; charset=utf-8"); response.setHeader("Content-Disposition", "attachment; filename=" + file.getName()); out = response.getOutputStream(); out.write(Files.readAllBytes(file.toPath())); out.flush(); } catch (IOException e) { e.printStackTrace(); } finally { if (out != null) { try { out.close(); } catch (IOException e) { e.printStackTrace(); } } } }
04 文件的上传
package com.saiyou.entity; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListener; import com.alibaba.fastjson.JSON; import com.saiyou.service.ExcelUserService; import lombok.extern.slf4j.Slf4j; import java.util.ArrayList; import java.util.List; /** * @author : lyn * 技术点 : * @description: excel 的监听器 * @date : 2021/12/4 14:43 */ @Slf4j public class ExcelUserListener extends AnalysisEventListener<ExcelUser> { /** * 每隔5条存储数据库,实际使用中可以3000条,然后清理list ,方便内存回收 */ private static final int BATCH_COUNT = 5; List<ExcelUser> list = new ArrayList<ExcelUser>(); /** * 假设这个是一个DAO,当然有业务逻辑这个也可以是一个service。当然如果不用存储这个对象没用。 */ private ExcelUserService excelUserService; public ExcelUserListener(){} /** * 如果使用了spring,请使用这个构造方法。每次创建Listener的时候需要把spring管理的类传进来 * * @param excelUserService */ public ExcelUserListener(ExcelUserService excelUserService) { this.excelUserService = excelUserService; } /** * 这个每一条数据解析都会来调用 * * @param data * one row value. Is is same as {@link AnalysisContext#readRowHolder()} * @param context */ @Override public void invoke(ExcelUser data, AnalysisContext context) { log.info("解析到一条数据:{}", JSON.toJSONString(data)); list.add(data); // 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM if (list.size() >= BATCH_COUNT) { saveData(); // 存储完成清理 list list.clear(); } } /** * 所有数据解析完成了 都会来调用 * * @param context */ @Override public void doAfterAllAnalysed(AnalysisContext context) { // 这里也要保存数据,确保最后遗留的数据也存储到数据库 saveData(); log.info("所有数据解析完成!"); } /** * 加上存储数据库 */ private void saveData() { log.info("{}条数据,开始存储数据库!", list.size()); //调用service保存到数据库 excelUserService.saveBatch(list); log.info("存储数据库成功!"); } }
controller接口
@Autowired private ExcelUserService excelUserService; /** * 文件上传 * <p>1. 创建excel对应的实体对象 参照{@link ExcelUser} * <p>2. 由于默认一行行的读取excel,所以需要创建excel一行一行的回调监听器, * <p>3. 直接读即可 */ @PostMapping("/upload") public String upload(MultipartFile file) throws IOException { EasyExcel.read(file.getInputStream(), ExcelUser.class, new ExcelUserListener(excelUserService)).sheet().doRead(); return "success"; }
需要自己补充service和mapper
package com.saiyou.utils; import com.alibaba.excel.EasyExcel; import com.alibaba.excel.write.builder.ExcelWriterBuilder; import com.baomidou.mybatisplus.core.toolkit.StringUtils; import com.saiyou.entity.ExcelUser; import com.saiyou.entity.ExcelUserListener; import lombok.extern.slf4j.Slf4j; import javax.servlet.http.HttpServletResponse; import java.io.File; import java.io.IOException; import java.io.OutputStream; import java.nio.file.Files; import java.util.Arrays; import java.util.List; import java.util.Set; /** * @author : lyn * 技术点 : * @description: excel的读写,上传和下载 * @date : 2021/12/4 13:50 */ @Slf4j public class ExcelFileUtils { /** * 写excel文件 * @param excelFile * 导出的文件路径 * @param ignoreFiledNames * 忽略的字段 * @param template * 数据模板 * @param sheetName * sheet名 * @param data * 数据 */ public static void writeExcel(String excelFile, Set<String> ignoreFiledNames, Class template, String sheetName, List<?> data) { ExcelWriterBuilder builder = EasyExcel.write(excelFile, template); if (ignoreFiledNames != null) { builder.excludeColumnFiledNames(ignoreFiledNames); } builder.sheet(sheetName).doWrite(data); } /** * 读取excel文件,不能通用吗? * @param fileName */ public static void readExcel(String fileName) { // 这里 需要指定读用哪个class去读,然后读取第一个sheet 文件流会自动关闭 EasyExcel.read(fileName, ExcelUser.class, new ExcelUserListener() ).sheet().doRead(); } /** * 下载文件 * * @param response * 相应response * @param filePath * 文件路径 */ public static void downLoadFile(HttpServletResponse response, String filePath) { if (StringUtils.isBlank(filePath)) { return; } File file = new File(filePath); if (!file.exists()) { return; } OutputStream out = null; try { response.reset(); response.setContentType("application/octet-stream; charset=utf-8"); response.setHeader("Content-Disposition", "attachment; filename=" + file.getName()); out = response.getOutputStream(); out.write(Files.readAllBytes(file.toPath())); out.flush(); } catch (IOException e) { e.printStackTrace(); } finally { if (out != null) { try { out.close(); } catch (IOException e) { e.printStackTrace(); } } } } public static void main(String[] args) { ExcelUser user = new ExcelUser(); user.setName("李四"); user.setAge(56); user.setHeight(126.6); writeExcel("D:/excel-test.xlsx",null,ExcelUser.class,"表一", Arrays.asList(user)); } }