ajax实现文档导出及下载
问题说明:Ajax是无法实现文件传输的,本文只是模拟了Ajax不刷新页面就可以请求并返回数据的效果。实质上还是通过提交form表单来返回文件流的输出。
分步实现逻辑:
- ajax请求服务器,访问数据库,根据查询到的数据生成一个数据文件,返回前台一个json对象(可放置生成成功标记,文件路径等信息)。
- 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, // 花瓣长度 width: 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; width: 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() }
-------------------------------------------
个性签名:独学而无友,则孤陋而寡闻。做一个灵魂有趣的人!
如果觉得这篇文章对你有小小的帮助的话,记得在右下角点个“推荐”哦,博主在此感谢!
万水千山总是情,打赏一分行不行,所以如果你心情还比较高兴,也是可以扫码打赏博主,哈哈哈(っ•̀ω•́)っ✎⁾⁾!


posted on 2018-05-17 20:10 一个大西瓜咚咚咚 阅读(13984) 评论(0) 编辑 收藏 举报
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构