专栏首页nice_每一天Ajax下载文件(页面无刷新)

Ajax下载文件(页面无刷新)

说明:Ajax是无法实现文件传输的,本文只是模拟了Ajax不刷新页面就可以请求并返回数据的效果。实质上还是通过提交form表单来返回文件流的输出。

分步实现逻辑:

  1. ajax请求服务器,访问数据库,根据查询到的数据生成一个数据文件,返回前台一个json对象(可放置生成成功标记,文件路径等信息)。
  2. ajax success回调函数部分,根据返回的json对象,调用手写的js下载文件的方法,实现页面无刷新下载文件。

贴上部分代码供参考:

js代码:

1. js写一个动态创建并提交form表单的方法,依赖于jQuery插件。

// 文件下载
jQuery.download = function(url, method, filedir, filename){
    jQuery('<form action="'+url+'" method="'+(method||'post')+'">' +  // action请求路径及推送方法
                '<input type="text" name="filedir" value="'+filedir+'"/>' + // 文件路径
                '<input type="text" name="filename" value="'+filename+'"/>' + // 文件名称
            '</form>')
    .appendTo('body').submit().remove();
};

2. 查询数据,输出到文件,保存到服务器,并调用download方法实现下载

// 查询数据,输出到文件,保存到服务器,并实现下载
function exportOilDetection() {
    var ids = ['1','2','3','4']; // 查询参数代表(可根据实际情况修改),需要导出数据的id
    $.ajax({
            type : 'POST',
            dataType : 'json',
            async : false,
            url : "${pageContext.request.contextPath}/oilDetectionAction!ajaxExportOilDetectionInfos.action", // 生成文件,保存在服务器
            data : {
                ids : ids,
            },
            success : function(data) {
                var result = data["data"];
                if (result[0] == "success") {
                    // result[0] -- 文件生成成功标记
                    // result[1] -- 路径
                    // result[2] -- 文件名称
                    $.download('oilDetectionAction!ajaxDownloadDataExcel.action', 'post', result[1], result[2]); // 下载文件
                } else {
                    alert("数据导出失败!");
                }
            },
            error : function(XMLHttpRequest, textStatus, e) {
                console.log("oilDetection.js  method exportOilDetection" + e);
            }
    });
}

action文件配置

  • ajax生成文件后,会返回json类型结果
        <action name="oilDetectionAction" class="oilDetectionAction">
            <result name="ajax" type="json">
                <param name="root">result</param>
            </result>
            <result name="success">/page/oilDetection.jsp</result>
        </action>

java代码:

  • 返回文件流需借助response对象,所以action类需要实现ServletResponseAware接口,并声明response对象自动注入
public class OilDetectionAction implements ServletResponseAware {
    
    HttpServletResponse response;
    
    /**
     * 自动注入response
     */
    public void setServletResponse(HttpServletResponse response) {
        this.response = response;
    }
    
     ....
}
  • 下载文件部分代码:
public class OilDetectionAction implements ServletResponseAware {
    
     ....
     
    /**
     * 将生成的文件网络传输到客户端
     */
    public void ajaxDownloadDataExcel() throws IOException {
        InputStream ins = null;
        BufferedInputStream bins = null;
        OutputStream outs = null;
        BufferedOutputStream bouts = null;
        String file_name = getRequest().getParameter("file_name").trim(); // 文件名
        String file_dir = getRequest().getParameter("file_dir").trim(); // 文件路径
        System.out.println("获取到文件路径:" + file_dir + File.separator + file_name);
        try {
            if (!"".equals(file_name)) {
                File file = new File(file_dir + File.separator + file_name);
                if (file.exists()) {
                    ins = new FileInputStream(file_dir + File.separator
                            + file_name);
                    bins = new BufferedInputStream(ins);
                    outs = response.getOutputStream();
                    bouts = new BufferedOutputStream(outs);
                    response.setContentType("application/x-download");
                    response.setHeader(
                            "Content-disposition",
                            "attachment;filename="
                                    + URLEncoder.encode(file_name, "UTF-8"));
                    int bytesRead = 0;
                    byte[] buffer = new byte[8192];
                    while ((bytesRead = bins.read(buffer, 0, 8192)) != -1) {
                        bouts.write(buffer, 0, bytesRead);
                    }
                    bouts.flush();
                } else {
                    throw new Exception("下载的文件不存在!");
                }
            } else {
                throw new Exception("导出文件时发生错误!");
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        } finally {
            if (null != ins) {
                ins.close();
            }
            if (null != bins) {
                bins.close();
            }
            if (null != outs) {
                outs.close();
            }
            if (null != bouts) {
                bouts.close();
            }
        }
    }
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • spring+spring mvc+mybatis 实现主从数据库配置

    @DataSourceChange(slave = true)只对service(业务)层起作用。

    用户1518699
  • 理解 IntelliJ IDEA 的项目配置和Web部署

    IDEA 中最重要的各种设置项,就是这个 Project Structre 了,关乎你的项目运行,缺胳膊少腿都不行。最近公司正好也是用之前自己比较熟悉的IDEA...

    用户1518699
  • h5怎么做分享到QQ 、朋友圈、微信 、微博等功能

     微信已经成为我们日常聊天联系基本的必备工具,所以小菜我首先介绍一下如何调用微信的分享功能。其实除了可以在微信上分享到朋友圈和发送给好友,微信的分享接口还提供了...

    用户1518699
  • 重装系统快速恢复使用习惯(各种图标摆放位置、环境变量、C盘可能存放的文件备份、编辑器配置、语言环境导出)

    本文的操作是借助于移动硬盘来实现的(同时也默认你有 东西不常放C盘 的好习惯),你可以

    suwanbin
  • 【PAT乙级】旧键盘打字

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 ...

    喜欢ctrl的cxk
  • 运维实战技能Get---OpenV**搭建.

    作为运维人员经常会遇到各种故障,那我们就需要远程解决,为了保障服务器的安全性,此时我们需要连接内网,然后连接到跳板机,openvpn是我们常用解决方案!下面我们...

    用户5766185
  • 资产瞎配模型(二):对瞎配(一)中净值计算错误的纠正

    上上周发的那篇资产瞎配模型,事实证明,果然是瞎配,有大佬指出组合净值计算有一定的问题,所以这里对净值计算部分及进行改正,重新计算结果。

    量化小白
  • asp.net mvc输出自定义404等错误页面,非302跳转。

    朋友问到一个问题,如何输出自定义错误页面,不使用302跳转。当前页面地址不能改变.

    旺财的城堡
  • 大数据学习之_01_Linux学习_02_组管理和权限管理+定时任务调度+linux磁盘分区、挂载+linux的网络配置+进程管理(重点)+软件包管理+大厂面试题+感悟分享+资料附录

    案例2:每隔1分钟,将当前日期和日历信息,都追加到/tmp/mycal.log 文件中 步骤: 1) 编写一个文件/home/mytask2.sh,文...

    黑泽君
  • 【DB笔试面试459】ORA-00904: "wm_concat":invalid identifier错误如何解决?

    ORA-00904: "wm_concat":invalid identifier错误如何解决?

    小麦苗DBA宝典

扫码关注云+社区

领取腾讯云代金券