2010-12-31 36 views
24

Tôi đang cố ghi vào tệp văn bản trong bộ nhớ rồi tải xuống tệp đó mà không lưu tệp vào đĩa cứng. Tôi đang sử dụng số StringWriter để viết nội dung:Tạo tệp văn bản và tải xuống

StringWriter oStringWriter = new StringWriter(); 
oStringWriter.Write("This is the content"); 

Làm cách nào để tải xuống tệp này?

EDIT: Đó là sự kết hợp các câu trả lời đã cho tôi giải pháp của tôi. Ở đây là:

StringWriter oStringWriter = new StringWriter(); 
oStringWriter.WriteLine("Line 1"); 
Response.ContentType = "text/plain"; 

Response.AddHeader("content-disposition", "attachment;filename=" + string.Format("members-{0}.csv",string.Format("{0:ddMMyyyy}",DateTime.Today))); 
Response.Clear(); 

using (StreamWriter writer = new StreamWriter(Response.OutputStream, Encoding.UTF8)) 
{ 
    writer.Write(oStringWriter.ToString()); 
} 
Response.End(); 
+0

http://www.xefteri.com/articles/show.cfm?id=8 – fejesjoco

Trả lời

13

Thay vì lưu trữ các dữ liệu trong bộ nhớ và sau đó gửi nó cho những dòng trả lời, bạn có thể viết trực tiếp vào luồng phản hồi:

using (StreamWriter writer = new StreamWriter(Response.OutputStream, Encoding.UTF8)) { 
    writer.Write("This is the content"); 
} 

Ví dụ sử dụng mã hóa UTF-8, bạn nên thay đổi điều đó nếu bạn đang sử dụng mã hóa khác.

+0

Xin chào Guffa - làm thế nào để tôi nhận luồng phản hồi để tải xuống? – higgsy

+0

@higgsy: Bạn thêm hướng dẫn về bố cục nội dung và loại nội dung trong tiêu đề để trình duyệt biết nó là gì. Klaus Byskow Hoffman có một số ví dụ trong câu trả lời của mình, nhưng bạn không phải sử dụng trình xử lý HTTP để trả về phản hồi, nó cũng hoạt động với một trang thông thường. Bạn cũng nên chỉ định bảng mã trong kiểu nội dung, ví dụ 'text/plain; charset = utf-8'. – Guffa

0

này rất đơn giản, và câu trả lời có thể được nhìn thấy trong Microsoft KB Article: How to write binary files to the browser using ASP.NET and C#

+0

này không thực sự trả lời câu hỏi ... higgsy xác định rằng các tập tin không nên được ghi vào cứng đĩa. – BG100

+2

Xin chào, chính xác, tệp không được ghi vào ổ cứng. – higgsy

5

Về cơ bản bạn tạo một HttpHandler bằng cách thực hiện các giao diện IHttpHandler. Trong phương thức ProcessRequest, về cơ bản bạn chỉ cần viết văn bản của mình là context.Response. Bạn cũng cần phải thêm một tiêu đề Content-Disposition http:

context.Response.AddHeader("Content-Disposition", "attachment; filename=YourFileName.txt"); 

Cũng nên nhớ để thiết lập ContentType:

context.Response.ContentType = "text/plain"; 
2

Chỉ là một bổ sung nhỏ cho các câu trả lời khác. Vào cuối bản tải xuống tôi thực thi:

context.Response.Flush(); 
context.ApplicationInstance.CompleteRequest(); 

Tôi đã học được rằng nếu không, tải xuống đôi khi không hoàn tất thành công.

This Google Groups posting cũng lưu ý rằng Response.End ném một số ThreadAbortException mà bạn có thể tránh bằng cách sử dụng phương thức CompleteRequest.

+1

thực sự khi tôi sử dụng các dòng bạn đã thêm, tệp được tạo chứa văn bản tôi đã viết trong luồng cộng với mã html được hiển thị nên tôi phải lấy lại mã và chỉ cần đặt dòng "Response.End" và nó đã hoạt động bình thường ! – Glolita

+1

Thông thường, tôi chỉ cung cấp tải xuống thông qua trình xử lý ASHX riêng biệt, không phải trong các trang ASPX. –

16

này giải quyết cho tôi:

 MemoryStream ms = new MemoryStream(); 
     TextWriter tw = new StreamWriter(ms); 
     tw.WriteLine("Line 1"); 
     tw.WriteLine("Line 2"); 
     tw.WriteLine("Line 3"); 
     tw.Flush(); 
     byte[] bytes = ms.ToArray(); 
     ms.Close(); 

     Response.Clear(); 
     Response.ContentType = "application/force-download"; 
     Response.AddHeader("content-disposition", "attachment; filename=file.txt"); 
     Response.BinaryWrite(bytes); 
     Response.End();  
