メモリ内のテキストファイルに書き込み、そのファイルをハードディスクに保存せずにダウンロードしようとしています。私は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();
データをメモリに保存してから応答ストリームに送信する代わりに、応答ストリームに直接書き込むことができます。
using (StreamWriter writer = new StreamWriter(Response.OutputStream, Encoding.UTF8)) {
writer.Write("This is the content");
}
この例ではUTF-8エンコーディングを使用していますが、他のエンコーディングを使用している場合は変更する必要があります。
これは私のために解決しました:
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();
基本的に、 IHttpHandler
インターフェイスを実装してHttpHandlerを作成します。 ProcessRequest
メソッドでは、基本的にcontext.Response
にテキストを書き込むだけです。 Content-Disposition
httpヘッダーも追加する必要があります。
context.Response.AddHeader("Content-Disposition", "attachment; filename=YourFileName.txt");
ContentType
を設定することも忘れないでください:
context.Response.ContentType = "text/plain";
他の答えへのほんの小さな追加。ダウンロードの最後に実行します:
context.Response.Flush();
context.ApplicationInstance.CompleteRequest();
そうしないと、ダウンロードが正常に完了しない場合があることがわかりました。
このGoogleグループの投稿 は、Response.End
はThreadAbortException
をスローします。これはCompleteRequest
メソッドを使用することで回避できます。
これには多くの問題がありました。 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");
}
@Vinicious回答の拡張。
カンマを含めることができるデータがありました。一般的な解決策は、データの一部である可能性のある引用符もエスケープすることを確認しながら、そのデータを引用符で囲むことでそのデータをエスケープすることです。
CSVを記述する際の1つの摩擦と警告により、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)));