咔片PPT · AI自动生成演示文稿,模板丰富、排版精美 讯飞智文 · 一键生成PPT和Word,高效应对学习与办公

前言

最近在开发一个运营端的系统,而运营端系统,经常有数据通过Excel文件上传、导出的功能,也就是涉及到Excel文件的读写操作。

我们都知道,在Java开发中,Excel相关的操作,我们都使用POI进行开发。但是Excel文件的读写,经常有这么一个场景,就是涉及到大量数据的读写,使用POI经常会遇到机器内存使用率过高的问题,而EasyExcel就很好地解决了这个问题。

Excel导出

我们先进行简单的Excel数据导出实践。

1.Maven依赖

可以到mvnrepository上搜索EasyExcel,选择一个最新的版本即可。

com.alibaba easyexcel 3.1.3

笔者采用的,是目前最新的3.1.3版本,生产环境还是建议使用稳定版。

2.MySQL数据

生产环境Excel数据导出,一般都是从MySQL数据库中获取。为了贴近正常场景,我们事先在MySQL上存储部分数据,然后试着将这些数据通过Excel格式导出。

3.Excel对象映射

EasyExcel有一个很不错的设计,就是Excel文件的列,是和Java对象的字段,一一对应的。这点和操作MySQL、JPA一样,毕竟Excel也可以理解为一个关系数据库文件。

package com.example.springbooteasyexcel.domain; import com.alibaba.excel.annotation.ExcelProperty; import lombok.Data; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.Table; import java.math.BigDecimal; import java.util.Date; /** * 商品信息 * * @author hongcunlin */ @Entity @Data @Table public class ProductInfo { /** * 自增ID */ @Id @GeneratedValue @ExcelProperty("商品id") private Long id; /** * 商品名 */ @ExcelProperty("商品名称") private String name; /** * 商品价格 */ @ExcelProperty("商品价格") private BigDecimal price; /** * 创建时间 */ @ExcelProperty("商品创建时间") private Date createTime = new Date(); }

通过@ExcelProperty注解,是Excel列和Java对象中的字段对应起来。

4.Excel导出HTTP接口

通过JPA将数据从MySQL中读取出来,通过EasyExcel将数据通过Excel文件导出。

package com.example.springbooteasyexcel.controller; import com.alibaba.excel.EasyExcel; import com.example.springbooteasyexcel.domain.ProductInfo; import com.example.springbooteasyexcel.repository.ProductInfoRepository; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.List; /** * Excel读写HTTP接口 * * @author hongcunlin */ @RestController @RequestMapping("/productInfoController") public class ProductInfoController { /** * 商品信息repository */ @Resource private ProductInfoRepository productInfoRepository; /** * Excel数据导出 * * @param response excel文件 * @throws IOException e */ @GetMapping("/exportProductInfo") public void exportProductInfo(HttpServletResponse response) throws IOException { List

productInfoList = productInfoRepository.findAll(); response.setContentType("application/vnd.ms-excel"); response.setCharacterEncoding("utf-8"); response.setHeader("Content-disposition", "attachment;filename=test.xlsx"); EasyExcel.write(response.getOutputStream(), ProductInfo.class).sheet().doWrite(productInfoList); } }

Excel导出的API使用起来还是很简单,它导出完Excel数据,还会帮你关闭文件流,这点很关键。

5.Excel导出测试

我们访问我上面编写的接口,即可得到我们想要的Excel文件了,内容如下:

符合我们的预期。

Excel上传

Excel上传写起来,稍微复杂一点点,主要是多了一个Excel读取的监听器

1.Excel监听器

package com.example.springbooteasyexcel.listener; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListener; import com.alibaba.excel.metadata.CellExtra; import com.example.springbooteasyexcel.domain.ProductInfo; import lombok.Getter; import java.util.ArrayList; import java.util.List; /** * 商品列表导出监听器 * * @author hongcunlin */ @Getter public class ProductInfoListener extends AnalysisEventListener

{ /** * 商品列表 */ private final List

productInfoList = new ArrayList<>(); @Override public void onException(Exception exception, AnalysisContext context) throws Exception { super.onException(exception, context); } @Override public void invoke(ProductInfo productInfo, AnalysisContext analysisContext) { productInfoList.add(productInfo); } @Override public void extra(CellExtra extra, AnalysisContext context) { super.extra(extra, context); } @Override public void doAfterAllAnalysed(AnalysisContext analysisContext) { } @Override public boolean hasNext(AnalysisContext context) { return super.hasNext(context); } }

主要继承AnalysisEventListener父类,并实现了相关方法。主要是invoke方法,里边是Excel数据读取之后的处理逻辑。

2.Excel文件上传HTTP接口

package com.example.springbooteasyexcel.controller; import com.alibaba.excel.EasyExcel; import com.example.springbooteasyexcel.domain.ProductInfo; import com.example.springbooteasyexcel.listener.ProductInfoListener; import com.example.springbooteasyexcel.repository.ProductInfoRepository; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.List; /** * Excel读写HTTP接口 * * @author hongcunlin */ @Slf4j @RestController @RequestMapping("/productInfoController") public class ProductInfoController { /** * 商品信息repository */ @Resource private ProductInfoRepository productInfoRepository; /** * Excel数据上传 * * @param file excel文件 * @throws IOException e */ @PostMapping(value = "/uploadProductInfo", headers = "content-type=multipart/form-data") public void uploadProductInfo(MultipartFile file) throws IOException { ProductInfoListener productInfoListener = new ProductInfoListener(); EasyExcel.read(file.getInputStream(), ProductInfo.class, productInfoListener).sheet().doRead(); productInfoRepository.saveAll(productInfoListener.getProductInfoList()); } }

和Excel文件读取差不多,也是很简洁的API,不再赘述。

3.准备Excel数据

我们编写2条Excel数据,后面用于文件的上传

4.上传测试

我们通过Swagger2提供的界面,进行Excel文件的上传测试。

可以看到,我们上传的Excel文件中的数据,已经导入数据库中了,符合我们的预期。

其他

本文通过EasyExcel,轻松的进行了Excel文件的读取。本文是入门实践篇,后面关于Excel更多的细节,笔者有空再另起文章。