由来:考试系统中导出学生成绩,当时可能是自己的疏忽,觉得调试时能很成功的导出成绩,就不会有什么大问题,但是当真正使用的时候,应用发布的版本导出成绩系统却没有任何反应,也不提示任何错误。原因?
问题一:代码
如下是两种方式的导出excel的代码:
代码1:
/// <summary> /// 导出Excel /// </summary> /// <param name="dt"></param> /// <param name="ExportFileName"></param> public void ToExcel(DataTable dt) { DataGrid dgExcel = new DataGrid(); dgExcel.DataSource = dt; dgExcel.DataBind(); HttpContext.Current.Response.Charset = "GB2312"; string fileName = HttpUtility.UrlEncode(Guid.NewGuid().ToString(), System.Text.Encoding.UTF8); string str = "attachment;filename=" + fileName + ".xls"; HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.UTF8; HttpContext.Current.Response.ContentType = "application/ms-excel"; HttpContext.Current.Response.AppendHeader("content-disposition", str); StringWriter sw = new StringWriter(); HtmlTextWriter htmTextWriter = new HtmlTextWriter(sw); dgExcel.RenderControl(htmTextWriter); HttpContext.Current.Response.Write("<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />"); string style = "<style>td{mso-number-format:\"\\@\";}</style>";//防止导出excel时将以0开头的全数字数据的0去掉 HttpContext.Current.Response.Write(style); HttpContext.Current.Response.Write("</head><body>"); HttpContext.Current.Response.Write(sw); HttpContext.Current.Response.Write("</body></html>"); HttpContext.Current.Response.Flush(); sw.Close(); htmTextWriter.Close(); }
//导出excel public void ToExcel(System.Data.DataTable dt) { //新建Excel程序 Application excelApp = new Application(); //设置Excel程序显示 excelApp.Visible = true; //新建工作簿 Workbook workBook = excelApp.Workbooks.Add(true); //获取工作表 Worksheet workSheet = workBook.Worksheets[1]; //设置所有列为文本格式 workSheet.Columns.NumberFormatLocal = "@"; //填充Excel工作表 //填充表头 int countRow;//行计数变量 int countCol;//列计数变量 for (countCol = 0; countCol < dt.Columns.Count; countCol++) { workSheet.Cells[1, countCol + 1] = dt.Columns[countCol].ColumnName; } //填充内容 for (countRow = 0; countRow < dt.Rows.Count; countRow++) { for (countCol = 0; countCol < dt.Columns.Count; countCol++) { workSheet.Cells[countRow + 2, countCol + 1] = dt.Rows[countRow][countCol].ToString(); } } /*---------------设置Excel单元格的格式-------------*/ //获取最后一列的内容区 Range errorMessageRange = workSheet.Range[workSheet.Cells[2, countCol], workSheet.Cells[countRow + 1, countCol]]; //获取第一行 Range headRange = workSheet.Range["A1", workSheet.Cells[1, countCol]]; //设置第一行字体加粗 headRange.Font.Bold = true; //设置所有列宽自适应 workSheet.Columns.EntireColumn.AutoFit(); }
同样是以datatable来导出excel,分析一下这两种代码的异同!使用第二种方式的时候导出excel大家有没有注意到,点击导出后,excel立即打开,单元格中填充着我们要的数据,但是为什么当我们将系统一发布,导出excel就失效了,还没有任何异常抛出。当你看到excel导出成功并直接打开,有没有考虑过什么是web开发?
在调试的过程中,因为觉得未发布没有问题,那么应该不是代码的问题,就一直在网上查找原因,各种方式的尝试,直到分析代码时才察觉到问题的所在。
其实当我们发现在本地导出excel时,它直接打开excel就应该发现问题。
Web开发的B/S是浏览器/服务器模式则无需客户端软件,只要客户端安装Web浏览器就能够使用系统功能,而系统的更新也只需要管理员替换服务器文件就可以实现,无需用户去下载客户端。流程:客户端发送路径(网址)用来向服务端请求服务,通了之后服务端会返回来一些信息来提供服务。
既然是这样,那么在这个过程中怎么可能出现代码2的编写方式呢,不可能客户端自己建立excel呀!而是第一种方式请求服务器,从服务器下载下来的才是我们的需要呀!固如图:
问题二:UpdatePanel的慎用
ScriptManager和UpdatePanel控件联合使用可以实现页面异步局部更新的效果。其中的UpdatePanel就是设置页面中异步局部更新区域,它必须依赖于ScriptManager存在,因为ScriptManger控件提供了客户端脚本生成与管理UpdatePanel的功能。
UpdatePanel可以避免页面的频繁刷新!当然它的优点是简单易用,但是也容易引起一些功能(弹出框,导出excel,分页等)的失效(本应刷新的内容却被阻止)!
注意:
使用UpdatePanel时,尽量让UpdatePanel仅包含必要的内容,不要盲目的扩大UpdatePanel的包含范围!
总结:
本身就这个问题而言应该不是什么难实现的功能,在实现的时候也没有考虑很多,将这次开发的大前提忽视了。出现问题时也一直觉得代码不会有问题,毕竟可以实现,对于发布不成功一直以为是发布过程中缺少了什么。通过这次教训更深刻的理解了BS的运行的机制,对于BS的前后台有了一个更清晰的概念。
下篇博客将继续介绍UpdatePanel的用法!