ASP.Net MVC中數據庫數據導出Excel,供HTTP下載


本文來自:http://www.cnblogs.com/hipo/archive/2012/03/13/2394019.html

 

一、關於下載

一般對下載權限有沒有限制,或安全性要求不高的情況下,基於web的下載可以直接采用提供服務器文件路徑的方式,瀏覽器端就可以下載。當然對於這種方式的弊端顯而易見,用戶可以獲得下載文件在服務器端的絕對路徑,下載的權限也沒有辦法進行控制。如果你的網站提供的下載有復雜的邏輯判斷,那么這種方式就不能解決問題。

要解決這個問題,我們可以采用以文件流的方式提供下載。客戶端發出下載請求,在服務器端收到請求后,找到后台相應的處理邏輯代碼,首先驗證請求是否符合下載條件,在做出相應的相應。若驗證成功,將請求下載文件轉化為文件流,傳給瀏覽器;若不成功,直接拒絕下載。

在ASP.Net 中這個HTTP請求的后台處理邏輯,可用一般處理文件*.ashx。這個文件的抽象度沒有.aspx那么高,相比之下比較原始,所以我們可以自定義處理邏輯。

下面來分析下ASP.Net MVC況下,關於安全下載的實現。ASP.Net MVC已經為我們做好封裝,即FileResult ,但是FileResult是個抽象,而具體包括FilePathResult、FileStreamResult、FileContentResult三個之類,可向客戶端傳送文件(二進制形式),例如存在服務器磁盤word文檔,或者存儲在數據庫中巨大數據等。只需要設置FileDownloadName屬性,就可以達到添加HTTP報頭的作用,在客戶端出現下載對話框。當具體實現的時候,可以使用工廠模式

二、數據庫導出Excel

1. POINPIO

目前,常用的數據庫導出Excel的方法,是借助第三方的類庫。第三類庫中很重要的一個就是PIO,是Apache下一個開源項目,提供一個Java類庫對Microsoft Office進行讀寫操作。當然,這里要介紹的不是PIO,而是.Net環境下,基於PIO的NPIO,可以理解為.Net POI。NPOI是微軟開源社區CodePlex的一個開源項目,旨在提供.net平台上操作Office的服務。

點擊這里參看NPOI的教程文檔。

2. 在NPOI中包括了兩個dll:Ionic.Zip.dll和NPOI.dll。

 

三、一個ASP.Net MVC 2.0下導出Excel並提供下載的例子

通過以下幾步,建立一個項目:

1. 創建ASP.Net MVC 2.0項目SQLServer2Excel;

2. 添加對於NPOI類庫的引用,包括Ionic.Zip.dll和NPOI.dll;

1

3.鏈接本地數據庫Test,在web.config做如下配置:

 

   1: <connectionStrings>  
   2:    <add name="TestConnectionString" connectionString="Data Source=(local);Initial Catalog=Test;Integrated Security=True"
   3:      providerName="System.Data.SqlClient" />
   4:  </connectionStrings>

 

通過以上幾步,我們已經建立了基本環境,下面我們來中點介紹下NPOI和FileResult的使用:

1.寫NPOI導出方法,首先必須using命名空間NPOI.SS.UserModel和NPOI.HSSF.UserModel。在這個例子中,NPOI將輸入DataSet對象,轉化為Excel表格,並且保存了MemoryStream的內存流對象,這樣做的好處:在提供下載的同時,不會在服務器端產生中間文件。

