2010-09-23 172 views
22

在C#ASP.net中,有人能告訴我如何將數組/列表中的條目寫入服務器上的CSV文件,然後打開該文件嗎?我認爲第二部分會像 - Response.Redirect(「http://myserver.com/file.csv」),但不知道如何在服務器上寫入文件。寫入CSV文件並將其導出?

此外,如果此頁面被許多用戶訪問,每次生成新的CSV文件還是覆蓋同一個文件會更好?如果兩個用戶都嘗試訪問相同的CSV文件等,是否會有讀/寫/鎖定問題?


更新:

這可能是一個愚蠢的問題,我已經搜索在谷歌,但我無法找到一個明確的答案 - 你怎麼寫一個CSV文件到網絡服務器和導出在C#ASP.net?我知道如何生成它,但我想將它保存到www.mysite.com/my.csv然後導出它。

+0

CSV文件對所有用戶來說總是相同嗎? – TheGeekYouNeed 2010-09-23 11:43:24

回答

47

ROM檢查出csvreader /寫庫,你這樣做是錯誤的。您不想將文件寫入磁盤,以便IIS可以爲其提供服務。這增加了安全隱患並增加了複雜性。您真正需要做的就是直接將CSV保存到響應流中。

這裏是場景:用戶希望下載csv。用戶提交表單並提供他們想要的csv的詳細信息。您準備csv,然後爲用戶提供一個可以用於構建csv文件並將其寫入響應流的aspx頁面的URL。用戶點擊鏈接。 aspx頁面是空白的;在頁面代碼隱藏中,只需將csv寫入響應流並結束即可。

您可以添加以下的(我相信這是正確的)Load事件:

string attachment = "attachment; filename=MyCsvLol.csv"; 
HttpContext.Current.Response.Clear(); 
HttpContext.Current.Response.ClearHeaders(); 
HttpContext.Current.Response.ClearContent(); 
HttpContext.Current.Response.AddHeader("content-disposition", attachment); 
HttpContext.Current.Response.ContentType = "text/csv"; 
HttpContext.Current.Response.AddHeader("Pragma", "public"); 

var sb = new StringBuilder(); 
foreach(var line in DataToExportToCSV) 
    sb.AppendLine(TransformDataLineIntoCsv(line)); 

HttpContext.Current.Response.Write(sb.ToString()); 

寫入響應流碼ganked from here

+1

謹慎使用Response.End()。更多信息:http://stackoverflow.com/questions/1087777/is-response-end-considered-harmful – 2015-05-18 16:14:40

1

如何在用戶每次訪問的頁面......每個接入將採取行動以自己的名義它的時間寫入文件(在谷歌搜索方便)... 1st Search Result

至於創建文件。你的商業案例將決定行爲。

案例1 - 相同的文件,但不會改變(這種類型的案件可以被定義多種方式)

  • 你會在需要的時候創建該文件的邏輯,如果一代只能訪問文件不需要。

案例2 - 每個用戶都需要自己生成的文件

  • 你會決定你如何識別每個用戶,爲每個用戶創建一個文件並訪問他們應該看到的文件...這可以很容易地與案例1合併。然後,如果需要持久性,則在服務內容後刪除該文件。

案例3 - 每個接入

  • 使用案例2需要相同的文件,但一代,這將導致一代每次但清理一次訪問。
4

這是我寫的一個CSV操作結果,它需要一個DataTable並將其轉換爲CSV。你可以從你的視圖中返回它,它會提示用戶下載文件。你應該能夠很容易地將它轉換成一個List兼容的表格,甚至可以將你的列表放入一個DataTable中。

using System; 
using System.Text; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 
using System.Web.Mvc; 
using System.Data; 

namespace Detectent.Analyze.ActionResults 
{ 
    public class CSVResult : ActionResult 
    { 
     /// <summary> 
     /// Converts the columns and rows from a data table into an Microsoft Excel compatible CSV file. 
     /// </summary> 
     /// <param name="dataTable"></param> 
     /// <param name="fileName">The full file name including the extension.</param> 
     public CSVResult(DataTable dataTable, string fileName) 
     { 
      Table = dataTable; 
      FileName = fileName; 
     } 

     public string FileName { get; protected set; } 
     public DataTable Table { get; protected set; } 




     public override void ExecuteResult(ControllerContext context) 
     { 
      StringBuilder csv = new StringBuilder(10 * Table.Rows.Count * Table.Columns.Count); 

      for (int c = 0; c < Table.Columns.Count; c++) 
      { 
       if (c > 0) 
        csv.Append(","); 
       DataColumn dc = Table.Columns[c]; 
       string columnTitleCleaned = CleanCSVString(dc.ColumnName); 
       csv.Append(columnTitleCleaned); 
      } 
      csv.Append(Environment.NewLine); 
      foreach (DataRow dr in Table.Rows) 
      { 
       StringBuilder csvRow = new StringBuilder(); 
       for(int c = 0; c < Table.Columns.Count; c++) 
       { 
        if(c != 0) 
         csvRow.Append(","); 

        object columnValue = dr[c]; 
        if (columnValue == null) 
         csvRow.Append(""); 
        else 
        { 
         string columnStringValue = columnValue.ToString(); 


         string cleanedColumnValue = CleanCSVString(columnStringValue); 

         if (columnValue.GetType() == typeof(string) && !columnStringValue.Contains(",")) 
         { 
          cleanedColumnValue = "=" + cleanedColumnValue; // Prevents a number stored in a string from being shown as 8888E+24 in Excel. Example use is the AccountNum field in CI that looks like a number but is really a string. 
         } 
         csvRow.Append(cleanedColumnValue); 
        } 
       } 
       csv.AppendLine(csvRow.ToString()); 
      } 

      HttpResponseBase response = context.HttpContext.Response; 
      response.ContentType = "text/csv"; 
      response.AppendHeader("Content-Disposition", "attachment;filename=" + this.FileName); 
      response.Write(csv.ToString()); 
     } 

     protected string CleanCSVString(string input) 
     { 
      string output = "\"" + input.Replace("\"", "\"\"").Replace("\r\n", " ").Replace("\r", " ").Replace("\n", "") + "\""; 
      return output; 
     } 
    } 
} 
+0

非常感謝。幫助我使用csv文件的邏輯並從瀏覽器下載。 – Soader03 2014-06-04 14:48:56

6

約威爾的答案評論,您可能希望與HttpContext.Current.ApplicationInstance.CompleteRequest();更換HttpContext.Current.Response.End();的原因是Response.End()拋出一個System.Threading.ThreadAbortException。它會中止一個線程。如果你有一個異常記錄器,它將被拋出ThreadAbortException異常,在這種情況下它是預期的行爲。

直觀地說,向瀏覽器發送CSV文件不應引發異常。

在這裏看到更多Is Response.End() considered harmful?

21

下面是C#一個非常簡單的免費開源的CsvExport類。底部有一個ASP.NET MVC示例。

https://github.com/jitbit/CsvExport

大約需要換行符,逗號,引號逃逸,MS Excel中了兼容性護理...只是一個短期.cs文件添加到您的項目,你是好去。

(聲明:我是其中一位參與者)

+6

我個人想感謝您的分享和這項偉大的工作。 – LikePod 2016-03-08 22:26:20

+0

謝謝。它似乎在工作。 – Reza 2017-03-28 14:11:40

相關問題