springboot+vue实现页面下载文件

本文实例为大家分享了springboot+vue页面下载文件的具体代码,供大家参考,具体内容如下

1.前端代码:

<template v-slot:operate="{ row }">
   <vxe-button style="color: #409eff; font-weight: bolder" class="el-icon-download" title="成果下载" circle @click="downloadFile(row)"></vxe-button>
</template>
downloadFile(row) {
 window.location = "http://localhost:8001/file/downloadFile?taskId=" + row.id;
}

2.后端代码:

package com.gridknow.analyse.controller;

import com.alibaba.fastjson.JSON;
import com.gridknow.analyse.entity.DataInfo;
import com.gridknow.analyse.service.FileService;
import com.gridknow.analyse.utils.Download;
import com.gridknow.analyse.utils.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.List;
import java.util.Map;

/**
 * @ClassName FileController
 * @Description: TODO
 * @Author Administrator
 * @Date 2020/8/20 14:02
 * @Version TODO
 **/

@Controller
@RequestMapping("/file")
public class FileController {

 @Value("${gridknow.mltc.imgurl}")
 private String imgUrl;

 @Autowired
 private FileService fileService;

 @CrossOrigin
 @RequestMapping(value = "/upload", method = RequestMethod.POST)
 @ResponseBody
 public Result upload(MultipartHttpServletRequest request) {
  List<MultipartFile> multipartFiles = request.getFiles("file");
  Map<String, Object> map = (Map<String, Object>) JSON.parse(request.getParameter("body"));
  String companyId = request.getParameter("companyId");
  String companyName = request.getParameter("companyName");
  boolean bool = fileService.uploadAndInsert(multipartFiles, map, companyId, companyName);
  if (bool) {
   return new Result(200);
  } else {
   return new Result(500);
  }
 }

 @GetMapping("/downloadFile")
 public ResponseEntity<Object> downloadFile(@RequestParam("taskId") String taskId, HttpServletResponse response) {
  DataInfo dataInfo = fileService.queryTaskById(taskId);
  if (dataInfo == null) {
   return null;
  }
  File file = new File(dataInfo.getResponseUrl());
  // 文件下载
  if (file.isFile()) {
   return downloadFile(taskId);
  }
  // 文件夹压缩成zip下载
  if (file.isDirectory()) {
   String parent = file.getParent();
   // 创建临时存放文件夹
   File temDir = new File(parent + "/" + taskId);
   if (!temDir.exists()) {
    temDir.mkdirs();
   }
   // 将需要下载的文件夹和内容拷贝到临时文件夹中
   try {
    Download.copyDir(dataInfo.getResponseUrl(), parent + "/" + taskId);
   } catch (IOException e) {
    e.printStackTrace();
   }
   // 设置头部格式
   response.setContentType("application/zip");
   response.setHeader("Content-Disposition", "attachment; filename="+taskId+".zip");
   // 调用工具类,下载zip压缩包
   try {
    Download.toZip(temDir.getPath(), response.getOutputStream(), true);
   } catch (IOException e) {
    e.printStackTrace();
   }
   // 删除临时文件夹和内容
   Download.delAllFile(new File(parent + "/" + taskId));
  }
  return null;

 }

 public ResponseEntity<Object> downloadFile(String taskId) {
  DataInfo dataInfo = fileService.queryTaskById(taskId);
  if (dataInfo == null) {
   return null;
  }
  File file = new File(dataInfo.getResponseUrl());
  String fileName = file.getName();
  InputStreamResource resource = null;
  try {
   resource = new InputStreamResource(new FileInputStream(file));
  } catch (Exception e) {
   e.printStackTrace();
  }
  HttpHeaders headers = new HttpHeaders();
  headers.add("Content-Disposition", String.format("attachment;filename=\"%s", fileName));
  headers.add("Cache-Control", "no-cache,no-store,must-revalidate");
  headers.add("Pragma", "no-cache");
  headers.add("Expires", "0");
  ResponseEntity<Object> responseEntity = ResponseEntity.ok()
    .headers(headers)
    .contentLength(file.length())
    .contentType(MediaType.parseMediaType("application/octet-stream"))
    .body(resource);
  return responseEntity;
 }
}

工具类

package com.gridknow.analyse.utils;

import lombok.extern.slf4j.Slf4j;

import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * @ClassName Download
 * @Description: TODO
 * @Author Administrator
 * @Date 2020/9/2 9:54
 * @Version TODO
 **/
@Slf4j
public class Download {

 private static final int BUFFER_SIZE = 2 * 1024;

