zoukankan      html  css  js  c++  java
  • 使用Easy-Excel导出、读写Excel

    EasyExcel

    EasyExcel是阿里推出的一款高性能的开源excel读写框架,主要解决读大文件poi占内存大的问题,同时也提供了一些简单的excel操作API。2.0.5以后的改动比较大,结合网上的,自己整理了一个demo,方便以后复用。

    文档:https://www.yuque.com/easyexcel/doc/easyexcel
    本文git:https://gitee.com/proper128/springboot-easyexcel

    1. 引入依赖

          <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>easyexcel</artifactId>
                <version>2.2.3</version>
            </dependency>
    

    2. 工具类 EasyExcelUtil

    public class EasyExcelUtil {
        /**
         * web导出excel文件
         * @param response response
         * @param list 实体数据
         * @param fileName 文件名 
         * @param sheetName sheet名
         * @param clazz 实体类
         * @throws Exception
         */
        public static void exprotExcel(HttpServletResponse response, List<?> list, String fileName, String sheetName,Class<?> clazz)throws Exception  {
            EasyExcel.write(getOutputStream(fileName,response), clazz)
                    .sheet(sheetName)
                    .doWrite(list);
        }
        /**
         * 导出文件时为Writer生成OutputStream
         * @param fileName
         * @param response
         * @return
         */
        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("utf8");
                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表格失败!", e);
            }
        }
    
    
        /**
         * 同步无模型读(默认读取sheet0,从第2行开始读)
         *
         * @param filePath
         * @return
         */
        public static List<Map<Integer, String>> syncRead(String filePath) {
            return EasyExcelFactory.read(filePath).sheet().doReadSync();
        }
    
        /**
         * 同步无模型读(默认表头占一行,从第2行开始读)
         *
         * @param filePath
         * @param sheetNo  sheet页号,从0开始
         * @return
         */
        public static List<Map<Integer, String>> syncRead(String filePath, Integer sheetNo) {
            return EasyExcelFactory.read(filePath).sheet(sheetNo).doReadSync();
        }
    
        /**
         * 同步无模型读(指定sheet和表头占的行数)
         *
         * @param inputStream
         * @param sheetNo     sheet页号,从0开始
         * @param headRowNum  表头占的行数,从0开始(如果要连表头一起读出来则传0)
         * @return List<Map < colNum, cellValue>>
         */
        public static List<Map<Integer, String>> syncRead(InputStream inputStream, Integer sheetNo, Integer headRowNum) {
            return EasyExcelFactory.read(inputStream).sheet(sheetNo).headRowNumber(headRowNum).doReadSync();
        }
    
        /**
         * 同步无模型读(指定sheet和表头占的行数)
         *
         * @param file
         * @param sheetNo    sheet页号,从0开始
         * @param headRowNum 表头占的行数,从0开始(如果要连表头一起读出来则传0)
         * @return List<Map < colNum, cellValue>>
         */
        public static List<Map<Integer, String>> syncRead(File file, Integer sheetNo, Integer headRowNum) {
            return EasyExcelFactory.read(file).sheet(sheetNo).headRowNumber(headRowNum).doReadSync();
        }
    
        /**
         * 同步无模型读(指定sheet和表头占的行数)
         *
         * @param filePath
         * @param sheetNo    sheet页号,从0开始
         * @param headRowNum 表头占的行数,从0开始(如果要连表头一起读出来则传0)
         * @return List<Map < colNum, cellValue>>
         */
        public static List<Map<Integer, String>> syncRead(String filePath, Integer sheetNo, Integer headRowNum) {
            return EasyExcelFactory.read(filePath).sheet(sheetNo).headRowNumber(headRowNum).doReadSync();
        }
    
        /**
         * 同步按模型读(默认读取sheet0,从第2行开始读)
         *
         * @param filePath
         * @param clazz    模型的类类型(excel数据会按该类型转换成对象)
         * @return
         */
        public static List<T> syncReadModel(String filePath, Class clazz) {
            return EasyExcelFactory.read(filePath).sheet().head(clazz).doReadSync();
        }
    
        /**
         * 同步按模型读(默认表头占一行,从第2行开始读)
         *
         * @param filePath
         * @param clazz    模型的类类型(excel数据会按该类型转换成对象)
         * @param sheetNo  sheet页号,从0开始
         * @return
         */
        public static List<T> syncReadModel(String filePath, Class clazz, Integer sheetNo) {
            return EasyExcelFactory.read(filePath).sheet(sheetNo).head(clazz).doReadSync();
        }
    
        /**
         * 同步按模型读(指定sheet和表头占的行数)
         *
         * @param inputStream
         * @param clazz       模型的类类型(excel数据会按该类型转换成对象)
         * @param sheetNo     sheet页号,从0开始
         * @param headRowNum  表头占的行数,从0开始(如果要连表头一起读出来则传0)
         * @return
         */
        public static List<T> syncReadModel(InputStream inputStream, Class clazz, Integer sheetNo, Integer headRowNum) {
            return EasyExcelFactory.read(inputStream).sheet(sheetNo).headRowNumber(headRowNum).head(clazz).doReadSync();
        }
    
        /**
         * 同步按模型读(指定sheet和表头占的行数)
         *
         * @param file
         * @param clazz      模型的类类型(excel数据会按该类型转换成对象)
         * @param sheetNo    sheet页号,从0开始
         * @param headRowNum 表头占的行数,从0开始(如果要连表头一起读出来则传0)
         * @return
         */
        public static List<T> syncReadModel(File file, Class clazz, Integer sheetNo, Integer headRowNum) {
            return EasyExcelFactory.read(file).sheet(sheetNo).headRowNumber(headRowNum).head(clazz).doReadSync();
        }
    
        /**
         * 同步按模型读(指定sheet和表头占的行数)
         *
         * @param filePath
         * @param clazz      模型的类类型(excel数据会按该类型转换成对象)
         * @param sheetNo    sheet页号,从0开始
         * @param headRowNum 表头占的行数,从0开始(如果要连表头一起读出来则传0)
         * @return
         */
        public static List<T> syncReadModel(String filePath, Class clazz, Integer sheetNo, Integer headRowNum) {
            return EasyExcelFactory.read(filePath).sheet(sheetNo).headRowNumber(headRowNum).head(clazz).doReadSync();
        }
    
        /**
         * 异步无模型读(默认读取sheet0,从第2行开始读)
         *
         * @param excelListener 监听器,在监听器中可以处理行数据LinkedHashMap,表头数据,异常处理等
         * @param filePath      表头占的行数,从0开始(如果要连表头一起读出来则传0)
         * @return
         */
        public static void asyncRead(String filePath, AnalysisEventListener<T> excelListener) {
            EasyExcelFactory.read(filePath, excelListener).sheet().doRead();
        }
    
        /**
         * 异步无模型读(默认表头占一行,从第2行开始读)
         *
         * @param filePath      表头占的行数,从0开始(如果要连表头一起读出来则传0)
         * @param excelListener 监听器,在监听器中可以处理行数据LinkedHashMap,表头数据,异常处理等
         * @param sheetNo       sheet页号,从0开始
         * @return
         */
        public static void asyncRead(String filePath, AnalysisEventListener<T> excelListener, Integer sheetNo) {
            EasyExcelFactory.read(filePath, excelListener).sheet(sheetNo).doRead();
        }
    
        /**
         * 异步无模型读(指定sheet和表头占的行数)
         *
         * @param inputStream
         * @param excelListener 监听器,在监听器中可以处理行数据LinkedHashMap,表头数据,异常处理等
         * @param sheetNo       sheet页号,从0开始
         * @param headRowNum    表头占的行数,从0开始(如果要连表头一起读出来则传0)
         * @return
         */
        public static void asyncRead(InputStream inputStream, AnalysisEventListener<T> excelListener, Integer sheetNo, Integer headRowNum) {
            EasyExcelFactory.read(inputStream, excelListener).sheet(sheetNo).headRowNumber(headRowNum).doRead();
        }
    
        /**
         * 异步无模型读(指定sheet和表头占的行数)
         *
         * @param file
         * @param excelListener 监听器,在监听器中可以处理行数据LinkedHashMap,表头数据,异常处理等
         * @param sheetNo       sheet页号,从0开始
         * @param headRowNum    表头占的行数,从0开始(如果要连表头一起读出来则传0)
         * @return
         */
        public static void asyncRead(File file, AnalysisEventListener<T> excelListener, Integer sheetNo, Integer headRowNum) {
            EasyExcelFactory.read(file, excelListener).sheet(sheetNo).headRowNumber(headRowNum).doRead();
        }
    
        /**
         * 异步无模型读(指定sheet和表头占的行数)
         *
         * @param filePath
         * @param excelListener 监听器,在监听器中可以处理行数据LinkedHashMap,表头数据,异常处理等
         * @param sheetNo       sheet页号,从0开始
         * @param headRowNum    表头占的行数,从0开始(如果要连表头一起读出来则传0)
         * @return
         */
        public static void asyncRead(String filePath, AnalysisEventListener<T> excelListener, Integer sheetNo, Integer headRowNum) {
            EasyExcelFactory.read(filePath, excelListener).sheet(sheetNo).headRowNumber(headRowNum).doRead();
        }
    
        /**
         * 异步按模型读取(默认读取sheet0,从第2行开始读)
         *
         * @param filePath
         * @param excelListener 监听器,在监听器中可以处理行数据LinkedHashMap,表头数据,异常处理等
         * @param clazz         模型的类类型(excel数据会按该类型转换成对象)
         */
        public static void asyncReadModel(String filePath, AnalysisEventListener<T> excelListener, Class clazz) {
            EasyExcelFactory.read(filePath, clazz, excelListener).sheet().doRead();
        }
    
        /**
         * 异步按模型读取(默认表头占一行,从第2行开始读)
         *
         * @param filePath
         * @param excelListener 监听器,在监听器中可以处理行数据LinkedHashMap,表头数据,异常处理等
         * @param clazz         模型的类类型(excel数据会按该类型转换成对象)
         * @param sheetNo       sheet页号,从0开始
         */
        public static void asyncReadModel(String filePath, AnalysisEventListener<T> excelListener, Class clazz, Integer sheetNo) {
            EasyExcelFactory.read(filePath, clazz, excelListener).sheet(sheetNo).doRead();
        }
    
        /**
         * 异步按模型读取
         *
         * @param inputStream
         * @param excelListener 监听器,在监听器中可以处理行数据LinkedHashMap,表头数据,异常处理等
         * @param clazz         模型的类类型(excel数据会按该类型转换成对象)
         * @param sheetNo       sheet页号,从0开始
         * @param headRowNum    表头占的行数,从0开始(如果要连表头一起读出来则传0)
         */
        public static void asyncReadModel(InputStream inputStream, AnalysisEventListener<T> excelListener, Class clazz, Integer sheetNo, Integer headRowNum) {
            EasyExcelFactory.read(inputStream, clazz, excelListener).sheet(sheetNo).headRowNumber(headRowNum).doRead();
        }
    
        /**
         * 异步按模型读取
         *
         * @param file
         * @param excelListener 监听器,在监听器中可以处理行数据LinkedHashMap,表头数据,异常处理等
         * @param clazz         模型的类类型(excel数据会按该类型转换成对象)
         * @param sheetNo       sheet页号,从0开始
         * @param headRowNum    表头占的行数,从0开始(如果要连表头一起读出来则传0)
         */
        public static void asyncReadModel(File file, AnalysisEventListener<T> excelListener, Class clazz, Integer sheetNo, Integer headRowNum) {
            EasyExcelFactory.read(file, clazz, excelListener).sheet(sheetNo).headRowNumber(headRowNum).doRead();
        }
    
        /**
         * 异步按模型读取
         *
         * @param filePath
         * @param excelListener 监听器,在监听器中可以处理行数据LinkedHashMap,表头数据,异常处理等
         * @param clazz         模型的类类型(excel数据会按该类型转换成对象)
         * @param sheetNo       sheet页号,从0开始
         * @param headRowNum    表头占的行数,从0开始(如果要连表头一起读出来则传0)
         */
        public static void asyncReadModel(String filePath, AnalysisEventListener<T> excelListener, Class clazz, Integer sheetNo, Integer headRowNum) {
            EasyExcelFactory.read(filePath, clazz, excelListener).sheet(sheetNo).headRowNumber(headRowNum).doRead();
        }
    
        /**
         * 无模板写文件
         *
         * @param filePath
         * @param head     表头数据
         * @param data     表内容数据
         */
        public static void write(String filePath, List<List<String>> head, List<List<Object>> data) {
            EasyExcel.write(filePath).head(head).sheet().doWrite(data);
        }
    
        /**
         * 无模板写文件
         *
         * @param filePath
         * @param head      表头数据
         * @param data      表内容数据
         * @param sheetNo   sheet页号,从0开始
         * @param sheetName sheet名称
         */
        public static void write(String filePath, List<List<String>> head, List<List<Object>> data, Integer sheetNo, String sheetName) {
            EasyExcel.write(filePath).head(head).sheet(sheetNo, sheetName).doWrite(data);
        }
    
        /**
         * 根据excel模板文件写入文件
         *
         * @param filePath
         * @param templateFileName
         * @param headClazz
         * @param data
         */
        public static void writeTemplate(String filePath, String templateFileName, Class headClazz, List data) {
            EasyExcel.write(filePath, headClazz).withTemplate(templateFileName).sheet().doWrite(data);
        }
    
        /**
         * 根据excel模板文件写入文件
         *
         * @param filePath
         * @param templateFileName
         * @param data
         */
        public static void writeTemplate(String filePath, String templateFileName, List data) {
            EasyExcel.write(filePath).withTemplate(templateFileName).sheet().doWrite(data);
        }
    
        /**
         * 按模板写文件
         *
         * @param filePath
         * @param headClazz 表头模板
         * @param data      数据
         */
        public static void write(String filePath, Class headClazz, List data) {
            EasyExcel.write(filePath, headClazz).sheet().doWrite(data);
        }
    
        /**
         * 按模板写文件
         *
         * @param filePath
         * @param headClazz 表头模板
         * @param data      数据
         * @param sheetNo   sheet页号,从0开始
         * @param sheetName sheet名称
         */
        public static void write(String filePath, Class headClazz, List data, Integer sheetNo, String sheetName) {
            EasyExcel.write(filePath, headClazz).sheet(sheetNo, sheetName).doWrite(data);
        }
    
        /**
         * 按模板写文件
         *
         * @param filePath
         * @param headClazz    表头模板
         * @param data         数据
         * @param writeHandler 自定义的处理器,比如设置table样式,设置超链接、单元格下拉框等等功能都可以通过这个实现(需要注册多个则自己通过链式去调用)
         * @param sheetNo      sheet页号,从0开始
         * @param sheetName    sheet名称
         */
        public static void write(String filePath, Class headClazz, List data, WriteHandler writeHandler, Integer sheetNo, String sheetName) {
            EasyExcel.write(filePath, headClazz).registerWriteHandler(writeHandler).sheet(sheetNo, sheetName).doWrite(data);
        }
    
        /**
         * 按模板写文件(包含某些字段)
         *
         * @param filePath
         * @param headClazz   表头模板
         * @param data        数据
         * @param includeCols 过滤包含的字段,根据字段名称过滤
         * @param sheetNo     sheet页号,从0开始
         * @param sheetName   sheet名称
         */
        public static void writeInclude(String filePath, Class headClazz, List data, Set<String> includeCols, Integer sheetNo, String sheetName) {
            EasyExcel.write(filePath, headClazz).includeColumnFiledNames(includeCols).sheet(sheetNo, sheetName).doWrite(data);
        }
    
        /**
         * 按模板写文件(排除某些字段)
         *
         * @param filePath
         * @param headClazz   表头模板
         * @param data        数据
         * @param excludeCols 过滤排除的字段,根据字段名称过滤
         * @param sheetNo     sheet页号,从0开始
         * @param sheetName   sheet名称
         */
        public static void writeExclude(String filePath, Class headClazz, List data, Set<String> excludeCols, Integer sheetNo, String sheetName) {
            EasyExcel.write(filePath, headClazz).excludeColumnFiledNames(excludeCols).sheet(sheetNo, sheetName).doWrite(data);
        }
    
        /**
         * 多个sheet页的数据链式写入
         * ExcelUtil.writeWithSheets(outputStream)
         * .writeModel(ExcelModel.class, excelModelList, "sheetName1")
         * .write(headData, data,"sheetName2")
         * .finish();
         *
         * @param outputStream
         * @return
         */
        public static EasyExcelWriterFactory writeWithSheets(OutputStream outputStream) {
            EasyExcelWriterFactory excelWriter = new EasyExcelWriterFactory(outputStream);
            return excelWriter;
        }
    
        /**
         * 多个sheet页的数据链式写入
         * ExcelUtil.writeWithSheets(file)
         * .writeModel(ExcelModel.class, excelModelList, "sheetName1")
         * .write(headData, data,"sheetName2")
         * .finish();
         *
         * @param file
         * @return
         */
        public static EasyExcelWriterFactory writeWithSheets(File file) {
            EasyExcelWriterFactory excelWriter = new EasyExcelWriterFactory(file);
            return excelWriter;
        }
    
        /**
         * 多个sheet页的数据链式写入
         * ExcelUtil.writeWithSheets(filePath)
         * .writeModel(ExcelModel.class, excelModelList, "sheetName1")
         * .write(headData, data,"sheetName2")
         * .finish();
         *
         * @param filePath
         * @return
         */
        public static EasyExcelWriterFactory writeWithSheets(String filePath) {
            EasyExcelWriterFactory excelWriter = new EasyExcelWriterFactory(filePath);
            return excelWriter;
        }
    
        /**
         * 多个sheet页的数据链式写入(失败了会返回一个有部分数据的Excel)
         * ExcelUtil.writeWithSheets(response, exportFileName)
         * .writeModel(ExcelModel.class, excelModelList, "sheetName1")
         * .write(headData, data,"sheetName2")
         * .finish();
         *
         * @param response
         * @param exportFileName 导出的文件名称
         * @return
         */
        public static EasyExcelWriterFactory writeWithSheetsWeb(HttpServletResponse response, String exportFileName) throws IOException {
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");
            // 这里URLEncoder.encode可以防止中文乱码
            String fileName = URLEncoder.encode(exportFileName, "UTF-8");
            response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
            EasyExcelWriterFactory excelWriter = new EasyExcelWriterFactory(response.getOutputStream());
            return excelWriter;
        }
    }
    

    3. 监听器 UserExcelListener

    /**
     * @description: 模型解析监听器--> 2.0.5以后每个模型创建一个监听器
     *               每解析一行会回调invoke()方法,整个excel解析结束会执行doAfterAllAnalysed()方法
     *               有个很重要的点 UserExcelListener 不能被spring管理,要每次读取excel都要new,然后里面用到spring可以构造方法传进去
     * @author: Li Kang
     * @create: 2020-05-04 11:08
     */
    @Slf4j
    public class UserExcelListener<User> extends AnalysisEventListener<User> {
    
        private final List<User> userList = Lists.newArrayList();
    
    
        /**
         * 每隔5条存储数据库,实际使用中可以3000条,然后清理list ,方便内存回收
         */
        private static final int BATCH_COUNT = 5;
    
    
        // -----------------------------------------------------------------------------------
    
        /**
         * 假设这个是一个DAO,当然有业务逻辑这个也可以是一个service。当然如果不用存储这个对象没用。
         */
        private UserDAO userDAO;
        public UserExcelListener() {
            // 这里是demo,所以随便new一个。实际使用如果到了spring,请使用下面的有参构造函数
            userDAO = new UserDAO();
        }
    
        /**
         * 如果使用了spring,请使用这个构造方法。每次创建Listener的时候需要把spring管理的类传进来
         *
         * @param userDAO
         */
        public UserExcelListener(UserDAO userDAO) {
            this.userDAO = userDAO;
        }
    
        // -----------------------------------------------------------------------------------
    
    
        @Override
        public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
            log.info("解析到一条头数据:{}", JSON.toJSONString(headMap));
        }
    
        @Override
        public void invoke(User user, AnalysisContext context) {
            log.info("解析到一条数据:{}", JSON.toJSONString(user));
            userList.add(user);
            // 实际数据量比较大时,rows里的数据可以存到一定量之后进行批量处理(比如存到数据库),
            // 然后清空列表,以防止内存占用过多造成OOM
            // 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM
            if (userList.size() >= BATCH_COUNT) {
                saveUserList();
                // 存储完成清理 list
                userList.clear();
            }
        }
    
        @Override
        public void doAfterAllAnalysed(AnalysisContext context) {
            log.info("read {} rows", userList.size());
            // 这里也要保存数据,确保最后遗留的数据也存储到数据库
            saveUserList();
        }
    
        /**
         * 在转换异常 获取其他异常下会调用本接口。抛出异常则停止读取。如果这里不抛出异常则 继续读取下一行。
         *
         * @param exception
         * @param context
         * @throws Exception
         */
        @Override
        public void onException(Exception exception, AnalysisContext context) {
            log.error("解析失败,但是继续解析下一行:{}", exception.getMessage());
            if (exception instanceof ExcelDataConvertException) {
                ExcelDataConvertException excelDataConvertException = (ExcelDataConvertException) exception;
                log.error("第{}行,第{}列解析异常,数据为:{}", excelDataConvertException.getRowIndex(),
                        excelDataConvertException.getColumnIndex(), excelDataConvertException.getCellData());
            }
        }
    
        public List<User> getRows() {
            return userList;
        }
    
        /**
         * 加上存储数据库
         */
        private void saveUserList() {
            log.info("{}条数据,开始存储数据库!", userList.size());
            userDAO.save((List<com.lk.model.User>) userList);
            log.info("存储数据库成功!");
        }
    
    
    }
    

    4. EasyExcelWriterFactory

    import com.alibaba.excel.EasyExcel;
    import com.alibaba.excel.ExcelWriter;
    
    import java.io.File;
    import java.io.OutputStream;
    import java.util.List;
    
    /**
     * 自定义EasyExcel写工厂
     */
    public class EasyExcelWriterFactory
    {
        private int sheetNo = 0;
        private ExcelWriter excelWriter = null;
    
        public EasyExcelWriterFactory(OutputStream outputStream) {
            excelWriter = EasyExcel.write(outputStream).build();
        }
    
        public EasyExcelWriterFactory(File file) {
            excelWriter = EasyExcel.write(file).build();
        }
    
        public EasyExcelWriterFactory(String filePath) {
            excelWriter = EasyExcel.write(filePath).build();
        }
    
        /**
         * 链式模板表头写入
         * @param headClazz 表头格式
         * @param data 数据 List<ExcelModel> 或者List<List<Object>>
         * @return
         */
        public EasyExcelWriterFactory writeModel(Class headClazz, List data, String sheetName){
            excelWriter.write(data, EasyExcel.writerSheet(this.sheetNo++, sheetName).head(headClazz).build());
            return this;
        }
    
        /**
         * 链式自定义表头写入
         * @param head
         * @param data 数据 List<ExcelModel> 或者List<List<Object>>
         * @param sheetName
         * @return
         */
        public EasyExcelWriterFactory write(List<List<String>> head, List data, String sheetName){
            excelWriter.write(data, EasyExcel.writerSheet(this.sheetNo++, sheetName).head(head).build());
            return this;
        }
    
        public void finish() {
            excelWriter.finish();
        }
    }
    
    

    5. 实体类 User

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class User implements Serializable {
    
        @ExcelProperty(value = "用户名", index = 0)
        private String username ;
    
        /**
         * 忽略这个字段
         */
        @ExcelIgnore
        private String password ;
    
        @ExcelProperty(value = "年龄", index = 1)
        private Integer age;
    
        @ExcelProperty(value = "注册时间", index = 2)
        @DateTimeFormat("yyyy/MM/dd")
        private Date createTime;
    
    
    }
    
    

    6. DAO

    /**
     * @description: 假设这个是你的DAO存储。当然还要这个类让spring管理,当然你不用需要存储,也不需要这个类。
     * @author: Li Kang
     * @create: 2020-05-04 17:16
     */
    @Slf4j
    public class UserDAO {
        public void save(List<User> userList) {
            // 如果是mybatis,尽量别直接调用多次insert,自己写一个mapper里面新增一个方法batchInsert,所有数据一次性插入
            log.info("insert操作");
        }
    }
    

    7. Controller

    @Controller
    public class TestController {
    
        /**
         * 导出测试
         * @param response
         * @throws Exception
         */
        @GetMapping("/exportTest")
        void exportTest(HttpServletResponse response) throws Exception {
            //单sheet,单table导出测试
            List<User> userList = Lists.newArrayList();
            for (int i = 0; i < 5 ; i++) {
                User user = new User("admin"+i,"123"+i,1+i,new Date());
                userList.add(user);
            }
            EasyExcelUtil.exprotExcel(response,userList,"导出测试","sheet单1",User.class);
        }
        /**
         * 上传测试
         * @param file
         * @return
         * @throws IOException
         */
        @PostMapping("upload")
        @ResponseBody
        public String upload(MultipartFile file) throws IOException {
    //        EasyExcel.read(file.getInputStream(), User.class, new UploadDataListener(uploadDAO)).sheet().doRead();
              EasyExcelUtil.asyncReadModel(file.getInputStream(),new UserExcelListener<>(),User.class,0,0);
            return "success";
        }
    }
    
    

    8. 测试类

    @Slf4j
    @SpringBootTest
    public class ApplicationTests {
    
        @BeforeEach
        void testBefore() {
            log.info("测试开始!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
        }
    
        @AfterEach
        void testAfter() {
            log.info("测试结束!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
        }
    
    
        @Test
        public void write() {
            List<User> userList = Lists.newArrayList();
            for (int i = 0; i < 11; i++) {
                User user = new User("admin" + i, "123" + i, 18 + i,new Date());
                userList.add(user);
            }
            EasyExcelUtil.write("E:\3.xlsx", User.class, userList);
        }
    
        @Test
        public void read() {
            String fileName = "E:\3.xlsx";
            // 同步读
            // List<T> ts = EasyExcelUtil.syncReadModel(fileName, User.class);
            // log.info(JSON.toJSONString(ts));
    
            // 异步读
            EasyExcelUtil.asyncReadModel(fileName,new UserExcelListener<>(),User.class);
    
        }
    }
    
  • 相关阅读:
    第一次留下自己的随笔
    NSOperation多线程方式
    NSThread多线程方式
    GCD多线程机制
    GCD创建单例常用的两种方法
    线程锁
    使用KVO模式,设置应用角标数字
    keyChain RSA加密 KVO
    NSURLConnection网络处理和NSURLSession网络处理
    UIAlertView和UIAlertViewController
  • 原文地址:https://www.cnblogs.com/proper128/p/12827495.html
Copyright © 2011-2022 走看看