SpringBoot之结合前端Axios及其他多种方式下载文件

news/2024/7/10 2:32:46 标签: spring boot, 前端, 后端, vue, axios

SpringBoot之结合前端Axios及其他多种方式下载文件

文章目录

  • SpringBoot之结合前端Axios及其他多种方式下载文件
  • 1. 后端
    • 1. 文件下载工具类
    • 2. 文件下载controller
  • 2. 前端多种方式下载
    • 1. 下载方式1(a标签)
    • 2. 下载方式2(window.location.href)
    • 3. 下载方式3(axios)
    • 4. 使用fileDownload插件

1. 后端

spring boot工程为例进行文件下载

1. 文件下载工具类

package com.yuan.utils;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;

/**
 * @Description: 文件操作工具类
 * @Author: 袁金生
 * @CreateTime: 2022-11-15 14:56
 * @LastEditors: 袁金生
 * @LastEditTime: 2022-11-15 14:56
 */
@Slf4j
public class FileUtil {
    /**
     * 文件下载
     *
     * @param response 响应对象
     * @param fileName 文件全名
     * @param filePath 文件路径(路径+文件名)
     */
    public final static void fileDownload(HttpServletResponse response, String fileName, String filePath) {
        OutputStream outputStream = null;
        try {
            File saveFile = new File(filePath);
            if (saveFile.exists()) {
                //设置返回类型
                response.setContentType("application/octet-stream");
                //对文件名称进行编码,解决文件名称中中文乱码问题
                response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
                //获取文件输入流字节数组,这里使用的是org.apache.commons.io.FileUtil工具类
                byte[] byteArray = FileUtils.readFileToByteArray(saveFile);
                //输入流转输出流返回给客户端
                outputStream = new BufferedOutputStream(response.getOutputStream());
                if (byteArray != null && byteArray.length > 0) {
                    outputStream.write(byteArray);
                }
            } else {
                //设置头信息
                response.setContentType("text/html;charset=utf-8");
                PrintWriter writer = response.getWriter();
                writer.write("[" + fileName + "]文件不存在!");
                log.warn("[{}]文件不存在!", fileName);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (outputStream != null) {
                try {
                    outputStream.flush();
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        log.info("下载完成:{}", fileName);
    }
}

2. 文件下载controller

package com.yuan.wechat.controller;

import com.yuan.utils.ApiResult;
import com.yuan.utils.FileUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletResponse;

/**
 * <p>
 * 通用跳转前端控制器
 * </p>
 *
 * @author 袁金生
 * @since 2022-11-02
 */
@RestController
@RequestMapping("/wechat")
public class CommonController {

    /**
     * 通用跳转
     *
     * @param pageName
     * @return
     */
    @RequestMapping("/toPage")
    public ModelAndView toPage(@RequestParam String pageName) {
        return new ModelAndView(pageName);
    }

    @GetMapping("/downloadReport")
    public Object downloadReport(@RequestParam("reportName") String reportName, @RequestParam("reportPath") String reportPath, HttpServletResponse response) {
        if (StringUtils.isBlank(reportName) || StringUtils.isBlank(reportPath)) {
            return ApiResult.error("报告名或报告路径不能为空");
        }
        String diskFilePath = reportPath + reportName;
        FileUtil.fileDownload(response, reportName, diskFilePath);
        return null;
    }
}

2. 前端多种方式下载

前端是基于springboot单体下结合vue+axios进行下载

1. 下载方式1(a标签)

const downloadReport = (reportName, reportPath) => {
        console.log("下载报告reportName===1》", reportName)
        console.log("下载报告reportPath===1》", reportPath)
        reportName = "Java开发手册(黄山版).pdf";
        reportPath = "D:/aa/files/"
       /* const url = ctxPath + '/wechat/downloadReport?reportName='+reportName+'&reportPath='+reportPath
        let link = document.createElement('a');
        link.href = url
        //link.download = item.fileName || '下载文件';//下载后文件名
        document.body.appendChild(link);
        link.click();//点击下载
        link.remove();//下载完成移除元素
        window.URL.revokeObjectURL(link.href); //用完之后使用URL.revokeObjectURL()释放;*/
        // 上述请求也可以按以下方式完成(可选)
        axios.get(ctxPath + '/wechat/downloadReport', {
            params: {
                reportName,
                reportPath
            },
            responseType: 'blob',//响应类型为流
            onDownloadProgress: (ProgressEvent) => {//用来计算下载量(实际项目中可以用来显示下载进度)
                let total = item.fileLength;
                console.log(total);
                let load = ProgressEvent.loaded;
                console.log(load);
            }
        }).then(function (resp) {
            console.log("resp",resp);
            if (resp) {
                let blob = new Blob([resp]);//处理文档流
                let url = window.URL.createObjectURL(blob);
                let link = document.createElement('a');
                link.href = url
                link.download = reportName || '下载文件';//下载后文件名
                document.body.appendChild(link);
                link.click();//点击下载
                link.remove();//下载完成移除元素
                window.URL.revokeObjectURL(link.href); //用完之后使用URL.revokeObjectURL()释放;
            } else {
                console.error('文件下载失败,请重试!');
            }
        }).catch(function (error) {
            console.log(error);
        }).finally(() => {
            //请求结束回调
        })
        // http://localhost:7001/lims/wechat/toPage?pageName=wechat/tabbar
        //window.location.href = ctxPath + "wechat/toPage?pageName=wechat/pdfView";
    };

2. 下载方式2(window.location.href)

const downloadReport = (reportName, reportPath) => {
        console.log("下载报告reportName===1》", reportName)
        console.log("下载报告reportPath===1》", reportPath)
        reportName = "Java开发手册(黄山版).pdf";
        reportPath = "D:/aa/files/"
        window.location.href = ctxPath + '/wechat/downloadReport?reportName='+reportName+'&reportPath='+reportPath
    };

axios_197">3. 下载方式3(axios)

  1. 案例1,文件名从响应对象中获取
const downloadReport = () => {
        axios(ctxPath + '/generator/genCloudCode', {
            method: 'post', // 默认值get
            data: {...cloudForm},
            //更多配置查看官网 https://www.axios-http.cn/docs/req_config
            responseType: 'blob',//表示浏览器将要响应的数据类型(默认json),选项包括 'arraybuffer', 'document', 'json', 'text', 'stream';浏览器专属:'blob'
            headers: {'Content-Type': 'application/json; application/octet-stream'},
            onDownloadProgress: (ProgressEvent) => {//用来计算下载量(实际项目中可以用来显示下载进度)
                let load = ProgressEvent.loaded;
                console.log(load);
            }
        }).then(function (resp) {
            console.log("resp", resp);
            //响应回来后其实还是使用的a标签进行下载的
            if (resp) {
                //从响应对象中获取头信息,content-disposition包含了服务端返回的文件名
                let header = resp.headers['content-disposition'];
                const fileName = decodeURI(header.substring(header.indexOf("=") + 1));
                console.log("header",header)
                console.log("fileName",fileName)

                let blob = new Blob([resp.data], {type: resp.headers['content-type']});//type指定响应的ContentType,这里从响应头中获取
                let url = window.URL.createObjectURL(blob);
                let link = document.createElement('a');
                link.href = url
                link.download = fileName || '下载文件';//下载后文件名
                document.body.appendChild(link);
                link.click();//点击下载
                link.remove();//下载完成移除元素
                window.URL.revokeObjectURL(link.href); //用完之后使用URL.revokeObjectURL()释放;
            } else {
                console.error('文件下载失败,请重试!');
            }
        }).catch(function (error) {
            console.log(error);
        }).finally(() => {
            //请求结束回调
        })
    };
  1. 案例2,文件名自定义
const downloadReport = (reportName, reportPath) => {
        console.log("下载报告reportName===1》", reportName)
        console.log("下载报告reportPath===1》", reportPath)
        reportName = "Java开发手册(黄山版).pdf";
        reportPath = "D:/aa/files/"
        axios.get(ctxPath + '/wechat/downloadReport', {
            params: {
                reportName,
                reportPath
            },
            responseType: 'blob',//响应类型为流,这里可以指定为blob或arraybuffer
            onDownloadProgress: (ProgressEvent) => {//用来计算下载量(实际项目中可以用来显示下载进度)
                let load = ProgressEvent.loaded;
                console.log(load);
            }
        }).then(function (resp) {
            console.log("resp",resp);
            //响应回来后其实还是使用的a标签进行下载的
            if (resp) {
                let blob = new Blob([resp.data]);
                let url = window.URL.createObjectURL(blob);
                let link = document.createElement('a');
                link.href = url
                link.download = reportName || '下载文件';//下载后文件名
                document.body.appendChild(link);
                link.click();//点击下载
                link.remove();//下载完成移除元素
                window.URL.revokeObjectURL(link.href); //用完之后使用URL.revokeObjectURL()释放;
            } else {
                console.error('文件下载失败,请重试!');
            }
        }).catch(function (error) {
            console.log(error);
        }).finally(() => {
            //请求结束回调
        })
    };

4. 使用fileDownload插件

fileDownload插件git地址:FileDownload

const downloadReport = (reportName, reportPath) => {
      console.log("下载报告reportName===1》", reportName)
      console.log("下载报告reportPath===1》", reportPath)
      reportName = "Java开发手册(黄山版).pdf";
      reportPath = "D:/aa/files/"
      axios.get(ctxPath + '/wechat/downloadReport', {
            params: {
                reportName,
                reportPath
            },
        responseType: 'blob',
      }).then(res => {
        fileDownload(res.data, reportName);
      });
    };

http://www.niftyadmin.cn/n/5358041.html

相关文章

Open CASCADE学习| IGES 文件读取

IGES&#xff08;Initial Graphics Exchange Specification&#xff09; 即图形初始交换规范&#xff0c;是一种用来描述大型三维CAD/CAM系统之间信息交换的工业国际标准文件。它是一种半向量图形格式&#xff0c;它涉及多个主题&#xff0c;如设计图&#xff0c;模型图以及三维…

075:vue+mapbox 利用高德地址逆转换,点击地图,弹出地址信息

第075个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+mapbox中利用高德逆地理编码,点击地图,弹出某点坐标和地址信息。这里要仔细阅读高德地图的逆编码API,同时要注意的是,这种转换在中国很好用,到了欧美国家就不好使了。同时这个底图是天地图的图像和标记。 直接…

thinkphp项目之发送邮件

引用 新用户注册需要采用邮箱注册&#xff0c;这就需要向用户注册的邮箱发送激活链接。 实现 项目采用thinkphp开发&#xff0c;引入phpmail&#xff0c;前面的一篇文章专门做了介绍&#xff0c;如果不了解的可以参考前面的博文。 $mail new PHPMailer(); $mail->From y…

ubuntu20配置mysql8

首先更新软件包索引运行 sudo apt update命令。然后运行 sudo apt install mysql-server安装MySQL服务器。 安装完成后&#xff0c;MySQL服务将作为systemd服务自动启动。你可以运行 sudo systemctl status mysql命令验证MySQL服务器是否正在运行。 连接MySQL 当MySQL安装…

获取Webshell的一些思路

1️⃣CMS获取webshell方法&#xff1a; 1、什么是CMS? CMS系统指的是内容管理系统。已经有别人开发好了整个网站的前后端&#xff0c;使用者只需要部署cms&#xff0c;然后通过后台添加数据&#xff0c;修改图片等工作&#xff0c;就能搭建好一个的WEB系统。 2、如何查看CM…

mac上,配置bundletool,将aab转为apk

1.第一步打开终端&#xff0c;安装brew 2.安装bundletool brew install bundletool 3.aab转apk bundletool build-apks --bundle/MyApp/my_app.aab --output/MyApp/my_app.apks 如果下载了bundletool--xxx.jar&#xff0c;脚本命令前加 java -jar bundletool-all-1.5.0.j…

浏览器前进后退实现思路

1. 使用浏览器的历史对象&#xff1a; 浏览器提供了 window.history 对象&#xff0c;通过该对象可以访问浏览器的历史记录。 2. 前进&#xff08;Forward&#xff09;&#xff1a; 要实现前进操作&#xff0c;可以使用 window.history.forward() 方法。 // 前进一步 windo…

Tensorflow2.0笔记 - where,scatter_nd, meshgrid相关操作

本笔记记录tf.where进行元素位置查找&#xff0c;scatter_nd用于指派元素到tensor的特定位置&#xff0c;meshgrid用作绘图的相关操作。 import tensorflow as tf import numpy as np import matplotlib.pyplot as plttf.__version__#where操作查找元素位置 #输入的tensor是Tr…