1. 程式人生 > 實用技巧 >若依管理系統前後端分離版基於ElementUI和SpringBoot怎樣實現Excel匯入和匯出

若依管理系統前後端分離版基於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-upload
        
ref="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>

那麼點選匯出按鈕就能實現匯出了