• ajax实现文档导出及下载


    做导出一直遇到个问题就是不能用ajax实现一步导出文档,即导出加下载。今天突然想到可以分开来做就上网搜了下,发现一篇比较不错的文章(http://www.cnblogs.com/zj0208/p/5961181.html),先摘录下来。

    问题说明: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方法实现下载

     

      //ajax交互导出文档并获取文档路径及预下载文件名,返回格式{"result":"success","filePath":"","fileName":""}
            function DownFilesAjax(url, prams, downurl) {
                showLoading(true);//调用加载动画http://spin.js.org/
                $.ajax({
                    type: 'POST',
                    dataType: 'json',
                    async: false,
                    url: url,// 生成文件,保存在服务器
                    data: prams,
                    success: function (data) {
                        if (data.result == "success") {
                            $.download(downurl, 'post', data.filePath, data.fileName); // 下载文件 
                           showLoading(false);//隐藏加载动画http://spin.js.org/
                        } else {
                            alert("数据导出失败!");
                            showLoading(false);
                        }
                    },
                    error: function (XMLHttpRequest, textStatus, e) {
                        //console.log("oilDetection.js  method exportOilDetection" + e);
                        alert("数据传输发生错误,请联系管理员!");
                        showLoading(false);
                    }
                });
            }

    附上spin加载动画调用js及其容器的遮罩样式。

    调用js:

     var opts = {
                lines: 9, // 花瓣数目
                length: 0, // 花瓣长度
                 10, // 花瓣宽度
                radius: 15, // 花瓣距中心半径
                corners: 1, // 花瓣圆滑度 (0-1)
                rotate: 0, // 花瓣旋转角度
                direction: 1, // 花瓣旋转方向 1: 顺时针, -1: 逆时针
                color: '#fff', // 花瓣颜色
                speed: 1, // 花瓣旋转速度
                trail: 60, // 花瓣旋转时的拖影(百分比)
                shadow: false, // 花瓣是否显示阴影
                hwaccel: false, //spinner 是否启用硬件加速及高速旋转
                className: 'spinner', // spinner css 样式名称 easyui里用这个类样式,若引用了easyui.css务必换个类名,其他前端框架未知
                zIndex: 2e9, // spinner的z轴 (默认是2000000000)
                top: '50%', // spinner 相对父容器Top定位 单位 px
                left: '50%'// spinner 相对父容器Left定位 单位 px
            };
            var spinner = new Spinner(opts);
            //显示与隐藏加载动画
            function showLoading(result) {
                var spinContainer = document.getElementById("foo");
                if (result) {
               var target = $(spinContainer).get(0);
                spinner.spin(target);
                spinContainer.style.height = document.documentElement.clientHeight + "px";
               $(spinContainer).show();
                } else {
                spinner.spin();
               $(spinContainer).hide();
             }
            }

    遮罩样式:

     #foo {
                position: fixed;
                left: 0;
                top: 0;
                _position: absolute;
                 100%;
                background: #000;
                opacity: 0.5;
                filter: alpha(opacity=50);
                z-index: 999;
            display:none;
            }

    以下一般处理程序中的相关代码。

    导出文档:

      public void ExportALLNianDuGongZuo(HttpContext context)
        {
            string result = string.Empty;
            string Name = DateTime.Now.Year + "导出的文件" + ".xls";//下载文档名
            try
            {
                #region 导出过程
                DataTable dt = new DataTable();
                DataColumn dc = null;
                dc = dt.Columns.Add("序号", Type.GetType("System.Int32"));
                dc.AutoIncrement = true;//自动增加
                dc.AutoIncrementSeed = 1;//起始为1
                dc.AutoIncrementStep = 1;//步长为1
                dc.AllowDBNull = false;//
                dc = dt.Columns.Add("col1", Type.GetType("System.String"));
                dc = dt.Columns.Add("col2", Type.GetType("System.String"));
                dc = dt.Columns.Add("col3", Type.GetType("System.String"));
                dc = dt.Columns.Add("col4", Type.GetType("System.String"));
                dc = dt.Columns.Add("col5", Type.GetType("System.String"));
    
                IList<object> list = object.FindAll(@"IsEnable=1", "GOrder, PaiXu", null, 0, 0);//数据列表
                foreach (var item in list)
                {
                        DataRow newRow;
                        newRow = dt.NewRow();
                        newRow["col1"] = item.Name;
                        newRow["col2"] = item.Ext3;
                        newRow["col3"] = item.XieZuoDeptName;
                        newRow["col4"] = item.Ext2;
                        newRow["col5"] = IsShangHui.Trim();
                        dt.Rows.Add(newRow);
                }
                MemoryStream ms = new MemoryStream();
                string Path = context.Server.MapPath("~/UploadFile/" + DateTime.Now.ToString("yyyyMMddHHmmss") + ".xls");//文件保存地址
                string templatePath = context.Server.MapPath("~/UploadFile/模版.xls");//所用模版地址
                ms = NPOIExcelHelper.DataTableToExcel(dt, templatePath, 2);//详见NPOI导出execl
                using (FileStream fs = new FileStream(Path, FileMode.Create, FileAccess.Write))
                {
                    byte[] data = ms.ToArray();
                    fs.Write(data, 0, data.Length);
                    fs.Flush();
                }
                #endregion
                result = "{"result":"success","filePath":"" + ReplaceString(Path) + "","fileName":"" + Name + ""}";
            }
            catch (Exception ex)
            {
                result = "{"result":"fail"}";
                Unionstars.Trace.Log.WriteLine("导出发生错误:【" + ex + "");
            }
            context.Response.ContentType = "application/Json";
            context.Response.Write(result);
            context.Response.End();
    }

    ajax无法传输文件,另新建web页面用来下载即可。

    下载文档页面后台代码(前台删得只剩第一句即可):

      protected void Page_Load(object sender, EventArgs e)
        {
            string fileName = Request["filename"];//下载文档名
            string filePath = Request["filedir"];
            FileInfo fileInfo = new FileInfo(filePath);
            Response.Clear();
            Response.ClearContent();
            Response.ClearHeaders();
            String userAgent = System.Web.HttpContext.Current.Request.UserAgent;
            //判断是否为ie10以下及ie11浏览器
            if (userAgent.Contains("MSIE") || userAgent.Contains("rv:11"))
            {
                fileName = System.Web.HttpUtility.UrlEncode(fileName);
            }
            Response.AddHeader("Content-Disposition", string.Format("attachment;filename="{0}"", fileName));
            Response.AddHeader("Content-Length", fileInfo.Length.ToString());
            Response.AddHeader("Content-Transfer-Encoding", "binary");
            Response.ContentType = "application/octet-stream";
            Response.ContentEncoding = System.Text.Encoding.GetEncoding("gb2312");
            Response.WriteFile(fileInfo.FullName);
            Response.Flush();
            Response.End();
        }

    终极方法,哈哈哈,留到最后
     
        function download(url, downLoadFileRename) {
            var xhr = new XMLHttpRequest();
            xhr.open('GET', url, true);        // 也可以使用POST方式,根据接口
            xhr.responseType = "blob";    // 返回类型blob
            // 定义请求完成的处理函数,请求前也可以增加加载框/禁用下载按钮逻辑
            xhr.onload = function () {
                // 请求完成
                if (this.status === 200) {
                    // 返回200
                    var blob = this.response;
                    var reader = new FileReader();
                    reader.readAsDataURL(blob);    // 转换为base64,可以直接放入a表情href
                    reader.onload = function (e) {
                        // 转换完成,创建一个a标签用于下载
                        var a = document.createElement('a');
                        a.download = downLoadFileRename;
                        a.href = e.target.result;
                        $("body").append(a);    // 修复firefox中无法触发click
                        a.click();
                        $(a).remove();
                    }
                }
            };
            // 发送ajax请求
            xhr.send()
        }
     
     
  • 相关阅读:
    虚拟列表
    vue中使用postcsspxtorem实现适配
    打包工具 rollup.js 入门教程
    后端一次给你10万条数据,如何优雅展示,到底考察我什么
    手写Promise原理
    react路由集中管理及鉴权 reactrouterconfig
    结合代码实践,全面学习前端工程化
    KDE 全局菜单文字颜色不随 Plasma Style 变化
    vue使用intro.js引导组件
    第五章、Vue3高级
  • 原文地址:https://www.cnblogs.com/wyt007/p/8989765.html
Copyright © 2020-2023  润新知