批量下载文件JSP
最近项目有个需求,用户想对挂有附件的数据记录 实现一键下载全部附件(目前项目仅支持每次点击单条记录进行附件下载),下面记录我实现的解决方案。
项目框架基于SSM
service业务实现层(impl):
//获取配置的文件夹默认位置 (我的properties配的是E\:\\work\\files)
@Value("#{configProperties['FILE.DOCUMENT_PATH']}")
private String documentPath;
//获取附件信息需要调用的mapper
@Autowired
JcglSystemHelpMapper jcglSystemHelpMapper;
//参数ids : 为前台传的记录id集 (格式:12345,12346,12347)
@Override
public void downloadPlanFile(String ids,HttpServletRequest request,HttpServletResponse response){
//响应头的设置
response.reset();
response.setCharacterEncoding("utf-8");
response.setContentType("multipart/form-data");
//设置压缩包的名字
String dates = DateFormatUtils.formatJxp2(new Date());//获取时间戳
String billname = "附件包-"+dates;
String downloadName = billname+".zip";
//返回客户端浏览器的版本号、类型
String agent = request.getHeader("USER-AGENT");
try {
//针对IE或者以IE为内核的浏览器:
if (agent.contains("MSIE")||agent.contains("Trident")) {
downloadName = java.net.URLEncoder.encode(downloadName, "UTF-8");
} else {
//非IE浏览器的处理:
downloadName = new String(downloadName.getBytes("UTF-8"),"ISO-8859-1");
}
} catch (Exception e) {
e.printStackTrace();
}
response.setHeader("Content-Disposition", "attachment;fileName=\"" + downloadName + "\"");
//设置压缩流:直接写入response,实现边压缩边下载
ZipOutputStream zipos = null;
try {
zipos = new ZipOutputStream(new BufferedOutputStream(response.getOutputStream()));
zipos.setMethod(ZipOutputStream.DEFLATED); //设置压缩方法
} catch (Exception e) {
e.printStackTrace();
}
//循环将文件写入压缩流
DataOutputStream os = null;
//查询数据库获取文件信息
Map<String,Object> map = new HashMap<String, Object>();
map.put("ids", ids);
List<AuthAttachmentDetail> list = jcglSystemHelpMapper.queryAllDetailByDataIds(map);
//遍历文件信息(主要获取文件名/文件路径等)
for (AuthAttachmentDetail authAttachmentDetail : list) {
//文件路径
String filePath = documentPath + File.separator + authAttachmentDetail.getFilePath();
System.out.println("filePath==="+filePath);
File file = new File(filePath);
if (!file.exists()) {
throw new BusinessException("文件已不存在");
}else{
try {
//添加ZipEntry,并ZipEntry中写入文件流
String fileName = authAttachmentDetail.getFileName();//.substring(0,authAttachmentDetail.getFileName().indexOf("."));
zipos.putNextEntry(new ZipEntry(fileName));
os = new DataOutputStream(zipos);
InputStream is = new FileInputStream(file);
byte[] b = new byte[100];
int length = 0;
while((length = is.read(b))!= -1){
os.write(b, 0, length);
}
is.close();
zipos.closeEntry();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//关闭流
try {
os.flush();
os.close();
zipos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
调用的dao层(mapper) 以及前台传的参数 根据自己业务来定,目的就是为了能拿到需要批量下载的文件信息(文件名/文件路径等),再进行遍历 做文件流处理。
controller 及 service 做过渡及调用工作。
controller代码如下:
/**
* 批量下载
* @param ids 业务记录id集(格式xx,xx2,xx3) 用于查询相关表获取文件信息
* @param request
* @param response
*/
@RequestMapping(value = "downloadPlanFile")
public void downloadPlanFile(String ids,HttpServletRequest request,HttpServletResponse response){
reqPlanService.downloadPlanFile(ids,request,response);
}
service代码如下:
/**
* 批量下载
* @param ids 记录id集合
* @return
*/
public void downloadPlanFile(String ids,HttpServletRequest request,HttpServletResponse response);
前端在进行下载前可用ajax做一些校验工作,只要不满足下载就提前抛业务异常。
前端代码如下:(前端框架采用的easyui)
//批量下载附件
attachmentMore:function(){
//获取选择的记录
var rows = $('#xqglReqPlanGrid').datagrid('getChecked');
if(rows.length <1){
_alert('请选择记录');
return false;
}
//开启遮罩(进度条)
$.messager.progress();
//ids参数准备 用逗号隔开id
var ids = '';
$.each(rows,function(index,data){
if(rows.length == index+1){
ids += data.id;
}else{
ids += data.id + ",";
}
})
console.log(ids);
//下载前的一个业务校验
$.ajax({
type : "POST",
url : Config.sysUrl +'/xqglReqPlan/isDownloadPlanFile',
data:{"ids":ids},
cache : false,
success : function(data) {
//关闭遮罩(进度条)
$.messager.progress('close');
//回调成功进行下载
if(data.success){
window.location.href=Config.sysUrl+ "/xqglReqPlan/downloadPlanFile?ids="+ids;
}
}
});
}
前端调用后台下载 我采用的是window.location.href=url 的方式输出。采用这种方式输出流的话,如果期间后台报错抛异常了 前台是不会返回错误信息的,因此我把必要的业务校验用一个ajax提前调用后台进行校验,确保满足下载条件再进行下载。
详细配置信息可以参考我写的这篇文章:http://blog.ncmem.com/wordpress/2019/08/28/java%e6%89%b9%e9%87%8f%e4%b8%8b%e8%bd%bd/
批量下载文件JSP的更多相关文章
- 批量下载文件web
最近需要这个所以写了一个例子一般批量下载由以下步骤组成: 1.确定下载的源文件位置 2.对文件进行打包成临时文件,这里会用到递归调用,需要的嵌套的文件夹进行处理,并返回文件保存位置 3.将打包好的文件 ...
- C#异步批量下载文件
C#异步批量下载文件 实现原理:采用WebClient进行批量下载任务,简单的模拟迅雷下载效果! 废话不多说,先看掩饰效果: 具体实现步骤如下: 1.新建项目:WinBatchDownload 2.先 ...
- Java批量下载文件并zip打包
客户需求:列表勾选需要的信息,点击批量下载文件的功能.这里分享下我们系统的解决方案:先生成要下载的文件,然后将其进行压缩,生成zip压缩文件,然后使用浏览器的下载功能即可完成批量下载的需求.以下是zi ...
- java批量下载文件为zip包
批量下载文件为zip包的工具类 package com.meeno.trainsys.util; import javax.servlet.http.HttpServletRequest; impor ...
- php批量下载文件
最近用codeigniter开发一个图片网站,发现单文件下载很容易实现,批量下载的话,就有点麻烦. 普通php下载比较简单,比如我封装的一个函数: function shao_download($fi ...
- python_crawler,批量下载文件
这个第一个python3网络爬虫,参考书籍是<python网络数据采集>.该爬虫的主要功能是爬取某个网站,并将.rar,.doc,.docx,.zip文件批量下载. 后期将要改进的是,用后 ...
- PowerShell 实现批量下载文件
简介 批量文件下载器 PowerShell 版,类似于迅雷批量下载功能,且可以破解 Referer 防盗链 源代码 [int]$script:completed = 0 # 下载完成数量 [int]$ ...
- ASP.NET批量下载文件的方法
一.实现步骤 在用户操作界面,由用户选择需要下载的文件,系统根据所选文件,在服务器上创建用于存储所选文件的临时文件夹,将所选文件拷贝至临时文件夹.然后调用 RAR程序,对临时文件夹进行压缩,然后输出到 ...
- ASP.NET批量下载文件
一.实现步骤 在用户操作界面,由用户选择需要下载的文件,系统根据所选文件,在服务器上创建用于存储所选文件的临时文件夹,将所选文件拷贝至临时文件夹.然后调用 RAR程序,对临时文件夹进行压缩,然后输出到 ...
随机推荐
- Java之Swing体系——制作自己的登录界面
我们制作登陆界面是简单的图形模式,并不具备其他功能: 这里使用两个库,如下: javax.swing.*; java.awt.*; 构造窗体对象要用到很多类,废话不多,直接代码~ package co ...
- 正则的?:pattern, ?=pattern, ?!pattern学习整理
真正学习这次正则知识前,我是被这道题给难住了: # 目标文本 str1 = "ever1, ever2, never1, never2, never3, forever1, forever2 ...
- 深入理解java:1.3.1 JVM内存区域的划分(运行时数据区)
学习Java GC机制,可以帮助我们在日常工作中 排查各种内存溢出或泄露问题,解决性能瓶颈,达到更高的并发量,写出更高效的程序. 我们将从4个方面学习Java GC机制, 1,内存是如何分配的: 2, ...
- 2019JAVA第一次編程总结
2019第二周实验报告 Java实验报告 班级 计算机科学与技术二班 学号 20188442 姓名 吴怡君 完成时间 2019/9/7 评分等级 实验一 Java开发环境与简单Java程序 一. 实验 ...
- Linux rsync 远程同步部署篇
rsync官网: www.samba.org/ftp/rsync.html端口:873上机实战系列项目100台规模集群全网数据备份解决方案3.本项目提供免费实战讲解视频:Linux集群全网服务器数据备 ...
- [BZOJ 3625] [Codeforces 438E] 小朋友的二叉树 (DP+生成函数+多项式开根+多项式求逆)
[BZOJ 3625] [Codeforces 438E] 小朋友的二叉树 (DP+生成函数+多项式开根+多项式求逆) 题面 一棵二叉树的所有点的点权都是给定的集合中的一个数. 让你求出1到m中所有权 ...
- [LeetCode] 126. 单词接龙 II
题目链接 : https://leetcode-cn.com/problems/word-ladder-ii/ 题目描述: 给定两个单词(beginWord 和 endWord)和一个字典 wordL ...
- 远程连接mysql出现1130的错误
数据库权限不足 连接数据以后执行以下命令 GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '您的数据库密码' WITH GRANT OP ...
- django + celery的队列,路由与弹性
#celery_app.py #!/usr/bin/env python # -*- coding: utf-8 -*- from __future__ import absolute_import ...
- 北京师范大学第十五届ACM决赛-重现赛J Just A String (kmp算法延伸)
链接:https://ac.nowcoder.com/acm/contest/3/J 来源:牛客网 Just A String 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 2621 ...