一、后端

1、导入字段的类

public class UploadAjgl {
    private String ajnd;
    private String ajh;
    private String gjh;
    private String djh;
//记得get和set,toString
......
}

1、监听器

package cn.xxx.util;

import cn.xxx.models.UploadAjgl;
import cn.xxx.services.AjglService;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;

import java.util.ArrayList;
import java.util.List;

public class AjglListener extends AnalysisEventListener<UploadAjgl> {

    /**
     * 每隔5120条存储数据库,然后清理list ,方便内存回收
     */
    private static final int BATCH_COUNT = 128;
    private List<String> errMessage;

    List<UploadAjgl> list = new ArrayList<>();


    private AjglService ajglService;
    private int year;

    public AjglListener(AjglService ajglService, int year) {
        this.ajglService = ajglService;
        this.year = year;
        errMessage = new ArrayList<>();
    }


    @Override
    public void invoke(UploadAjgl data, AnalysisContext context) {
        list.add(data);
        // 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM
        if (list.size() >= BATCH_COUNT) {
            errMessage.addAll(saveData());
            //  存储完成清理 list
            list.clear();
        }
//        list.forEach(item -> System.out.println(item.toString()));
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        errMessage.addAll(saveData());
        list.clear();
    }

    /**
     * 加上存储数据库
     */
    private List<String> saveData() {
        return ajglService.save(list, year);
    }

    public List<String> getErrMessage() {
        return errMessage;
    }

    public int getYear() {
        return year;
    }

    public void setYear(int year) {
        this.year = year;
    }

    public void setErrMessage(List<String> errMessage) {
        this.errMessage = errMessage;
    }

}

3、service的实现类

 @Transactional(rollbackFor = Exception.class)
    @Override
    public List<String> save(List<UploadAjgl> list, int year) {
  
        ArrayList<String> errMessage = new ArrayList<>();
        long num = 0;
            for (var aj : list) {
                num++;
                if (aj.getAjnd() != null) {
//Excel导入时整数会带点,比如excel里面是23,拿到的数据会是23.0,需要用Double.valueOf(aj.getAjnd()).intValue() 转成23
                    if (Double.valueOf(aj.getAjnd()).intValue() == year) {
                        Ajgl ajgl = new Ajgl();
                        Date date = new Date();
                       .......
                        ironAjglRepository.save(ajgl);

                    } else {
                        errMessage.add("请检查导入数据中第【" + num + "】条数据的【年度】是否为当前的年份");
                    }
                } else {
                    errMessage.add("请检查导入数据中第【" + num + "】条数据的【年度】,不能为空");
                }
            }
        return errMessage;
    }

4、Controller

@PostMapping("upload")
    @ResponseBody
    public HashMap<String, Object> upload(@RequestParam(value = "file") MultipartFile file,
                                          @RequestParam(value = "year") int year) throws IOException {
        AjglListener ajglListener = new AjglListener(ajglService, year);
        EasyExcel.read(file.getInputStream(), UploadAjgl.class, ajglListener).sheet("导入模板").doReadSync();//这里的sheet里面放的是sheet的表名,和表名一样的才能导入,也可以是其他的,进去看源码就行
        HashMap<String, Object> hashMap = new HashMap<>();
        List<String> errMessage = ajglListener.getErrMessage();
        if (errMessage.isEmpty()) {
            hashMap.put("success", true);
        } else {
            hashMap.put("success", false);
            hashMap.put("errMessage", errMessage);
        }
        return hashMap;
    }

二、前端

............  
<el-upload
          style="float:left;margin-left:5px;"
          class="upload-demo"
          action="/api/xxx/ajgl/upload"
          :data="{year:year}"
          :headers="uploadHeaders"
          :limit="1"
          :file-list="excelFileList"
          :on-success="successUploadFile"
          accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel"
        >
          <el-button size="small" type="primary">导入</el-button>
        </el-upload>
  <el-dialog title="提示,有未导入成功数据" :visible.sync="dialogVisible" width="30%">
        <div class="infinite-list" style="overflow:auto;height:300px;">
          <el-tag
            v-for="(errMessageItem,index) in errMessageList"
            :key="index"
            type="danger"
            style="margin:.3rem;"
          >{{errMessageItem}}</el-tag>
        </div>
        <span slot="footer" class="dialog-footer">
          <el-button @click="dialogVisible = false">取 消</el-button>
          <el-button type="primary" @click="reloadPage">确 定</el-button>
        </span>
      </el-dialog>
...........
<script>
import {
  upload as uploadHeaders,
} from "@/request";
export default {
  data() {
    return {
      excelFileList: [],
      dialogVisible: false,
      errMessageList: []
    };
  },
  computed: {
    uploadHeaders
  },
 created() {},
methods: {
 reloadPage() {
      this.dialogVisible = false;
      this.excelFileList = [];
      this.onCurrentChange(1);//自定义查数据
    },
    successUploadFile(response) {
      if (response.success) {
        this.$message.success("导入成功");
        this.excelFileList = [];
        this.onCurrentChange(1);//自定义查数据
      } else {
        this.dialogVisible = true;
        this.errMessageList = response.errMessage;
      }
    },
.........
}
..........

 

export const upload=()=>{
 return {
     'Authorization':`Bearer ${getToken()}`
 }

}

 getToken()是获取Token值的,不同的公司封装获取Token值方式不一样。