這里采用的是以基於Column和Row的方式解析Dataset對象的。

   1: using System;
   2: using System.Collections.Generic;
   3: using System.Linq;
   4: using System.Web;
   5: using System.IO;
   6: using NPOI.SS.UserModel;
   7: using NPOI.HSSF.UserModel;
   8: using System.Data;
   9:  
  10: namespace SQLServer2Excel.Models
  11: {
  12:     public class ExportTool
  13:     {
  14:         /// <summary>
  15:         /// 將DataSet數據集轉換HSSFworkbook對象,並保存為Stream流
  16:         /// </summary>
  17:         /// <param name="ds"></param>
  18:         /// <returns>返回數據流Stream對象</returns>
  19:         public static MemoryStream ExportDatasetToExcel(DataSet ds)
  20:         {
  21:             try
  22:             {
  23:                 //文件流對象
  24:                  MemoryStream stream = new MemoryStream();
  25:  
  26:                 //打開Excel對象
  27:                 HSSFWorkbook workbook = new HSSFWorkbook();
  28:  
  29:                 //Excel的Sheet對象
  30:                 NPOI.SS.UserModel.Sheet sheet = workbook.CreateSheet("sheet1");
  31:  
  32:                 //set date format
  33:                 CellStyle cellStyleDate = workbook.CreateCellStyle();
  34:                 DataFormat format = workbook.CreateDataFormat();
  35:                 cellStyleDate.DataFormat = format.GetFormat("yyyy年m月d日");
  36:  
  37:                 //使用NPOI操作Excel表
  38:                 NPOI.SS.UserModel.Row row = sheet.CreateRow(0);
  39:                 int count = 0;
  40:                 for (int i = 0; i < ds.Tables[0].Columns.Count; i++) //生成sheet第一行列名 
  41:                 {
  42:                     NPOI.SS.UserModel.Cell cell = row.CreateCell(count++);
  43:                     cell.SetCellValue(ds.Tables[0].Columns[i].Caption);
  44:                 }
  45:                 //將數據導入到excel表中
  46:                 for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
  47:                 {
  48:                     NPOI.SS.UserModel.Row rows = sheet.CreateRow(i + 1);
  49:                     count = 0;
  50:                     for (int j = 0; j < ds.Tables[0].Columns.Count; j++)
  51:                     {
  52:                         NPOI.SS.UserModel.Cell cell = rows.CreateCell(count++);
  53:                         Type type = ds.Tables[0].Rows[i][j].GetType();
  54:                         if (type == typeof(int) || type == typeof(Int16)
  55:                             || type == typeof(Int32) || type == typeof(Int64))
  56:                         {
  57:                             cell.SetCellValue((int)ds.Tables[0].Rows[i][j]);
  58:                         }
  59:                         else
  60:                         {
  61:                             if (type == typeof(float) || type == typeof(double) || type == typeof(Double))
  62:                             {
  63:                                 cell.SetCellValue((Double)ds.Tables[0].Rows[i][j]);
  64:                             }
  65:                             else
  66:                             {
  67:                                 if (type == typeof(DateTime))
  68:                                 {
  69:                                     cell.SetCellValue(((DateTime)ds.Tables[0].Rows[i][j]).ToString("yyyy-MM-dd HH:mm"));
  70:                                 }
  71:                                 else
  72:                                 {
  73:                                     if (type == typeof(bool) || type == typeof(Boolean))
  74:                                     {
  75:                                         cell.SetCellValue((bool)ds.Tables[0].Rows[i][j]);
  76:                                     }
  77:                                     else
  78:                                     {
  79:                                         cell.SetCellValue(ds.Tables[0].Rows[i][j].ToString());
  80:                                     }
  81:                                 }
  82:                             }
  83:                         }
  84:                     }
  85:                 }
  86:  
  87:                 //保存excel文檔
  88:                 sheet.ForceFormulaRecalculation = true;
  89:  
  90:                 workbook.Write(stream);
  91:                 workbook.Dispose();
  92:  
  93:                 return stream;
  94:             }
  95:             catch
  96:             {
  97:                 return new MemoryStream();
  98:             }
  99:         }
 100:     }
 101: }

 

2. FileResult的使用,這里實際上用到的是其之類FileStreamResult。

   1: public FileResult DownloadFile()
   2:         {
   3:             DataSet ds = Person.GetPersonDataSet(new DataSet());
   4:  
   5:             MemoryStream stream = ExportTool.ExportDatasetToExcel(ds);
   6:             stream.Seek(0, SeekOrigin.Begin);
   7:  
   8:             return File(stream, "application/vnd.ms-excel", "spreadsheet1.xls");
   9:         }
這里說明一下兩點: a. 第6行代碼的作用:如果沒有這行代碼,可能保存的數據大小為0kb,這是因為調整下輸出流的開始位置;
                         b.第8行File()方法,此方法的各種重載方法,可以返回FileResult的之類對象。在這里第二參數“application/vnd.ms-                            excel”代表Excel文件,第三個參數給定文件名。
最終效果圖: 2


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM