Vue element ui結合java後臺匯出Excel(二進位制檔案流)

Are楊發表於2020-07-10

Vue結合後臺詳解匯入匯出Excel問題

今天講講 前臺Vue配合後臺(java)匯出Excel 後臺返回的資料是 二進位制檔案流 如何將此變為 彈框下載

當時開發呢,我們後臺是java 有控制元件 可以直接將資料匯出並生成Excel檔案,但是前後臺傳輸是不可能直接傳輸檔案的,是以二進位制檔案流進行傳輸的,此時呢就會遇到一個問題,因為是後臺,必然會涉及到許可權,許可權就涉及到token,token傳輸就會出現限制問題,所以我會列出三種方法

我的是Vue專案~~
1.不需要token的方法

 <template>
		 <div>
 		<el-button @click="downloadFile" type="primary">匯出 Excel</el-button> 
 		<iframe id="ifile" style="display:none"></iframe>
 	</div>
  </template>
  <script>
  methods:{
         // 匯出 Excel
         downloadFile() {
             var dom=document.getElementById('ifile');
             dom.src= this.downloadFileUrl +`/pay/exportExcel?userId=${this.form.userId}&orderNumber=${this.form.orderNumber}&stime=${this.form.stime}&etime=${this.form.etime}&status=${this.form.status}&payChannel=${this.form.payChannel}`;
         }
     },
 </script>

這個的意思呢就是寫一個類似的隱藏域 ifram 標籤獨有的特性 , 不明白的可以去W3cschool 查一查, 後面拼接的引數就是匯出條件,按個人需要進行,這個親測有效!

2.第二種就涉及到token了 , 就是使用javascript的內建物件來解析,方法就是使用axios請求 請求過來的二進位制檔案流進行解析

// 匯出 Excel
downloadFile() { // 這是methods中的方法
    downLoadPayListFn({...this.form}).then(res => { // 這個是我封裝的方法 就是通過axios請求進行攔截 新增token  form是data中的資料 也就是篩選條件 
		const fileName = '測試表格123.xls';
		if ('download' in document.createElement('a')) { // 非IE下載
            const blob = new Blob([res], {type: 'application/ms-excel'});
            const elink = document.createElement('a');
            elink.download = fileName;
            elink.style.display = 'none';
            elink.href = URL.createObjectURL(blob);
            document.body.appendChild(elink);
            elink.click();
            URL.revokeObjectURL(elink.href); // 釋放URL 物件
            document.body.removeChild(elink);
        }
    })
},

這個blob是js的內建物件 就是將其轉化為檔案 詳情解釋可以去查 blob

import fetch from 'utils/fetch';
import Qs from 'qs';

// 匯出資料
export function downLoadPayListFn(obj) {
    return fetch({
        url: '/admin/pay/exportExcel',
        method: 'get',
        params: obj,
        responseType: 'blob',
        /* header: {
            'Content-Type': "application/x-www-form-urlencoded; charset=utf-8"
        } */
    });
}

在這裡一定要加上  responseType: 'blob',否則不會生效 切記!!!!

看網上寫的是這個樣子 當然也根據後臺返回給你的資料進行展示 我們後臺返回的資料沒有進行包裝 所以直接就是response,搞就完事了.

3.第三種方法 使用form 表單提交 隱藏域使用

<template>
    <div id="rechargeRecord">
        <!-- 支付管理 -->
        <div class="title">
            <el-form  label-width="100px">
                <form class="form" :action="downloadFileUrl+`/pay/exportExcel`" method="post">
                    <input type="hidden" name="userId"      :value="form.userId">      <!-- 使用者id -->
                    <input type="hidden" name="orderNumber" :value="form.orderNumber"> <!-- 訂單單號 -->
                    <input type="hidden" name="stime"       :value="form.stime">       <!-- 時間 -->
                    <input type="hidden" name="etime"       :value="form.etime">       <!-- 時間 -->
                    <input type="hidden" name="status"      :value="form.status">      <!-- 交易狀態(1開始,2進行中,3失敗,4成功) -->
                    <input type="hidden" name="type"        :value="form.type">        <!-- 支付型別(1.扣除  2.返還 3.轉換 4.贈送) -->
                    <input type="hidden" name="ctimeState"  :value="form.ctimeState">  <!-- 建立時間狀態(1:正序、2:倒序) -->
                    <input type="hidden" name="payChannel"  :value="form.payChannel">  <!-- 支付渠道 -->
                    <input type="hidden" name="token"  :value="token">  <!-- 支付渠道 -->
                    <input type="submit" value="匯出 Excel"  @click="submitBtn(event)" class="submit" >
                </form>
            </el-form>
        </div>
    </div>
</template>
<script>
    import { getPayListFn, downLoadPayListFn } from 'api/game/money/rechargeRecord';
    import { mapGetters } from "vuex";
    import { getToken } from "utils/auth.js"; // 這是我自己封裝的方法 獲取token的方法
    export default {
        data(){
            return{
                form: {
                    pageIndex: 1, // 當前頁數
                    pageSize: 10, //請求行數
                    userId: '',   // 使用者id
                    orderNumber: '', // 訂單單號
                    stime: '', // 建立時間(開始)
                    etime: '', // 建立時間(結束)
                    status: '', // 交易狀態(1開始,2進行中,3失敗,4成功)
                    type:   '', // 支付型別(1.扣除  2.返還 3.轉換 4.贈送)
                    ctimeState: '', // 建立時間狀態(1:正序、2:倒序)
                    payChannel: '', // 支付渠道
                },
                token: getToken() , // 這裡獲取token
            }
        },
        // 頁面一載入的時候
        created() {
            this.getdata();
        },
        methods:{
            submitBtn(e) {
                e.preventDefault(); // 這個必須要有, 不然不生效
                return false; // 這個必須要有, 不然不生效
            }
        },
    }
</script>
<style rel="stylesheet/scss" scoped>
    .form {
        display: inline-block;
        border-color: #20a0ff;
        margin-left: 0.6rem;
    }
    .submit {
        line-height: 1;
        white-space: nowrap;
        cursor: pointer;
        background: #fff;
        border: 1px solid #c4c4c4;
        color: #1f2d3d;
        margin: 0;
        padding: 10px 15px;
        border-radius: 4px;
        border-color: #20a0ff;
    }
</style>

這個就需要後臺配合配置一下閘道器,如果有header中有token的話就去header中取 沒有的話就去引數中取,這個親測好使。

相關文章