国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

vue導(dǎo)出文件流獲取附件名稱并下載(在response.headers里解析filename導(dǎo)出)

這篇具有很好參考價值的文章主要介紹了vue導(dǎo)出文件流獲取附件名稱并下載(在response.headers里解析filename導(dǎo)出)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報違法"按鈕提交疑問。

需求

  之前實(shí)現(xiàn)的導(dǎo)出都是各自的業(yè)務(wù)層,調(diào)用接口,使用blob對象轉(zhuǎn)換,最終a標(biāo)簽導(dǎo)出,需要自定義文件名跟文件后綴。
  現(xiàn)在統(tǒng)一在攔截器配置,根據(jù)后端返回的response.headers解析是否是文件流,統(tǒng)一做配置處理,然后對后端返回的filename進(jìn)行轉(zhuǎn)碼,后端統(tǒng)一配置文件名及類型。前端只管a標(biāo)簽下載即可。

以往實(shí)現(xiàn)的方法(各自的業(yè)務(wù)層寫方法)

//數(shù)據(jù)導(dǎo)出
    indexExport() {
      let statYear = {
        statDate: this.form.statDate,
        dataType: "1",
      };
      let infoMsg = this.$notify.info({
        title: "消息",
        message: "正在下載文件,勿退出,請稍后",
        duration: 0,
      });
      gljyjcDataExport(statYear).then((res) => {
        infoMsg.close(); //下載成功,等待下載提示框關(guān)閉
        this.$notify({
          title: "成功",
          message: "下載完成",
          type: "success",
        });
        let blob = new Blob([res], {
          type: "",
        });
        let url = window.URL.createObjectURL(blob);
        const link = document.createElement("a"); // 創(chuàng)建a標(biāo)簽
        link.href = url;
        link.download = "數(shù)據(jù)清單(" + this.form.statDate + ").xlsx"; // 重命名文件
        link.click();
        URL.revokeObjectURL(url); // 釋放內(nèi)存
      });
    },

現(xiàn)在實(shí)現(xiàn)的方法(axios里攔截器統(tǒng)一配置處理)

主要看注釋行“文件下載”,因?yàn)楹蠖朔祷亓魑募r候攜帶的response.headers會多Content-Disposition這個字段。然后拿到里邊的filename后,對filename包含的信息進(jìn)行轉(zhuǎn)碼就可
decodeURIComponent、decodeURI都可進(jìn)行轉(zhuǎn)碼,具體二者有啥區(qū)別,水平有限沒大看懂,可自行百度查閱符合選項(xiàng)

//攔截器里肯定有請求攔截代碼axios.interceptors.request。怕展示代碼冗余就不多貼了
...
axios.interceptors.response.use(
    response => {
    
        const res = response.data;
        const config = response.config;
        console.log(response.headers,"response.headers")//這塊可以看一下response.headers究竟是什么
        // 文件下載(主要看這塊)
        if (response.headers['content-disposition']) {
            let downLoadMark = response.headers['content-disposition'].split(';');
            if (downLoadMark[0] === 'attachment') {
                // 執(zhí)行下載
                let fileName = downLoadMark[1].split('filename=')[1];
                if (fileName) {
                    //fileName = decodeURIComponent(filename);//對filename進(jìn)行轉(zhuǎn)碼
                    fileName = decodeURI(fileName);
                    if (window.navigator.msSaveOrOpenBlob) {
                        navigator.msSaveBlob(new Blob([res]), fileName);
                    } else {
                        let url = window.URL.createObjectURL(new Blob([res]));
                        let link = document.createElement('a');
                        link.style.display = 'none';
                        link.href = url;
                        link.setAttribute('download', fileName);
                        document.body.appendChild(link);
                        link.click();
                        return;
                    }
                } else {
                    return res;
                }
            }
        }

        // 全局異常處理(獲取code做正常的攔截操作,根據(jù)自己的業(yè)務(wù)層code寫符合的就可)
        if (res.code !== CODE_SUCCESS) {
            if (res.code == '205') {
                Message.error({ message: res.data || "登錄失敗" });
                store.dispatch("user/logout").then(() => {
                    window.location.reload();
                  });
                return
            }
            if (res.code === WARN_TIP) {
                Message.warning({
                    message: res.message
                });
            }

            if (res.code === LOGIN_FAIL) {
                Message.error({ message: res.message || "登錄失敗" });
            }
            // 其他狀態(tài)碼特殊處理
            return Promise.reject(new Error(res.message || "Error"));
        }

        return res;
    }, error => {
        // 防重復(fù)提交
        if (error.message) {
            allowRequest(reqList, error.message.url);
        }
        if (error.response) {
            if (error.response.data.code == 600 && !tipCode) {
                tipCode = true;
                Message.error({ message: '系統(tǒng)登錄身份令牌失效,請重新登錄!' });
            } else if (error.response.status == 500) {
                Message.error({ message: '系統(tǒng)異常' });
            }
        }
        return Promise.reject(error);
    }
);