 public static void toZip(String srcDir, OutputStream out, boolean KeepDirStructure) throws RuntimeException {

  long start = System.currentTimeMillis();
  ZipOutputStream zos = null;
  try {
   zos = new ZipOutputStream(out);
   File sourceFile = new File(srcDir);
   compress(sourceFile, zos, sourceFile.getName(), KeepDirStructure);
   long end = System.currentTimeMillis();
   log.info("压缩完成,耗时:" + (end - start) + " ms");
  } catch (Exception e) {
   throw new RuntimeException("zip error from ZipUtils", e);
  } finally {
   if (zos != null) {
    try {
     zos.close();
    } catch (IOException e) {
     e.printStackTrace();
    }
   }
  }
 }

 /**
  * 递归压缩方法
  *
  * @param sourceFile  源文件
  * @param zos    zip输出流
  * @param name    压缩后的名称
  * @param KeepDirStructure 是否保留原来的目录结构, true:保留目录结构;
  *       false:所有文件跑到压缩包根目录下(注意:不保留目录结构可能会出现同名文件,会压缩失败)
  * @throws Exception
  *
  */

 private static void compress(File sourceFile, ZipOutputStream zos, String name, boolean KeepDirStructure)
   throws Exception {

  byte[] buf = new byte[BUFFER_SIZE];
  if (sourceFile.isFile()) {
   // 向zip输出流中添加一个zip实体,构造器中name为zip实体的文件的名字
   zos.putNextEntry(new ZipEntry(name));
   // copy文件到zip输出流中
   int len;
   FileInputStream in = new FileInputStream(sourceFile);
   while ((len = in.read(buf)) != -1) {
    zos.write(buf, 0, len);
   }
   // Complete the entry
   zos.closeEntry();
   in.close();
  } else {
   File[] listFiles = sourceFile.listFiles();
   if (listFiles == null || listFiles.length == 0) {
    // 需要保留原来的文件结构时,需要对空文件夹进行处理
    if (KeepDirStructure) {
     // 空文件夹的处理
     zos.putNextEntry(new ZipEntry(name + "/"));
     // 没有文件,不需要文件的copy
     zos.closeEntry();
    }
   } else {
    for (File file : listFiles) {
     // 判断是否需要保留原来的文件结构
     if (KeepDirStructure) {
      // 注意:file.getName()前面需要带上父文件夹的名字加一斜杠,
      // 不然最后压缩包中就不能保留原来的文件结构,即:所有文件都跑到压缩包根目录下了
      compress(file, zos, name + "/" + file.getName(), KeepDirStructure);
     } else {
      compress(file, zos, file.getName(), KeepDirStructure);
     }
    }
   }
  }
 }

 /**
  * 拷贝文件夹
  *
  * @param oldPath 原文件夹
  * @param newPath 指定文件夹
  */
 public static void copyDir(String oldPath, String newPath) throws IOException {
  File file = new File(oldPath);
  //文件名称列表
  String[] filePath = file.list();

  if (!(new File(newPath)).exists()) {
   (new File(newPath)).mkdir();
  }

  for (int i = 0; i < filePath.length; i++) {
   if ((new File(oldPath + File.separator + filePath[i])).isDirectory()) {
    copyDir(oldPath + File.separator + filePath[i], newPath + File.separator + filePath[i]);
   }

   if (new File(oldPath + File.separator + filePath[i]).isFile()) {
    copyFile(oldPath + File.separator + filePath[i], newPath + File.separator + filePath[i]);
   }

  }
 }

 /**
  * 拷贝文件
  *
  * @param oldPath 资源文件
  * @param newPath 指定文件
  */
 public static void copyFile(String oldPath, String newPath) throws IOException {
  File oldFile = new File(oldPath);
  File file = new File(newPath);
  FileInputStream in = new FileInputStream(oldFile);
  FileOutputStream out = new FileOutputStream(file);;

  byte[] buffer=new byte[2097152];

  while((in.read(buffer)) != -1){
   out.write(buffer);
  }
  in.close();
  out.close();
 }

