EasyExcel快速读写Excel数据
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了EasyExcel快速读写Excel数据相关的知识,希望对你有一定的参考价值。
参考技术Aps: 其实本人并没有对比过POI,只是网络上资料都有这么一说,再对比了GitHub的star数,最后直接选用了EasyExcel
本文介绍一下,如何使用实体映射关系直接读取Excel数据
假设需要读取的数据如下:
首先定义实体类 User ,需要继承 BaseRowModel
实现Excel数据的读取和写入
四EasyExcel实现Excel读写,封装工具类
在项目中,我们经常用到EasyExcel框架实现:对Excel文件的读写操作。为了方便后续其他项目中的使用,将对Excel文件的读写操作,封装成工具类。
一、EasyExcel实现Excel读写,封装工具类
1.1、后端代码
- ExcelUtil工具类,完成读写操作
package com.deewin.aftermarket.admin.utils;
import cn.hutool.core.convert.Convert;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelReader;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.read.metadata.ReadSheet;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.deewin.aftermarket.admin.excel.listener.ExcelListener;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
/**
* Excel读写工具类
* @Author bitaotao
* @Description Excel读写工具类
* @Date 2021-11-23
*/
public class ExcelUtil
private static final String SUFFIX_XLSX = ".xlsx";
private static final String SUFFIX_XLS=".xls";
/**
* 读取Excel(多个sheet可以用同一个实体类解析)
* @param excelInputStream
* @param fileName
* @param clazz
* @param <T>
* @return
*/
public static <T> List<T> readExcel(InputStream excelInputStream, String fileName,Class<T> clazz)
ExcelListener excelListener = new ExcelListener();
ExcelReader excelReader = getReader(excelInputStream, fileName,clazz, excelListener);
if (excelReader == null)
return new ArrayList<>();
List<ReadSheet> readSheetList = excelReader.excelExecutor().sheetList();
for (ReadSheet readSheet : readSheetList)
excelReader.read(readSheet);
excelReader.finish();
return Convert.toList(clazz, excelListener.getDataList());
/**
* 导出Excel(一个sheet)
*
* @param response HttpServletResponse
* @param list 数据list
* @param fileName 导出的文件名
* @param sheetName 导入文件的sheet名
* @param clazz 实体类
*/
public static <T> void writeExcel(HttpServletResponse response, List<T> list, String fileName, String sheetName, Class<T> clazz)
OutputStream outputStream = getOutputStream(response, fileName);
ExcelWriter excelWriter = EasyExcel.write(outputStream, clazz).build();
WriteSheet writeSheet = EasyExcel.writerSheet(sheetName).build();
excelWriter.write(list, writeSheet);
excelWriter.finish();
/**
* 导出时生成OutputStream
*/
private static OutputStream getOutputStream(HttpServletResponse response, String fileName)
// 文件名
String fileFullName = fileName.concat(SUFFIX_XLSX);
try
// 防止中文乱码
fileFullName = URLEncoder.encode(fileFullName, "UTF-8");
response.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + fileFullName);
return response.getOutputStream();
catch (IOException e)
e.printStackTrace();
return null;
/**
* 返回ExcelReader
* @param inputStream 输入流
* @param fileName 文件
* @param clazz 实体类
* @param excelListener
*/
private static <T> ExcelReader getReader(InputStream inputStream, String fileName, Class<T> clazz, ExcelListener excelListener)
try
if (fileName == null
|| (!fileName.toLowerCase().endsWith(SUFFIX_XLS) && !fileName.toLowerCase().endsWith(SUFFIX_XLSX)))
return null;
ExcelReader excelReader = EasyExcel.read(inputStream, clazz, excelListener).build();
inputStream.close();
return excelReader;
catch (Exception e)
e.printStackTrace();
return null;
- 监听器,ExcelListener.java
package com.deewin.aftermarket.admin.excel.listener;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import lombok.extern.slf4j.Slf4j;
import java.util.ArrayList;
import java.util.List;
/**
* Excel监听类
* @Author bitaotao
* @Description 监听类
* @Date 2021-11-23
*/
@Slf4j
public class ExcelListener extends AnalysisEventListener
/**
* 可以通过实例获取该值
*/
private List<Object> dataList = new ArrayList<>();
@Override
public void invoke(Object object, AnalysisContext context)
//数据存储到list,供批量处理,或后续自己业务逻辑处理。
dataList.add(object);
handleBusinessLogic();
/*
//如数据过大,可以进行定量分批处理
if(dataList.size()>=200)
handleBusinessLogic();
dataList.clear();
*/
@Override
public void doAfterAllAnalysed(AnalysisContext context)
//非必要语句,查看导入的数据
log.info("导入的数据条数为: " + dataList.size());
/**
* 根据业务自行实现该方法,例如将解析好的dataList存储到数据库中
*/
private void handleBusinessLogic()
// TODO
public List<Object> getDataList()
return dataList;
public void setDataList(List<Object> dataList)
this.dataList = dataList;
- 转换器
当读写的模板数据中有LocalDateTime
类型的数据时,需要使用该转换器
package com.deewin.aftermarket.admin.excel.convert;
import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.property.ExcelContentProperty;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
/**
* LocalDateTime 转换器
* @Author bitaotao
* @Date 2021-11-23
*/
public class LocalDateTimeConverter implements Converter<LocalDateTime>
@Override
public Class<LocalDateTime> supportJavaTypeKey()
return LocalDateTime.class;
@Override
public CellDataTypeEnum supportExcelTypeKey()
return CellDataTypeEnum.STRING;
@Override
public LocalDateTime convertToJavaData(CellData cellData, ExcelContentProperty contentProperty,
GlobalConfiguration globalConfiguration)
return LocalDateTime.parse(cellData.getStringValue(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
@Override
public CellData<String> convertToExcelData(LocalDateTime value, ExcelContentProperty contentProperty,
GlobalConfiguration globalConfiguration)
return new CellData<>(value.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
- Excel读写模版实体
package com.deewin.aftermarket.admin.excel.model;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.deewin.aftermarket.admin.excel.convert.LocalDateTimeConverter;
import lombok.*;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
* <p>
* 采销订单
* Excel导出模型
* </p>
*
* @author bitaotao
* @since 2021-11-24
*/
@Data
@EqualsAndHashCode(callSuper = false)
public class PurchaseSalesOrderExcelModel
@TableId(value = "id", type = IdType.AUTO)
@ExcelProperty(value = "序号")
private Long id;
@ExcelProperty(value = "采购单号")
@ColumnWidth(20)
private String orderNo;
@ExcelProperty(value = "申请时间",converter = LocalDateTimeConverter.class)
@ColumnWidth(20)
private LocalDateTime createTime;
@ExcelProperty(value = "采购方")
@ColumnWidth(40)
private String createDeptName;
@ExcelProperty(value = "产品品类")
@ColumnWidth(20)
private String productKindName;
@ExcelProperty(value = "品牌")
@ColumnWidth(20)
private String brandName;
@ExcelProperty(value = "产品总数量")
@ColumnWidth(20)
private Integer productTotalNumber;
@ExcelProperty(value = "采购总金额")
@ColumnWidth(20)
private BigDecimal orderTotalAmount;
@ExcelProperty(value = "付款方式")
@ColumnWidth(20)
private String paymentMethodName;
@ExcelProperty(value = "合同号")
@ColumnWidth(20)
private String contractNo;
- 控制层代码
控制层方法exportPurchaseOrder
,接受的参数是前端通过封装form表单发起的POST请求。
/**
* 采销订单导出
* @param productKindId 产品品类
* @param productModel 产品品类
* @param paymentMethod 收/付款方式
* @param contractNo 合同号
* @param orderNo 采购单号
* @param brandName 采购单号
* @param response
*/
@RequestMapping("export")
@ResponseBody
public void exportPurchaseOrder(Long productKindId, String productModel, String paymentMethod, String contractNo,
String orderNo, String brandName, HttpServletResponse response)
purchaseSalesOrderService.exportPurchaseOrder(productKindId, productModel, paymentMethod, contractNo, orderNo, brandName, response);
1.2、前端代码
用Ajax 以post 请求进行文件下载,通过封装form表单,提交post请求。
https://blog.csdn.net/qq_33378853/article/details/86507094
function exportPurchaseOrder()
var productKindId = $("#productKindId").val(); //产品品类
var productModel = $("#productModel").val(); //产品型号
var paymentMethod = $("#paymentMethod").val(); //收/付款方式
var contractNo = $("#contractNo").val();//合同号
var orderNo = $("#orderNo").val();//采购单号
var brandName = $("#brandName").val();//采购单号
var form = $('<form method="POST" action="/purchaseSalesOrder/export">');
form.append($('<input type="hidden" name="productKindId" value="' + productKindId + '">'));
form.append($('<input type="hidden" name="productModel" value="' + productModel + '">'));
form.append($('<input type="hidden" name="paymentMethod" value="' + paymentMethod + '">'));
form.append($('<input type="hidden" name="contractNo" value="' + contractNo + '">'));
form.append($('<input type="hidden" name="orderNo" value="' + orderNo + '">'));
form.append($('<input type="hidden" name="brandName" value="' + brandName + '">'));
$('body').append(form);
form.submit();
以上是关于EasyExcel快速读写Excel数据的主要内容,如果未能解决你的问题,请参考以下文章