Springboot如何导出文件
发表于:2025-11-07 作者:千家信息网编辑
千家信息网最后更新 2025年11月07日,这篇文章主要介绍Springboot如何导出文件,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!后端代码可以把请求设置为post,我这里是Get @RequestMapping(
千家信息网最后更新 2025年11月07日Springboot如何导出文件
这篇文章主要介绍Springboot如何导出文件,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!
后端代码
可以把请求设置为post,我这里是Get
@RequestMapping(value = "/download", method = RequestMethod.POST) public void download(HttpServletRequest request, HttpServletResponse res) throws Exception { File excelFile = new File("/Users/i501695/GitHUbProject/EN_ProductIntergration/databaseclient/src/main/resources/Files/ProductTemplateCopy.xlsx"); res.setCharacterEncoding("UTF-8"); String realFileName = excelFile.getName(); res.setHeader("content-type", "application/octet-stream;charset=UTF-8"); res.setContentType("application/octet-stream;charset=UTF-8"); //加上设置大小下载下来的.xlsx文件打开时才不会报"Excel 已完成文件级验证和修复。此工作簿的某些部分可能已被修复或丢弃" res.addHeader("Content-Length", String.valueOf(excelFile.length())); try { res.setHeader("Content-Disposition", "attachment;filename=" + java.net.URLEncoder.encode(realFileName.trim(), "UTF-8")); } catch (UnsupportedEncodingException e1) { e1.printStackTrace(); } byte[] buff = new byte[1024]; BufferedInputStream bis = null; OutputStream os = null; try { os = res.getOutputStream(); bis = new BufferedInputStream(new FileInputStream(excelFile)); int i = bis.read(buff); while (i != -1) { os.write(buff, 0, buff.length); os.flush(); i = bis.read(buff); } }catch (Exception e){ e.printStackTrace(); }finally { if (bis != null) { try { bis.close(); } catch (IOException e) { e.printStackTrace(); } } } }前端伪代码结合Axios(核心代码一样,只是结合了Axios)
Axios({ // 用axios发送post请求 method: 'post', url: 'http://127.0.0.1:8762/dataService/download', // 请求地址 data: formData, // 参数 responseType: 'blob' // 表明返回服务器返回的数据类型 }) .then((res) => { // 处理返回的文件流 let blob = new Blob([res.data], {type: res.data.type}) const fileName = 'ProductTemplateCopy.xlsx'; let downloadElement = document.createElement('a') let href = window.URL.createObjectURL(blob); //创建下载的链接 downloadElement.href = href; downloadElement.download = fileName; //下载后文件名 document.body.appendChild(downloadElement); downloadElement.click(); //点击下载 document.body.removeChild(downloadElement); //下载完成移除元素 window.URL.revokeObjectURL(href); //释放blob message.success('upload successfully.'); }) .catch(function (error) { console.log(error); });SpringBoot文件下载的几种方式
1. 将文件以流的形式一次性读取到内存
通过响应输出流输出到前端
/** * @param path 想要下载的文件的路径 * @param response * @功能描述 下载文件: */@RequestMapping("/download")public void download(String path, HttpServletResponse response) { try { // path是指想要下载的文件的路径 File file = new File(path); log.info(file.getPath()); // 获取文件名 String filename = file.getName(); // 获取文件后缀名 String ext = filename.substring(filename.lastIndexOf(".") + 1).toLowerCase(); log.info("文件后缀名:" + ext); // 将文件写入输入流 FileInputStream fileInputStream = new FileInputStream(file); InputStream fis = new BufferedInputStream(fileInputStream); byte[] buffer = new byte[fis.available()]; fis.read(buffer); fis.close(); // 清空response response.reset(); // 设置response的Header response.setCharacterEncoding("UTF-8"); //Content-Disposition的作用:告知浏览器以何种方式显示响应返回的文件,用浏览器打开还是以附件的形式下载到本地保存 //attachment表示以附件方式下载 inline表示在线打开 "Content-Disposition: inline; filename=文件名.mp3" // filename表示文件的默认名称,因为网络传输只支持URL编码的相关支付,因此需要将文件名URL编码后进行传输,前端收到后需要反编码才能获取到真正的名称 response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8")); // 告知浏览器文件的大小 response.addHeader("Content-Length", "" + file.length()); OutputStream outputStream = new BufferedOutputStream(response.getOutputStream()); response.setContentType("application/octet-stream"); outputStream.write(buffer); outputStream.flush(); } catch (IOException ex) { ex.printStackTrace(); }}2. 将输入流中的数据循环写入到响应输出流中
而不是一次性读取到内存,通过响应输出流输出到前端
/*** @param path 指想要下载的文件的路径* @param response* @功能描述 下载文件:将输入流中的数据循环写入到响应输出流中,而不是一次性读取到内存*/@RequestMapping("/downloadLocal")public void downloadLocal(String path, HttpServletResponse response) throws IOException { // 读到流中 InputStream inputStream = new FileInputStream(path);// 文件的存放路径 response.reset(); response.setContentType("application/octet-stream"); String filename = new File(path).getName(); response.addHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(filename, "UTF-8")); ServletOutputStream outputStream = response.getOutputStream(); byte[] b = new byte[1024]; int len; //从输入流中读取一定数量的字节,并将其存储在缓冲区字节数组中,读到末尾返回-1 while ((len = inputStream.read(b)) > 0) { outputStream.write(b, 0, len); } inputStream.close();}3. 下载网络文件到本地
/*** @param path 下载后的文件路径和名称* @param netAddress 文件所在网络地址* @功能描述 网络文件下载到服务器本地*/@RequestMapping("/netDownloadLocal")public void downloadNet(String netAddress, String path) throws IOException { URL url = new URL(netAddress); URLConnection conn = url.openConnection(); InputStream inputStream = conn.getInputStream(); FileOutputStream fileOutputStream = new FileOutputStream(path); int bytesum = 0; int byteread; byte[] buffer = new byte[1024]; while ((byteread = inputStream.read(buffer)) != -1) { bytesum += byteread; System.out.println(bytesum); fileOutputStream.write(buffer, 0, byteread); } fileOutputStream.close();}4. 网络文件获取到服务器后
经服务器处理后响应给前端
/** * @param netAddress * @param filename * @param isOnLine * @param response * @功能描述 网络文件获取到服务器后,经服务器处理后响应给前端 */@RequestMapping("/netDownLoadNet")public void netDownLoadNet(String netAddress, String filename, boolean isOnLine, HttpServletResponse response) throws Exception { URL url = new URL(netAddress); URLConnection conn = url.openConnection(); InputStream inputStream = conn.getInputStream(); response.reset(); response.setContentType(conn.getContentType()); if (isOnLine) { // 在线打开方式 文件名应该编码成UTF-8 response.setHeader("Content-Disposition", "inline; filename=" + URLEncoder.encode(filename, "UTF-8")); } else { //纯下载方式 文件名应该编码成UTF-8 response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(filename, "UTF-8")); } byte[] buffer = new byte[1024]; int len; OutputStream outputStream = response.getOutputStream(); while ((len = inputStream.read(buffer)) > 0) { outputStream.write(buffer, 0, len); } inputStream.close();}5. 常见异常和问题
(1)响应对象无需通过return返回
原因: 响应对象是可以不用作为方法返回值返回的,其在方法执行时已经开始输出,且其无法与@RestController配合,以JSON格式返回给前端
解决办法: 删除return语句
(2)返回前端的文件名必须进行URL编码
原因: 网络传输只能传输特定的几十个字符,需要将汉字、特殊字符等经过Base64等编码来转化为特定字符,从而进行传输,而不会乱码
URLEncoder.encode(fileName, "UTF-8")
(3)IO流有待学习
1:read() :
从输入流中读取数据的下一个字节,返回0到255范围内的int字节值。如果因为已经到达流末尾而没有可用的字节,则返回-1。在输入数据可用、检测到流末尾或者抛出异常前,此方法一直阻塞。
2:read(byte[] b) :
从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中。以整数形式返回实际读取的字节数。在输入数据可用、检测到文件末尾或者抛出异常前,此方法一直阻塞。如果 b 的长度为 0,则不读取任何字节并返回 0;否则,尝试读取至少一个字节。如果因为流位于文件末尾而没有可用的字节,则返回值 -1
以上是"Springboot如何导出文件"这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注行业资讯频道!
文件
字节
UTF-8
前端
输入
文件名
编码
网络
输出
数据
服务器
服务
方式
末尾
路径
传输
功能
一次性
代码
内存
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
湖北it软件开发培训
软件开发和程序员有关吗
数据库计算显示百分比
上海挖媒网络技术
软件开发项目完成交接表
宁夏电力系统软件开发
网络安全靶场搭建
lunux系统软件开发
停止数据库服务代码
国防网络安全员
lol韩服几个服务器
安居客全国小区数据库
玩游戏租服务器好吗
服务器硬件结构及组装
国家网络安全瓶颈
ncbi数据库文件怎么看
继承者计划软件开发
sql 收缩数据库
租云服务器的重要性
食品安全股票网络安全股票
江苏重型软件开发生产过程
互联网创新科技方面
linux服务器管理器
学校讲的数据库系统原理
济南浪潮存储服务器哪家服务好
福建特种网络技术
管理型会计软件开发
地质灾害数据库有哪些数据
lol为什么服务器未响应
自贡市二手服务器回收