问题: 后端返回文件流,前端使用axios下载或者在线预览

下载文件流

import axios from 'axios'
// 设置响应类型为blob
axios.get('/api/app/xxx/downloadExcel', { responseType: 'blob' }).then(resp => {
    let temp = document.createElement('a') // 创建a标签
    temp.download = 'excel.xls'// 设置下载名称
    // 创建blob对象,在javascript中blob代表一个二进制流对象,不可修改
    const blob = new Blob([resp.data], {
        // 类型从响应头中获取
        type: resp.headers["content-type"]
    });
    // 创建对象url,并赋值给a标签
    let URL = window.URL || window.webkitURL;
    temp.href = URL.createObjectURL(blob);
    // 手动触发点击事件
    temp.click()
})

提示:document.createElement()方法创建的标签,不挂载到document树中,会自动销毁。不用担心内存问题。

在线预览pdf

import axios from 'axios'
axios('/api/app/xxx/pdf', { responseType: 'blob' }).then(res => {
    const blob = new Blob([res.data], { type: res.headers["content-type"] });
    var URL = window.URL || window.webkitURL;
    let href = URL.createObjectURL(blob);
    // 方法一:使用浏览器自带
    window.open(href)
    // 方法二:使用pdf.js(将pdf.js下载至项目pdf文件夹)
    this.pdfUrl = `/pdf/web/viewer.html?file=${encodeURIComponent(href)}`
})

后端工具类

package com.tons.utils;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLEncoder;
public class ResponseFileUtils {
    public static void responseFile(HttpServletResponse resp, File file) throws IOException {
        responseFile(resp, file, false);
    }
    public static void responseFile(HttpServletResponse resp, File file, boolean pdfDownload) throws IOException {
        // 错误处理
        if (!file.exists()) throw new RuntimeException(file.getAbsolutePath() + " 文件不存在");
        // 判断是否pdf
        int a = file.getName().toLowerCase().lastIndexOf('.');
        int b = file.getName().toLowerCase().indexOf("pdf");
        if (a < b && !pdfDownload) {
            // 允许浏览器预览
            resp.setHeader("content-type", "application/pdf;chartset=UTF-8");
            resp.setHeader("Content-Disposition", "fileName=" + URLEncoder.encode(file.getName(), "utf-8"));
        } else {
            resp.setHeader("content-type", "application/octet-stream");
            // attachment 告知浏览器,这个文件流应该是下载的
            resp.setHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode(file.getName(), "utf-8"));
        }
        // 读取文件,响应给浏览器
        ServletOutputStream out = resp.getOutputStream();
        FileInputStream in = new FileInputStream(file);
        int size = 0;
        byte[] data = new byte[1024];
        while (true) {
            int n = in.read(data, 0, data.length);
            if (n <= 0) break;
            size += n;
            out.write(data, 0, n);
        }
        resp.setContentLength(size); // 返回大小
    }
}

发表回复