spring mvc 文件下载

在web中下载的方式大多基于servlet,在web.xml中配置下载路径,这里再介绍json(转成base64字符串)和blob的使用方式

servlet

WEB-INF/web.xml

XML 复制代码
<!--url映射-->
<servlet-mapping>
	<servlet-name>DowloadServlet</servlet-name>
	<url-pattern>/servlet/dowloadFile</url-pattern>
</servlet-mapping>


<!--指定servlet-->
<servlet>
	<servlet-name>DowloadServlet</servlet-name>
	<servlet-class>com.xxxxxx.servlet.DowloadServlet</servlet-class>
</servlet>

servlet代码

java 复制代码
protected void download(String path, String fileName) {
        File file = new File(path);
        if (!file.exists()) {
            logger.error("下载的文件不存在 path=" + path + ",fileName=" + fileName);
        }
        //下载
        OutputStream out = null;
        BufferedInputStream in = null;
        try {
            getResponse().setCharacterEncoding("UTF-8");
            getResponse().setContentType("application/vnd.ms-excel");
            getResponse().setHeader("Content-Disposition", "attachment; filename=" + fileName);
            out = getResponse().getOutputStream();
            in = new BufferedInputStream(new FileInputStream(path));
            int line;
            while ((line = in.read()) != -1) {
                out.write(line);
            }
        } catch (Exception ex) {
            logger.error("下载文件失败 path=" + path, ex);
        } finally {
            if (null != out) {
                try {
                    out.close();
                } catch (Exception ex) {
                    logger.error("关闭out异常 path=" + path, ex);
                }
            }
            if (null != in) {
                try {
                    in.close();
                } catch (Exception ex) {
                    logger.error("关闭in异常 path=" + path, ex);
                }
            }
        }
    }

js代码

通过浏览器进行下载

html 复制代码
<a href="/serlvet/dowloadFile">下载</a> 

或者

window.open("/serlvet/dowloadFile")

blob

controller

关键在这响应头:application/octet-stream

java 复制代码
protected void download(String path, String fileName) {
        File file = new File(path);
        if (!file.exists()) {
            logger.error("下载的文件模板不存在 path=" + path + ",fileName=" + fileName);
        }
        //下载
        OutputStream out = null;
        BufferedInputStream in = null;
        try {
            getResponse().setCharacterEncoding("UTF-8");
            getResponse().setContentType("application/octet-stream");
            getResponse().setHeader("Content-Disposition", "attachment; filename=" + fileName);
            out = getResponse().getOutputStream();
            in = new BufferedInputStream(new FileInputStream(path));
            int line;
            while ((line = in.read()) != -1) {
                out.write(line);
            }
        } catch (Exception ex) {
            logger.error("下载文件失败 path=" + path, ex);
        } finally {
            if (null != out) {
                try {
                    out.close();
                } catch (Exception ex) {
                    logger.error("关闭out异常 path=" + path, ex);
                }
            }
            if (null != in) {
                try {
                    in.close();
                } catch (Exception ex) {
                    logger.error("关闭in异常 path=" + path, ex);
                }
            }
        }
    }

js代码引用博客

javascript 复制代码
// 通过后端接口下载文件
function downloadFile() {
  // 发起Ajax请求获取文件数据
  $.ajax({
    url: '/download',
    type: 'GET',
    dataType: 'binary',
    success: function(response) {
      // 创建Blob对象
      var blob = new Blob([response]);

      // 创建URL对象
      var url = URL.createObjectURL(blob);

      // 创建a标签并设置相关属性
      var link = document.createElement('a');
      link.href = url;
      link.download = 'file.txt';

      // 触发点击事件进行下载
      link.click();

      // 释放URL对象
      URL.revokeObjectURL(url);
    }
  });
}

json

controller

java 复制代码
public Result execute() throws Exception {
		Result result = new Result();
		result.setErr_no(0);
		try {
			String xlsBase64 = xlsToBase64(param.getAbsDownPath(filePath);
			DataRow dr = new DataRow();
			dr.set("fileName",param.getFileName()+".xlsx");
			dr.set("fileBase64Str",xlsBase64);
			result.setResult(dr);
		}catch (Exception ex){
			result.setErr_no(-99);
			result.setErr_info("系统错误");
			logger.error("模板下载异常", ex);
		}
		return result;
}

protected  String xlsToBase64(String path){
        File file = new File(path);
        if (!file.exists()) {
            logger.error("下载的文件模板不存在 path=" + path );
            return null;
        }
        try{
            return Base64Util.encodeBase64String(FileUtils.readFileToByteArray(file));
        }catch (Exception e){
            logger.error("xls文件转Base64失败 path=" + path, e);
        }
        return null;
    }

javascript 【引用博客】

javascript 复制代码
var raw = window.atob(data.result.fileBase64Str);
var uInt8Array = new Uint8Array(raw.length);
for (var i = 0; i < raw.length; i++) {
  uInt8Array[i] = raw.charCodeAt(i);
}

const link = document.createElement("a");
const blob = new Blob([uInt8Array],{
   type: 'application/vnd.ms-excel'
})

link.style.display = 'none';
link.href = URL.createObjectURL(blob);
link.setAttribute('download',data.result.fileName+'.xls');

document.body.appendChild(link)
link.click()

document.body.removeChild(link)
相关推荐
IT枫斗者枫哥36 分钟前
MyBatis一对多分页:LIMIT 20,为什么凑不齐20个订单?
java·数据库
知守观36 分钟前
@Transactional 事务失效排查,try-catch 吞异常导致回滚失败(附源码分析)
后端·spring
代码方舟37 分钟前
Java数据工程:利用天远全网运营商三要素优化线上实名认证合规体验
java·人工智能
BBmmo37 分钟前
我的 Java 学习笔记 · 第 7 篇:泛型与通配符
java
独泪了无痕38 分钟前
Hutool之RandomUtil:随机数生成的终极利器
java·后端
花开路口38 分钟前
深入理解 Java/Kotlin 协变与逆变
java·kotlin
运行时异常38 分钟前
【WMS 仓储系统集成 AI Agent 实战】第 7 讲:Vue3 前端工程化——Token 刷新锁、Markdown 渲染踩坑与权限体系
java
她的男孩39 分钟前
开放接口限流从 20 改到 200 还是每分钟 20 次:拆完防重放+幂等+限流,我找到 5 个静默失效的坑
java·后端·架构
天天被压力1 小时前
【Python 量化取数指南 #13】Python 把行情落库:sqlite 一键存,回测随用随取
java·人工智能·python
天天被压力1 小时前
【Python 量化取数指南 #14】Python 清洗行情数据:复权停牌对齐,回测不翻车
java·人工智能·python