vue導(dǎo)出文件流獲取附件名稱并下載(在response.headers里解析filename導(dǎo)出),vue,vue.js,前端,javascript
vue導(dǎo)出文件流獲取附件名稱并下載(在response.headers里解析filename導(dǎo)出),vue,vue.js,前端,javascript

以上是未解析之前瀏覽器看到的文件夾名
經(jīng)過decodeURIComponent或decodeURI解析后,前端就能獲取到后端返回的中文文件名了。

vue導(dǎo)出文件流獲取附件名稱并下載(在response.headers里解析filename導(dǎo)出),vue,vue.js,前端,javascript

把文章鏈接復(fù)制粘貼給后端,讓大佬自己賞閱。

截止目前,前端能干的活就到此為止了。
那么有人就想問了,那后端response.headers里沒返回我想要的Content-Disposition,前端怎么捕獲。
對此呢,我又找我們后端大佬要了一下后端實(shí)現(xiàn)的代碼,我就原封不動貼出來了,因?yàn)槲腋究床欢f的是什么意思

Controller端代碼(啥是Controller,根本不懂)
 @PostMapping(value="/exportAddresses")
    public Result exportAddresses(HttpServletResponse response){
        String[] titles = new String[] {"id","tableCode","columnName"};
        List<Map<String,Object>> objList = new ArrayList<>();
        DownLoadFileController addressService;
        List<NpColumns> npColumnsList = npColumnsService.findByTableCode("APP_TASK_CASE_INFO");
        for(NpColumns item : npColumnsList){
            Map<String,Object> tempMap = new HashMap<>();
            tempMap.put("id", item.getId());
            tempMap.put("tableCode", item.getTableCode());
            tempMap.put("columnName", item.getColumnName());
            objList.add(tempMap);
        }
        try {
            FileUtils.exportExcel(response,"地址樹",titles,objList);
            return ResultGenerator.genSuccessResult("導(dǎo)出成功!");
        }catch (Exception e){
            e.printStackTrace();
            return ResultGenerator.genFailResult("導(dǎo)出失??!");
        }
    }
工具類方法(啥是工具類,也不懂)
public static void exportExcel(HttpServletResponse response,String fileName,String[] titles,List<Map<String,Object>> result){
        HSSFWorkbook wb;
        OutputStream output = null;
        String tempName = fileName;
        try {
            Date date = new Date();
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
            fileName +="_"+df.format(date)+".xls";
            String encodedFilename = URLEncoder.encode(fileName, "UTF-8");
            wb= new HSSFWorkbook();
            HSSFSheet sh = wb.createSheet();
            // 設(shè)置列寬
            for(int i = 0; i < titles.length-1; i++){
                sh.setColumnWidth( i, 256*15+184);
            }
            // 第一行表頭標(biāo)題,CellRangeAddress 參數(shù):行 ,行, 列,列
            HSSFRow row = sh.createRow(0);
            HSSFCell cell = row.createCell(0);
            cell.setCellValue(new HSSFRichTextString(tempName));
            //cell.setCellStyle(fontStyle(wb));
            sh.addMergedRegion(new CellRangeAddress(0, 0, 0,titles.length-1));
            // 第二行
            HSSFRow row3 = sh.createRow(1);
            // 第二行的列
            for(int i=0; i < titles.length; i++){
                cell = row3.createCell(i);
                cell.setCellValue(new HSSFRichTextString(titles[i]));
                //cell.setCellStyle(fontStyle(wb));
            }
            //填充數(shù)據(jù)的內(nèi)容  i表示行,z表示數(shù)據(jù)庫某表的數(shù)據(jù)大小,這里使用它作為遍歷條件
            int i = 2, z = 0;
            while (z < result.size()) {
                row = sh.createRow(i);
                Map<String,Object> map = result.get(z);
                for(int j=0;j < titles.length;j++) {
                    cell = row.createCell(j);
                    if(map.get(titles[j]) !=null) {
                        cell.setCellValue(map.get(titles[j]).toString());
                    }else {
                        cell.setCellValue("");
                    }
                }
                i++;
                z++;
            }
            output = response.getOutputStream();
            response.reset();
            response.addHeader("Content-Type","application/octet-stream;charset=utf-8");
            response.setHeader("Content-disposition", "attachment; filename="+encodedFilename);
            response.setContentType("application/msexcel");
            wb.write(output);
            output.flush();
            output.close();
        }catch (Exception e){
            e.printStackTrace();
        }
    }
最后還有個中文處理亂碼那塊(這都是啥啥啥,還是不懂)
String encodedFilename = URLEncoder.encode(fileName, "UTF-8");設(shè)置文件名的中文編碼
response.addHeader("Content-Type","application/octet-stream;charset=utf-8");//這里也設(shè)置了相同的編碼格式
response.setHeader("Content-disposition", "attachment; filename="+encodedFilename);

大家有更好的實(shí)現(xiàn)方案話歡迎多交流文章來源地址http://www.zghlxwxcb.cn/news/detail-660395.html

