获取jqGrid中的所有数据导出并生成Excel文件流供用户下载(post请求实现文件下载)

版权声明:个人博客:yjz.life 欢迎前来交流!~本篇文章未经同意请勿转载! https://blog.csdn.net/m0_38072683/article/details/82990629

最近有一个需求是:

将jqGrid表格中的数据生成报表Excel文件返回给用户。

我的想法是获取jqGrid中的数据然后生成json数据,传给后端,生成文件流,响应到前端,保存为excel文件。

ajax为什么不能够实现下载文件

ajax的返回值类型是json,text,html,xml类型,或者可以说ajax的接收类型只能是string字符串,不是流类型,所以无法实现文件下载。

但用ajax仍然可以获得文件的内容,该文件将被保留在内存中,无法将文件保存到磁盘。这是因为JavaScript无法和磁盘进行交互,否则这会是一个严重的安全问题,js无法调用到浏览器的下载处理机制和程序,会被浏览器阻塞。

并且 我用ajax实现的时候出现了很多bug。

在网上参考好多博客,经过不断的调试,我还是选择了原生的XMLHttpRequest对象进行post请求。

blob(HTML5 新特性)

二进制大对象,是一个可以存储二进制文件的容器。

作用

Js一直以来都没有比较好的可以直接处理二进制的方法。而Blob的存在,允许我们可以通过JS直接操作二进制数据。

Blob对象可以看做是存放二进制数据的容器,此外还可以通过Blob设置二进制数据的MIME类型。

BLOB是一个大文件,典型的BLOB是一张图片或一个声音文件,由于它们的尺寸,必须使用特殊的方式来处理(例如:上传、下载或者存放到一个数据库)。

重点应用
  • 目前做的通过URL下载文件。
  • 分片上传文件(将大文件分片,轮询向后台提交各文件片段)。

后端代码

/**
 * 生成Excel报表
 * Error:存在问题
 * 1. 前端表格中没有Student对象的一些属性,生成报表时不必要显示的属性字段在Excel中显示。
 *    solve:加判断控制。
 * 2. (由于blob是HTML5新出的)兼容性问题:chrome、firefox、opera无问题,
 * 3. 检测grid表格中有无字段名称冲突问题。
 *    solve:细心检查即可
 * 4. 下载完Excel,打开出现"文件已损坏 无法打开"问题,这是因为office受保护试图导致(安全问题)
 *    solve:在office选项里边修改一下即可(客户端问题)
 * @param list
 * @param response
 */
@RequestMapping(value = "/exstudent",consumes = "application/json;charset=utf-8")
public void export (@RequestBody List<Student> list, HttpServletResponse  response){
    OutputStream out = null;
    String name = "学生信息管理表";

    for (Student stu:list) {
        System.out.println(stu.getStudentname());
    }
    try {
        response.setHeader("content-type", "application/octet-stream");
        response.setContentType("application/octet-stream");
        response.setHeader("Content-Disposition", "attachment;filename=" +URLEncoder.encode(name, "UTF-8")+".xlsx");
        out = response.getOutputStream();
        //调用老师自己写的库,本篇文章不详细说生成Excel文件的事情。
        TExcel.exportExcel(name,Student.class,list,out);
        System.out.println("下载ok");
        out.flush();
        out.close();
    } catch (Exception e) {
        e.printStackTrace();
    }finally{

    }
}

前端代码:

//导出按钮被点击之后,将按钮制为无效(防止多次生成)
function abideBtn(){
    console.log("禁止按钮......");
    $("#download").attr({"href":"#"});
    $("#download").css("cursor","not-allowed");
}
//下载过程中出错误,
function downloadError(){
    console.log("发生错误,下载失败");
    alert("下载中出现错误!请重试");
    $("#download").attr({"href":"javascript:exportData();"});
    $("#download").css("cursor","pointer");
}
//导出表格数据
//注意:下面获取jqGrid中所有行数据的前提是分页在前端,而不是后端。
//如果你是在后端分页,那么你会发现,你会将所有数据都显示出来。
function exportData() {
    var grid = jQuery("#grid");
    //获取当前显示的数据
    var rowNum = grid.jqGrid('getGridParam', 'rowNum'); //获取显示配置记录数量
    var total = grid.jqGrid('getGridParam', 'records'); //获取查询得到的总记录数量
    //设置rowNum为总记录数量并且刷新jqGrid,使所有记录现出来调用getRowData方法才能获取到所有数据
    grid.jqGrid('setGridParam',{rowNum: total,}).trigger('reloadGrid');
    var rows = o.jqGrid('getRowData');
    grid.jqGrid('setGridParam',{rowNum: rowNum,}).trigger('reloadGrid');
    postToPOM(rows);
}
//发送post请求
function postToPOM(rows) {
    console.log(rows);
    var url = "../student/exstudent";
    var xhr = new XMLHttpRequest();
    xhr.open('POST',url,true);
    xhr.responseType = "blob";
    xhr.setRequestHeader("Content-Type"
        , "application/json;charset=utf-8");
    //添加监听事件。
    xhr.addEventListener("load",abideBtn,false);
    xhr.addEventListener("error",downloadError,false);
    xhr.onload = function (){
        if(this.status === 200){
            //创建Bolb对象
            var blob = this.response;//html5新出的
            var reader = new FileReader();
            reader.readAsDataURL(blob);
            reader.onload = function(e){
                //创建a标签,构造下载弹窗
                var a = document.createElement("a");
                a.id = "downloadTag";
                a.download = '学生信息管理表.xlsx';
                a.href = e.target.result;
                $("body").append(a);
                a.click();
                $("#downloadTag").remove();
                console.log("下载完成!");
                //恢复按钮
                $("#download").attr({"href":"javascript:exportData();"});
                $("#download").css("cursor","pointer");
            }
        }
    };
    xhr.send(JSON.stringify(rows));
}

猜你喜欢

转载自blog.csdn.net/m0_38072683/article/details/82990629