Создать текстовый файл и скачать - PullRequest
26 голосов
/ 31 декабря 2010

Я пытаюсь записать текстовый файл в памяти, а затем загрузить этот файл без сохранения файла на жестком диске.Я использую StringWriter для записи содержимого:

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

Как мне загрузить этот файл?

РЕДАКТИРОВАТЬ: Это была комбинация ответов, которая дала мне мое решение.Вот оно:

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

Ответы [ 7 ]

17 голосов
/ 03 октября 2013

Это решено для меня:

        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();     
15 голосов
/ 31 декабря 2010

Вместо того, чтобы хранить данные в памяти и затем отправлять их в поток ответов, вы можете записать их непосредственно в поток ответов:

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

В примере используется кодировка UTF-8, вам следует изменитьчто если вы используете другую кодировку.

5 голосов
/ 31 декабря 2010

По сути, вы создаете HttpHandler, реализуя интерфейс IHttpHandler.В методе ProcessRequest вы просто пишете свой текст в context.Response.Вам также необходимо добавить Content-Disposition http заголовок:

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

Также не забудьте установить ContentType:

context.Response.ContentType = "text/plain";
2 голосов
/ 31 декабря 2010

Просто небольшое дополнение к другим ответам. В самом конце загрузки я выполняю:

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

Я узнал, что в противном случае загрузка иногда не завершается успешно.

В этой публикации групп Google также отмечается, что Response.End выдает ThreadAbortException, которого можно избежать, используя метод CompleteRequest.

0 голосов
/ 07 февраля 2017

Расширение @Vinicious ответа.

У меня были данные, которые могли содержать запятые.Распространенное решение состоит в том, чтобы избавиться от этого фрагмента данных, заключив его в кавычки, а также избежать кавычек, которые также могут быть частью данных.Excel не понравится вам, если вы поставите пробелы после запятых. обнаружил решение моей проблемы из ответа суперпользователя

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

Ниже приведу проблему для Excel.В Excel первая цитата станет частью данных и, следовательно, будет разделена запятой.Места плохие.

 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 голосов
/ 04 февраля 2016

У меня было много проблем с этим.Finnaly нашел решение, которое, кажется, работает каждый раз.

В большинстве случаев пользователь нажимает кнопку для загрузки.На этом этапе лучше перенаправить страницу обратно в то же место.добавить параметр в URL, который вы можете взять и прочитать.

пример (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 голосов
/ 31 декабря 2010

Это очень просто, и ответ можно увидеть в этой статье Microsoft KB: Как записать двоичные файлы в браузер, используя ASP.NET и C #

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...