由来:考试系统中导出学生成绩,当时可能是自己的疏忽,觉得调试时能很成功的导出成绩,就不会有什么大问题,但是当真正使用的时候,应用发布的版本导出成绩系统却没有任何反应,也不提示任何错误。原因?
问题一:代码
如下是两种方式的导出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();
}
代码2:
//导出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的用法!