需求:
把数据库中某表转换为excel,用户通过浏览器可以直接保存到桌面。
想法:
由于是第一次接触,当时的想法是用户点击某个按钮后弹出一个savefiledialog,然后选择路径给保存起来。一看就是典型的Winform思想。至于程序实现当时猜测的是需要使用excel相关的dll来根据数据库表的结构来填充,程序实现的话可以使用服务端或者客服端。服务端即服务端生成后下载下来,客户端就直接客户端生成。
解决:
查了下资料,没有这么复杂。
Step1:根据DataTable生成Excel
/// <summary>
/// 把DataTable内容导出伟excel并返回客户端
/// 需要注意的是,导出excel之前要把datatable的列名更改为客户要求的文字,就ok了。因为是从DataTable导出的,所以这种方法解决了分页数据的问题,堪称终极解决方案。
/// </summary>
/// <param name="dgData">待导出的DataTable</param>
public static void DataTable2Excel(System.Data.DataTable dtData)
{
System.Web.UI.WebControls.DataGrid dgExport = null;
// 当前对话
System.Web.HttpContext curContext = System.Web.HttpContext.Current;
// IO用于导出并返回excel文件
System.IO.StringWriter strWriter = null;
System.Web.UI.HtmlTextWriter htmlWriter = null;
if (dtData != null)
{
// 设置编码和附件格式
curContext.Response.ContentType = "application/vnd.ms-excel";
curContext.Response.ContentEncoding = System.Text.Encoding.UTF8;
curContext.Response.Charset = "utf-8";
//attachment表示作为附件下载,filename指定输出文件名称,这里我强制设置了文件后缀为.xls
//因为经过测试若不设置后缀,使用firefox,遨游这些的都没有问题。但使用IE会出现问题,下载的文件没有后缀。
curContext.Response.AppendHeader("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode("调查问卷导出.xls", Encoding.UTF8).ToString());
// 导出excel文件
strWriter = new System.IO.StringWriter();
htmlWriter = new System.Web.UI.HtmlTextWriter(strWriter);
// 为了解决dgData中可能进行了分页的情况,需要重新定义一个无分页的DataGrid
dgExport = new System.Web.UI.WebControls.DataGrid();
dgExport.DataSource = dtData.DefaultView;
dgExport.AllowPaging = false;
dgExport.DataBind();
// 返回客户端
dgExport.RenderControl(htmlWriter);
curContext.Response.Write(strWriter.ToString());
curContext.Response.End();
}
}
Step2:剩下的工作便是获得DataTable,并为DataTable的字段使用客户需要的文字(主要是中文)
DataTable myDataTable = new DataTable();
int count = columnField.Count;// columnField为List<string>类型 存储了最后需要显示的名称
for (int j = 0; j < count; j++)
{
DataColumn myDataColumn = new DataColumn(columnField[j].ToString(), typeof(string));//设置字段名称和类型
myDataTable.Columns.Add(myDataColumn);
}
return myDataTable;
Step3:接着是填充只有字段名称的数据表的属性
while (MyOleDbDataReader.Read())
{
DataRow dr = myDataTable.NewRow();
for (int i = 0; i < count; i++)
{
//dr[i] = MyOleDbDataReader.GetString(i); //该方法出错后会报错“Specified cast is not valid.”,使用mysql数据库测试的时候没有报错,使用access报错。于是换成GetValue(int i)来获得属性值
dr[i] = MyOleDbDataReader.GetValue(i).ToString();
}
myDataTable.Rows.Add(dr);