最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Vue 前端導(dǎo)出后端返回的excel文件方式

 更新時(shí)間:2022年04月07日 10:49:18   作者:第二莊  
這篇文章主要介紹了Vue 前端導(dǎo)出后端返回的excel文件方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

前端導(dǎo)出后端返回的excel文件

在網(wǎng)上搜索了一番之后,決定采用Blob方式,這也是大家推薦的一種的方式,特此做下記錄。

頁面:

clipboard.png

先篩選,向后端請(qǐng)求接口返回excel文件,代碼如下:

    const apiUrl = this.Global.httpUrl + '/laima/export/new/exportTackOutOrder'
    console.log(this.form)
    let param = new URLSearchParams();
    param.append("startDate", "2019-01-01");
    param.append("endDate", "2019-02-01");
    this.$axios.post(apiUrl, param,{responseType: 'blob'}).then((res) => {
        console.log( res.data)
        const link = document.createElement('a')
        let blob = new Blob([res.data],{type: 'application/vnd.ms-excel'});
        link.style.display = 'none'
        link.href = URL.createObjectURL(blob);
        let num = ''
        for(let i=0;i < 10;i++){
            num += Math.ceil(Math.random() * 10)
        }
        link.setAttribute('download', '外賣統(tǒng)計(jì)_' + num + '.xlsx')
        document.body.appendChild(link)
        link.click()
        document.body.removeChild(link)
    })

仔細(xì)看axios請(qǐng)求加了個(gè)responseType: 'blob'配置,這是很重要的

clipboard.png

可以看到請(qǐng)求返回了一個(gè)Blob對(duì)象,你如果沒有正確的加上responseType: 'blob’這個(gè)參數(shù),返回的就不是個(gè)Blob對(duì)象,而是字符串了。

然后就自動(dòng)下載了! 

處理文件的下載(后端Excel導(dǎo)出)

大概有兩種方法(通常對(duì)應(yīng)的是需要不需要攜帶 token),原理都是通過 a 標(biāo)簽下載

  • 通過 Ajax 請(qǐng)求,拿到 response ,轉(zhuǎn)換為 blob 格式(主要是為了處理 type),為其生成下載鏈接,下載即可
  • 直接拼接 URL,拼出來對(duì)應(yīng)請(qǐng)求鏈接,直接訪問即可(不需要二次 token 認(rèn)證)

后端文件流

首先點(diǎn)擊導(dǎo)出 Excel ,這里調(diào)用接口成功

接下來看一下后臺(tái)返回的數(shù)據(jù)是什么樣,是文件流格式(OutputStream)

在處理之前,說幾個(gè)要注意的點(diǎn)?。?!

1.注意:后端在這里一般會(huì)設(shè)置如下幾個(gè)請(qǐng)求頭

后端還可能開啟 jwt token 驗(yàn)證,如果開啟請(qǐng)移步第 2 點(diǎn)請(qǐng)求攔截設(shè)置 headers

注意: 由于跨域?yàn)g覽器處于安全考慮不讓自定義響應(yīng)頭通過 JS 獲取 ,也就是說 Content-Disposition 前端在 Network 里是能看到的,但是無法通過 JS 獲取到,這里后端需要將其暴露出去

跨域情況默認(rèn)只暴露:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma 六個(gè)屬性

// 設(shè)置返回類型為excel
response.setContentType("application/vnd.ms-excel; charset=UTF-8");  
// 設(shè)置返回文件名為filename.xls 
response.setHeader("Content-Disposition", "filename.xls"); 
// 請(qǐng)求或響應(yīng)消息不能走緩存
response.setHeader("Cache-Control", "no-cache");
// 將Content-Disposition暴露出去,這樣就可以用過JS獲取到了
response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");

2.注意:前端在 Axios 請(qǐng)求和響應(yīng)攔截的時(shí)候,需要對(duì)其進(jìn)行處理

請(qǐng)求攔截一般我們都是會(huì)設(shè)置 headers,這里只是簡(jiǎn)單處理一下,實(shí)際會(huì)根據(jù)不同情況設(shè)置 headers

響應(yīng)攔截一般我們都是把 response.data 進(jìn)行返回,但是這里我們需要把整個(gè) response 返回(因?yàn)槲募?headers 里面)

