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