最近项目有个需求,用户想对挂有附件的数据记录 实现一键下载全部附件(目前项目仅支持每次点击单条记录进行附件下载),下面记录我实现的解决方案。
项目框架基于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的更多相关文章

  1. 批量下载文件web

    最近需要这个所以写了一个例子一般批量下载由以下步骤组成: 1.确定下载的源文件位置 2.对文件进行打包成临时文件,这里会用到递归调用,需要的嵌套的文件夹进行处理,并返回文件保存位置 3.将打包好的文件 ...

  2. C#异步批量下载文件

    C#异步批量下载文件 实现原理:采用WebClient进行批量下载任务,简单的模拟迅雷下载效果! 废话不多说,先看掩饰效果: 具体实现步骤如下: 1.新建项目:WinBatchDownload 2.先 ...

  3. Java批量下载文件并zip打包

    客户需求:列表勾选需要的信息,点击批量下载文件的功能.这里分享下我们系统的解决方案:先生成要下载的文件,然后将其进行压缩,生成zip压缩文件,然后使用浏览器的下载功能即可完成批量下载的需求.以下是zi ...

  4. java批量下载文件为zip包

    批量下载文件为zip包的工具类 package com.meeno.trainsys.util; import javax.servlet.http.HttpServletRequest; impor ...

  5. php批量下载文件

    最近用codeigniter开发一个图片网站,发现单文件下载很容易实现,批量下载的话,就有点麻烦. 普通php下载比较简单,比如我封装的一个函数: function shao_download($fi ...

  6. python_crawler,批量下载文件

    这个第一个python3网络爬虫,参考书籍是<python网络数据采集>.该爬虫的主要功能是爬取某个网站,并将.rar,.doc,.docx,.zip文件批量下载. 后期将要改进的是,用后 ...

  7. PowerShell 实现批量下载文件

    简介 批量文件下载器 PowerShell 版,类似于迅雷批量下载功能,且可以破解 Referer 防盗链 源代码 [int]$script:completed = 0 # 下载完成数量 [int]$ ...

  8. ASP.NET批量下载文件的方法

    一.实现步骤 在用户操作界面,由用户选择需要下载的文件,系统根据所选文件,在服务器上创建用于存储所选文件的临时文件夹,将所选文件拷贝至临时文件夹.然后调用 RAR程序,对临时文件夹进行压缩,然后输出到 ...

  9. ASP.NET批量下载文件

    一.实现步骤 在用户操作界面,由用户选择需要下载的文件,系统根据所选文件,在服务器上创建用于存储所选文件的临时文件夹,将所选文件拷贝至临时文件夹.然后调用 RAR程序,对临时文件夹进行压缩,然后输出到 ...

随机推荐

  1. IntelliJ IDEA 2019.1.1 maven框架web.xml中web-app版本过低导致不能正常使用EL表达式的解决方案

     1.软件版本 IDEA版本:IntelliJ IDEA 2019.1.1 maven版本:apache-maven-3.6.1 Tomcat版本:tomcat-8.5 2.问题描述 IDEA使用如下 ...

  2. IDEA激活—免费永久激活(lookdiv.com)

    网址: http://lookdiv.com/ 钥匙就是网址 钥匙:lookdiv.com 亲测有效!非常好用.

  3. 12.持久性后门----Ettercap之ARP中毒----RAR/ZIP & linux密码破解----kali上检测rootkits

    持久性后门 生成PHP shell weevely generate 密码 /root/Desktop/404.php 靶机IP/404.php weevely http://192.168.1.10 ...

  4. 无法在发送 HTTP 标头之后进行重定向

    public ActionResult Index2() { Response.Buffer = true; Response.Clear(); return Redirect("/Wech ...

  5. python下对mysql数据库的链接操作

    参考网址: https://blog.csdn.net/guofeng93/article/details/53994112 https://blog.csdn.net/Chen_Eris/artic ...

  6. 使用eclipse创建mavenWeb项目,中途遇到的问题及解决方案!

    创建MavenWeb项目的步骤,如下: 1).new--->Maven --->maven project,如图: 之后, next,最后finish,项目创建完成,项目的目录如下: 将w ...

  7. Java GC日志

    JVM 命令:-Xms5m -Xmx20m -XX:+PrintGCDetails -XX:+PrintCommandLineFlags -XX:+UseSerialGC [GC (Allocatio ...

  8. 终于有人把 Docker 讲清楚了,万字详解!

    一.简介 1.了解Docker的前生LXC LXC为Linux Container的简写.可以提供轻量级的虚拟化,以便隔离进程和资源,而且不需要提供指令解释机制以及全虚拟化的其他复杂性.相当于C++中 ...

  9. P1076寻宝

    ---恢复内容开始--- 这是2012noip普及组的一个模拟题,第一次得了50,看了题解后剪枝拿到100. N层楼,m个房间,逆时针排序.每个房间有一个指示牌,也可能有楼梯,找到第(上楼的第一个房间 ...

  10. java 覆盖

    作者:又见那斯 java中覆盖基于面向对象三大特征之:继承,同时又和另一特征:多态有重要的联系,本文中讨论的有关java中覆盖的一些知识,其实在写代码的时候或许不会用到,不过知道的话总会有用处.如有错 ...