web-dev-qa-db-ja.com

EPPlusでExcelファイルを生成できません

EPPlusを使用してExcelファイルを生成しようとすると、Excelから次のエラーメッセージが表示されます。

ファイル形式またはファイル拡張子が無効なため、Excelはファイル 'myfilename.xlsx'を開くことができません。ファイルが破損していないこと、およびファイル拡張子がファイルの形式と一致していることを確認してください。

これが私のコードです:

public ActionResult Index()
{
    using (ExcelPackage package = new ExcelPackage())
    {
        // I populate the worksheet here.  I'm 90% sure this is fine
        // because the stream file size changes based on what I pass to it.

        var stream = new MemoryStream();
        package.SaveAs(stream);

        string fileName = "myfilename.xlsx";
        string contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";

        var cd = new System.Net.Mime.ContentDisposition
        {
            Inline = false,
            FileName = fileName
        };
        Response.AppendHeader("Content-Disposition", cd.ToString());
        return File(stream, contentType, fileName);
    }
}

私が間違っていることについて何か考えはありますか?

14
Matt Grande

ストリームの位置をリセットするだけです。 _stream.Position = 0;_

あなたResponseに直接書き込むべきではありません、それはMVCの方法ではありません。正しいMVCパイプラインに従わず、コントローラーのアクションコードをResponseオブジェクトに緊密に結合します。

File()の3番目のパラメーターとしてファイル名を追加すると、MVCは正しい_Content-Disposition_ヘッダーを自動的に追加します...したがって、手動で追加する必要はありません。

それの不足は、これはあなたが望むものです:

_public ActionResult Index()
{
    using (ExcelPackage package = new ExcelPackage())
    {
        // I populate the worksheet here.  I'm 90% sure this is fine
        // because the stream file size changes based on what I pass to it.

        var stream = new MemoryStream();
        package.SaveAs(stream);

        string fileName = "myfilename.xlsx";
        string contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";

        stream.Position = 0;
        return File(stream, contentType, fileName);
    }
}
_
28
Charlino

あなたのコードは、streamHttpResponseに書き込まれていることを示していません-おそらくあなたが投稿していないFileメソッドで行われています。

動作する1つの方法は、次のとおりです。

Response.Clear();
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.AddHeader(
            "content-disposition", String.Format(CultureInfo.InvariantCulture, "attachment; filename={0}", fileName));
Response.BinaryWrite(package.GetAsByteArray());
Response.End();
10
Joe

ジョーの答えと同様に、私はまだResponse.ClearHeaders()を呼び出さなければなりませんでした。

   protected void btnDownload_Click(object sender, EventArgs e)
   {

       ExcelPackage pck = new ExcelPackage();
       var ws = pck.Workbook.Worksheets.Add("Sample2");

       ws.Cells["A1"].Value = "Sample 2";
       ws.Cells["A1"].Style.Font.Bold = true;
       var shape = ws.Drawings.AddShape("Shape1", eShapeStyle.Rect);
       shape.SetPosition(50, 200);
       shape.SetSize(200, 100);
       shape.Text = "Sample 2 outputs the sheet using the Response.BinaryWrite method";
       Response.Clear();    
       Response.ClearHeaders();
       Response.BinaryWrite(pck.GetAsByteArray());
       Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
       Response.AddHeader("content-disposition", "attachment;  filename=Sample2.xlsx");
       Response.End();
  }
2
Ewald Stieger