Springboot如何导出文件
发表于:2024-12-13 作者:千家信息网编辑
千家信息网最后更新 2024年12月13日,这篇文章主要介绍Springboot如何导出文件,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!后端代码可以把请求设置为post,我这里是Get @RequestMapping(
千家信息网最后更新 2024年12月13日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安全错误
数据库的锁怎样保障安全
软件开发毕业论文设计题目
互联网科技构架
mysql远程备份数据库
温州app软件开发费用明细
柯美c6000服务器连接不上
多个应用使用同一个数据库
镇江联盟网络技术
徐州江苏圣斗士网络技术有限公司
软件开发架构模式
进销存商品信息数据库
成都华速网络技术服务
服务器限制访问音乐
wdc服务器管理系统怎么打开
互联网金融科技板块
香港服务器搭建游戏平台
数据库保存上传文件信息
成立软件开发工作领导小组
学计算机网络技术基础题
最新关于加强网络安全的通知
杭州有哪些网络技术公司
eosbet软件开发
网络安全计算机病毒的启动方式
网络安全法》八项基本制度
停机卡免流需要买什么服务器
定时修改数据库数据
网络安全审查知识问答
rust有多少个服务器
计算机网络技术要练盲打吗
南京新大陆软件开发
红色讲堂数据库开通试用