Asp.NetはExcelファイルを生成してダウンロードする(更新:ファイルではなく迅雷ダウンロードページを使用する問題を解決する)

10164 ワード

ここではサービス側でExcelファイルを作成し、ファイルアドレスを利用してダウンロードする方法を採用しています.
Excelファイルを生成する方法については、「元」を参照してください.Net Excelファイルの作成(データの挿入、フォーマットの変更、グラフの生成)方法
まずResponseを使ってみます.WriteFileの方法:
FileInfo fi = new FileInfo(excelFile);//excelFile           
HttpResponse contextResponse = HttpContext.Current.Response;
contextResponse.Clear();
contextResponse.Buffer = true;
contextResponse.Charset = "GB2312"; //                
contextResponse.AppendHeader("Content-Disposition", String.Format("attachment;filename={0}", excelName)); //           
contextResponse.AppendHeader("Content-Length", fi.Length.ToString());
contextResponse.ContentEncoding = Encoding.Default;
contextResponse.ContentType = "application/ms-excel";//         excel  。 

contextResponse.WriteFile(fi.FullName);
contextResponse.Flush();
contextResponse.End();

最初の行のexcelFileは、サーバ上のExcelファイルのアドレスです.たとえば、「C:WebsiteExcelxx.xlsx」などです.
この方法もネット上で一般的に提供されている方法ですが、実際の操作では、意向がないという問題が発生しています.
Chromeの下で
すべて正常で、ExcelファイルはChromeのデフォルトのダウンロードフォルダに直接ダウンロードされます.
Firefoxで
FlashGotプラグインがインストールされているため、アプリケーションのダウンロードツールが先に選択されます.
ここでは正常に表示され、「ファイルの保存」を選択すると、Excelファイルもデフォルトフォルダに保存されますが、サードパーティ製ダウンロードツール(迅雷など)を試用すると、次のようなウィンドウが表示されます.
 
 
Webサイトの欄に注意すると、実際のページアドレスの後にView State情報が追加され、保存名もExcelファイル自体の名前ではなく、ページの名前になります.
OKをクリックすると、ダウンロードされたファイルが実際のファイルになります(先に.zipファイルになり、実際のファイルになる場合があります)
IE 7で
保存ダイアログを弾き出すことができて、ファイルは正常で、同様に雷をインストールしたため、点が保存する時、雷のダウンロードダイアログを弾き出すことができて、Firefoxの下と異なって、ウェブサイトの後ろにView Stateの情報がありません.
 
 
 
 
 
ポイントOK、ダウンロードされたページファイル:
もし迅雷のダウンロードのダイアログボックスの中でクリックしてキャンセルするならば、IEのダウンロードを使うことができて、ここのファイルはまた正しいです:
迅雷はダウンロードダイアログのURLに基づいてダウンロードを再要求した疑いがあり、要求を開始したページとは関係なく、IEはView State情報を迅雷に伝えず、ダウンロードしたファイルが欲しいExcelページではない.
その後、セグメントダウンロードの方法を試みたが、実際には無効だった.迅雷はあなたが提供したダウンロードメカニズムをまったく気にしないため、Firefoxの下で迅雷を呼び出すと、セグメントダウンロードのViewstateにはExcelファイルの完全な情報が含まれていないため、迅雷がダウンロードしたのも欠けているファイルだった.
最後に最も古い解決方法しか採用できない:Response.Redirect()は、実際のファイルアドレスに移動します.
FileInfo fi = new FileInfo(excelFile);
HttpResponse contextResponse = HttpContext.Current.Response;
contextResponse.Redirect(string.Format("~/Template/{0}", excelName), false);

これで3つのブラウザの下でテストが正常になりました.実際のファイルのアドレスが要求されているので、迅雷に表示されているのも実際のファイルのアドレスです.ダウンロードで問題は発生しません.しかし,これはクライアントユーザファイルの実際のアドレスを通知することに相当し,プライバシー性が悪い.しかし、ここではあまりプライバシーを必要とせず、ファイルは一定時間後に削除されるので、あまり問題ではありません.
 
上は初めて考えた結果ですが、やはり怠け者のようです・・・
後で考えてみると、実際にURLを再要求するたびに、Excelファイルを生成できるURLを迅雷に伝えるべきだ.
つまり、「Excelの生成」ボタンをクリックしたときに、別のExportページに移動し、このページのPage_Loadメソッドでは、Excelファイルを生成し、Excelファイルをダウンロードする手順を完了します.
String fileName = Request.QueryString["FileName"];
String exportName = Request.QueryString["Export"];
if(fileName != null)
{
    ExportManger.CreateExcel(fileName);//        Excel  。
    Response.Redirect(String.Format("{0}?Export={1}",Request.Path.ToString(),fileName));//       , Query    Export。
}
else if(exportName != null)
{
    ExportManger.ExportExcel(exportName);//  Excel  。
}

ここのページは2回ジャンプして、1回目はExcelを生成して、2回目はExcelをダウンロードします.
2回ジャンプしたのは、雷が最後のURLをキャプチャし、生成とダウンロードを一緒に行うと、雷がダウンロードされたときにもう一度Excelファイルを生成することを繰り返すからです.ExcelファイルのコードExportMangerをダウンロードします.ExportExcel(exportName)は、本明細書の冒頭で説明するResponseを使用する.Writeメソッドは、セグメントでダウンロードする方法もあります.
if(fi.Length > 0)
{
    FileStream sr = new FileStream(fi.FullName,System.IO.FileMode.Open,System.IO.FileAccess.Read, System.IO.FileShare.Read);
    int size = 1024;//        。
    for (int i = 0; i < fi.Length / size + 1; i++)
    {
        byte[] buffer = new byte[size];
        int length = sr.Read(buffer, 0, size);
        contextResponse.OutputStream.Write(buffer, 0, length);
    }
    sr.Close();
}
else
{
    contextResponse.WriteFile(fi.FullName);
}

ここでの結果は,一度だけExcelを生成してサーバに保持し,以降はダウンロードのたびに「Export」というパラメータを用いて同じファイルをダウンロードする.では、必要なファイルが使い捨てで、ダウンロードするたびに再生成する必要がある場合は、Exportページのダウンロードと生成を一緒にするだけです.そして冒頭のResponse.Writeメソッドは最終的に次のようになります.
contextResponse.Flush();
fi.Delete();
contextResponse.End();
              ,     。

これにより、ダウンロードツールを用いたダウンロードができないという問題を解決するとともに、サーバファイルアドレスのプライバシーを保護し、大きなファイルをセグメント化して書き込むことができ、生成したファイルを必要に応じてサーバスペースを占有することなく即時に削除することができる.