import axios from 'axios'
import { getToken } from '@/utils/auth'
import { AUTHOR_KEY } from '@/global'
const service = axios.create({
  baseURL: process.env.NODE_ENV === 'development' ? '' : 'http://127.0.0.1:9999'
  withCredentials: true,
  timeout: 5000
})
// 請(qǐng)求攔截器
service.interceptors.request.use(
  config => {
    config.headers[AUTHOR_KEY] = getToken()
    return config
  },
  error => console.log(error)
)
// 響應(yīng)攔截器
service.interceptors.response.use(
  response => {
    if (response.config.responseType === 'blob') {
      return response
    }
    return response.data
  },
  error => console.log(error)
)
export default service

接下來要處理這個(gè)文件流,大概有兩種方法(通常對(duì)應(yīng)的是需要不需要攜帶 token),原理都是通過 a 標(biāo)簽下載

  • 通過 Ajax 請(qǐng)求,拿到 response ,轉(zhuǎn)換為 blob 格式(主要是為了處理 type),為其生成下載鏈接,下載即可
  • 拼接 URL,拼出來對(duì)應(yīng)請(qǐng)求鏈接,直接訪問即可

通過 Blob 下載

Blob 通常用于存儲(chǔ)大文件,典型的 Blob 內(nèi)容是一張圖片或一個(gè)音頻

默認(rèn)情況下 axios 不會(huì)處理二進(jìn)制數(shù)據(jù),即請(qǐng)求可以正常被瀏覽器接收,但 axios 不會(huì)去處理。需要在請(qǐng)求的時(shí)候設(shè)置 responseType: 'blob' 才可以

  • 拿到文件流之后,需要生成一個(gè) URL 才可以下載,可以通過URL.createObjectURL()方法生成一個(gè)鏈接
  • a 標(biāo)簽添加文件名
  • 正常情況下,通過 window.location = url 就可以下載文件。瀏覽器判斷這個(gè)鏈接是一個(gè)資源而不是頁面的時(shí)候,就會(huì)下載文件。但是通過文件流生成的 url 對(duì)應(yīng)的資源是沒有文件名的,需要添加文件名。這時(shí)候可以用到 download 屬性指定下載的文件名

由于有瀏覽器問題可能會(huì)出現(xiàn) content-disposition 匹配不到,最好做一下判斷看 content-disposition 和 Content-Disposition 哪個(gè)能取到 

