C#导出EXCEL方法总结
下面介绍下我根据网上学习C#中导出EXCEL的几种方法:
一、asp.net导出Excel
1.将整个html全部输出到Excel
此方法会将html中所有的内容,如按钮、表格、图片等全部输出
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 Response.Clear(); 2 Response.Buffer= true; 3 Response.AppendHeader("Content-Disposition","attachment;filename="+DateTime.Now.ToString("yyyyMMdd")+".xls"); 4 Response.ContentEncoding=System.Text.Encoding.UTF8; 5 Response.ContentType = "application/vnd.ms-excel"; 6 this.EnableViewState = false;
2.将DataGrid控件中的数据导出到Excel(也可以是其他控件)
此方法若使用分页,则导出当前页DataGrid中显示的信息。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public void DGToExcel(System.Web.UI.Control ctl) 2 { 3 HttpContext.Current.Response.AppendHeader("Content-Disposition","attachment;filename=Excel.xls"); 4 HttpContext.Current.Response.Charset ="UTF-8"; 5 HttpContext.Current.Response.ContentEncoding =System.Text.Encoding.Default; 6 HttpContext.Current.Response.ContentType ="application/ms-excel"; 7 ctl.Page.EnableViewState =false; 8 System.IO.StringWriter tw = new System.IO.StringWriter() ; 9 System.Web.UI.HtmlTextWriter hw = new System.Web.UI.HtmlTextWriter (tw); 10 ctl.RenderControl(hw); 11 HttpContext.Current.Response.Write(tw.ToString()); 12 HttpContext.Current.Response.End(); 13 }
用法DGToExcel(datagrid1);
3.将DataSet中的数据导出到Excel
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public void CreateExcel(DataSet ds,string FileName) 2 { 3 HttpResponse resp; 4 resp = Page.Response; 5 resp.ContentEncoding = System.Text.Encoding.GetEncoding("GB2312"); 6 resp.AppendHeader("Content-Disposition", "attachment;filename="+FileName); 7 string colHeaders= "", ls_item=""; 8 9 //定义表对象与行对象,同时用DataSet对其值进行初始化 10 DataTable dt=ds.Tables[0]; 11 DataRow[] myRow=dt.Select();//可以类似dt.Select("id>10")之形式达到数据筛选目的 12 int i=0; 13 int cl=dt.Columns.Count; 14 15 //取得数据表各列标题,各标题之间以t分割,最后一个列标题后加回车符 16 for(i=0;i<cl;i++) 17 { 18 if(i==(cl-1))//最后一列,加n 19 { 20 colHeaders +=dt.Columns[i].Caption.ToString() +"n"; 21 } 22 else 23 { 24 colHeaders+=dt.Columns[i].Caption.ToString()+"t"; 25 } 26 27 } 28 resp.Write(colHeaders); 29 //向HTTP输出流中写入取得的数据信息 30 31 //逐行处理数据 32 foreach(DataRow row in myRow) 33 { 34 //当前行数据写入HTTP输出流,并且置空ls_item以便下行数据 35 for(i=0;i<cl;i++) 36 { 37 if(i==(cl-1))//最后一列,加n 38 { 39 ls_item +=row[i].ToString()+"n"; 40 } 41 else 42 { 43 ls_item+=row[i].ToString()+"t"; 44 } 45 46 } 47 resp.Write(ls_item); 48 ls_item=""; 49 50 } 51 resp.End();
以ms-excel的格式response到http流,参数ds为填充有数据表的DataSet,文件名是全名,包括后缀名,如Excel2006.xls。
4.将dataview导出到Excel
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public void OutputExcel(DataView dv,string str) 2 { 3 //dv为要输出到Excel的数据,str为标题名称 4 GC.Collect(); 5 Application excel;// = new Application(); 6 int rowIndex=4; 7 int colIndex=1; 8 9 _Workbook xBk; 10 _Worksheet xSt; 11 12 excel= new ApplicationClass(); 13 14 xBk = excel.Workbooks.Add(true); 15 16 xSt = (_Worksheet)xBk.ActiveSheet; 17 18 // 19 //取得标题 20 // 21 foreach(DataColumn col in dv.Table.Columns) 22 { 23 colIndex++; 24 excel.Cells[4,colIndex] = col.ColumnName; 25 xSt.get_Range(excel.Cells[4,colIndex],excel.Cells[4,colIndex]).HorizontalAlignment = XlVAlign.xlVAlignCenter;//设置标题格式为居中对齐 26 } 27 28 // 29 //取得表格中的数据 30 // 31 foreach(DataRowView row in dv) 32 { 33 rowIndex ++; 34 colIndex = 1; 35 foreach(DataColumn col in dv.Table.Columns) 36 { 37 colIndex ++; 38 if(col.DataType == System.Type.GetType("System.DateTime")) 39 { 40 excel.Cells[rowIndex,colIndex] = (Convert.ToDateTime(row[col.ColumnName].ToString())).ToString("yyyy-MM-dd"); 41 xSt.get_Range(excel.Cells[rowIndex,colIndex],excel.Cells[rowIndex,colIndex]).HorizontalAlignment = XlVAlign.xlVAlignCenter;//设置日期型的字段格式为居中对齐 42 } 43 else 44 if(col.DataType == System.Type.GetType("System.String")) 45 { 46 excel.Cells[rowIndex,colIndex] = "'"+row[col.ColumnName].ToString(); 47 xSt.get_Range(excel.Cells[rowIndex,colIndex],excel.Cells[rowIndex,colIndex]).HorizontalAlignment = XlVAlign.xlVAlignCenter;//设置字符型的字段格式为居中对齐 48 } 49 else 50 { 51 excel.Cells[rowIndex,colIndex] = row[col.ColumnName].ToString(); 52 } 53 } 54 } 55 // 56 //加载一个合计行 57 // 58 int rowSum = rowIndex + 1; 59 int colSum = 2; 60 excel.Cells[rowSum,2] = "合计"; 61 xSt.get_Range(excel.Cells[rowSum,2],excel.Cells[rowSum,2]).HorizontalAlignment = XlHAlign.xlHAlignCenter; 62 // 63 //设置选中的部分的颜色 64 // 65 xSt.get_Range(excel.Cells[rowSum,colSum],excel.Cells[rowSum,colIndex]).Select(); 66 xSt.get_Range(excel.Cells[rowSum,colSum],excel.Cells[rowSum,colIndex]).Interior.ColorIndex = 19;//设置为浅黄色,共计有56种 67 // 68 //取得整个报表的标题 69 // 70 excel.Cells[2,2] = str; 71 // 72 //设置整个报表的标题格式 73 // 74 xSt.get_Range(excel.Cells[2,2],excel.Cells[2,2]).Font.Bold = true; 75 xSt.get_Range(excel.Cells[2,2],excel.Cells[2,2]).Font.Size = 22; 76 // 77 //设置报表表格为最适应宽度 78 // 79 xSt.get_Range(excel.Cells[4,2],excel.Cells[rowSum,colIndex]).Select(); 80 xSt.get_Range(excel.Cells[4,2],excel.Cells[rowSum,colIndex]).Columns.AutoFit(); 81 // 82 //设置整个报表的标题为跨列居中 83 // 84 xSt.get_Range(excel.Cells[2,2],excel.Cells[2,colIndex]).Select(); 85 xSt.get_Range(excel.Cells[2,2],excel.Cells[2,colIndex]).HorizontalAlignment = XlHAlign.xlHAlignCenterAcrossSelection; 86 // 87 //绘制边框 88 // 89 xSt.get_Range(excel.Cells[4,2],excel.Cells[rowSum,colIndex]).Borders.LineStyle = 1; 90 xSt.get_Range(excel.Cells[4,2],excel.Cells[rowSum,2]).Borders[XlBordersIndex.xlEdgeLeft].Weight = XlBorderWeight.xlThick;//设置左边线加粗 91 xSt.get_Range(excel.Cells[4,2],excel.Cells[4,colIndex]).Borders[XlBordersIndex.xlEdgeTop].Weight = XlBorderWeight.xlThick;//设置上边线加粗 92 xSt.get_Range(excel.Cells[4,colIndex],excel.Cells[rowSum,colIndex]).Borders[XlBordersIndex.xlEdgeRight].Weight = XlBorderWeight.xlThick;//设置右边线加粗 93 xSt.get_Range(excel.Cells[rowSum,2],excel.Cells[rowSum,colIndex]).Borders[XlBordersIndex.xlEdgeBottom].Weight = XlBorderWeight.xlThick;//设置下边线加粗 94 // 95 //显示效果 96 // 97 excel.Visible=true; 98 99 //xSt.Export(Server.MapPath(".")+""+this.xlfile.Text+".xls",SheetExportActionEnum.ssExportActionNone,Microsoft.Office.Interop.OWC.SheetExportFormat.ssExportHTML); 100 xBk.SaveCopyAs(Server.MapPath(".")+""+this.xlfile.Text+".xls"); 101 102 ds = null; 103 xBk.Close(false, null,null); 104 105 excel.Quit(); 106 System.Runtime.InteropServices.Marshal.ReleaseComObject(xBk); 107 System.Runtime.InteropServices.Marshal.ReleaseComObject(excel); 108 System.Runtime.InteropServices.Marshal.ReleaseComObject(xSt); 109 xBk = null; 110 excel = null; 111 xSt = null; 112 GC.Collect(); 113 string path = Server.MapPath(this.xlfile.Text+".xls"); 114 115 System.IO.FileInfo file = new System.IO.FileInfo(path); 116 Response.Clear(); 117 Response.Charset="GB2312"; 118 Response.ContentEncoding=System.Text.Encoding.UTF8; 119 // 添加头信息,为"文件下载/另存为"对话框指定默认文件名 120 Response.AddHeader("Content-Disposition", "attachment; filename=" + Server.UrlEncode(file.Name)); 121 // 添加头信息,指定文件大小,让浏览器能够显示下载进度 122 Response.AddHeader("Content-Length", file.Length.ToString()); 123 124 // 指定返回的是一个不能被客户端读取的流,必须被下载 125 Response.ContentType = "application/ms-excel"; 126 127 // 把文件流发送到客户端 128 Response.WriteFile(file.FullName); 129 // 停止页面的执行 130 131 Response.End(); 132 }
二、winform中导出Excel的方法
1.方法
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 SqlConnection conn=new SqlConnection(System.Configuration.ConfigurationSettings.AppSettings["conn"]); 2 SqlDataAdapter da=new SqlDataAdapter("select * from tb1",conn); 3 DataSet ds=new DataSet(); 4 da.Fill(ds,"table1"); 5 DataTable dt=ds.Tables["table1"]; 6 string name=System.Configuration.ConfigurationSettings.AppSettings["downloadurl"].ToString()+DateTime.Today.ToString("yyyyMMdd")+new Random(DateTime.Now.Millisecond).Next(10000).ToString()+".csv";//存放到web.config中downloadurl指定的路径,文件格式为当前日期+4位随机数 7 FileStream fs=new FileStream(name,FileMode.Create,FileAccess.Write); 8 StreamWriter sw=new StreamWriter(fs,System.Text.Encoding.GetEncoding("gb2312")); 9 sw.WriteLine("自动编号,姓名,年龄"); 10 foreach(DataRow dr in dt.Rows) 11 { 12 sw.WriteLine(dr["ID"]+","+dr["vName"]+","+dr["iAge"]); 13 } 14 sw.Close(); 15 Response.AddHeader("Content-Disposition", "attachment; filename=" + Server.UrlEncode(name)); 16 Response.ContentType = "application/ms-excel";// 指定返回的是一个不能被客户端读取的流,必须被下载 17 Response.WriteFile(name); // 把文件流发送到客户端 18 Response.End(); 19 20 21 public void Out2Excel(string sTableName,string url) 22 { 23 Excel.Application oExcel=new Excel.Application(); 24 Workbooks oBooks; 25 Workbook oBook; 26 Sheets oSheets; 27 Worksheet oSheet; 28 Range oCells; 29 string sFile="",sTemplate=""; 30 // 31 System.Data.DataTable dt=TableOut(sTableName).Tables[0]; 32 33 sFile=url+"myExcel.xls"; 34 sTemplate=url+"MyTemplate.xls"; 35 // 36 oExcel.Visible=false; 37 oExcel.DisplayAlerts=false; 38 //定义一个新的工作簿 39 oBooks=oExcel.Workbooks; 40 oBooks.Open(sTemplate,Type.Missing,Type.Missing,Type.Missing,Type.Missing,Type.Missing,Type.Missing,Type.Missing,Type.Missing,Type.Missing,Type.Missing,Type.Missing,Type.Missing, Type.Missing, Type.Missing); 41 oBook=oBooks.get_Item(1); 42 oSheets=oBook.Worksheets; 43 oSheet=(Worksheet)oSheets.get_Item(1); 44 //命名该sheet 45 oSheet.Name="Sheet1"; 46 47 oCells=oSheet.Cells; 48 //调用dumpdata过程,将数据导入到Excel中去 49 DumpData(dt,oCells); 50 //保存 51 oSheet.SaveAs(sFile,Excel.XlFileFormat.xlTemplate,Type.Missing,Type.Missing, Type.Missing, Type.Missing, Excel.XlSaveAsAccessMode.xlNoChange, Type.Missing, Type.Missing, Type.Missing); 52 oBook.Close(false, Type.Missing,Type.Missing); 53 //退出Excel,并且释放调用的COM资源 54 oExcel.Quit(); 55 56 GC.Collect(); 57 KillProcess("Excel"); 58 } 59 60 private void KillProcess(string processName) 61 { 62 System.Diagnostics.Process myproc= new System.Diagnostics.Process(); 63 //得到所有打开的进程 64 try 65 { 66 foreach (Process thisproc in Process.GetProcessesByName(processName)) 67 { 68 if(!thisproc.CloseMainWindow()) 69 { 70 thisproc.Kill(); 71 } 72 } 73 } 74 catch(Exception Exc) 75 { 76 throw new Exception("",Exc); 77 } 78 }
2.方法
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 protected void ExportExcel() 2 { 3 gridbind(); 4 if(ds1==null) return; 5 6 string saveFileName=""; 7 // bool fileSaved=false; 8 SaveFileDialog saveDialog=new SaveFileDialog(); 9 saveDialog.DefaultExt ="xls"; 10 saveDialog.Filter="Excel文件|*.xls"; 11 saveDialog.FileName ="Sheet1"; 12 saveDialog.ShowDialog(); 13 saveFileName=saveDialog.FileName; 14 if(saveFileName.IndexOf(":")<0) return; //被点了取消 15 // excelapp.Workbooks.Open (App.path & 工程进度表.xls) 16 17 Excel.Application xlApp=new Excel.Application(); 18 object missing=System.Reflection.Missing.Value; 19 20 21 if(xlApp==null) 22 { 23 MessageBox.Show("无法创建Excel对象,可能您的机子未安装Excel"); 24 return; 25 } 26 Excel.Workbooks workbooks=xlApp.Workbooks; 27 Excel.Workbook workbook=workbooks.Add(Excel.XlWBATemplate.xlWBATWorksheet); 28 Excel.Worksheet worksheet=(Excel.Worksheet)workbook.Worksheets[1];//取得sheet1 29 Excel.Range range; 30 31 32 string oldCaption=Title_label .Text.Trim (); 33 long totalCount=ds1.Tables[0].Rows.Count; 34 long rowRead=0; 35 float percent=0; 36 37 worksheet.Cells[1,1]=Title_label .Text.Trim (); 38 //写入字段 39 for(int i=0;i<ds1.Tables[0].Columns.Count;i++) 40 { 41 worksheet.Cells[2,i+1]=ds1.Tables[0].Columns.ColumnName; 42 range=(Excel.Range)worksheet.Cells[2,i+1]; 43 range.Interior.ColorIndex = 15; 44 range.Font.Bold = true; 45 46 } 47 //写入数值 48 Caption .Visible = true; 49 for(int r=0;r<ds1.Tables[0].Rows.Count;r++) 50 { 51 for(int i=0;i<ds1.Tables[0].Columns.Count;i++) 52 { 53 worksheet.Cells[r+3,i+1]=ds1.Tables[0].Rows[r]; 54 } 55 rowRead++; 56 percent=((float)(100*rowRead))/totalCount; 57 this.Caption.Text= "正在导出数据["+ percent.ToString("0.00") +"%] "; 58 Application.DoEvents(); 59 } 60 worksheet.SaveAs(saveFileName,missing,missing,missing,missing,missing,missing,missing,missing); 61 62 this.Caption.Visible= false; 63 this.Caption.Text= oldCaption; 64 65 range=worksheet.get_Range(worksheet.Cells[2,1],worksheet.Cells[ds1.Tables[0].Rows.Count+2,ds1.Tables[0].Columns.Count]); 66 range.BorderAround(Excel.XlLineStyle.xlContinuous,Excel.XlBorderWeight.xlThin,Excel.XlColorIndex.xlColorIndexAutomatic,null); 67 68 range.Borders[Excel.XlBordersIndex.xlInsideHorizontal].ColorIndex = Excel.XlColorIndex.xlColorIndexAutomatic; 69 range.Borders[Excel.XlBordersIndex.xlInsideHorizontal].LineStyle =Excel.XlLineStyle.xlContinuous; 70 range.Borders[Excel.XlBordersIndex.xlInsideHorizontal].Weight =Excel.XlBorderWeight.xlThin; 71 72 if(ds1.Tables[0].Columns.Count>1) 73 { 74 range.Borders[Excel.XlBordersIndex.xlInsideVertical].ColorIndex=Excel.XlColorIndex.xlColorIndexAutomatic; 75 } 76 workbook.Close(missing,missing,missing); 77 xlApp.Quit(); 78 }
3.从DataGridView里导出
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /// <summary> 2 /// 常用方法,列之间加\t开。 3 /// </summary> 4 /// <remarks> 5 /// using System.IO; 6 /// </remarks> 7 /// <param name="dgv"></param> 8 private void DataGridViewToExcel(DataGridView dgv) 9 { 10 SaveFileDialog dlg = new SaveFileDialog(); 11 dlg.Filter = "Execl files (*.xls)|*.xls"; 12 dlg.CheckFileExists = false; 13 dlg.CheckPathExists = false; 14 dlg.FilterIndex = 0; 15 dlg.RestoreDirectory = true; 16 dlg.CreatePrompt = true; 17 dlg.Title = "保存为Excel文件"; 18 19 if (dlg.ShowDialog() == DialogResult.OK) 20 { 21 Stream myStream; 22 myStream = dlg.OpenFile(); 23 StreamWriter sw = new StreamWriter(myStream, System.Text.Encoding.GetEncoding(-0)); 24 string columnTitle = ""; 25 try 26 { 27 //写入列标题 28 for (int i = 0; i < dgv.ColumnCount; i++) 29 { 30 if (i > 0) 31 { 32 columnTitle += "\t"; 33 } 34 columnTitle += dgv.Columns[i].HeaderText; 35 } 36 sw.WriteLine(columnTitle); 37 38 //写入列内容 39 for (int j = 0; j < dgv.Rows.Count; j++) 40 { 41 string columnValue = ""; 42 for (int k = 0; k < dgv.Columns.Count; k++) 43 { 44 if (k > 0) 45 { 46 columnValue += "\t"; 47 } 48 if (dgv.Rows[j].Cells[k].Value == null) 49 columnValue += ""; 50 else 51 columnValue += dgv.Rows[j].Cells[k].Value.ToString().Trim(); 52 } 53 sw.WriteLine(columnValue); 54 } 55 sw.Close(); 56 myStream.Close(); 57 } 58 catch (Exception e) 59 { 60 MessageBox.Show(e.ToString()); 61 } 62 finally 63 { 64 sw.Close(); 65 myStream.Close(); 66 } 67 } 68 }
4.把Excel数据读到DataSet里
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 OpenFileDialog dlg = new OpenFileDialog(); 2 dlg.Filter = "Execl files (*.xls)|*.xls"; 3 dlg.CheckFileExists = false; 4 dlg.CheckPathExists = false; 5 dlg.FilterIndex = 0; 6 dlg.RestoreDirectory = true; 7 dlg.Title = "将Excel文件数据导入到DataSet"; 8 dlg.ShowDialog(); 9 10 DataSet ds = new DataSet(); 11 string strConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + dlg.FileName.Trim() + ";Extended Properties='Excel 8.0;HDR=False;IMEX=1'"; 12 using (OleDbConnection OleConn = new OleDbConnection(strConn)) 13 { 14 OleConn.Open(); 15 String sql = "SELECT * FROM [Sheet1$]"; 16 OleDbDataAdapter OleDaExcel = new OleDbDataAdapter(sql, OleConn); 17 OleDaExcel.Fill(ds); 18 OleConn.Close(); 19 }
三、字符串导出方法
1.通用导出Excel的方法
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /// <summary> 2 /// 导出Execel 3 /// </summary> 4 /// <param name="columnTitle">列名以"\t分隔"如 列2\t列3\t列4</param> 5 /// <param name="resutl">行,要与上面的列对应,列名以"\t分隔"如 列2\t列3\t列4 第行使用\n分隔 </param> 6 private void ToExcel(string columnTitle, string resutl) 7 { 8 SaveFileDialog dlg = new SaveFileDialog(); 9 dlg.Filter = "Execl files (*.xls)|*.xls"; 10 dlg.FilterIndex = 0; 11 dlg.RestoreDirectory = true; 12 dlg.Title = "保存为Excel文件"; 13 14 if (dlg.ShowDialog() == DialogResult.OK) 15 { 16 Stream myStream; 17 myStream = dlg.OpenFile(); 18 StreamWriter sw = new StreamWriter(myStream, System.Text.Encoding.GetEncoding(-0)); 19 try 20 { 21 //写入列名称 22 sw.WriteLine(columnTitle); 23 //写入行 24 sw.WriteLine(resutl); 25 26 sw.Close(); 27 myStream.Close(); 28 } 29 catch (Exception e) 30 { 31 MessageBox.Show(e.ToString()); 32 } 33 finally 34 { 35 sw.Close(); 36 myStream.Close(); 37 } 38 } 39 40 }
2.给个例子
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 给个例子吧,希望对你有帮助。 2 #region 导出用户信息到Excel 3 /// <summary> 4 /// 导出用户信息到Excel 5 /// </summary> 6 /// <param name="sender"></param> 7 /// <param name="e"></param> 8 protected void btnExcelOut_Click(object sender, EventArgs e) 9 { 10 T_SYS_UserBLL userBll = new T_SYS_UserBLL(); 11 12 Response.Clear(); 13 Response.ContentType = "application/vnd.ms-excel"; 14 Response.Charset = "GB2312"; 15 Page.EnableViewState = false; 16 Response.ContentEncoding = System.Text.Encoding.GetEncoding("GB2312");//使输出的中文不乱码 17 string FileName = "人员导出Execel" + DateTime.Now.ToString("yyyy-MM-dd") + ".xls"; 18 Response.AppendHeader("Content-Disposition", "attachment;filename= " + HttpUtility.UrlEncode(FileName, Encoding.UTF8).ToString()); 19 Response.Write("<html><head><meta http-equiv=Content-Type content=\"text/html;charset=GB2312\"><title>Copyright by SDU</title></head><body><form runat=server id=b1>"); 20 Response.Write("<table border='1' cellpadding='0' cellspacing='0'><tr><td width='280' hight='40' align=\"center\"><strong>用户编号</strong>" 21 + "</td><td width='140' align=\"center\"><strong>用户姓名</strong></td><td width='140' align=\"center\"><strong>用户登录名</strong>" 22 + "</td><td width='140' align=\"center\"><strong>用户性别</strong></td><td width='140' align=\"center\"><strong>用户QQ</strong>" 23 + "</td><td width='140' align=\"center\"><strong>用户手机</strong></td><td width='140' align=\"center\"><strong>用户状态</strong>" 24 + "<td width='140' align=\"center\"><strong>用户备注</strong></td></tr>"); 25 26 27 DataSet ds = userBll.GetUserInfoList(""); 28 29 for (int i = 0; i < ds.Tables[0].Rows.Count; i++) 30 { 31 string userID = ds.Tables[0].Rows[i]["User_ID"].ToString(); //用户编号 32 string loginName = ds.Tables[0].Rows[i]["User_LoginName"].ToString(); //用户登录名 33 string realName = ds.Tables[0].Rows[i]["User_RealName"].ToString(); //用户登录名 34 35 string userSex = ""; //用户性别 36 int Sex = Convert.ToInt32(ds.Tables[0].Rows[i]["User_SEX"]); 37 if (Sex == 1) 38 { 39 userSex = "男"; 40 } 41 else if (Sex == 0) 42 { 43 userSex = "女"; 44 } 45 46 string userQQ = ds.Tables[0].Rows[i]["User_QQ"].ToString(); 47 string mobile = ds.Tables[0].Rows[i]["User_Mobile"].ToString(); 48 string userStatus = ""; 49 int status = Convert.ToInt32(ds.Tables[0].Rows[i]["User_Status"]); 50 if (status == 1) 51 { 52 userStatus = "已停用"; 53 } 54 else if (status == 0) 55 { 56 userStatus = "正常"; 57 } 58 string userDes = ds.Tables[0].Rows[i]["User_Des"].ToString(); 59 60 Response.Write("<tr><td align=\"center\" height=\"20px\">" + userID + "</td>" 61 + "<td align=\"center\" height=\"20px\">" + realName + "</td>" 62 + "<td align=\"center\" height=\"20px\">" + loginName + "</td>" 63 + "<td align=\"center\" height=\"20px\">" + userSex + "</td>" 64 + "<td align=\"center\" height=\"20px\">" + userQQ + "</td>" 65 + "<td align=\"center\" height=\"20px\">" + mobile + "</td>" 66 + "<td align=\"center\" height=\"20px\">" + userStatus + "</td>" 67 + "<td align=\"center\" height=\"20px\">" + userDes + "</td>" 68 + "</tr>"); 69 } 70 Response.Write("</table></form></body></html>"); 71 Response.End(); 72 } 73 #endregion
3.学习下他人的
如果你仅仅只有Asp.net Web Forms背景转而学习Asp.net MVC的,我想你的第一个经历或许是那些曾经让你的编程变得愉悦无比的服务端控件都驾鹤西去了.FileUpload就是其中一个,而这个控件的缺席给我们带来一些小问题。这篇文章主要说如何在Asp.net MVC中上传文件,然后如何再从服务器中把上传过的文件下载下来.
在Web Forms中,当你把一个FileUpload控件拖到设计器中,你或许没有注意到在生成的HTML中会在form标签中加入一条额外属性enctype="multipart/form-data". 而FileUpload控件本身会生成为<input type=”file” />,在MVC的view里,有许多种方法可以做到同样效果,第一种的HTML如下:
<form action="/" method="post" enctype="multipart/form-data"> <input type="file" name="FileUpload1" /><br /> <input type="submit" name="Submit" id="Submit" value="Upload" /> </form>
注意form标签已经包括了enctype标签,而method属性则设为”post”,这样设置并不多于因为默认的提交时通过HTTP get方式进行的。下面这种方式,使用Html.BeginForm()扩展方法,会生成和上面同样的HTML:
<% using (Html.BeginForm("", "home", FormMethod.Post, new {enctype="multipart/form-data"})) {%> <input type="file" name="FileUpload1" /><br /> <input type="submit" name="Submit" id="Submit" value="Upload" /> <% }%>
注意<input type=”file”>标签的name属性,我们在后面再讨论,上面代码会如下图:
OK,现在我们可以浏览本地文件然后通过Upload提交按钮将文件提交到服务器端,下一步就是在服务器端处理上传的文件,在使用fileUpload控件时,你可以很轻松的通过FileUpload的hasFile方法来查看文件是否被上传。但是在Asp.net MVC中貌似就不是这么方便了,你会和原始的HTTP更接近一些,然而,一个扩展方法可以处理这些:
public static bool HasFile(this HttpPostedFileBase file) { return (file != null && file.ContentLength > 0) ? true : false; }
当你看到对应的Controller类的代码时,你会发现Request对象作为HttpRequestBase类型的一个属性存在。HttpReuqestBase其实是HTTP请求的一个封装,暴漏了很多属性,包括Files collection(其实是HttpFileCollectionBase的集合),在集合中的每一个元素都是HttpPostedFileBase的集合,扩展方法是用于确保上传的文件是否存在。实际上,这和FileUpload.HasFile()方法的工作原理一致。
在Controller Action中使用起来其实很容易:
public class HomeController : Controller { public ActionResult Index() { foreach (string upload in Request.Files) { if (!Request.Files[upload].HasFile()) continue; string path = AppDomain.CurrentDomain.BaseDirectory + "uploads/"; string filename = Path.GetFileName(Request.Files[upload].FileName); Request.Files[upload].SaveAs(Path.Combine(path, filename)); } return View(); } }
多文件上传
或许你已经比我更早的想到如何更好的将Request.Files作为一个集合使用。这意味着它不仅仅只能容纳一个文件,而能容纳多个,我们将上面的View改为如下:
<% using (Html.BeginForm("", "home", FormMethod.Post, new {enctype="multipart/form-data"})) {%> <input type="file" name="FileUpload1" /><br /> <input type="file" name="FileUpload2" /><br /> <input type="file" name="FileUpload3" /><br /> <input type="file" name="FileUpload4" /><br /> <input type="file" name="FileUpload5" /><br /> <input type="submit" name="Submit" id="Submit" value="Upload" /> <% }%>
效果如下:
在Controller的代码中已经检查了是否所有的文件上传框中都有文件,所以即使对于多文件上传,我们也不再需要修改Controller的代码,注意每一个<input type=”file”>都有不同的name属性,如果你需要调用其中一个,比如说,你需要引用第三个输入框只需要使用:Request.Files["FileUpload3"].
存入数据库
在你冲我狂吼”关注点分离”之前,我想声明下面的代码仅仅用于作为说明功能.我将ADO.Net的代码放入Controller action中,但我们都知道,这并不好。数据访问的代码应该放在Model中某个部分的数据访问层中.但是,下面这段代码仅仅可以给大家怎样将上传的文件存入数据库中一个更直观的印象,首先,我们需要创建一个数据表(FileTest)并创建一个表:FileStore
CREATE TABLE [dbo].[FileStore]( [ID] [int] IDENTITY(1,1) NOT NULL, [FileContent] [image] NOT NULL, [MimeType] [nvarchar](50) NOT NULL, [FileName] [nvarchar](50) NOT NULL ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
FileContent域是image数据类型,用于存储以二进制数据形成的文件,而Index Action改为:
public ActionResult Index() { foreach (string upload in Request.Files) { if (!Request.Files[upload].HasFile()) continue; string mimeType = Request.Files[upload].ContentType; Stream fileStream = Request.Files[upload].InputStream; string fileName = Path.GetFileName(Request.Files[upload].FileName); int fileLength = Request.Files[upload].ContentLength; byte[] fileData = new byte[fileLength]; fileStream.Read(fileData, 0, fileLength); const string connect = @"Server=.\SQLExpress;Database=FileTest;Trusted_Connection=True;"; using (var conn = new SqlConnection(connect)) { var qry = "INSERT INTO FileStore (FileContent, MimeType, FileName) VALUES (@FileContent, @MimeType, @FileName)"; var cmd = new SqlCommand(qry, conn); cmd.Parameters.AddWithValue("@FileContent", fileData); cmd.Parameters.AddWithValue("@MimeType", mimeType); cmd.Parameters.AddWithValue("@FileName", fileName); conn.Open(); cmd.ExecuteNonQuery(); } } return View(); }
修改后的代码会以循环的方式遍历Web页面中所有的上传文件,并检查<input type=”file”>中是否已经加入文件,然后,从文件中提取出3个信息:文件名,MIME类型(文件的类型),HTTP Request中的二进制流。二进制数据被转换为byte数组,并以image数据类型存入数据库。MIME类型和文件名对于用户从数据库中提取文件来说非常重要。
将数据库中的文件返回给用户:
你如何将文件传送给用户取决于你最开始如何存储它,如果你将文件存入数据库,你会用流的方式将文件返还给用户,如果你将文件存在硬盘中,你只需要提供一个超链接即可,或者也可以以流的方式。每当你需要以流的方式将文件送到浏览器中,你都的使用到File()方法的重载(而不是使用我们先前一直使用的View()方法),对于File()方法有3类返回类型:FilePathResult,FileContentResult和FileStreamResult,第一种类型用于直接从磁盘返回文件;第二种类型用于将byte数组返回客户端;而第三种方式将已经生成并打开的流对象的内容返回客户端。
如果你还记得的话,我们将上传的文件存入了数据库,并以byte数组的形式存入FileContent域内.而当需要提取时,它仍然会以一个byte数组进行提取,这意味着我们使用返回FileContentResult的File()重载,如果我们想让提取的文件名更有意义,我们使用接受3个参数的重载,三个参数是:byte数组,MIME类型,文件名:
public FileContentResult GetFile(int id) { SqlDataReader rdr; byte[] fileContent = null; string mimeType = "";string fileName = ""; const string connect = @"Server=.\SQLExpress;Database=FileTest;Trusted_Connection=True;"; using (var conn = new SqlConnection(connect)) { var qry = "SELECT FileContent, MimeType, FileName FROM FileStore WHERE ID = @ID"; var cmd = new SqlCommand(qry, conn); cmd.Parameters.AddWithValue("@ID", id); conn.Open(); rdr = cmd.ExecuteReader(); if (rdr.HasRows) { rdr.Read(); fileContent = (byte[])rdr["FileContent"]; mimeType = rdr["MimeType"].ToString(); fileName = rdr["FileName"].ToString(); } } return File(fileContent, mimeType, fileName); }
在View中最简单的使用来使用这个Action只需提供一个超链接:
<a href="/GetFile/1">Click to get file</a>
如果在数据库中存储的图片是图片类型,和使用超链接不同的是,我们通过指向Controller action的一个带有src属性的<image>标签来获取:
<img src="/GetFile/1" alt="My Image" />
下面再让我们来看看使用FilePathResult(用于从硬盘提取文件)是多简单的事:
public FilePathResult GetFileFromDisk() { string path = AppDomain.CurrentDomain.BaseDirectory + "uploads/"; string fileName = "test.txt"; return File(path + fileName, "text/plain", "test.txt"); }
而这也可以用过超链接提取:
<a href="/GetFileFromDisk">Click to get file</a>
而最后一个选择FileStreamResult也可以从磁盘中提取文件:
public FileStreamResult StreamFileFromDisk() { string path = AppDomain.CurrentDomain.BaseDirectory + "uploads/"; string fileName = "test.txt"; return File(new FileStream(path + fileName, FileMode.Open), "text/plain", fileName); }
FilePathResult和FileStreamResult的区别是什么?我们又该如何取舍呢?主要的区别是FilePathResult使用HttpResponse.TransmitFile来将文件写入Http输出流。这个方法并不会在服务器内存中进行缓冲,所以这对于发送大文件是一个不错的选择。他们的区别很像DataReader和DataSet的区别。于此同时, TransmitFile还有一个bug,这可能导致文件传到客户端一半就停了,甚至无法传送。而FileStreamResult在这方面就很棒了。比如说:返回Asp.net Chart 控件在内存中生成的图表图片,而这并不需要将图片存到磁盘中.
------------------------------------------------
原文链接:http://www.mikesdotnetting.com/Article/125/ASP.NET-MVC-Uploading-and-Downloading-Files
译文连接:http://www.cnblogs.com/CareySon/archive/2009/12/23/1630902.html
注明:均在网上转载,经整理分享大家学习!