一、后端
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值方式不一样。