简体   繁体   English

在ASP.NET / C#中使用EPPlus损坏Excel文件输出

[英]Corrupt Excel file output using EPPlus in ASP.NET / C#

I'm trying to use EPPlus to create a report inside an ASP.NET application. 我正在尝试使用EPPlus在ASP.NET应用程序中创建报告。 I tried using the code provided into samples package but I'm having some troubles. 我尝试使用样本包中提供的代码,但遇到了一些麻烦。

The following code is executed without error: 以下代码执行无误:

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

        _ws.Cells["A1"].Value = "COD. CONV.";
        _ws.Cells["A1"].Style.Font.Bold = true;
        _ws.Cells["A1"].Style.Border.Bottom.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thick;
        _ws.Cells["B1"].Value = "RAGIONE SOCIALE";
        _ws.Cells["B1"].Style.Font.Bold = true;
        _ws.Cells["B1"].Style.Border.Bottom.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thick;
        _ws.Cells["C1"].Value = "COMMERCIALE A";
        _ws.Cells["C1"].Style.Font.Bold = true;
        _ws.Cells["C1"].Style.Border.Bottom.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thick;
        _ws.Cells["D1"].Value = "PROVINCIA";
        _ws.Cells["D1"].Style.Font.Bold = true;
        _ws.Cells["D1"].Style.Border.Bottom.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thick;
        _ws.Cells["E1"].Value = "ZONA";
        _ws.Cells["E1"].Style.Font.Bold = true;
        _ws.Cells["E1"].Style.Border.Bottom.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thick;
        _ws.Cells["F1"].Value = "TELEFONO";
        _ws.Cells["F1"].Style.Font.Bold = true;
        _ws.Cells["F1"].Style.Border.Bottom.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thick;
        _ws.Cells["G1"].Value = "EMAIL";
        _ws.Cells["G1"].Style.Font.Bold = true;
        _ws.Cells["G1"].Style.Border.Bottom.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thick;

        int _i = 2;

        foreach (DataRow _drRow in dtAnagrafiche.Rows)
        {
            _ws.Cells["A"+_i.ToString()].Value = _drRow["codice"].ToString();
            _ws.Cells["B"+_i.ToString()].Value = _drRow["Nome"].ToString();
            _ws.Cells["C"+_i.ToString()].Value = "";
            _ws.Cells["D"+_i.ToString()].Value = _drRow["Provincia"].ToString();
            _ws.Cells["E"+_i.ToString()].Value = _drRow["Zona"].ToString();
            _ws.Cells["F"+_i.ToString()].Value = _drRow["Telefono"].ToString();
            _ws.Cells["G"+_i.ToString()].Value = _drRow["Email"].ToString();

            _i++;
        }

        Response.BinaryWrite(_pck.GetAsByteArray());
        Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
        Response.AddHeader("content-disposition", "attachment;  filename=Lista_Anagrafiche.xlsx");

but the resulting file cannot be opened by Microsoft office if not 'recovered', other MS Office compatibile applications (ie OpenOffice) cannot open the file. 但是如果未“恢复”,则Microsoft Office无法打开生成的文件,其他MS Office兼容应用程序(例如OpenOffice)也无法打开该文件。

I can provide the output file if needed. 如果需要,我可以提供输出文件。

https://drive.google.com/file/d/0B-lPXYt7laDrbUFKbFZEWEwxckk/view?usp=sharing https://drive.google.com/file/d/0B-lPXYt7laDrbUFKbFZEWEwxckk/view?usp=sharing

BTW I'm using the last (4.0.5) EPPlus package obtained trough nuget, and running it in ASP.NET 4.5 web appplication. 顺便说一句,我使用的是最后一个(4.0.5)EPPlus程序包,它通过nuget获得,并在ASP.NET 4.5 Web应用程序中运行。

You're missing a call to Response.End() . 您缺少对Response.End()的调用。 Without this, you're sending the response with the binary payload (the .xlsx file), which is coming over correctly, then the .aspx page that you're coding this under is being sent in the payload as well. 否则,您将发送带有二进制有效负载(.xlsx文件)的响应,该响应将正确传递,然后在有效负载中也将发送您正在其下编码的.aspx页面。 Proof here as shown in a hex editor. 如十六进制编辑器所示,此处的证明。

    Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
    Response.AddHeader("content-disposition", "attachment;  filename=Lista_Anagrafiche.xlsx");
    Response.BinaryWrite(_pck.GetAsByteArray());
    Response.End();

Should do the trick. 应该做到的。

As an aside, I would suggest saving the file, then doing a Response.Redirect() to the URL of the file, instead, but that's unrelated to this specific issue. 顺便说一句,我建议保存文件,然后对文件的URL执行Response.Redirect() ,但这与此特定问题无关。

EDIT: Notably, in normal circumstances, I would suggest avoiding Response.End() , but, that is the quickest way to solve the problem you've coded yourself into. 编辑:值得注意的是,在正常情况下,我建议避免使用Response.End() ,但这是解决您自己编写的问题的最快方法。 I would suggest looking for better ways to serve up these files in general, as per my above suggestion to Response.Redirect() to a saved location of the file. 我建议根据我上面对Response.Redirect()建议,寻求一种更好的方式来处理这些文件,并将其保存到文件的位置。

Try changing your code to the following notice how I am using the string.Format function to create the filename + extension 尝试将代码更改为以下注意事项,我如何使用string.Format函数创建文件名和扩展名

you need to declare a constant fileName. 您需要声明一个常量fileName。 if worse comes to worse change the .xlsx to .xls 如果情况变得更糟,请将.xlsx更改为.xls

Response.Clear();    
Response.ClearHeaders();
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.AppendHeader("Content-Disposition", string.Format("attachment;filename={0}.xlsx", fileName));
Response.BinaryWrite(_pck.GetAsByteArray());
Response.Flush();
Response.End();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM