若依管理系统前后端分离版基于ElementUI和SpringBoot怎样实现Excel导入和导出
場景
使用若依前后端分離版實(shí)現(xiàn)Excel的導(dǎo)入和導(dǎo)出。
前端:Vue+ElementUI
后端:SpringBoot+POI+Mysql
注:
博客:
https://blog.csdn.net/badao_liumang_qizhi
關(guān)注公眾號
霸道的程序猿
獲取編程相關(guān)電子書、教程推送與免費(fèi)下載。
實(shí)現(xiàn)
Excel導(dǎo)入
點(diǎn)擊導(dǎo)入按鈕時的效果
?
選中Excel后
?
首先是前端頁面,添加導(dǎo)入的dialog
??? <el-dialog :title="upload.title" :visible.sync="upload.open" width="400px" append-to-body><el-uploadref="upload":limit="1"accept=".xlsx, .xls":headers="upload.headers":action="upload.url":disabled="upload.isUploading":on-progress="handleFileUploadProgress":on-success="handleFileSuccess":auto-upload="false":data="{updateSupport:upload.updateSupport}"drag><i class="el-icon-upload"></i><div class="el-upload__text">將文件拖到此處,或<em>點(diǎn)擊上傳</em></div><div class="el-upload__tip" slot="tip"><el-checkbox v-model="upload.updateSupport" />是否更新已經(jīng)存在的下井次數(shù)設(shè)置數(shù)據(jù)<el-linktype="info"style="font-size:12px"@click="downloadTemplate('xjszTemplate.xlsx')">下載模板</el-link></div><divclass="el-upload__tip"style="color:red"slot="tip">提示:僅允許導(dǎo)入“xls”或“xlsx”格式文件!是否全勤中:1代表全勤,0代表固定次數(shù),不得有空值!!</div></el-upload><div slot="footer" class="dialog-footer"><el-button type="primary" @click="submitFileForm">確 定</el-button><el-button @click="upload.open = false">取 消</el-button></div></el-dialog>通過:visible.sync="upload.open"控制默認(rèn)隱藏,其中upload是聲明的用于存儲上傳相關(guān)的參數(shù)的model
需要聲明它
export default {name: "Xjcssz",data() {return {// 導(dǎo)入?yún)?shù)upload: {// 是否顯示彈出層open: false,// 彈出層標(biāo)題title: "",// 是否禁用上傳isUploading: false,// 是否更新已經(jīng)存在的數(shù)據(jù)updateSupport: 0,// 設(shè)置上傳的請求頭部headers: { Authorization: "Bearer " + getToken() },// 上傳的地址url: process.env.VUE_APP_BASE_API + "/kqgl/xjcssz/importData",},這里的getToken()是從auth中引入
import { getToken } from "@/utils/auth";是要獲取登錄的token
export function getToken() {return Cookies.get(TokenKey) }文件上傳組件使用的是e-upload組件,設(shè)置其一些屬性
limit限制只能選擇一個文件
accept限制能選擇的文件類型
headers設(shè)置請求頭攜帶token
action設(shè)置上傳請求的url
disabled設(shè)置正在上傳時禁用
on-progress設(shè)置正在上傳時的處理事件
on-success設(shè)置上傳成功后的事件
auto-upload設(shè)置自動提交為false,用來實(shí)現(xiàn)手動提交時才提交
data設(shè)置上傳時攜帶的數(shù)據(jù)
drag表示支持可拖拽
設(shè)置on-progress正在上傳時將其禁用
??? // 文件上傳中處理handleFileUploadProgress(event, file, fileList) {this.upload.isUploading = true;},設(shè)置on-success上傳成功后關(guān)閉上傳窗口并設(shè)置上傳可用,然后清除選擇的文件并提示導(dǎo)入結(jié)果然后刷新數(shù)據(jù)。
??? // 文件上傳成功處理handleFileSuccess(response, file, fileList) {this.upload.open = false;this.upload.isUploading = false;this.$refs.upload.clearFiles();this.$alert(response.msg, "導(dǎo)入結(jié)果", { dangerouslyUseHTMLString: true });this.getList();},這里是攜帶了參數(shù) 是否更新已經(jīng)存在的數(shù)據(jù),將其與勾選框進(jìn)行雙向數(shù)據(jù)綁定
<el-checkbox v-model="upload.updateSupport" />是否更新已經(jīng)存在的下井次數(shù)設(shè)置數(shù)據(jù)并且作為參數(shù)在提交時進(jìn)行傳遞
:data="{updateSupport:upload.updateSupport}"注意傳遞參數(shù)時的格式。
然后點(diǎn)擊確定按鈕時觸發(fā)事件
?<el-button type="primary" @click="submitFileForm">確 定</el-button>在事件處理中,通過設(shè)置的ref屬性將表單提交
??? submitFileForm() {this.$refs.upload.submit();},此時表單就會提交到指定的url的后臺接口。
來到后臺接口
??? @RequestMapping("/importData")@ResponseBody@ApiOperation("導(dǎo)入下井次數(shù)設(shè)置數(shù)據(jù)")public AjaxResult importData(@RequestParam MultipartFile file, @RequestParam boolean updateSupport) throws Exception {ExcelUtil<KqXjcssz> util = new ExcelUtil<KqXjcssz>(KqXjcssz.class);List<KqXjcssz> xjcsszList = util.importExcel(file.getInputStream());//循環(huán)插入數(shù)據(jù)for (KqXjcssz xjcssz:xjcsszList) {if(xjcssz.getGh()==null){return? AjaxResult.error("存在為空的工號數(shù)據(jù)");}xjcssz.setSzrq(new Date());xjcssz.setSzr(SecurityUtils.getUsername());//根據(jù)工號查詢是否已經(jīng)存在Integer count = kqXjcsszService.isExistByGh(xjcssz.getGh());if(count>0){//如果設(shè)置了更新if(updateSupport){kqXjcsszService.updateKqXjcssz(xjcssz);}else{//選擇了不更新 啥也不干}}else{//之前不存在直接插入kqXjcsszService.insertKqXjcssz(xjcssz);}}return AjaxResult.success("導(dǎo)入成功");}這里的后臺接口使用@RequestMapping接收,并且使用@ResponseBody注解響應(yīng)json數(shù)據(jù)。
接受請求參數(shù)時,文件必須是@RequestParam MultipartFile file,且名稱為file,如果不進(jìn)行更改指定的話。
然后第二個參數(shù)要與傳遞時的參數(shù)名一致。
然后調(diào)用若依自帶的工具類
??????? ExcelUtil<KqXjcssz> util = new ExcelUtil<KqXjcssz>(KqXjcssz.class);List<KqXjcssz> xjcsszList = util.importExcel(file.getInputStream());以及實(shí)體類上的注解
??? /** 工號 */@Excel(name = "工號")private String gh;等就能實(shí)現(xiàn)解析Excel的數(shù)據(jù)并獲取成對象的list。
這里的導(dǎo)入時的模板建議用下面的導(dǎo)出的EXCEL作為導(dǎo)入模板用。
然后上傳時點(diǎn)擊下載模板時調(diào)用公共下載接口。
Excel導(dǎo)出
頁面上添加導(dǎo)出按鈕
??????? <el-buttontype="warning"icon="el-icon-download"size="mini"@click="handleExport"v-hasPermi="['kqgl:bcgl:export']">導(dǎo)出</el-button>導(dǎo)出按鈕對應(yīng)的處理方法
??? /** 導(dǎo)出按鈕操作 */handleExport() {const queryParams = this.queryParams;this.$confirm("是否確認(rèn)導(dǎo)出所有數(shù)據(jù)項(xiàng)?", "警告", {confirmButtonText: "確定",cancelButtonText: "取消",type: "warning",}).then(function () {return exportBcgl(queryParams);}).then((response) => {this.download(response.msg);}).catch(function () {});},會彈窗提示,點(diǎn)擊確定后執(zhí)行exportBcgl方法,此方法是從外部js中引入
import {exportBcgl, } from "@/api/kqgl/bcgl";在js方法中
export function exportBcgl(query) {return request({url: '/kqgl/bcgl/export',method: 'get',params: query}) }在此方法中發(fā)送get請求給SpringBoot后臺接口。
其中request是來自request.js,封裝的axios發(fā)送請求的對象。
在對應(yīng)的SpringBoot后臺接口
??? @GetMapping("/export")public AjaxResult export(KqBcgl kqBcgl){List<KqBcgl> list = kqBcglService.getBcListByNameToExport(kqBcgl);ExcelUtil<KqBcgl> util = new ExcelUtil<KqBcgl>(KqBcgl.class);return util.exportExcel(list, "bcgl");}直接調(diào)用若依自帶的Excel工具類就可以實(shí)現(xiàn)導(dǎo)出。
其中KqBcgl是對應(yīng)的業(yè)務(wù)的實(shí)體類,可以使用代碼生成工具去生成。
在實(shí)體類中通過添加注解的方式就能實(shí)現(xiàn)將此屬性導(dǎo)出,如果不加此注解則不導(dǎo)出
??? /** 編號 */@Excel(name = "編號")private String bcbh;而且注解里面的name屬性就是導(dǎo)出時那列的標(biāo)題。
關(guān)于這個注解還有好多個屬性,具體可以參考其源碼
public @interface Excel {/*** 導(dǎo)出到Excel中的名字.*/public String name() default "";/*** 日期格式, 如: yyyy-MM-dd*/public String dateFormat() default "";/*** 讀取內(nèi)容轉(zhuǎn)表達(dá)式(如:0=男,1=女,2=未知)*/public String readConverterExp() default "";/*** 導(dǎo)出類型(0數(shù)字 1字符串)*/public ColumnType cellType() default ColumnType.STRING;/*** 導(dǎo)出時在excel中每個列的高度 單位為字符*/public double height() default 14;/*** 導(dǎo)出時在excel中每個列的寬 單位為字符*/public double width() default 16;/*** 文字后綴,如% 90 變成90%*/public String suffix() default "";/*** 當(dāng)值為空時,字段的默認(rèn)值*/public String defaultValue() default "";/*** 提示信息*/public String prompt() default "";/*** 設(shè)置只能選擇不能輸入的列內(nèi)容.*/public String[] combo() default {};/*** 是否導(dǎo)出數(shù)據(jù),應(yīng)對需求:有時我們需要導(dǎo)出一份模板,這是標(biāo)題需要但內(nèi)容需要用戶手工填寫.*/public boolean isExport() default true;/*** 另一個類中的屬性名稱,支持多級獲取,以小數(shù)點(diǎn)隔開*/public String targetAttr() default "";/*** 字段類型(0:導(dǎo)出導(dǎo)入;1:僅導(dǎo)出;2:僅導(dǎo)入)*/Type type() default Type.ALL;public enum Type{ALL(0), EXPORT(1), IMPORT(2);private final int value;Type(int value){this.value = value;}public int value(){return this.value;}}public enum ColumnType{NUMERIC(0), STRING(1);private final int value;ColumnType(int value){this.value = value;}public int value(){return this.value;}} }還有一種情況是,在導(dǎo)出前的查詢數(shù)據(jù)的方法,如果調(diào)用的是和查詢接口一樣的方法。
某些屬性比如某某狀態(tài)等需要用到字典表的列。在查詢接口可能就是直接查詢出來,返回值
直接就是1或者2等這些字典的值。然后返回給前端,前端再進(jìn)行格式化顯示。
但是在導(dǎo)出時必須要顯示對應(yīng)的字典表的label,所以需要修改查詢數(shù)據(jù)的方法getBcListByNameToExport
將要查詢的表與字典表相關(guān)聯(lián),查詢出其label值作為對應(yīng)的屬性,如果有多個需要關(guān)聯(lián)字典表的屬性,則關(guān)聯(lián)兩次,下面是示例代碼
??? <select id="getBcListByNameToExport" parameterType="KqBcgl" resultMap="KqBcglResult">SELECTb.id,b.bcbh,b.bcmc,s.dict_label AS bclx,sfkt,b.xss,b.jgs,b.sfyb,kqts,b.mzxx,b.bz,s1.dict_label AS jxbclxFROMkq_bcgl bLEFT JOIN sys_dict_data s ON b.bclx = s.dict_valueAND s.dict_type = "kq_kqgl_bcgl_bclx"LEFT JOIN sys_dict_data s1 ON b.jxbclx = s1.dict_valueAND s1.dict_type = "kq_kqgl_bcgl_jxbclx"<where><if test="bcmc != null? and bcmc != ''"> and bcmc LIKE "%"#{bcmc}"%"</if></where></select>那么點(diǎn)擊導(dǎo)出按鈕就能實(shí)現(xiàn)導(dǎo)出了
?
總結(jié)
以上是生活随笔為你收集整理的若依管理系统前后端分离版基于ElementUI和SpringBoot怎样实现Excel导入和导出的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MyBatis+Mysql实现从记录表中
- 下一篇: 若依前后端分离版怎样修改主页面和浏览器上