2017-08-30 54 views
0

因此,我試圖做的是從我的數據庫中讀取選擇存儲過程,將數據保存在csv文件中,並使用戶能夠通過Web應用程序下載它。我能夠通過將文件臨時保存到我的程序foldel並使用文件流來獲得所需的結果。我現在要做的是跳過保存文件的部分到我的電腦上,然後暫時保存在RAM內存中。從我理解我必須使用內存流而不是文件流,但我真的不明白我能做到這一點。從我所瞭解的是我讀到的是,而不是我使用一個文件,我需要將我的數據轉換爲字節使內存流出來,然後在我的FileStreamResult中使用它。我在這裏糾正?如何利用內存流而不是文件流

方法,當我從程序讀取並保存到csvfile:

public static String StoreApproved() 
{   
    string path1 = HttpRuntime.AppDomainAppPath + "Report.csv"; 
    SqlConnection sqlConnection1 = new SqlConnection("CONNECTIONSTRING"); 
    SqlCommand cmd = new SqlCommand(); 
    SqlDataReader reader; 
    cmd.CommandText = "ExportApproved"; 
    cmd.CommandType = CommandType.StoredProcedure; 
    cmd.Connection = sqlConnection1; 
    sqlConnection1.Open(); 
    reader = cmd.ExecuteReader(); 
    List<ModelStoreProcedureApproved> TestList = new List<ModelStoreProcedureApproved>(); 
    ModelStoreProcedureApproved test ; 

    while (reader.Read()) 
    { 
     test = new ModelStoreProcedureApproved(); 
     // test.Id = int.Parse(reader["IdTimeTracker"].ToString()); 
     test.Month = reader["Month"].ToString(); 
     test.EmailUser = reader["Email"].ToString(); 
     test.Project = reader["Name"].ToString(); 
     test.Approved = reader["Description"].ToString(); 
     test.Month = reader["Month"].ToString(); 
     test.Year = reader["Year"].ToString(); 
     TestList.Add(test); 
    } 

    File.Create(path1).Close(); 
    var i = TestList.FirstOrDefault(); 
    using (TextWriter fileReader = new StreamWriter(path1)) 
    { 
     var csv = new CsvWriter(fileReader); 
     csv.Configuration.Encoding = Encoding.UTF8; 
     foreach (var value in TestList) 
     { 
      csv.WriteRecord(value); 
     } 
     fileReader.Close(); 
    } 
    sqlConnection1.Close(); 
    return path1; 
} 

控制器代碼:

public ActionResult ExportToCSV() 
{ 
    string path = Repositories.UserRepository.StoreApproved(); 
    var fileStream = new FileStream(path, 
            FileMode.Open, 
            FileAccess.Read); 

    return new FileStreamResult(fileStream, "text/csv") { FileDownloadName = "export.csv" }; 
} 

有人可以解釋我怎麼做到這一點的最好辦法是什麼? 其他職位我讀 Serialize and Deserialize using BinaryFormatter

BinaryFormatter and Deserialization Complex objects

Using CSVHelper to output stream to browser

回答

1

你可以這樣說:

public static byte[] StoreApproved() 
{   
    string path1 = HttpRuntime.AppDomainAppPath + "Report.csv"; 
    SqlConnection sqlConnection1 = new SqlConnection("CONNECTIONSTRING"); 
    SqlCommand cmd = new SqlCommand(); 
    SqlDataReader reader; 
    cmd.CommandText = "ExportApproved"; 
    cmd.CommandType = CommandType.StoredProcedure; 
    cmd.Connection = sqlConnection1; 
    sqlConnection1.Open(); 
    reader = cmd.ExecuteReader(); 
    List<ModelStoreProcedureApproved> TestList = new List<ModelStoreProcedureApproved>(); 
    ModelStoreProcedureApproved test ; 

    while (reader.Read()) 
    { 
     test = new ModelStoreProcedureApproved(); 
     // test.Id = int.Parse(reader["IdTimeTracker"].ToString()); 
     test.Month = reader["Month"].ToString(); 
     test.EmailUser = reader["Email"].ToString(); 
     test.Project = reader["Name"].ToString(); 
     test.Approved = reader["Description"].ToString(); 
     test.Month = reader["Month"].ToString(); 
     test.Year = reader["Year"].ToString(); 
     TestList.Add(test); 
    } 

    var i = TestList.FirstOrDefault(); 
    var mem = new MemoryStream(); 
    using (TextWriter fileReader = new StreamWriter(mem)) 
    { 
     var csv = new CsvWriter(fileReader); 
     csv.Configuration.Encoding = Encoding.UTF8; 
     foreach (var value in TestList) 
     { 
      csv.WriteRecord(value); 
     } 
    } 
    sqlConnection1.Close(); 
    return mem.ToArray(); 
} 

public ActionResult ExportToCSV() 
{ 
    byte[] bytes = Repositories.UserRepository.StoreApproved(); 
    Stream stream = new MemoryStream(bytes); 
    return new FileStreamResult(stream, "text/csv") { FileDownloadName = "export.csv" }; 
} 
+0

我得到一個exeption說:System.ObjectDisposedException:無法訪問封閉的流。 –

+0

嘗試使用字節,然後不知道爲什麼發生。我更新了代碼以使用字節來傳遞結果。 –

+0

工作!非常感謝你。當它允許我批准答案時 –

0

我建議你關注清晰的分離,因爲你也使用ASP .Net MVC。不要在同一個方法內讀取和創建內存流,而要先讀取/獲取所需的數據集合,然後將數據從方法中返回。然後在動作方法中,您可以根據您的要求使用所需的格式(綁定到UI或返回文件等)對其進行修飾。

雖然這不是對您的問題的直接答案,並且如果您所看到的只是因爲正在使用內存流,有很多示例可供使用,例如here以及您接受的答案等。

希望這對您有所幫助。

+0

你說得對。我會按照你的說法去做,並將代碼分割成多個方法,這樣就很容易計算出所有的東西。謝謝你的提示,我很感激。 –