it-swarm.com.de

Erstellen Sie eine Textdatei und laden Sie sie herunter

Ich versuche, eine Textdatei in den Speicher zu schreiben und diese Datei dann herunterzuladen, ohne die Datei auf der Festplatte zu speichern. Ich verwende StringWriter, um den Inhalt zu schreiben:

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

Wie lade ich diese Datei dann herunter?

EDIT: Es war eine Kombination von Antworten, die mir meine Lösung gab. Hier ist es:

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();
25
higgsy

Anstatt die Daten im Speicher zu speichern und dann an den Antwortstream zu senden, können Sie sie direkt in den Antwortstream schreiben:

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

Das Beispiel verwendet die UTF-8-Codierung. Sie sollten diese Einstellung ändern, wenn Sie eine andere Codierung verwenden.

14
Guffa

Dies wurde für mich gelöst:

        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();     
17
VINICIUS SIN

Grundsätzlich erstellen Sie einen HttpHandler, indem Sie die IHttpHandler -Schnittstelle implementieren. In der ProcessRequest-Methode schreiben Sie Ihren Text grundsätzlich in context.Response. Sie müssen auch einen Content-Disposition http-Header hinzufügen:

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

Denken Sie auch daran, die ContentType einzustellen:

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

Nur eine kleine Ergänzung zu den anderen Antworten. Am Ende eines Downloads führe ich aus:

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

Ich habe gelernt, dass der Download sonst manchmal nicht erfolgreich abgeschlossen wird. 

Dieses Google Groups-Posting stellt auch fest, dass Response.End eine ThreadAbortException auslöst, die Sie mit der CompleteRequest-Methode vermeiden könnten.

2
Uwe Keim

Ich hatte viele Probleme damit. Finnaly hat eine Lösung gefunden, die immer zu funktionieren scheint.

In den meisten Fällen wird der Benutzer auf eine Schaltfläche für den Download klicken. An diesem Punkt empfiehlt es sich, die Seite wieder an dieselbe Stelle umzuleiten. Fügen Sie der URL einen Parameter hinzu, den Sie abrufen und lesen können. 

beispiel (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
Mike

Erweiterung der @Vinicious-Antwort.

Ich hatte Daten, die Kommas enthalten könnten. Die gebräuchlichste Lösung besteht darin, diesen Datenbestandteilen zu entgehen, indem sie in Anführungszeichen eingeschlossen werden, und dabei sicherzustellen, dass auch Anführungszeichen verwendet werden, die möglicherweise Teil der Daten sind.

Eine Unebenheit, gegen die ich gekommen bin, und eine Warnung beim Schreiben von CSV. Excel wird Sie nicht mögen, wenn Sie Leerzeichen hinter Ihre Kommas setzen. Lösung für mein Problem von Superuser-Antwort gefunden

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;
    }
}

Unten wird ein Problem für Excel verursacht. In Excel wird das erste Zitat Teil der Daten und folglich getrennt vom eingebetteten Komma. Räume schlecht.

 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)));
0
eric1825