web-dev-qa-db-ja.com

Response.TransmitFile()を使用して.xlsxファイルをダウンロードします

私は、Excelスプレッドシートをサーバー側で生成し、それをユーザーにダウンロードするコードに取り組んでいます。 ExcelPackage を使用してファイルを生成しています。

世代はうまく機能しています。生成されたファイルをExcel2007を使用して問題なく開くことができます。しかし、Response.TransmitFile()でファイルをダウンロードするのに問題があります。

現在、次のコードがあります。

//Generate the file using ExcelPackage
string fileName = generateExcelFile(dataList, "MyReportData");

Response.AddHeader("content-disposition", "attachment;filename=FileName.xls");
Response.ContentType = "application/vnd.xls"
Response.Charset = "";
Response.TransmitFile(fileName);

Excel 2007が上記のようにダウンロードされたファイルを開くと、「ファイル形式が拡張子と一致しません」という警告が表示されます。警告を過ぎてクリックすると、Excelはファイルの生のxmlコンテンツを表示します。

ファイル拡張子を変更すると、

Response.AddHeader("content-disposition", "attachment;filename=FileName.xlsx");

Excel 2007では、「Excelでファイル内の読み取り不可能なコンテンツが見つかりました」というエラーが表示され、その後にWeb上でコンバーターを見つけるためのダイアログが表示されます。このダイアログで「いいえ」をクリックすると、Excelデータをロードできます。

また、application/vnd.ms-Excelapplication/vnd.openxmlformats-officedocument.spreadsheetml.sheetなどのさまざまなMIMEタイプを、.xlsおよび.xlsxのファイル拡張子と組み合わせて実験しました。すべての組み合わせにより、上記の2つの動作のいずれかになります。

このシナリオで使用するファイル拡張子とMIMEタイプの正しい組み合わせは何ですか?不適切なMIMEタイプまたは拡張子以外に、この失敗を引き起こす可能性のあるものは他にありますか?

参考までに、これはVisualStudioの組み込み開発Webサーバーで発生しています。私はまだIISでこれを試していません。

15
Odrade

あなたのアプローチに何か問題があるとは断言できませんが、似たようなことをしたときの観察結果をいくつか紹介します。

ヘッダーはパスカルケースです。ほとんどのブラウザーは気にする必要はありませんが、content-dispositionをContent-Dispositionに変更します。文字セットを変更する必要はなく、関連性もありません。コンテンツタイプは問題ないはずです。実際にファイルのコンテンツである場合は、application/vnd.openxmlformats-officedocument.spreadsheetml.sheetと.xlsxのみを使用します。それ以外の場合は、application /vnd.ms-Excelと.xlsを使用します。

考慮すべきもう1つのことは、ブラウザーにContent-Lengthを送信することです。

Response.AddHeader("Content-Length", new System.IO.FileInfo("FileName.xlsx").Length);

また、複数のブラウザでこれを試しましたか?それがベンダー固有の問題かどうか疑問に思っています。

最後の努力として、Content-Typeをapplication/octet-streamに設定できます。どのブラウザーでもダウンロードを提案する必要があります。ほとんどのブラウザーでは、拡張機能に基づいてダウンロードした後に開くことができます。

16
Brad Nabholz

これを使って

HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment;filename=\"filename + ".Zip" + "\"");
                Response.TransmitFile(zipPath);
                Response.Flush();
                Response.Close();
                Response.End();

あなたのコードには

Response.AddHeader("content-disposition", "attachment;filename=\FileName.xlsx\");
3
mohsen nikzadeh

このようにしてみてください

public void DataTableToExcel(DataTable dt, string Filename)
{
    MemoryStream ms = DataTableToExcelXlsx(dt, "Sheet1");
    ms.WriteTo(HttpContext.Current.Response.OutputStream);
    HttpContext.Current.Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
    HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment;filename=" + Filename);
    HttpContext.Current.Response.StatusCode = 200;
    HttpContext.Current.Response.End();
}

public static MemoryStream DataTableToExcelXlsx(DataTable table, string sheetName)
{
    MemoryStream result = new MemoryStream();
    ExcelPackage excelpack = new ExcelPackage();
    ExcelWorksheet worksheet = excelpack.Workbook.Worksheets.Add(sheetName);
    int col = 1;
    int row = 1;
    foreach (DataColumn column in table.Columns)
    {
        worksheet.Cells[row, col].Value = column.ColumnName.ToString();
        col++;
    }
    col = 1;
    row = 2;
    foreach (DataRow rw in table.Rows)
    {
        foreach (DataColumn cl in table.Columns)
        {
            if (rw[cl.ColumnName] != DBNull.Value)
                worksheet.Cells[row, col].Value = rw[cl.ColumnName].ToString();
            col++;
        }
        row++;
        col = 1;
    }
    excelpack.SaveAs(result);
    return result;
}
0
Karthikeyan P