若依管理系統前後端分離版基於ElementUI和SpringBoot怎樣實現Excel匯入和匯出
場景
使用若依前後端分離版實現Excel的匯入和匯出。
前端:Vue+ElementUI
後端:SpringBoot+POI+Mysql
注:
部落格:
https://blog.csdn.net/badao_liumang_qizhi
關注公眾號
霸道的程式猿
獲取程式設計相關電子書、教程推送與免費下載。
實現
Excel匯入
點選匯入按鈕時的效果
選中Excel後
首先是前端頁面,新增匯入的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>點選上傳</em> </div> <div class="el-upload__tip" slot="tip"> <el-checkbox v-model="upload.updateSupport" />是否更新已經存在的下井次數設定資料 <el-link type="info" style="font-size:12px" @click="downloadTemplate('xjszTemplate.xlsx')" >下載模板</el-link> </div> <div class="el-upload__tip" style="color:red" slot="tip" >提示:僅允許匯入“xls”或“xlsx”格式檔案!是否全勤中:1代表全勤,0代表固定次數,不得有空值!!</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"控制預設隱藏,其中upload是宣告的用於儲存上傳相關的引數的model
需要宣告它
export default { name: "Xjcssz", data() { return { // 匯入引數 upload: { // 是否顯示彈出層 open: false, // 彈出層標題 title: "", // 是否禁用上傳 isUploading: false, // 是否更新已經存在的資料 updateSupport: 0, // 設定上傳的請求頭部 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元件,設定其一些屬性
limit限制只能選擇一個檔案
accept限制能選擇的檔案型別
headers設定請求頭攜帶token
action設定上傳請求的url
disabled設定正在上傳時禁用
on-progress設定正在上傳時的處理事件
on-success設定上傳成功後的事件
auto-upload設定自動提交為false,用來實現手動提交時才提交
data設定上傳時攜帶的資料
drag表示支援可拖拽
設定on-progress正在上傳時將其禁用
// 檔案上傳中處理 handleFileUploadProgress(event, file, fileList) { this.upload.isUploading = true; },
設定on-success上傳成功後關閉上傳視窗並設定上傳可用,然後清除選擇的檔案並提示匯入結果然後重新整理資料。
// 檔案上傳成功處理 handleFileSuccess(response, file, fileList) { this.upload.open = false; this.upload.isUploading = false; this.$refs.upload.clearFiles(); this.$alert(response.msg, "匯入結果", { dangerouslyUseHTMLString: true }); this.getList(); },
這裡是攜帶了引數 是否更新已經存在的資料,將其與勾選框進行雙向資料繫結
<el-checkbox v-model="upload.updateSupport" />是否更新已經存在的下井次數設定資料
並且作為引數在提交時進行傳遞
:data="{updateSupport:upload.updateSupport}"
注意傳遞引數時的格式。
然後點選確定按鈕時觸發事件
<el-button type="primary" @click="submitFileForm">確 定</el-button>
在事件處理中,通過設定的ref屬性將表單提交
submitFileForm() { this.$refs.upload.submit(); },
此時表單就會提交到指定的url的後臺介面。
來到後臺介面
@RequestMapping("/importData") @ResponseBody @ApiOperation("匯入下井次數設定資料") 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()); //迴圈插入資料 for (KqXjcssz xjcssz:xjcsszList) { if(xjcssz.getGh()==null) { return AjaxResult.error("存在為空的工號資料"); } xjcssz.setSzrq(new Date()); xjcssz.setSzr(SecurityUtils.getUsername()); //根據工號查詢是否已經存在 Integer count = kqXjcsszService.isExistByGh(xjcssz.getGh()); if(count>0) { //如果設定了更新 if(updateSupport) { kqXjcsszService.updateKqXjcssz(xjcssz); }else { //選擇了不更新 啥也不幹 } } else { //之前不存在直接插入 kqXjcsszService.insertKqXjcssz(xjcssz); } } return AjaxResult.success("匯入成功"); }
這裡的後臺介面使用@RequestMapping接收,並且使用@ResponseBody註解響應json資料。
接受請求引數時,檔案必須是@RequestParam MultipartFile file,且名稱為file,如果不進行更改指定的話。
然後第二個引數要與傳遞時的引數名一致。
然後呼叫若依自帶的工具類
ExcelUtil<KqXjcssz> util = new ExcelUtil<KqXjcssz>(KqXjcssz.class); List<KqXjcssz> xjcsszList = util.importExcel(file.getInputStream());
以及實體類上的註解
/** 工號 */ @Excel(name = "工號") private String gh;
等就能實現解析Excel的資料並獲取成物件的list。
這裡的匯入時的模板建議用下面的匯出的EXCEL作為匯入模板用。
然後上傳時點選下載模板時呼叫公共下載介面。
Excel匯出
頁面上新增匯出按鈕
<el-button type="warning" icon="el-icon-download" size="mini" @click="handleExport" v-hasPermi="['kqgl:bcgl:export']" >匯出</el-button>
匯出按鈕對應的處理方法
/** 匯出按鈕操作 */ handleExport() { const queryParams = this.queryParams; this.$confirm("是否確認匯出所有資料項?", "警告", { confirmButtonText: "確定", cancelButtonText: "取消", type: "warning", }) .then(function () { return exportBcgl(queryParams); }) .then((response) => { this.download(response.msg); }) .catch(function () {}); },
會彈窗提示,點選確定後執行exportBcgl方法,此方法是從外部js中引入
import { exportBcgl, } from "@/api/kqgl/bcgl";
在js方法中
export function exportBcgl(query) { return request({ url: '/kqgl/bcgl/export', method: 'get', params: query }) }
在此方法中傳送get請求給SpringBoot後臺介面。
其中request是來自request.js,封裝的axios傳送請求的物件。
在對應的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"); }
直接呼叫若依自帶的Excel工具類就可以實現匯出。
其中KqBcgl是對應的業務的實體類,可以使用程式碼生成工具去生成。
在實體類中通過添加註解的方式就能實現將此屬性匯出,如果不加此註解則不匯出
/** 編號 */ @Excel(name = "編號") private String bcbh;
而且註解裡面的name屬性就是匯出時那列的標題。
關於這個註解還有好多個屬性,具體可以參考其原始碼
public @interface Excel { /** * 匯出到Excel中的名字. */ public String name() default ""; /** * 日期格式, 如: yyyy-MM-dd */ public String dateFormat() default ""; /** * 讀取內容轉表示式(如:0=男,1=女,2=未知) */ public String readConverterExp() default ""; /** * 匯出型別(0數字 1字串) */ public ColumnType cellType() default ColumnType.STRING; /** * 匯出時在excel中每個列的高度 單位為字元 */ public double height() default 14; /** * 匯出時在excel中每個列的寬 單位為字元 */ public double width() default 16; /** * 文字字尾,如% 90 變成90% */ public String suffix() default ""; /** * 當值為空時,欄位的預設值 */ public String defaultValue() default ""; /** * 提示資訊 */ public String prompt() default ""; /** * 設定只能選擇不能輸入的列內容. */ public String[] combo() default {}; /** * 是否匯出資料,應對需求:有時我們需要匯出一份模板,這是標題需要但內容需要使用者手工填寫. */ public boolean isExport() default true; /** * 另一個類中的屬性名稱,支援多級獲取,以小數點隔開 */ public String targetAttr() default ""; /** * 欄位型別(0:匯出匯入;1:僅匯出;2:僅匯入) */ 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; } } }
還有一種情況是,在匯出前的查詢資料的方法,如果呼叫的是和查詢介面一樣的方法。
某些屬性比如某某狀態等需要用到字典表的列。在查詢介面可能就是直接查詢出來,返回值
直接就是1或者2等這些字典的值。然後返回給前端,前端再進行格式化顯示。
但是在匯出時必須要顯示對應的字典表的label,所以需要修改查詢資料的方法getBcListByNameToExport
將要查詢的表與字典表相關聯,查詢出其label值作為對應的屬性,如果有多個需要關聯字典表的屬性,則關聯兩次,下面是示例程式碼
<select id="getBcListByNameToExport" parameterType="KqBcgl" resultMap="KqBcglResult"> SELECT b.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 jxbclx FROM kq_bcgl b LEFT JOIN sys_dict_data s ON b.bclx = s.dict_value AND s.dict_type = "kq_kqgl_bcgl_bclx" LEFT JOIN sys_dict_data s1 ON b.jxbclx = s1.dict_value AND s1.dict_type = "kq_kqgl_bcgl_jxbclx" <where> <if test="bcmc != null and bcmc != ''"> and bcmc LIKE "%"#{bcmc}"%"</if> </where> </select>
那麼點選匯出按鈕就能實現匯出了