 /**
  * 删除文件或文件夹
  * @param directory
  */
 public static void delAllFile(File directory){
  if (!directory.isDirectory()){
   directory.delete();
  } else{
   File [] files = directory.listFiles();

   // 空文件夹
   if (files.length == 0){
    directory.delete();
    System.out.println("删除" + directory.getAbsolutePath());
    return;
   }

   // 删除子文件夹和子文件
   for (File file : files){
    if (file.isDirectory()){
     delAllFile(file);
    } else {
     file.delete();
     System.out.println("删除" + file.getAbsolutePath());
    }
   }

   // 删除文件夹本身
   directory.delete();
   System.out.println("删除" + directory.getAbsolutePath());
  }
 }

}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • springboot+vue实现文件上传下载

    本文实例为大家分享了springboot+vue实现文件上传下载的具体代码,供大家参考,具体内容如下 一.文件上传(基于axios的简单上传) 所使用的技术:axios.springboot.vue; 实现思路:通过h5 :input元素标签进行选择文件,获取所选选择的文件路径,new fromdata对象,设置fromdata的参数,设置axios对应的请求头,最后通过axios发送post请求后端服务.后端服务同过MultipartFile进行文件接收.具体代码如下: 前端代码: 1.创建v

  • springboot整合vue实现上传下载文件

    springboot整合vue实现上传下载文件,供大家参考,具体内容如下 环境 springboot 1.5.x 完整代码下载:springboot整合vue实现上传下载 1.上传下载文件api文件 设置上传路径,如例子: private final static String rootPath = System.getProperty("user.home")+File.separator+fileDir+File.separator; api接口: 下载url示例:http://l

  • springboot+vue实现页面下载文件

    本文实例为大家分享了springboot+vue页面下载文件的具体代码,供大家参考,具体内容如下 1.前端代码: <template v-slot:operate="{ row }"> <vxe-button style="color: #409eff; font-weight: bolder" class="el-icon-download" title="成果下载" circle @click="

  • vue+django实现下载文件的示例

    一.概述 在项目中,点击下载按钮,就可以下载文件. 传统的下载链接一般是get方式,这种链接是公开的,可以任意下载. 在实际项目,某些下载链接,是私密的.必须使用post方式,传递正确的参数,才能下载. 二.django项目 本环境使用django 3.1.5,新建项目download_demo 安装模块 pip3 install djangorestframework django-cors-headers 修改文件download_demo/settings.py INSTALLED_APP

  • SpringBoot上传和下载文件的原理解析

    技术概述 我们的项目是实现一个论坛.在论坛上发布博客时应该要可以上传文件,用户阅读博客是应该要可以下载文件.于是我去学习了SpringBoot的上传和下载文件,我感觉技术的难点在于使用图床并隐藏文件真实的存放地址. 技术详述 针对使用自己的服务器作为图床, 首先配置WebMvcConfigurer,SpringBoot2.0以后的版本可以使用WebMvcConfigurer实现类方式来进行配置 即创建一个实体类实现WebMvcConfigurer接口 public class WebConfig

  • 前端vue a链接下载文件失败的问题(未发现文件)

    目录 前端vue a链接下载文件失败(未发现文件) 错误案例 完整代码 vue点击下载的避坑指南 引入 避坑之路 blob对象 前端vue a链接下载文件失败(未发现文件) 错误案例 发现出现错误后,我们去下载内容里面看我们下载这个文件的地址 ps:ctrl + j  打开下载内容的快捷键   适用于 windows系统 可以发现这个文件夹路径不对  识别不了 我把路径写在根目录下面了 src/assets/...  ,应该把你需要下载的文件放在跟src同级的目录下或者放在publice目录里面

  • vue + axios get下载文件功能

    本文实例为大家分享了vue + axios 下载文件的具体代码,供大家参考,具体内容如下 这里是axios的get方法.post方法请点击这里=>here 注意点: Herder 请求头需注意 content-disposition:"attachment;filename=total.xls" content-type:"application/x-download;charset=utf-8" axios请求的responseType为blob respo

  • vue中如何下载文件导出保存到本地

    目录 vue下载文件导出保存到本地 另一种情况 vue中a标签下载本地文件-未找到,原因及解决 错误代码 原因 解决 vue下载文件导出保存到本地 先分析如何下载:先有一个链接地址,然后使用 location.href或window.open()下载到本地 看看返回数据 res.config.url 中是下载链接地址,res.data 中是返回的二进制数据 如何下载 ... <el-button icon="el-icon-download" @click="downl

  • Vue 中批量下载文件并打包的示例代码

    思路: 用 ajax 将文件下载, 然后用 jszip 压缩文件, 最后用 file-saver 生成文件 1. 准备工作 安装 3 个依赖: axios, jszip, file-saver yarn add axios yarn add jszip yarn add file-saver 2. 下载文件 import axios from 'axios' const getFile = url => { return new Promise((resolve, reject) => { a

  • vue单页面打包文件大?首次加载慢?nginx带你飞,从7.5M到1.3M蜕变过程(推荐)

    找到nginx多网站配置文件:类似 nginx/sites-available/www.baidu.com server { listen 80; index index.html index.htm index.nginx-debian.html; server_name www.baidu.com; location / { root /mnt/www/www.baidu.com; try_files $uri $uri/ /index.html; } } 参考页面:https://rout

  • vue项目页面的打印和下载PDF加loading效果的实现(加水印)

    目录 vue页面的打印和下载PDF(加水印) vue项目页面的打印 vue项目页面下载PDF 封装异步PDF下载函数并添加loading效果 总结 vue页面的打印和下载PDF(加水印) vue项目页面的打印 打印的不用说,调用 window.print() 的方法即可: 注意点:如果用到背景图的话,需要CSS中添加设置: // 标签看哪些地方用到背景图就加哪些,不然调打印机会把背景图隐藏掉 div { // webkit 为Google Chrome Safari 等浏览器内核 -webkit

随机推荐