zoukankan      html  css  js  c++  java
  • 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()
        }
     
     
  • 相关阅读:
    5 Things Every Manager Should Know about Microsoft SharePoint 关于微软SharePoint每个经理应该知道的五件事
    Microsoft SharePoint 2010, is it a true Document Management System? 微软SharePoint 2010,它是真正的文档管理系统吗?
    You think you use SharePoint but you really don't 你认为你使用了SharePoint,但是实际上不是
    Introducing Document Management in SharePoint 2010 介绍SharePoint 2010中的文档管理
    Creating Your Own Document Management System With SharePoint 使用SharePoint创建你自己的文档管理系统
    MVP模式介绍
    权重初始化的选择
    机器学习中线性模型和非线性的区别
    神经网络激励函数的作用是什么
    深度学习中,交叉熵损失函数为什么优于均方差损失函数
  • 原文地址:https://www.cnblogs.com/wyt007/p/8989765.html
Copyright © 2011-2022 走看看