到了這里,關(guān)于vue導(dǎo)出文件流獲取附件名稱并下載(在response.headers里解析filename導(dǎo)出)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Spring Boot學(xué)習(xí)隨筆- 文件上傳和下載(在線打開、附件下載、MultipartFile)

    Spring Boot學(xué)習(xí)隨筆- 文件上傳和下載(在線打開、附件下載、MultipartFile)

    學(xué)習(xí)視頻:【編程不良人】2021年SpringBoot最新最全教程 文件上傳是指將文件從客戶端計算機(jī)傳輸?shù)椒?wù)器的過程。 上傳思路 前端的上傳頁面:提交方式必須為 post , enctype 屬性必須為 multipart/form-data 開發(fā)后端的Controller 后端方法接收參數(shù)必須和前端標(biāo)簽的name名一致 upload.js

    2024年02月04日
    瀏覽(48)
  • uniapp下載附件保存到手機(jī)(文件、圖片)ios兼容

    downloadFile(file) ,其中 file 為下載的文件地址 uni.downloadFile 圖片 使用 uni.saveImageToPhotosAlbum 【安卓、ios都合適】 文件 使用 uni.openDocument 【安卓圖片也可以用這個,ios會失敗】

    2024年02月06日
    瀏覽(25)
  • java實(shí)現(xiàn)瀏覽器下載附件時文件名中文亂碼解決方案

    方案一:URLEncoder 解決 IE 和 谷歌瀏覽器的附件中文名問題。 如果客戶端瀏覽器是 IE 瀏覽器 或者 是谷歌瀏覽器。我們需要使用 URLEncoder 類先對中文名進(jìn)行 UTF-8 的編碼 操作。 因?yàn)?IE 瀏覽器和谷歌瀏覽器收到含有編碼后的字符串后會以 UTF-8 字符集進(jìn)行解碼顯示。 方案二:B

    2024年03月09日
    瀏覽(86)
  • vue前端獲取項(xiàng)目下的靜態(tài)資源文件夾中的文件并下載

    vue前端獲取項(xiàng)目下的靜態(tài)資源文件夾中的文件并下載

    前端項(xiàng)目/public/static/image文件夾下,兩張圖片,因?yàn)椴粫?jīng)常改變所以做成靜態(tài)資源 從項(xiàng)目中獲取這兩張圖片 html: 前端項(xiàng)目的 publicstaticfaultFile文件夾中放入模板文件: 實(shí)現(xiàn)效果: 代碼: 前端下載使用 a 標(biāo)簽的自帶的download下載 參考文章:require.context()的用法詳解

    2024年02月12日
    瀏覽(92)
  • vue 中從后端獲取到文件的 url 地址,前端根據(jù) url 地址下載文件

    vue 中從后端獲取到文件的 url 地址,前端根據(jù) url 地址下載文件

    項(xiàng)目用的是 vben admin 框架,用的是 vue3 + TS 項(xiàng)目需求數(shù)據(jù)導(dǎo)出功能,前端需要實(shí)現(xiàn)文件下載功能 后端返回的是文件的 url 地址 (本項(xiàng)目中返回的是阿里云 oss 的文件地址) 從后端得到的是一個 url 地址,先通過 fetch api 請求這個 url 地址并轉(zhuǎn)換成 blob 對象,通過 URL.createObjectUrl() 將 blo

    2024年02月06日
    瀏覽(27)
  • Java獲取文件的后綴名稱

    ??? 使用lastIndexOf()方法,找到文件名中最后一個點(diǎn)的位置, ??? 然后使用substring()方法,獲取點(diǎn)后面的字符串作為文件后綴名。 參考:java獲取文件后綴名怎么操作_千鋒教育

    2024年01月21日
    瀏覽(12)
  • 【java】如何獲取整個文件夾的文件名稱

    需求 有時候我們需要一個文件夾里的所有文件的名稱我們只能截圖,然后再使用微信提取出其中的文字,這樣是比較麻煩的,今天給大家介紹使用java提取所有文件的名字,代碼如下:

    2024年02月14日
    瀏覽(88)
  • 【前端】根據(jù)后端返回的url進(jìn)行下載并設(shè)置文件下載名稱

    ????????在我們項(xiàng)目當(dāng)中存儲文件是存儲到廠商的服務(wù)器上的,然后廠商返回一個可以直接下載url地址,但是前端使用這個url下載的時候永遠(yuǎn)都是保存一個名字,這時候我們就需要設(shè)置文件保存的名稱, ????????那么如何實(shí)現(xiàn)呢?使用了fetch將url轉(zhuǎn)換成了blob即可。 代碼

    2024年02月04日
    瀏覽(27)
  • Request Headers和Response Headers中的Content-Type以及ResponseType

    Request Headers和Response Headers中的Content-Type以及ResponseType

    HTTP請求響應(yīng)過程中的Content-type你真的清楚嗎 詳解get與post請求方式、content-type與responseType、@Requestbody與@Requestparam的使用場景 axios配置請求頭content-type淺談 HTTP 請求頭中的Content-Type類型 背景: Request Headers中的Content-Type: XMLHttpRequest 的 responseType 屬性 Response Headers中的Content-Type R

    2024年02月13日
    瀏覽(25)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包