若依管理系統前后端分離版基於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>

 

那么點擊導出按鈕就能實現導出了

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM