VUE vue-resource下载文件

目录

流的方式

后端代码

前端代码

其他几种方式


网上寻觅半晌,发现解决方案很多,但是能够满足要求的寥寥无几。

我需要做的是能够下载文件并且能够在后端指定文件名,In fact, It's very easy! e ha。

流的方式

后端代码

  • 获取response 对象:

方式较多,可以直接取controller方法中的response对象

RequestAttributes attributes = RequestContextHolder.currentRequestAttributes(); if (attributes instanceof ServletRequestAttributes) { HttpServletResponse response = ((ServletRequestAttributes) attributes).getResponse();

  • 设置响应头:
//将文件中文编码为字母数字,在前端获取后进行解码
String fileName = URLEncoder.encode(fileName, "UTF-8");
//让前端获取自定义的响应头(Attachment-Name)
response.setHeader("Access-Control-Expose-Headers","Attachment-Name");
response.setHeader("Attachment-Name", fileName + ".xlsx");
  • 参数接收
@PostMapping("/goods/saleInfo/export")
public void exportExcel(@RequestBody SaleInfoDto saleInfoDto) {
      //TODO:根据参数请求数据
      //TODO:设置响应头
      //TODO:设置响应体
      //TODO:刷新并关闭响应数据流
}
  • 参数接收对象
@Data
class SaleInfoDto{
    private String area;
}

前端代码

  • 构建请求体
var params = {
  area:'河南'
}
  • 发起POST请求
var url = "/goods/saleInfo/export";
this.$http.post(url, params, {
    responseType: "arraybuffer"
  }).then(function (response) {
    console.log(response);
    if ((response.ok = true)) {
      //获取自定义文件名
      var fileName = response.headers.map["attachment-name"][0];
      //生成Blob对象,通过创建的a标签点击下载
      var objectUrl = URL.createObjectURL(new Blob([response.data]));
      var link = document.createElement("a");
      console.log(link);
      link.download = decodeURIComponent(fileName);
      link.href = objectUrl;
      link.click();
    } else {
      this.$message({
        type: "info",
        message: "下载响应异常"
      });
    }
  }).catch(function (error) {
    console.log(error);
    this.$message({
      type: "info",
      message: "下载出现异常"
    });
  });

responseType: "arraybuffer")如果不加的话依然可以下载下来文件,但是发现会比实际的文件大几kb,并且 文件打不开!

decodeURIComponent(fileName);)将后端编码后的文件名解码为真实的文件名,可以有效防止中文乱码。

  • 发起GET请求

   var url = "/goods/saleInfo/export";
   this.$http.get(url,{

         params: params,
         responseType: "arraybuffer"
      }).then(function (response) {

   ...................................

   @GetMapping("/goods/saleInfo/export")
   public void exportExcel(SaleInfoDto saleInfoDto) {
      //TODO:根据参数请求数据
      //TODO:设置响应头
      //TODO:设置响应体
      //TODO:刷新并关闭响应数据流
   }

其他几种方式

let url = "/goods/saleInfo/export?area=河南"
let iframe = document.createElement('iframe')
iframe.src = url
iframe.style.display = 'none'
document.body.appendChild(iframe)

let url = "/goods/saleInfo/export?area=河南"
let link = document.createElement('a')
link.href = url 
link.style.display = 'none'
document.body.appendChild(link)
link.click()

let url = "/goods/saleInfo/export?area=河南"
window.open(url, '_blank');

无论上面的哪种方式,其原理是类似的,相当于由浏览器来直接解析响应头和响应数据流。此时response响应头信息配置如下:

String tmpFileName = fileName == null ? "export" : new String(fileName.getBytes("gbk"), "iso8859-1");
response.setHeader("Content-Disposition", "attachment; filename=" + tmpFileName + ".xlsx");
response.setContentType("multipart/form-data");

 

你可能感兴趣的:(vue-resource,vue,文件下载)