const mimeMap = {
  xlsx: 'application/vnd.ms-excel',
  zip: 'application/zip',
}
export const toExcel = params => {
  return request({
    method: 'get',
    url: '/dayReportToExcel/toExcel',
    responseType: 'blob',
    params
  }).then(res => resolveBlob(res, mimeMap.xlsx))
export function resolveBlob(res, mimeType) {
  // 創(chuàng)建a標(biāo)簽,并處理二級(jí)制數(shù)據(jù)
  const aLink = document.createElement('a')
  const blob = new Blob([res.data], { type: mimeType })
  // 生成下載鏈接
  const URL = window.URL || window.webkitURL
  aLink.href = URL.createObjectURL(blob)
  // 設(shè)置下載文件名稱
  let fileName = ''
  if (res.headers['content-disposition']) fileName = res.headers['content-disposition']
  if (res.headers['Content-Disposition']) fileName = res.headers['Content-Disposition']
  aLink.setAttribute('download', fileName)
  // 下載
  document.body.appendChild(aLink)
  aLink.click()
  // 釋放URL對(duì)象
  window.URL.revokeObjectURL(aLink.href)
  document.body.removeChild(aLink)
}

注意:一般情況下文件名都是需要匹配的,后端傳過來的可能是這樣的,首選需要 decodeURI 解碼一下,再用正則把文件名匹配出來(替換設(shè)置下載文件名那里即可)

export function resolveBlob(res, mimeType) {
  const aLink = document.createElement('a')
  const blob = new Blob([res.data], { type: mimeType })
  const pat = new RegExp('filename=([^;]+\\.[^\\.;]+)')
  let contentDisposition
  if (res.headers['content-disposition']) contentDisposition = res.headers['content-disposition']
  if (res.headers['Content-Disposition']) contentDisposition = res.headers['Content-Disposition']
  const result = pat.exec(decodeURI(contentDisposition))
  let fileName = result && result[1]
  const URL = window.URL || window.webkitURL
  aLink.href = URL.createObjectURL(blob)
  // 如果Content-Disposition沒有暴露,給文件一個(gè)默認(rèn)名字
  if (fileName == null) fileName = '日?qǐng)?bào)表'
  aLink.setAttribute('download', fileName)
  document.body.appendChild(aLink)
  aLink.click()
  // 釋放URL對(duì)象
  window.URL.revokeObjectURL(aLink.href)
  document.body.removeChild(aLink)
}

拼接 URL 下載

如果可以直接通過 URL 下載文件,則可以不需要發(fā)送 Ajax 請(qǐng)求(前提是沒有 token、headers 驗(yàn)證),直接下載

可以使用 a 標(biāo)簽進(jìn)行下載

import qs from 'qs'
export function downloadExcel(params) {
  const url = window.location.origin + '/dayReportToExcel/toExcel?' + qs.stringify(params)
  const aLink = document.createElement('a')
  aLink.setAttribute('download', '')
  aLink.setAttribute('target', '_blank')
  aLink.href = url
  aLink.click()
}

可以使用 window.open(url, '_blank')

import qs from 'qs'
export function downloadExcel(params) {
  const url = window.location.origin + '/dayReportToExcel/toExcel?' + qs.stringify(params)
  window.open(url, '_blank')
}

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • vue?data中的return使用方法示例

    vue?data中的return使用方法示例

    當(dāng)一個(gè)組件被定義,data必須聲明為返回一個(gè)初始數(shù)據(jù)對(duì)象的函數(shù),因?yàn)榻M件可能被用來創(chuàng)建多個(gè)實(shí)例,下面這篇文章主要給大家介紹了關(guān)于vue?data中return使用,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-07-07
  • vue3中給數(shù)組賦值丟失響應(yīng)式的解決

    vue3中給數(shù)組賦值丟失響應(yīng)式的解決

    這篇文章主要介紹了vue3中給數(shù)組賦值丟失響應(yīng)式的解決方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • element el-table 表格限制多選個(gè)數(shù)功能

    element el-table 表格限制多選個(gè)數(shù)功能

    這篇文章主要介紹了element el-table 表格限制多選個(gè)數(shù)功能,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2024-03-03
  • vue開發(fā)拖拽進(jìn)度條滑動(dòng)組件

    vue開發(fā)拖拽進(jìn)度條滑動(dòng)組件

    這篇文章主要為大家詳細(xì)介紹了vue開發(fā)拖拽進(jìn)度條滑動(dòng)組件,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-09-09
  • 解決keep-alive同一個(gè)組件不緩存問題

    解決keep-alive同一個(gè)組件不緩存問題

    這篇文章給大家介紹了如何解決keep-alive同一個(gè)組件不緩存問題,文中通過代碼示例給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2024-02-02
  • 如何快速上手Vuex

    如何快速上手Vuex

    本文主要介紹了Javascript中Vuex的相關(guān)知識(shí)。具有很好的參考價(jià)值,下面跟著小編一起來看下吧
    2017-02-02
  • Vue前端生成UUID的方法詳解

    Vue前端生成UUID的方法詳解

    這篇文章主要給大家介紹了關(guān)于Vue前端生成UUID的相關(guān)資料,前端需要生成一個(gè)唯一標(biāo)識(shí)符作為ID時(shí),可以使用Vue UUID插件,比如生成訂單號(hào)、用戶ID等等,需要的朋友可以參考下
    2023-09-09
  • 詳解vue項(xiàng)目打包步驟

    詳解vue項(xiàng)目打包步驟

    這篇文章主要介紹了vue項(xiàng)目打包步驟,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • Vue循環(huán)組件加validate多表單驗(yàn)證的實(shí)例

    Vue循環(huán)組件加validate多表單驗(yàn)證的實(shí)例

    今天小編就為大家分享一篇Vue循環(huán)組件加validate多表單驗(yàn)證的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2018-09-09
  • Vue+Jwt+SpringBoot+Ldap完成登錄認(rèn)證的示例代碼

    Vue+Jwt+SpringBoot+Ldap完成登錄認(rèn)證的示例代碼

    本篇文章主要介紹了Vue+Jwt+SpringBoot+Ldap完成登錄認(rèn)證的示例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-05-05

最新評(píng)論

永靖县| 昌黎县| 怀来县| 揭东县| 卢湾区| 东台市| 土默特右旗| 临安市| 利川市| 蒲江县| 仪陇县| 尖扎县| 通城县| 布尔津县| 抚顺市| 临城县| 横山县| 临洮县| 图片| 商南县| 朝阳市| 福海县| 岗巴县| 临沭县| 上虞市| 弥渡县| 陆川县| 佛山市| 星子县| 潜山县| 德昌县| 安徽省| 越西县| 高清| 闽清县| 同心县| 鄂州市| 海城市| 高密市| 云龙县| 镇赉县|