EasyExcel使用心得

最近项目中用到了阿里easyExcel做导入导出功能
下面是我写的一个工具类,带泛型的。拿来即用,有需求的小伙伴可以看看。
同时也欢迎大佬提出修改意见。

一、首先先写一个生成Excel表头的DTO类,也可以直接在自己的要处理的实体类加上@ExcelProperty注解。
value表示表头,index表示第几列。0等于第一列

          
public class ElecsignCertExcelDTO{
   /**
    * R3编码
    */
   @ApiModelProperty("R3编码")
   @ExcelProperty(value = "R3编码", index = 0)
   private String r3Code;

   /**
    * R3名称
    */
   @ApiModelProperty("R3名称")
   @ExcelProperty(value = "R3名称", index = 1)
   private String r3Name;


   /**
    * 用户名
    */
   @ApiModelProperty("用户名")
   @ExcelProperty(value = "用户名", index = 2)
   private String userName;
}

二、进行写操作所需的Listener类,需要继承easyExcel自带的监听器AnalysisEventListener。
我是参照官方文档进行编写,详情可以参照官方文档https://www.yuque.com/easyexcel/doc/easyexcel
也可以看其github演示地址https://github.com/alibaba/easyexcel/blob/master/src/test/java/com/alibaba/easyexcel/test/demo/read/ReadTest.java

/**
 * @author hhb
 * @date :2020/10/27 8:57
 */
@Slf4j
public class ReadExcelListener<T> extends AnalysisEventListener<T> {

    List<T> list = new ArrayList<>();
    /**
     * 这个每一条数据解析都会来调用
     *
     * @param data
     *            one row value. Is is same as {@link AnalysisContext#readRowHolder()}
     * @param context
     */
    @Override
    public void invoke(T data, AnalysisContext context) {
        log.info("解析到一条数据:{}", JSON.toJSONString(data));
        list.add(data);
    }
    /**
     * 所有数据解析完成了 都会来调用
     *
     * @param context
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        //清除数据
        log.info("所有数据解析完成!");
    }

    public List<T> getDatas() {
        return list;
    }

三、这一步就可以开始写Excel工具类了,


/**
 *
 *  用阿里easyExcel实现对Excel的读、写操作
 * @author hhb
 * @date :2020/10/14 15:55
 */


public class ExcelUtils {


    /**
     * 读Excel操作
     * @param file
     * @param cls
     * @param listener
     * @param <T>
     * @return
     */
    public static <T> List<T> readExcel(MultipartFile file,Class<T> cls,ReadExcelListener<T> listener){
//        EasyExcel.read(fileName, DemoData.class, new DemoDataListener()).sheet().doRead();
        List<T> data=new ArrayList<>();
        try {
            EasyExcel.read(file.getInputStream(),cls,listener).sheet().doRead();
            //根据实际业务需求来选择,是否有返回值
            data=listener.getDatas();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return data;
    }


    /**
     * 写Excel操作
     *
     *
     * @param response
     * @param fileName
     * @param cls
     * @param dataList
     * @param <T>
     */
    public static <T> void wirteExcel(HttpServletResponse response,String fileName,Class<T> cls,List<T> dataList){
//        EasyExcel.write(fileName, cls).sheet("sheet1").doWrite(dataList);
        try {
            EasyExcel.write(getOutputStream(fileName,response),cls).sheet("sheet1").doWrite(dataList);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * 导出文件时为Writer生成OutputStream
     * @param fileName
     * @param response
     * @return
     * @throws Exception
     */
    private static OutputStream getOutputStream(String fileName, HttpServletResponse response)
        throws Exception{
        try{
            fileName = URLEncoder.encode(fileName,"utf-8");
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");
            //此处指定了文件类型为xls,如果是xlsx的,请自行替换修改
            response.setHeader("Content-Disposition", "attachment; filename=" + fileName + ".xlsx");
            response.setHeader("Pragma", "public");
            response.setHeader("Cache-Control", "no-store");
            response.addHeader("Cache-Control", "max-age=0");
            return response.getOutputStream();
        } catch (IOException e){
            throw new Exception("导出文件失败!");
        }
    }

最后,你可以根据项目实际情况调用工具类,和对其进行修改。
需要注意的是!!!!!!
在写处理Excel数据的DTO类时需要保证类里面有一个无参构造器。我就是当时只写了一个将数据库实体类转化为DTO的有参构造器然后报错,浪费了半天时间。

posted @ 2020-10-27 14:08  樱岛麻衣Ss  阅读(321)  评论(0)    收藏  举报