0

tôi đã có nhiều vấn đề với điều này. Finnaly tìm thấy một giải pháp mà dường như làm việc mọi lúc.

Trong hầu hết các trường hợp, người dùng sẽ nhấp vào nút để tải xuống. Tại thời điểm này, tốt nhất là chuyển hướng trang trở lại cùng một vị trí. thêm một tham số trong url mà bạn có thể lấy và đọc.

dụ (www.somewhere.com/mypage.aspx?print=stuff)

<asp:Button ID="btn" runat="server" Text="print something" OnClick="btn_Click" /> 


    protected void Page_Load(object sender, EventArgs e) { 
     if (Request["print"] == "stuff") { Print("my test content"); } 
    } 

    /* or pass byte[] content*/ 
    private void Print(string content){ 
     Response.ContentType = "text/plain"; 
     Response.AddHeader("content-disposition", "attachment;filename=myFile.txt"); 
     // Response.BinaryWrite(content); 
     Response.Write(content); 
     Response.Flush(); 
     Response.End(); 
    } 

    protected void btn_Click(object sender, EventArgs e) { 
     // postbacks give you troubles if using async. 
     // Will give an error when Response.End() is called. 
     Response.Redirect(Request.Url + "?print=queue"); 
    } 
0

Gia hạn câu trả lời @Vinicious.

Tôi có dữ liệu có thể chứa dấu phẩy. Giải pháp phổ biến là để thoát khỏi đoạn dữ liệu đó bằng cách kèm theo nó trong dấu ngoặc kép, đồng thời đảm bảo thoát khỏi các dấu ngoặc kép cũng có thể là một phần của dữ liệu.

Một chà tôi đã phản đối và cảnh báo khi viết CSV, excel sẽ không thích bạn nếu bạn đặt dấu cách theo dấu phẩy của bạn.discovered solution to my problem from superuser answer

protected void btnDownload_Click(object sender, EventArgs e) 
{ 
    MemoryStream ms = new MemoryStream(); 
    TextWriter tw = new StreamWriter(ms, System.Text.Encoding.UTF8); 
    var structures = KAWSLib.BusinessLayer.Structure.GetStructuresInService(); 
    // *** comma delimited 
    tw.Write("Latitude, Longitude, CountySerial, StructureType, Orientation, District, RoutePre, RouteNo, LocationDesc"); 
    foreach (var s in structures) 
    { 
     tw.Write(Environment.NewLine + string.Format("{0:#.000000},{1:#.000000},{2},{3},{4},{5},{6},{7},{8}", s.LATITUDE, s.LONGITUDE, s.CO_SER, EscapeIfNeeded(s.SuperTypeLookup.SHORTDESC), EscapeIfNeeded(s.OrientationLookup.SHORTDESC), s.DISTRICT, s.ROUTE_PREFIX, s.RouteValue, EscapeIfNeeded(s.LOC_DESC))); 
    } 
    tw.Flush(); 
    byte[] bytes = ms.ToArray(); 
    ms.Close(); 

    Response.Clear(); 
    Response.ContentType = "application/force-download"; 
    Response.AddHeader("content-disposition", "attachment; filename=" + string.Format("kaws-structures-{0:yyyy.MM.dd}.csv", DateTime.Today)); 
    Response.BinaryWrite(bytes); 
    Response.End(); 
} 

string EscapeIfNeeded(string s) 
{ 
    if (s.Contains(",")) 
    { 
     return "\"" + s.Replace("\"", "\"\"") + "\""; 
    } 
    else 
    { 
     return s; 
    } 
} 

Dưới đây sẽ gây ra sự cố cho excel. Trong excel, báo giá đầu tiên sẽ trở thành một phần của dữ liệu và do đó tách biệt với dấu phẩy được nhúng. Không gian xấu.

tw.Write(Environment.NewLine + string.Format("{0:#.000000}, {1:#.000000}, {2}, {3}, {4}, {5}, {6}, {7}, {8}", s.LATITUDE, s.LONGITUDE, s.CO_SER, EscapeIfNeeded(s.SuperTypeLookup.SHORTDESC), EscapeIfNeeded(s.OrientationLookup.SHORTDESC), s.DISTRICT, s.ROUTE_PREFIX, s.RouteValue, EscapeIfNeeded(s.LOC_DESC))); 
Các vấn đề liên quan